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 << "done -- " << std::endl;
208};
209
210
211template<class SC,class LO,class GO,class NO>
212void NavierStokesAssFE<SC,LO,GO,NO>::reAssemble( MatrixPtr_Type& massmatrix, std::string type ) const
213{
214
215}
216
217
218
219template<class SC,class LO,class GO,class NO>
220void NavierStokesAssFE<SC,LO,GO,NO>::reAssemble(std::string type) const {
221
222
223 if (this->verbose_)
224 std::cout << "-- Reassembly Navier-Stokes ("<< type <<") ... " << std::flush;
225
226 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
227
228 MatrixPtr_Type ANW = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
229
230 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
231 u_rep_->importFromVector(u, true);
232
233 MultiVectorConstPtr_Type p = this->solution_->getBlock(1);
234 p_rep_->importFromVector(p, true);
235
236
237 if (type=="Rhs") {
238
239 this->system_->addBlock(ANW,0,0);
240
241 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"
242 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);
243
244 }
245 else if (type=="FixedPoint" ) {
246
247 this->system_->addBlock(ANW,0,0);
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);
249 }
250 else if(type=="Newton"){
251
252 this->system_->addBlock(ANW,0,0);
253 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);
254
255 }
256
257 this->system_->addBlock(ANW,0,0);
258
259 if (this->verbose_)
260 std::cout << "done -- " << std::endl;
261
262
263}
264
265
266template<class SC,class LO,class GO,class NO>
267void NavierStokesAssFE<SC,LO,GO,NO>::calculateNonLinResidualVec(std::string type, double time) const{
268
269 //this->reAssemble("FixedPoint");
270 this->reAssemble("Rhs");
271
272 // 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.
273 if(this->getDomain(0)->getFEType() == "P1"){
274
275 MultiVectorPtr_Type residualPressureTmp = Teuchos::rcp(new MultiVector_Type( this->getDomain(1)->getMapUnique() ));
276
277 this->system_->getBlock(1,1)->apply( *(this->solution_->getBlock(1)), *residualPressureTmp);
278
279 this->residualVec_->getBlockNonConst(1)->update(1.,*residualPressureTmp,1.);
280
281
282 }
283 // We need to account for different parameters of time discretizations here
284 // This is ok for bdf with 1.0 scaling of the system. Would be wrong for Crank-Nicolson - might be ok now for CN
285
286 /*if (this->coeff_.size() == 0)
287 this->system_->apply( *this->solution_, *this->residualVec_ );
288 else
289 this->system_->apply( *this->solution_, *this->residualVec_, this->coeff_ );*/
290
291 if (!type.compare("standard")){
292 this->residualVec_->update(-1.,*this->rhs_,1.);
293// if ( !this->sourceTerm_.is_null() )
294// this->residualVec_->update(-1.,*this->sourceTerm_,1.);
295 // this might be set again by the TimeProblem after addition of M*u
296 this->bcFactory_->setVectorMinusBC( this->residualVec_, this->solution_, time );
297
298 }
299 else if(!type.compare("reverse")){
300 this->residualVec_->update(1.,*this->rhs_,-1.); // this = -1*this + 1*rhs
301// if ( !this->sourceTerm_.is_null() )
302// this->residualVec_->update(1.,*this->sourceTerm_,1.);
303 // this might be set again by the TimeProblem after addition of M*u
304 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );
305
306 }
307
308}
309
310template<class SC,class LO,class GO,class NO>
311void NavierStokesAssFE<SC,LO,GO,NO>::calculateNonLinResidualVecWithMeshVelo(std::string type, double time, MultiVectorPtr_Type u_minus_w, MatrixPtr_Type P) const{
312
313
314 // this->reAssembleFSI( "FixedPoint", u_minus_w, P );
315
316 // We need to account for different parameters of time discretizations here
317 // This is ok for bdf with 1.0 scaling of the system. Would be wrong for Crank-Nicolson
318
319 this->system_->apply( *this->solution_, *this->residualVec_ );
320// this->residualVec_->getBlock(0)->writeMM("Ax.mm");
321// this->rhs_->getBlock(0)->writeMM("nsRHS.mm");
322 if (!type.compare("standard")){
323 this->residualVec_->update(-1.,*this->rhs_,1.);
324 if ( !this->sourceTerm_.is_null() )
325 this->residualVec_->update(-1.,*this->sourceTerm_,1.);
326 }
327 else if(!type.compare("reverse")){
328 this->residualVec_->update(1.,*this->rhs_,-1.); // this = -1*this + 1*rhs
329 if ( !this->sourceTerm_.is_null() )
330 this->residualVec_->update(1.,*this->sourceTerm_,1.);
331 }
332
333 // this might be set again by the TimeProblem after addition of M*u
334 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );
335
336// this->residualVec_->getBlock(0)->writeMM("b_Ax.mm");
337
338}
339
340/*template<class SC,class LO,class GO,class NO>
341void NavierStokesAssFE<SC,LO,GO,NO>::reAssembleFSI(std::string type, MultiVectorPtr_Type u_minus_w, MatrixPtr_Type P) const {
342
343 if (this->verbose_)
344 std::cout << "-- Reassembly Navier-Stokes ("<< type <<") for FSI ... " << std::flush;
345
346 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
347
348 MatrixPtr_Type ANW = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
349 if (type=="FixedPoint") {
350
351 MatrixPtr_Type N = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
352 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_minus_w, true );
353
354 N->resumeFill();
355 N->scale(density);
356 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
357 A_->addMatrix(1.,ANW,0.);
358
359 N->addMatrix(1.,ANW,1.);
360 // P must be scaled correctly in FSI
361 P->addMatrix(1.,ANW,1.);
362
363
364 }
365 else if(type=="Newton"){
366 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "reAssembleFSI should only be called for FPI-System.");
367 }
368 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
369
370 this->system_->addBlock( ANW, 0, 0 );
371
372 if (this->verbose_)
373 std::cout << "done -- " << std::endl;
374}*/
375
376
377template<class SC,class LO,class GO,class NO>
378void NavierStokesAssFE<SC,LO,GO,NO>::reAssembleExtrapolation(BlockMultiVectorPtrArray_Type previousSolutions){
379
380 if (this->verbose_)
381 std::cout << "-- Reassembly Navier-Stokes (Extrapolation) ... " << std::flush;
382
383
384 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
385
386 if (previousSolutions.size()>=2) {
387
388 MultiVectorPtr_Type extrapolatedVector = Teuchos::rcp( new MultiVector_Type( previousSolutions[0]->getBlock(0) ) );
389
390 extrapolatedVector->update( -1., *previousSolutions[1]->getBlock(0), 2. );
391
392 u_rep_->importFromVector(extrapolatedVector, true);
393 }
394 else if(previousSolutions.size()==1){
395 MultiVectorConstPtr_Type u = previousSolutions[0]->getBlock(0);
396 u_rep_->importFromVector(u, true);
397 }
398 else if (previousSolutions.size()==0){
399 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
400 u_rep_->importFromVector(u, true);
401 }
402
403 MatrixPtr_Type ANW = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
404
405 MatrixPtr_Type N = Teuchos::rcp(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
406 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_rep_, true );
407
408 N->resumeFill();
409 N->scale(density);
410 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
411
412 A_->addMatrix(1.,ANW,0.);
413 N->addMatrix(1.,ANW,1.);
414
415 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
416
417 this->system_->addBlock( ANW, 0, 0 );
418
419 if (this->verbose_)
420 std::cout << "done -- " << std::endl;
421}
422
423
424
425
426
427
428// Use converged solution to compute viscosity field
429template<class SC,class LO,class GO,class NO>
430void NavierStokesAssFE<SC,LO,GO,NO>::computeSteadyPostprocessingViscosity_Solution() {
431
432
433 MultiVectorConstPtr_Type u = this->solution_->getBlock(0); // solution_ is initialized in problem_def.hpp so the most general class
434 u_rep_->importFromVector(u, true); // this is the current velocity solution at the nodes - distributed at the processors with repeated values
435
436 MultiVectorConstPtr_Type p = this->solution_->getBlock(1);
437 p_rep_->importFromVector(p, true); // this is the current pressure solution at the nodes - distributed at the processors with repeated values
438
439 // Reset here the viscosity so at this moment this makes only sense to call at the end of a simulation
440 // to visualize viscosity field
441 // @ToDo Add possibility for transient problem to save viscosity solution in each time step
442 viscosity_element_ = Teuchos::rcp( new MultiVector_Type( this->getDomain(0)->getElementMap() ) );
443 this->feFactory_->computeSteadyViscosityFE_CM(this->dim_, this->getDomain(0)->getFEType(), this->getDomain(1)->getFEType(), this->dim_,1,u_rep_,p_rep_,this->parameterList_);
444
445 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
446 viscosity_element_->importFromVector(exportSolutionViscosityAssFE, true);
447
448
449
450}
451
452
453
454
455
456
457
458}
459
460#endif
Definition NonLinearProblem_decl.hpp:24
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:33