Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
NavierStokes_def.hpp
1#ifndef NAVIERSTOKES_def_hpp
2#define NAVIERSTOKES_def_hpp
3#include "NavierStokes_decl.hpp"
4
5#ifndef NAVIER_STOKES_START
6#define NAVIER_STOKES_START(A,S) Teuchos::RCP<Teuchos::TimeMonitor> A = Teuchos::rcp(new Teuchos::TimeMonitor(*Teuchos::TimeMonitor::getNewTimer(std::string("Assemble Navier-Stokes:") + std::string(S))));
7#endif
8
9#ifndef NAVIER_STOKES_STOP
10#define NAVIER_STOKES_STOP(A) A.reset();
11#endif
12
21
22void sxOne2D(double* x, double* res, double t, double* parameter){
23
24 res[0] = 1.;
25 res[1] = 0.;
26 return;
27}
28
29void syOne2D(double* x, double* res, double t, double* parameter){
30
31 res[0] = 0.;
32 res[1] = 1.;
33
34 return;
35}
36void sDummyFunc(double* x, double* res, double t, double* parameter){
37
38 return;
39}
40
41void zeroDirichletBC(double* x, double* res, double t, const double* parameters){
42
43 res[0] = 0.;
44
45 return;
46}
47
48double OneFunction(double* x, int* parameter)
49{
50 return 1.0;
51}
52
53void dummyFuncRhs(double* x, double* res, double* parameters){
54 if(parameters[0]==2)
55 res[0]=1;
56 else
57 res[0] = 0.;
58
59 return;
60}
61
62namespace FEDD {
63
64
65
66template<class SC,class LO,class GO,class NO>
67NavierStokes<SC,LO,GO,NO>::NavierStokes( const DomainConstPtr_Type &domainVelocity, std::string FETypeVelocity, const DomainConstPtr_Type &domainPressure, std::string FETypePressure, ParameterListPtr_Type parameterList ):
68NonLinearProblem<SC,LO,GO,NO>( parameterList, domainVelocity->getComm() ),
69A_(),
70pressureIDsLoc(new vec_int_Type(2)),
71u_rep_()
72{
73
74 this->nonLinearTolerance_ = this->parameterList_->sublist("Parameter").get("relNonLinTol",1.0e-6);
75 this->initNOXParameters();
76
77 this->addVariable( domainVelocity , FETypeVelocity , "u" , domainVelocity->getDimension());
78 this->addVariable( domainPressure , FETypePressure , "p" , 1);
79 this->dim_ = this->getDomain(0)->getDimension();
80
81 u_rep_ = Teuchos::rcp( new MultiVector_Type( this->getDomain(0)->getMapVecFieldRepeated() ) );
82
83 if (parameterList->sublist("Parameter").get("Calculate Coefficients",false)) {
84 vec2D_dbl_ptr_Type vectmpPointsPressure = domainPressure->getPointsUnique();
85 vec2D_dbl_Type::iterator it;
86 int front = -1;
87 int back = -1;
88 if (domainPressure->getDimension() == 2) {
89 it = find_if(vectmpPointsPressure->begin(), vectmpPointsPressure->end(),
90 [&] (const std::vector<double>& a){
91 if (a.at(0) >= 0.15-1.e-12 && a.at(0) <= 0.15+1.e-12
92 && a.at(1) >= 0.2-1.e-12 && a.at(1) <= 0.2+1.e-12) {
93 return true;
94 }
95 else {
96 return false;
97 }
98 });
99
100 if (it != vectmpPointsPressure->end()) {
101 front = distance(vectmpPointsPressure->begin(),it);
102 }
103 it = find_if(vectmpPointsPressure->begin(), vectmpPointsPressure->end(),
104 [&] (const std::vector<double>& a){
105 if (a.at(0) >= 0.25-1.e-12 && a.at(0) <= 0.25+1.e-12
106 && a.at(1) >= 0.2-1.e-12 && a.at(1) <= 0.2+1.e-12) {
107 return true;
108 }
109 else {
110 return false;
111 }
112 });
113
114 if (it != vectmpPointsPressure->end()) {
115 back = distance(vectmpPointsPressure->begin(),it);
116 }
117 pressureIDsLoc->at(0) = front;
118 pressureIDsLoc->at(1) = back;
119 }
120 else if(domainPressure->getDimension() == 3){
121#ifdef ASSERTS_WARNINGS
122 MYASSERT(false,"Not implemented to calc coefficients in 3D!");
123#endif
124 }
125 }
126
127 if(!this->parameterList_->sublist("General").get("Preconditioner Method","Diagonal").compare("PCD")
128 || !this->parameterList_->sublist("General").get("Preconditioner Method","Diagonal").compare("LSC")
129 || !this->parameterList_->sublist("Teko Parameters").sublist("Preconditioner Types").sublist("Teko").get("Inverse Type","SIMPLE").compare("PCD")
130 || !this->parameterList_->sublist("Teko Parameters").sublist("Preconditioner Types").sublist("Teko").get("Inverse Type","SIMPLE").compare("LSC-Pressure-Laplace") )
131 {
132 this->bcFactoryPCD_.reset(new BCBuilder<SC,LO,GO,NO>( ));
133 this->bcFactoryPCD_->addBC(zeroDirichletBC, 3, 0, Teuchos::rcp_const_cast<Domain_Type>( domainPressure ), "Dirichlet", 1);
134 }
135
136 if(this->parameterList_->sublist("General").get("Augmented Lagrange",false))
137 augmentedLagrange_ = true;
138
139}
140
141template<class SC,class LO,class GO,class NO>
142void NavierStokes<SC,LO,GO,NO>::info(){
143 this->infoProblem();
144 this->infoNonlinProblem();
145}
146
147template<class SC,class LO,class GO,class NO>
148void NavierStokes<SC,LO,GO,NO>::assemble( std::string type ) const{
149
150 if (type=="") {
151 if (this->verbose_)
152 std::cout << "-- Assembly Navier-Stokes ... " << std::endl;
153
154 assembleConstantMatrices();
155
156 if (this->verbose_)
157 std::cout << "done -- " << std::endl;
158 }
159 else if(type=="UpdateTime"){
160 this->newtonStep_ = 0;
161 // timeSteppingTool_->t_ = timeSteppingTool_->t_ + timeSteppingTool_->dt_prev_;
162 }
163 else if(type =="UpdateConvectionDiffusionOperator")
164 this->updateConvectionDiffusionOperator();
165 else
166 reAssemble( type );
167
168};
169
170template<class SC,class LO,class GO,class NO>
171void NavierStokes<SC,LO,GO,NO>::assembleConstantMatrices() const{
172
173 if (this->verbose_)
174 std::cout << "-- Assembly constant matrices Navier-Stokes ... " << std::flush;
175
176 double viscosity = this->parameterList_->sublist("Parameter").get("Viscosity",1.);
177 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
178
179 // Egal welcher Wert, da OneFunction nicht von parameter abhaengt
180 int* dummy;
181
182 A_.reset(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
183
184 if ( this->parameterList_->sublist("Parameter").get("Symmetric gradient",false) )
185 this->feFactory_->assemblyStress(this->dim_, this->domain_FEType_vec_.at(0), A_, OneFunction, dummy, true);
186 else
187 this->feFactory_->assemblyLaplaceVecField(this->dim_, this->domain_FEType_vec_.at(0), 2, A_, true);
188
189 A_->resumeFill();
190
191 A_->scale(viscosity);
192 A_->scale(density);
193
194 A_->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
195
196 if (this->system_.is_null())
197 this->system_.reset(new BlockMatrix_Type(2));
198
199 this->system_->addBlock( A_, 0, 0 );
200 assembleDivAndStab();
201
202#ifdef FEDD_HAVE_TEKO
203 if ( !this->parameterList_->sublist("General").get("Preconditioner Method","Monolithic").compare("Teko")
204 || !this->parameterList_->sublist("General").get("Preconditioner Method","Diagonal").compare("PCD")
205 || !this->parameterList_->sublist("General").get("Preconditioner Method","Diagonal").compare("LSC")) {
206
207 // ###############################################
208 // LSC Preconditioner
209 // Constructing velocity mass matrix
210 // If the Velocity Mass Matrix is the identity matrix,
211 // it results in the BFBt preconditioner
212 if (!this->parameterList_->sublist("Teko Parameters").sublist("Preconditioner Types").sublist("Teko").get("Inverse Type","None").compare("LSC")
213 || !this->parameterList_->sublist("Teko Parameters").sublist("Preconditioner Types").sublist("Teko").get("Inverse Type","None").compare("LSC-Pressure-Laplace")
214 || !this->parameterList_->sublist("Teko Parameters").sublist("Preconditioner Types").sublist("Teko").get("Inverse Type","None").compare("SIMPLE")
215 || !this->parameterList_->sublist("General").get("Preconditioner Method","Diagonal").compare("LSC")) {
216
217 MatrixPtr_Type Mvelocity(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getApproxEntriesPerRow() ) );
218 // Constructing velocity mass matrix
219 if(this->parameterList_->sublist("Parameter").get("BFBT",false)){
220 if(this->verbose_)
221 std::cout << "\n Setting M_u to be the identity Matrix to use BFBT preconditioner " << std::endl;
222
223 this->feFactory_->assemblyIdentity( Mvelocity );
224 }
225 else{
226 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(0), "Vector", Mvelocity, true );
227 }
228 // Adding the velocity mass matrix Mu to the preconditioner
229 this->getPreconditionerConst()->setVelocityMassMatrix( Mvelocity );
230
231 if (this->verbose_)
232 std::cout << "\n Velocity mass matrix for LSC block preconditioner is assembled and used for the preconditioner." << std::endl;
233
234 // For LSC-Pressure-Laplace approach we add also the Laplaian on the pressure space to the preconditioner
235 if(!this->parameterList_->sublist("Teko Parameters").sublist("Preconditioner Types").sublist("Teko").get("Inverse Type","SIMPLE").compare("LSC-Pressure-Laplace")
236 || !this->parameterList_->sublist("General").get("Preconditioner Method","Diagonal").compare("LSC"))
237 {
238 MatrixPtr_Type Lp(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
239 this->feFactory_->assemblyLaplace( this->dim_, this->domain_FEType_vec_.at(1), 2, Lp, true );
240
241 BlockMatrixPtr_Type bcBlockMatrix(new BlockMatrix_Type (1));
242 bcBlockMatrix->addBlock(Lp,0,0);
243 bcFactoryPCD_->setSystemScaled(bcBlockMatrix); // Setting boundary information where the Diagonal entry is kept
244
245 this->getPreconditionerConst()->setPressureLaplaceMatrix( Lp);
246 }
247 }
248 // ###############################################
249 // PCD Preconditioner
250 // For the PCD preconditioner we additionally need
251 // assemble the pressure mass matrix, the pressure
252 // Laplacian and the pressure convection diffusion
253 // opertor.
254 else if(!this->parameterList_->sublist("Teko Parameters").sublist("Preconditioner Types").sublist("Teko").get("Inverse Type","SIMPLE").compare("PCD")
255 || !this->parameterList_->sublist("General").get("Preconditioner Method","Diagonal").compare("PCD") ){
256
257 // ###############################################
258 // Velocity mass matrix: Currently this is set to not have an error in preconditioner. PLEASE FIX
259 MatrixPtr_Type Mvelocity(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getApproxEntriesPerRow() ) );
260 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(0), "Vector", Mvelocity, true );
261 this->getPreconditionerConst()->setVelocityMassMatrix( Mvelocity );
262 // ###############################################
263
264
265 // Pressure mass matrix
266 MatrixPtr_Type Mpressure(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
267 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(1), "Scalar", Mpressure, true );
268 Mp_= Mpressure;
269 this->getPreconditionerConst()->setPressureMassMatrix( Mpressure );
270 // --------------------------------------------------------------------------------------------
271
272 // --------------------------------------------------------------------------------------------
273 // Pressure Laplace matrix
274 MatrixPtr_Type Lp(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
275 this->feFactory_->assemblyLaplace( this->dim_, this->domain_FEType_vec_.at(1), 2, Lp, true );
276 Ap_.reset(new Matrix_Type(Lp)); // Setting Ap_ as Lp without any BC
277
278 // Adding boundary information to pressure Laplace operator
279 BlockMatrixPtr_Type bcBlockMatrix(new BlockMatrix_Type (1));
280 bcBlockMatrix->addBlock(Lp,0,0);
281
282 bcFactoryPCD_->setSystemScaled(bcBlockMatrix); // Setting boundary information where the Diagonal entry is kept
283 this->getPreconditionerConst()->setPressureLaplaceMatrix( Lp); // Adding pressure laplacian to preconditioner
284 // --------------------------------------------------------------------------------------------
285
286 // --------------------------------------------------------------------------------------------
287 // Pressure convection diffusion operator
288 MatrixPtr_Type Kp(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
289 // --------------------------------------------------------------------------------------------
290 // Advection component
291 MatrixPtr_Type AdvPressure(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
292 this->feFactory_->assemblyAdvectionVecFieldScalar( this->dim_, this->domain_FEType_vec_.at(1), this->domain_FEType_vec_.at(0),AdvPressure, u_rep_, true );
293
294 // Diffusion component: \nu * \Delta
295 MatrixPtr_Type Ap2(new Matrix_Type( Ap_) );
296
297 SC kinVisco = this->parameterList_->sublist("Parameter").get("Viscosity",1.); // Ap need to be scaled with viscosity
298 Ap2->resumeFill();
299 Ap2->scale(kinVisco);
300 Ap2->fillComplete();
301
302
303 MatrixPtr_Type K_robin(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getDimension() * this->getDomain(1)->getApproxEntriesPerRow()*2 ) );
304 vec_dbl_Type funcParameter(1,kinVisco);
305 this->feFactory_->assemblySurfaceRobinBC(this->dim_, this->getDomain(1)->getFEType(),this->getDomain(0)->getFEType(),u_rep_,K_robin, funcParameter, dummyFuncRhs,this->parameterList_);
306 K_robin->addMatrix(-1.,Kp,1.); // adding robin boundary condition to to Kp
307
308 // Adding laplace and convetion-diffusion operator to Kp
309 Ap2->addMatrix(1.,Kp,1.); // adding advection to diffusion
310 AdvPressure->addMatrix(1.,Kp,1.); // adding advection to diffusion
311
312 Kp->fillComplete();
313
314 bcBlockMatrix->addBlock(Kp,0,0);
315 bcFactoryPCD_->setSystemScaled(bcBlockMatrix);
316
317 // Adding Kp to the preconditioner
318 this->getPreconditionerConst()->setPCDOperator( Kp );
319 // --------------------------------------------------------------------------------------------
320
321 }
322 }
323#endif
324 std::string precType = this->parameterList_->sublist("General").get("Preconditioner Method","Monolithic");
325 if ( precType == "Diagonal" || precType == "Triangular" ) {
326 MatrixPtr_Type Mpressure(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
327
328 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(1), "Scalar", Mpressure, true );
329 SC kinVisco = this->parameterList_->sublist("Parameter").get("Viscosity",1.);
330
331 if(augmentedLagrange_){
332 double gamma = this->parameterList_->sublist("General").get("Gamma",1.0);
333 Mpressure->scale(-1./(kinVisco+gamma));
334 }
335 else{
336 Mpressure->scale(-1./kinVisco);
337 }
338 this->getPreconditionerConst()->setPressureMassMatrix( Mpressure );
339 }
340
341 if (this->verbose_)
342 std::cout << " Call Reassemble FixedPoint and Newton to allocate the Matrix pattern " << std::endl;
343
344 // This was moved here from 'create_W_op'.
345 // Here it will definetly be called before create_W_op and create_W_prec is called.
346 this->reAssemble("FixedPoint");
347 this->reAssemble("Newton");
348
349 if (this->verbose_)
350 std::cout << "done -- " << std::endl;
351
352};
353
354
355template<class SC,class LO,class GO,class NO>
356void NavierStokes<SC,LO,GO,NO>::updateConvectionDiffusionOperator() const{
357
358 if ( !this->parameterList_->sublist("Teko Parameters").sublist("Preconditioner Types").sublist("Teko").get("Inverse Type","SIMPLE").compare("PCD")
359 || !this->parameterList_->sublist("General").get("Preconditioner Method","Monolithic").compare("PCD"))
360 {
361
362 NAVIER_STOKES_START(ReassemblePCD," Reassembling Matrix for PCD ");
363
364 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
365 u_rep_->importFromVector(u, true);
366
367 // PCD Operator
368 MatrixPtr_Type Fp(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
369 // --------------------------------------------------------------------------------------------
370 // Advection component
371 MatrixPtr_Type AdvPressure(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
372 this->feFactory_->assemblyAdvectionVecFieldScalar( this->dim_, this->domain_FEType_vec_.at(1), this->domain_FEType_vec_.at(0),AdvPressure, u_rep_, true );
373
374 // Diffusion component: \nu * \Delta
375 MatrixPtr_Type Ap2(new Matrix_Type( Ap_ ) ); // We use A_p which we already stored
376 SC kinVisco = this->parameterList_->sublist("Parameter").get("Viscosity",1.);
377 Ap2->resumeFill();
378 Ap2->scale(kinVisco);
379 Ap2->fillComplete();
380
381 // ---------------------
382 // Robin boundary
383 MatrixPtr_Type Kext(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getDimension() * this->getDomain(1)->getApproxEntriesPerRow()*2 ) );
384 vec_dbl_Type funcParameter(1,kinVisco);
385 this->feFactory_->assemblySurfaceRobinBC(this->dim_, this->getDomain(1)->getFEType(),this->getDomain(0)->getFEType(),u_rep_,Kext, funcParameter, dummyFuncRhs,this->parameterList_);
386 Kext->addMatrix(-1.,Fp,1.); // adding advection to diffusion
387
388 // Adding laplace an convection together
389 Ap2->addMatrix(1.,Fp,1.); // adding advection to diffusion
390 AdvPressure->addMatrix(1.,Fp,1.); // adding advection to diffusion
391
392 // Finally if we deal with a transient problem we additionally add the Mass term 1/delta t M_p
393 if(this->parameterList_->sublist("Timestepping Parameter").get("dt",-1.)> -1 ){ // In case we have a timeproblem
394 MatrixPtr_Type Mp2(new Matrix_Type( Mp_ ) );
395 double dt = this->parameterList_->sublist("Timestepping Parameter").get("dt",-1.);
396 Mp2->resumeFill();
397 if(this->parameterList_->sublist("Timestepping Parameter").get("BDF",1) == 1) // BDF 1
398 Mp2->scale(1./dt);
399 else if(this->parameterList_->sublist("Timestepping Parameter").get("BDF",1) == 2) // BDF 1
400 Mp2->scale(3./(2.*dt));
401 else
402 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "PCD operator for transient problems only defined for BDF-1 and BDF-2.");
403
404 Mp2->fillComplete();
405 Mp2->addMatrix(1.,Fp,1.);
406 }
407 Fp->fillComplete();
408
409 BlockMatrixPtr_Type bcBlockMatrix(new BlockMatrix_Type (1));
410
411 bcBlockMatrix->addBlock(Fp,0,0);
412 bcFactoryPCD_->setSystemScaled(bcBlockMatrix); // We set the boundary conditions into Fp. Both Ap and Fp have Dirichlet zero bc on the outlet
413 // Addionally, a robin bc is applied to the inlet bc for Fp.
414 // Note, if no surfaces are available, the matrix Kext, containg the robin bc is zero,
415 // so no robin bc is applied.
416
417 this->getPreconditionerConst()->setPCDOperator( Fp );
418
419 NAVIER_STOKES_STOP(ReassemblePCD);
420 }
421}
422template<class SC,class LO,class GO,class NO>
423void NavierStokes<SC,LO,GO,NO>::assembleDivAndStab() const{
424
425 double viscosity = this->parameterList_->sublist("Parameter").get("Viscosity",1.);
426 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
427
428 MatrixPtr_Type BT(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(1)->getDimension() * this->getDomain(1)->getApproxEntriesPerRow() ) );
429
430 MapConstPtr_Type pressureMap;
431 if ( this->getDomain(1)->getFEType() == "P0" )
432 pressureMap = this->getDomain(1)->getElementMap();
433 else
434 pressureMap = this->getDomain(1)->getMapUnique();
435
436 MatrixPtr_Type B(new Matrix_Type( pressureMap, this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
437
438 MatrixPtr_Type C;
439
440 this->feFactory_->assemblyDivAndDivTFast(this->dim_, this->getFEType(0), this->getFEType(1), 2, B, BT, this->getDomain(0)->getMapVecFieldUnique(), pressureMap, true );
441
442 B->resumeFill();
443 BT->resumeFill();
444
445 B->scale(-1.);
446 BT->scale(-1.);
447
448 B->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), pressureMap );
449 BT->fillComplete( pressureMap, this->getDomain(0)->getMapVecFieldUnique() );
450
451 this->system_->addBlock( BT, 0, 1 );
452 this->system_->addBlock( B, 1, 0 );
453
454 if ( !this->getFEType(0).compare("P1") || !this->getFEType(0).compare("Q1") ) {
455 C.reset(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
456 this->feFactory_->assemblyBDStabilization( this->dim_, this->getFEType(0), C, true);
457 C->resumeFill();
458 C->scale( -1. / ( viscosity * density ) );
459 C->fillComplete( pressureMap, pressureMap );
460
461 this->system_->addBlock( C, 1, 1 );
462 }
463
464
465
466 // MatrixPtr_Type Mp2(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
467 // this->feFactory_->assemblyIdentity( Mp2 );
468 // Mp2->resumeFill();
469 // Mp2->scale(3.0);
470 // Mp2->fillComplete();
471
472 // MatrixPtr_Type Mp(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
473 // this->feFactory_->assemblyIdentity( Mp );
474
475 if(augmentedLagrange_){
476 NAVIER_STOKES_START(AssembleAugmentedLagrangianComponent,"AssembleDivAndStab: AL - Assemble BT Mp B");
477
478 double gamma = this->parameterList_->sublist("General").get("Gamma",1.0);
479
480 MatrixPtr_Type Mp(new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
481 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(1), "Scalar", Mp, true );
482
483 MatrixPtr_Type MpInv = Mp->buildDiagonalInverse("Diagonal");
484
485 MpInv->resumeFill();
486 MpInv->scale(gamma);
487 MpInv->fillComplete();
488
489
490 MatrixPtr_Type BT_M(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension()*this->getDomain(0)->getApproxEntriesPerRow() ) );
491 BT_M->Multiply(BT,false,MpInv,false);
492
493 BT_Mp_ = BT_M;
494
495 MatrixPtr_Type BT_M_B(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension()*this->getDomain(0)->getApproxEntriesPerRow() ) );
496 BT_M_B->Multiply(BT_M,false,B,false);
497
498 BT_Mp_B_ = BT_M_B;
499 // BT_Mp_B_->print();
500 // BT_Mp_B_->writeMM("BT_Mp_B_");
501
502 NAVIER_STOKES_STOP(AssembleAugmentedLagrangianComponent);
503 }
504
505 //k0 = MatrixMatrix<SC,LO,GO,NO>::Multiply(*B_T,false,*tmp,false,*fancy); //k0->describe(*fancy,VERB_EXTREME);
506
507};
508
509template<class SC,class LO,class GO,class NO>
510void NavierStokes<SC,LO,GO,NO>::reAssemble( MatrixPtr_Type& massmatrix, std::string type ) const
511{
512
513}
514
515template<class SC,class LO,class GO,class NO>
516void NavierStokes<SC,LO,GO,NO>::reAssembleFSI(std::string type, MultiVectorPtr_Type u_minus_w, MatrixPtr_Type P) const {
517
518 if (this->verbose_)
519 std::cout << "-- Reassembly Navier-Stokes ("<< type <<") for FSI ... " << std::flush;
520
521 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
522
523 MatrixPtr_Type ANW = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
524 if (type=="FixedPoint") {
525
526 MatrixPtr_Type N = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
527 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_minus_w, true );
528
529 N->resumeFill();
530 N->scale(density);
531 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
532 A_->addMatrix(1.,ANW,0.);
533
534 N->addMatrix(1.,ANW,1.);
535 // P must be scaled correctly in FSI
536 P->addMatrix(1.,ANW,1.);
537
538
539 }
540 else if(type=="Newton"){
541 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "reAssembleFSI should only be called for FPI-System.");
542 }
543 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
544
545 this->system_->addBlock( ANW, 0, 0 );
546
547 if (this->verbose_)
548 std::cout << "done -- " << std::endl;
549}
550
551
552template<class SC,class LO,class GO,class NO>
553void NavierStokes<SC,LO,GO,NO>::reAssemble(std::string type) const {
554
555
556 if (this->verbose_)
557 std::cout << "-- Reassembly Navier-Stokes ("<< type <<") ... " << std::flush;
558
559 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
560 int allocationFactor = 1;
561 if(augmentedLagrange_)
562 allocationFactor = 3;
563 MatrixPtr_Type ANW = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), allocationFactor*this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
564 if (type=="FixedPoint") {
565
566 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
567 u_rep_->importFromVector(u, true);
568
569 MatrixPtr_Type N = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
570 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_rep_, true );
571
572 N->resumeFill();
573 N->scale(density);
574 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
575
576 A_->addMatrix(1.,ANW,0.);
577 N->addMatrix(1.,ANW,1.);
578
579 }
580 else if(type=="Newton"){ // We assume that reAssmble("FixedPoint") was already called for the current iterate
581
582 MatrixPtr_Type W = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
583 this->feFactory_->assemblyAdvectionInUVecField( this->dim_, this->domain_FEType_vec_.at(0), W, u_rep_, true );
584 W->resumeFill();
585 W->scale(density);
586 W->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
587 this->system_->getBlock( 0, 0 )->addMatrix(1.,ANW,0.);
588 W->addMatrix(1.,ANW,1.);
589
590 }
591
592 if(augmentedLagrange_)
593 BT_Mp_B_->addMatrix(1.,ANW,1.);
594
595 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
596
597 this->system_->addBlock( ANW, 0, 0 );
598
599 if (this->verbose_)
600 std::cout << "done -- " << std::endl;
601}
602
603template<class SC,class LO,class GO,class NO>
604void NavierStokes<SC,LO,GO,NO>::reAssembleExtrapolation(BlockMultiVectorPtrArray_Type previousSolutions){
605
606 if (this->verbose_)
607 std::cout << "-- Reassembly Navier-Stokes (Extrapolation) ... " << std::flush;
608
609
610 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
611
612 if (previousSolutions.size()>=2) {
613
614 MultiVectorPtr_Type extrapolatedVector = Teuchos::rcp( new MultiVector_Type( previousSolutions[0]->getBlock(0) ) );
615
616 extrapolatedVector->update( -1., *previousSolutions[1]->getBlock(0), 2. );
617
618 u_rep_->importFromVector(extrapolatedVector, true);
619 }
620 else if(previousSolutions.size()==1){
621 MultiVectorConstPtr_Type u = previousSolutions[0]->getBlock(0);
622 u_rep_->importFromVector(u, true);
623 }
624 else if (previousSolutions.size()==0){
625 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
626 u_rep_->importFromVector(u, true);
627 }
628
629 MatrixPtr_Type ANW = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
630
631 MatrixPtr_Type N = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
632 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_rep_, true );
633
634 N->resumeFill();
635 N->scale(density);
636 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
637
638 A_->addMatrix(1.,ANW,0.);
639 N->addMatrix(1.,ANW,1.);
640
641 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
642
643 this->system_->addBlock( ANW, 0, 0 );
644
645 if (this->verbose_)
646 std::cout << "done -- " << std::endl;
647}
648
649//template<class SC,class LO,class GO,class NO>
650//int NavierStokes<SC,LO,GO,NO>::ComputeDragLift(vec_dbl_ptr_Type &values){
651//
652// int dimension = this->domainPtr_vec_.at(0)->GetDimension();
653// MultiVector_ptr_vec_ptr_Type sol_unique_vec(new std::vector<MultiVector_ptr_Type>(0));
654// this->system_->FillSplitVector64(*this->solution_, sol_unique_vec);
655// this->system_->BuildRepeatedVectorBlocks(sol_unique_vec);
656// Vector_ptr_Type u_rep(new Epetra_Vector(*(this->system_->GetRepeatedVec(0))));
657// Teuchos::RCP<Epetra_FECrsMatrix> N(new Epetra_FECrsMatrix(Epetra_DataAccess::Copy,*(this->domainPtr_vec_.at(0)->GetMapXDimUnique()),10));
658// u_rep.reset(new Epetra_Vector(*(this->system_->GetRepeatedVec(0))));
659// N.reset(new Epetra_FECrsMatrix(Epetra_DataAccess::Copy,*(this->domainPtr_vec_.at(0)->GetMapXDimUnique()),10));
660// this->feFactory_->AssemblyAdvectionXDim(dimension, this->domain_FEType_vec_.at(0), 7, N, u_rep /* u */, setZeros);
661//
662// Teuchos::RCP<Epetra_CrsMatrix> AN(new Epetra_CrsMatrix(Epetra_DataAccess::Copy,*(this->domainPtr_vec_.at(0)->GetMapXDimUnique()),10));
663//
664// EpetraExt::MatrixMatrix::Add(*A_,false,1.,*AN,1.);
665// EpetraExt::MatrixMatrix::Add(*N,false,1.,*AN,1.);
666//
667// AN.reset(new Epetra_CrsMatrix(Epetra_DataAccess::Copy,*(this->domainPtr_vec_.at(0)->GetMapXDimUnique()),10));
668// EpetraExt::MatrixMatrix::Add(*A_,false,1.,*AN,1.);
669// EpetraExt::MatrixMatrix::Add(*N,false,1.,*AN,1.);
670// AN->FillComplete();
671//
672//
673// Teuchos::RCP<Epetra_FECrsMatrix> B_T (new Epetra_FECrsMatrix(Epetra_DataAccess::Copy,*(this->domainPtr_vec_.at(0)->GetMapXDimUnique()),5));
674// Teuchos::RCP<Epetra_FECrsMatrix> B (new Epetra_FECrsMatrix(Epetra_DataAccess::Copy,*(this->domainPtr_vec_.at(1)->GetMapUnique()),5));
675// this->feFactory_->AssemblyDivergence(dimension, this->domain_FEType_vec_.at(0), this->domain_FEType_vec_.at(1), 2, B, B_T, setZeros, this->domainPtr_vec_.at(0)->GetMapXDimUnique(), this->domainPtr_vec_.at(1)->GetMapUnique());
676// B_T->Scale(-1.);
677// Teuchos::RCP<BlockElement> BE_AN(new BlockElement(AN));
678// Teuchos::RCP<BlockElement> BE_B_T(new BlockElement(B_T));
679//
680// BE_AN.reset(new BlockElement(AN));
681// BE_B_T.reset(new BlockElement(B_T));
682//
683// this->system_->ReplaceBlock(BE_AN,0,0);
684// this->system_->ReplaceBlock(BE_B_T,0,1);
685//
686// Teuchos::RCP<BCBuilder> bCFactoryDrag(new BCBuilder(sublist(this->parameterList_,"Parameter")));
687// Teuchos::RCP<BCBuilder> bCFactoryLift(new BCBuilder(sublist(this->parameterList_,"Parameter")));
688//
689// bCFactoryDrag->AddBC(sxOne2D, 4, 0, this->domainPtr_vec_.at(0), "Dirichlet", dimension);
690// bCFactoryDrag->AddBC(sDummyFunc, 666, 1, this->domainPtr_vec_.at(1), "Neumann", 1);
691//
692// bCFactoryLift->AddBC(syOne2D, 4, 0, this->domainPtr_vec_.at(0), "Dirichlet", dimension);
693// bCFactoryLift->AddBC(sDummyFunc, 666, 1, this->domainPtr_vec_.at(1), "Neumann", 1);
694//
695// Teuchos::RCP<Epetra_Vector> dragVec(new Epetra_Vector(*(*this->solution_)(0)));
696// Teuchos::RCP<Epetra_Vector> liftVec(new Epetra_Vector(*(*this->solution_)(0)));
697// dragVec->PutScalar(0.);
698// liftVec->PutScalar(0.);
699// bCFactoryDrag->SetRHS(this->system_, dragVec);
700// bCFactoryLift->SetRHS(this->system_, liftVec);
701//
702// Teuchos::RCP<Epetra_Vector> mat_sol(new Epetra_Vector(*(*this->solution_)(0)));
703// this->system_->Apply(*this->solution_,*mat_sol);
704// mat_sol->Scale(-1.);
705// double dragCoeff;
706// double liftCoeff;
707// mat_sol->Dot(*dragVec,&dragCoeff);
708// mat_sol->Dot(*liftVec,&liftCoeff);
709// values->at(0) = dragCoeff;
710// values->at(1) = liftCoeff;
711// if (this->verbose_) {
712// cout<< "Not scaled drag coefficient: " << dragCoeff<< endl;
713// cout<< "Not scaled lift coefficient: " << liftCoeff<< endl;
714// }
715// Teuchos::RCP<Epetra_Vector> pressureSolutuion( new Epetra_Vector(*((*(sol_unique_vec->at(1)))(0))));
716// double p1 = numeric_limits<double>::min();
717// double p2 = numeric_limits<double>::min();
718// if (pressureIDsLoc->at(0)>-1) {
719// p1 = (*pressureSolutuion)[pressureIDsLoc->at(0)];
720//
721// }
722// if (pressureIDsLoc->at(1)>-1) {
723// p2 = (*pressureSolutuion)[pressureIDsLoc->at(1)];
724// }
725// this->comm_->Barrier();
726// double res;
727// this->comm_->MaxAll(&p1,&res,1);
728// values->at(2) = res;
729// this->comm_->MaxAll(&p2,&res,1);
730// values->at(3) = res;
731// return 0;
732//}
733
734//template<class SC,class LO,class GO,class NO>
735//typename NavierStokes<SC,LO,GO,NO>::MultiVector_Type NavierStokes<SC,LO,GO,NO>::GetExactSolution(double time){
736//#ifdef ASSERTS_WARNINGS
737// MYASSERT(false,"no analytic solution.");
738//#endif
739// return *this->solution_;
740//}
741
742
743//template<class SC,class LO,class GO,class NO>
744//void NavierStokes<SC,LO,GO,NO>::set_x0(const Teuchos::ArrayView<const SC> &x0_in){
745//#ifdef TEUCHOS_DEBUG
746// TEUCHOS_ASSERT_EQUALITY(xSpace_->dim(), x0_in.size());
747//#endif
748// Thyra::DetachedVectorView<SC> x0(x0_);
749// x0.sv().values()().assign(x0_in);
750//}
751
752template<class SC,class LO,class GO,class NO>
753void NavierStokes<SC,LO,GO,NO>::calculateNonLinResidualVec(std::string type, double time) const{
754
755 if (this->verbose_)
756 std::cout << "-- NavierStokes::calculateNonLinResidualVec ("<< type <<") ... " << std::flush;
757
758 // this->updateConvectionDiffusionOperator();
759
760 this->reAssemble("FixedPoint");
761 // We need to account for different parameters of time discretizations here
762 // This is ok for bdf with 1.0 scaling of the system. Would be wrong for Crank-Nicolson - might be ok now for CN
763 if (this->coeff_.size() == 0)
764 this->system_->apply( *this->solution_, *this->residualVec_ );
765 else
766 this->system_->apply( *this->solution_, *this->residualVec_, this->coeff_ );
767
768 if(augmentedLagrange_){
769 MultiVectorPtr_Type rhsAL = Teuchos::rcp( new MultiVector_Type( this->residualVec_->getBlock(0) ) );
770 BT_Mp_->apply( *this->residualVec_->getBlock(1), *rhsAL );
771 this->residualVec_->getBlockNonConst(0)->update(1.,*rhsAL,1.);
772
773 }
774 if (!type.compare("standard")){
775 this->residualVec_->update(-1.,*this->rhs_,1.);
776// if ( !this->sourceTerm_.is_null() )
777// this->residualVec_->update(-1.,*this->sourceTerm_,1.);
778 // this might be set again by the TimeProblem after addition of M*u
779 this->bcFactory_->setVectorMinusBC( this->residualVec_, this->solution_, time );
780
781 }
782 else if(!type.compare("reverse")){
783 this->residualVec_->update(1.,*this->rhs_,-1.); // this = -1*this + 1*rhs
784// if ( !this->sourceTerm_.is_null() )
785// this->residualVec_->update(1.,*this->sourceTerm_,1.);
786 // this might be set again by the TimeProblem after addition of M*u
787 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );
788 }
789
790}
791
792template<class SC,class LO,class GO,class NO>
793void NavierStokes<SC,LO,GO,NO>::calculateNonLinResidualVecWithMeshVelo(std::string type, double time, MultiVectorPtr_Type u_minus_w, MatrixPtr_Type P) const{
794
795
796 this->reAssembleFSI( "FixedPoint", u_minus_w, P );
797
798 // We need to account for different parameters of time discretizations here
799 // This is ok for bdf with 1.0 scaling of the system. Would be wrong for Crank-Nicolson
800
801 this->system_->apply( *this->solution_, *this->residualVec_ );
802// this->residualVec_->getBlock(0)->writeMM("Ax.mm");
803// this->rhs_->getBlock(0)->writeMM("nsRHS.mm");
804 if (!type.compare("standard")){
805 this->residualVec_->update(-1.,*this->rhs_,1.);
806 if ( !this->sourceTerm_.is_null() )
807 this->residualVec_->update(-1.,*this->sourceTerm_,1.);
808 }
809 else if(!type.compare("reverse")){
810 this->residualVec_->update(1.,*this->rhs_,-1.); // this = -1*this + 1*rhs
811 if ( !this->sourceTerm_.is_null() )
812 this->residualVec_->update(1.,*this->sourceTerm_,1.);
813 }
814
815 // this might be set again by the TimeProblem after addition of M*u
816 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );
817
818}
819
820}
821
822#endif
Definition NonLinearProblem_decl.hpp:24
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:33