Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
NavierStokesAssFE_def.hpp
1#ifndef NAVIERSTOKESASSFE_def_hpp
2#define NAVIERSTOKESASSFE_def_hpp
3#include "NavierStokesAssFE_decl.hpp"
4
13
14/*void sxOne2D(double* x, double* res, double t, double* parameter){
15
16 res[0] = 1.;
17 res[1] = 0.;
18 return;
19}
20
21void syOne2D(double* x, double* res, double t, double* parameter){
22
23 res[0] = 0.;
24 res[1] = 1.;
25
26 return;
27}
28void sDummyFunc(double* x, double* res, double t, double* parameter){
29
30 return;
31}
32
33double OneFunction(double* x, int* parameter)
34{
35 return 1.0;
36}*/
37
38namespace FEDD {
39
40
41
42template<class SC,class LO,class GO,class NO>
43NavierStokesAssFE<SC,LO,GO,NO>::NavierStokesAssFE( const DomainConstPtr_Type &domainVelocity, std::string FETypeVelocity, const DomainConstPtr_Type &domainPressure, std::string FETypePressure, ParameterListPtr_Type parameterList ):
44NonLinearProblem<SC,LO,GO,NO>( parameterList, domainVelocity->getComm() ),
45A_(),
46pressureIDsLoc(new vec_int_Type(2)),
47u_rep_(),
48p_rep_(),
49viscosity_element_() // Added here also viscosity field
50{
51
52 this->nonLinearTolerance_ = this->parameterList_->sublist("Parameter").get("relNonLinTol",1.0e-6);
53 this->initNOXParameters();
54
55 this->addVariable( domainVelocity , FETypeVelocity , "u" , domainVelocity->getDimension());
56 this->addVariable( domainPressure , FETypePressure , "p" , 1);
57 this->dim_ = this->getDomain(0)->getDimension();
58
59 u_rep_ = Teuchos::rcp( new MultiVector_Type( this->getDomain(0)->getMapVecFieldRepeated() ) );
60
61 p_rep_ = Teuchos::rcp( new MultiVector_Type( this->getDomain(1)->getMapRepeated() ) );
62
63 if (parameterList->sublist("Parameter").get("Calculate Coefficients",false)) {
64 vec2D_dbl_ptr_Type vectmpPointsPressure = domainPressure->getPointsUnique();
65 vec2D_dbl_Type::iterator it;
66 int front = -1;
67 int back = -1;
68 if (domainPressure->getDimension() == 2) {
69 it = find_if(vectmpPointsPressure->begin(), vectmpPointsPressure->end(),
70 [&] (const std::vector<double>& a){
71 if (a.at(0) >= 0.15-1.e-12 && a.at(0) <= 0.15+1.e-12
72 && a.at(1) >= 0.2-1.e-12 && a.at(1) <= 0.2+1.e-12) {
73 return true;
74 }
75 else {
76 return false;
77 }
78 });
79
80 if (it != vectmpPointsPressure->end()) {
81 front = distance(vectmpPointsPressure->begin(),it);
82 }
83 it = find_if(vectmpPointsPressure->begin(), vectmpPointsPressure->end(),
84 [&] (const std::vector<double>& a){
85 if (a.at(0) >= 0.25-1.e-12 && a.at(0) <= 0.25+1.e-12
86 && a.at(1) >= 0.2-1.e-12 && a.at(1) <= 0.2+1.e-12) {
87 return true;
88 }
89 else {
90 return false;
91 }
92 });
93
94 if (it != vectmpPointsPressure->end()) {
95 back = distance(vectmpPointsPressure->begin(),it);
96 }
97 pressureIDsLoc->at(0) = front;
98 pressureIDsLoc->at(1) = back;
99 }
100 else if(domainPressure->getDimension() == 3){
101#ifdef ASSERTS_WARNINGS
102 MYASSERT(false,"Not implemented to calc coefficients in 3D!");
103#endif
104 }
105 }
106
107}
108
109template<class SC,class LO,class GO,class NO>
110void NavierStokesAssFE<SC,LO,GO,NO>::info(){
111 this->infoProblem();
112 this->infoNonlinProblem();
113}
114
115template<class SC,class LO,class GO,class NO>
116void NavierStokesAssFE<SC,LO,GO,NO>::assemble( std::string type ) const{
117
118 if (type=="") {
119 if (this->verbose_)
120 std::cout << "-- Assembly Navier-Stokes ... " << std::endl;
121
122 assembleConstantMatrices();
123
124 if (this->verbose_)
125 std::cout << "done -- " << std::endl;
126 }
127 else
128 reAssemble( type );
129
130};
131
132template<class SC,class LO,class GO,class NO>
133void NavierStokesAssFE<SC,LO,GO,NO>::assembleConstantMatrices() const{
134
135 if (this->verbose_)
136 std::cout << "-- Assembly constant matrices Navier-Stokes ... " << std::flush;
137
138 double viscosity = this->parameterList_->sublist("Parameter").get("Viscosity",1.);
139 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
140
141 // Egal welcher Wert, da OneFunction nicht von parameter abhaengt
142 int* dummy;
143
144 A_.reset(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
145
146 MapConstPtr_Type pressureMap;
147 if ( this->getDomain(1)->getFEType() == "P0" )
148 pressureMap = this->getDomain(1)->getElementMap();
149 else
150 pressureMap = this->getDomain(1)->getMapUnique();
151
152 if (this->system_.is_null())
153 this->system_.reset(new BlockMatrix_Type(2));
154
155 if (this->residualVec_.is_null())
156 this->residualVec_.reset(new BlockMultiVector_Type(2));
157
158 MatrixPtr_Type B(new Matrix_Type( pressureMap, this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
159 MatrixPtr_Type BT(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(1)->getDimension() * this->getDomain(1)->getApproxEntriesPerRow() ) );
160
161
162 this->system_->addBlock(A_,0,0);
163 this->system_->addBlock(BT,0,1);
164 this->system_->addBlock(B,1,0);
165
166 this->feFactory_->assemblyNavierStokes(this->dim_, this->getDomain(0)->getFEType(), this->getDomain(1)->getFEType(), 2, this->dim_,1,u_rep_,p_rep_,this->system_,this->residualVec_,this->coeff_, this->parameterList_,false, "Jacobian", true/*call fillComplete*/);
167
168 if ( !this->getFEType(0).compare("P1") ) {
169 MatrixPtr_Type C(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
170 this->feFactory_->assemblyBDStabilization( this->dim_, "P1", C, true);
171 C->resumeFill();
172 C->scale( -1. / ( viscosity * density ) );
173 C->fillComplete( pressureMap, pressureMap );
174
175 this->system_->addBlock( C, 1, 1 );
176 }
177
178
179
180
181#ifdef FEDD_HAVE_TEKO
182 if ( !this->parameterList_->sublist("General").get("Preconditioner Method","Monolithic").compare("Teko") ) {
183 if (!this->parameterList_->sublist("General").get("Assemble Velocity Mass",false)) {
184 MatrixPtr_Type Mvelocity(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getApproxEntriesPerRow() ) );
185 //
186 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(0), "Vector", Mvelocity, true );
187 //
188 this->getPreconditionerConst()->setVelocityMassMatrix( Mvelocity );
189 if (this->verbose_)
190 std::cout << "\nVelocity mass matrix for LSC block preconditioner is assembled." << std::endl;
191 } else {
192 if (this->verbose_)
193 std::cout << "\nVelocity mass matrix for LSC block preconditioner not assembled." << std::endl;
194 }
195 }
196#endif
197 std::string precType = this->parameterList_->sublist("General").get("Preconditioner Method","Monolithic");
198 if ( precType == "Diagonal" || precType == "Triangular" ) {
199 MatrixPtr_Type Mpressure(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
200
201 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(1), "Scalar", Mpressure, true );
202 SC kinVisco = this->parameterList_->sublist("Parameter").get("Viscosity",1.);
203 Mpressure->scale(-1./kinVisco);
204 this->getPreconditionerConst()->setPressureMassMatrix( Mpressure );
205 }
206 if (this->verbose_)
207 std::cout << " Call Reassemble FixedPoint and Newton to allocate the Matrix pattern " << std::endl;
208
209 // this->reAssemble("FixedPoint");
210 this->reAssemble("Newton");
211
212 if (this->verbose_)
213 std::cout << "done -- " << std::endl;
214
215};
216
217
218template<class SC,class LO,class GO,class NO>
219void NavierStokesAssFE<SC,LO,GO,NO>::reAssemble( MatrixPtr_Type& massmatrix, std::string type ) const
220{
221
222}
223
224
225
226template<class SC,class LO,class GO,class NO>
227void NavierStokesAssFE<SC,LO,GO,NO>::reAssemble(std::string type) const {
228
229
230 if (this->verbose_)
231 std::cout << "-- Reassembly Navier-Stokes ("<< type <<") ... " << std::flush;
232
233 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
234
235 MatrixPtr_Type ANW = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
236
237 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
238 u_rep_->importFromVector(u, true);
239
240 MultiVectorConstPtr_Type p = this->solution_->getBlock(1);
241 p_rep_->importFromVector(p, true);
242
243
244 if (type=="Rhs") {
245
246 this->system_->addBlock(ANW,0,0);
247
248 this->feFactory_->assemblyNavierStokes(this->dim_, this->getDomain(0)->getFEType(), this->getDomain(1)->getFEType(), 2, this->dim_,1,u_rep_,p_rep_,this->system_, this->residualVec_,this->coeff_,this->parameterList_, true, "FixedPoint", true); // We can also change that to "Jacobian"
249 this->feFactory_->assemblyNavierStokes(this->dim_, this->getDomain(0)->getFEType(), this->getDomain(1)->getFEType(), 2, this->dim_,1,u_rep_,p_rep_,this->system_, this->residualVec_,this->coeff_,this->parameterList_, true, "Rhs", true);
250
251 }
252 else if (type=="FixedPoint" ) {
253
254 this->system_->addBlock(ANW,0,0);
255 this->feFactory_->assemblyNavierStokes(this->dim_, this->getDomain(0)->getFEType(), this->getDomain(1)->getFEType(), 2, this->dim_,1,u_rep_,p_rep_,this->system_, this->residualVec_,this->coeff_,this->parameterList_, true, "FixedPoint", true);
256 }
257 else if(type=="Newton"){
258
259 this->system_->addBlock(ANW,0,0);
260 this->feFactory_->assemblyNavierStokes(this->dim_, this->getDomain(0)->getFEType(), this->getDomain(1)->getFEType(), 2, this->dim_,1,u_rep_,p_rep_,this->system_,this->residualVec_, this->coeff_,this->parameterList_, true,"Jacobian", true);
261
262 }
263
264 this->system_->addBlock(ANW,0,0);
265
266 if (this->verbose_)
267 std::cout << "done -- " << std::endl;
268
269
270}
271
272
273template<class SC,class LO,class GO,class NO>
274void NavierStokesAssFE<SC,LO,GO,NO>::calculateNonLinResidualVec(std::string type, double time) const{
275
276 //this->reAssemble("FixedPoint");
277 this->reAssemble("Rhs");
278
279 // We need to additionally add the residual component for the stabilization block, as it is not part of the AssembleFE routines and calculated externally here.
280 if(this->getDomain(0)->getFEType() == "P1"){
281
282 MultiVectorPtr_Type residualPressureTmp = Teuchos::rcp(new MultiVector_Type( this->getDomain(1)->getMapUnique() ));
283
284 this->system_->getBlock(1,1)->apply( *(this->solution_->getBlock(1)), *residualPressureTmp);
285
286 this->residualVec_->getBlockNonConst(1)->update(1.,*residualPressureTmp,1.);
287
288
289 }
290 // We need to account for different parameters of time discretizations here
291 // This is ok for bdf with 1.0 scaling of the system. Would be wrong for Crank-Nicolson - might be ok now for CN
292
293 /*if (this->coeff_.size() == 0)
294 this->system_->apply( *this->solution_, *this->residualVec_ );
295 else
296 this->system_->apply( *this->solution_, *this->residualVec_, this->coeff_ );*/
297
298 if (!type.compare("standard")){
299 this->residualVec_->update(-1.,*this->rhs_,1.);
300// if ( !this->sourceTerm_.is_null() )
301// this->residualVec_->update(-1.,*this->sourceTerm_,1.);
302 // this might be set again by the TimeProblem after addition of M*u
303 this->bcFactory_->setVectorMinusBC( this->residualVec_, this->solution_, time );
304
305 }
306 else if(!type.compare("reverse")){
307 this->residualVec_->update(1.,*this->rhs_,-1.); // this = -1*this + 1*rhs
308// if ( !this->sourceTerm_.is_null() )
309// this->residualVec_->update(1.,*this->sourceTerm_,1.);
310 // this might be set again by the TimeProblem after addition of M*u
311 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );
312
313 }
314
315}
316
317template<class SC,class LO,class GO,class NO>
318void NavierStokesAssFE<SC,LO,GO,NO>::calculateNonLinResidualVecWithMeshVelo(std::string type, double time, MultiVectorPtr_Type u_minus_w, MatrixPtr_Type P) const{
319
320
321 // this->reAssembleFSI( "FixedPoint", u_minus_w, P );
322
323 // We need to account for different parameters of time discretizations here
324 // This is ok for bdf with 1.0 scaling of the system. Would be wrong for Crank-Nicolson
325
326 this->system_->apply( *this->solution_, *this->residualVec_ );
327// this->residualVec_->getBlock(0)->writeMM("Ax.mm");
328// this->rhs_->getBlock(0)->writeMM("nsRHS.mm");
329 if (!type.compare("standard")){
330 this->residualVec_->update(-1.,*this->rhs_,1.);
331 if ( !this->sourceTerm_.is_null() )
332 this->residualVec_->update(-1.,*this->sourceTerm_,1.);
333 }
334 else if(!type.compare("reverse")){
335 this->residualVec_->update(1.,*this->rhs_,-1.); // this = -1*this + 1*rhs
336 if ( !this->sourceTerm_.is_null() )
337 this->residualVec_->update(1.,*this->sourceTerm_,1.);
338 }
339
340 // this might be set again by the TimeProblem after addition of M*u
341 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );
342
343// this->residualVec_->getBlock(0)->writeMM("b_Ax.mm");
344
345}
346
347/*template<class SC,class LO,class GO,class NO>
348void NavierStokesAssFE<SC,LO,GO,NO>::reAssembleFSI(std::string type, MultiVectorPtr_Type u_minus_w, MatrixPtr_Type P) const {
349
350 if (this->verbose_)
351 std::cout << "-- Reassembly Navier-Stokes ("<< type <<") for FSI ... " << std::flush;
352
353 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
354
355 MatrixPtr_Type ANW = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
356 if (type=="FixedPoint") {
357
358 MatrixPtr_Type N = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
359 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_minus_w, true );
360
361 N->resumeFill();
362 N->scale(density);
363 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
364 A_->addMatrix(1.,ANW,0.);
365
366 N->addMatrix(1.,ANW,1.);
367 // P must be scaled correctly in FSI
368 P->addMatrix(1.,ANW,1.);
369
370
371 }
372 else if(type=="Newton"){
373 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "reAssembleFSI should only be called for FPI-System.");
374 }
375 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
376
377 this->system_->addBlock( ANW, 0, 0 );
378
379 if (this->verbose_)
380 std::cout << "done -- " << std::endl;
381}*/
382
383
384template<class SC,class LO,class GO,class NO>
385void NavierStokesAssFE<SC,LO,GO,NO>::reAssembleExtrapolation(BlockMultiVectorPtrArray_Type previousSolutions){
386
387 if (this->verbose_)
388 std::cout << "-- Reassembly Navier-Stokes (Extrapolation) ... " << std::flush;
389
390
391 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
392
393 if (previousSolutions.size()>=2) {
394
395 MultiVectorPtr_Type extrapolatedVector = Teuchos::rcp( new MultiVector_Type( previousSolutions[0]->getBlock(0) ) );
396
397 extrapolatedVector->update( -1., *previousSolutions[1]->getBlock(0), 2. );
398
399 u_rep_->importFromVector(extrapolatedVector, true);
400 }
401 else if(previousSolutions.size()==1){
402 MultiVectorConstPtr_Type u = previousSolutions[0]->getBlock(0);
403 u_rep_->importFromVector(u, true);
404 }
405 else if (previousSolutions.size()==0){
406 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
407 u_rep_->importFromVector(u, true);
408 }
409
410 MatrixPtr_Type ANW = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
411
412 MatrixPtr_Type N = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
413 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_rep_, true );
414
415 N->resumeFill();
416 N->scale(density);
417 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
418
419 A_->addMatrix(1.,ANW,0.);
420 N->addMatrix(1.,ANW,1.);
421
422 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
423
424 this->system_->addBlock( ANW, 0, 0 );
425
426 if (this->verbose_)
427 std::cout << "done -- " << std::endl;
428}
429
430
431
432
433
434
435// Use converged solution to compute viscosity field
436template<class SC,class LO,class GO,class NO>
437void NavierStokesAssFE<SC,LO,GO,NO>::computeSteadyPostprocessingViscosity_Solution() {
438
439
440 MultiVectorConstPtr_Type u = this->solution_->getBlock(0); // solution_ is initialized in problem_def.hpp so the most general class
441 u_rep_->importFromVector(u, true); // this is the current velocity solution at the nodes - distributed at the processors with repeated values
442
443 MultiVectorConstPtr_Type p = this->solution_->getBlock(1);
444 p_rep_->importFromVector(p, true); // this is the current pressure solution at the nodes - distributed at the processors with repeated values
445
446 // Reset here the viscosity so at this moment this makes only sense to call at the end of a simulation
447 // to visualize viscosity field
448 // @ToDo Add possibility for transient problem to save viscosity solution in each time step
449 viscosity_element_ = Teuchos::rcp( new MultiVector_Type( this->getDomain(0)->getElementMap() ) );
450 this->feFactory_->computeSteadyViscosityFE_CM(this->dim_, this->getDomain(0)->getFEType(), this->getDomain(1)->getFEType(), this->dim_,1,u_rep_,p_rep_,this->parameterList_);
451
452 Teuchos::RCP<const MultiVector<SC,LO,GO,NO>> exportSolutionViscosityAssFE = this->feFactory_->const_output_fields->getBlock(0); // For now we assume that viscosity is always saved in first block
453 viscosity_element_->importFromVector(exportSolutionViscosityAssFE, true);
454
455
456
457}
458
459
460
461
462
463
464
465}
466
467#endif
Definition NonLinearProblem_decl.hpp:24
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:33