1#ifndef NAVIERSTOKESASSFE_def_hpp
2#define NAVIERSTOKESASSFE_def_hpp
13#include "feddlib/core/FE/Domain.hpp"
14#include "feddlib//core/FE/FE.hpp"
15#include "feddlib/problems/Solver/Preconditioner.hpp"
16#include "feddlib/core/General/BCBuilder.hpp"
47template<
class SC,
class LO,
class GO,
class NO>
48NavierStokesAssFE<SC,LO,GO,NO>::NavierStokesAssFE(
const DomainConstPtr_Type &domainVelocity, std::string FETypeVelocity,
const DomainConstPtr_Type &domainPressure, std::string FETypePressure, ParameterListPtr_Type parameterList ):
51pressureIDsLoc(new vec_int_Type(2)),
57 this->nonLinearTolerance_ = this->parameterList_->sublist(
"Parameter").get(
"relNonLinTol",1.0e-6);
58 this->initNOXParameters();
60 this->addVariable( domainVelocity , FETypeVelocity ,
"u" , domainVelocity->getDimension());
61 this->addVariable( domainPressure , FETypePressure ,
"p" , 1);
62 this->dim_ = this->getDomain(0)->getDimension();
64 u_rep_ = Teuchos::rcp(
new MultiVector_Type( this->getDomain(0)->getMapVecFieldRepeated() ) );
66 p_rep_ = Teuchos::rcp(
new MultiVector_Type( this->getDomain(1)->getMapRepeated() ) );
68 if (parameterList->sublist(
"Parameter").get(
"Calculate Coefficients",
false)) {
69 vec2D_dbl_ptr_Type vectmpPointsPressure = domainPressure->getPointsUnique();
70 vec2D_dbl_Type::iterator it;
73 if (domainPressure->getDimension() == 2) {
74 it = find_if(vectmpPointsPressure->begin(), vectmpPointsPressure->end(),
75 [&] (
const std::vector<double>& a){
76 if (a.at(0) >= 0.15-1.e-12 && a.at(0) <= 0.15+1.e-12
77 && a.at(1) >= 0.2-1.e-12 && a.at(1) <= 0.2+1.e-12) {
85 if (it != vectmpPointsPressure->end()) {
86 front = distance(vectmpPointsPressure->begin(),it);
88 it = find_if(vectmpPointsPressure->begin(), vectmpPointsPressure->end(),
89 [&] (
const std::vector<double>& a){
90 if (a.at(0) >= 0.25-1.e-12 && a.at(0) <= 0.25+1.e-12
91 && a.at(1) >= 0.2-1.e-12 && a.at(1) <= 0.2+1.e-12) {
99 if (it != vectmpPointsPressure->end()) {
100 back = distance(vectmpPointsPressure->begin(),it);
102 pressureIDsLoc->at(0) = front;
103 pressureIDsLoc->at(1) = back;
105 else if(domainPressure->getDimension() == 3){
106#ifdef ASSERTS_WARNINGS
107 MYASSERT(
false,
"Not implemented to calc coefficients in 3D!");
114template<
class SC,
class LO,
class GO,
class NO>
115void NavierStokesAssFE<SC,LO,GO,NO>::info(){
117 this->infoNonlinProblem();
120template<
class SC,
class LO,
class GO,
class NO>
125 std::cout <<
"-- Assembly Navier-Stokes ... " << std::endl;
127 assembleConstantMatrices();
130 std::cout <<
"done -- " << std::endl;
137template<
class SC,
class LO,
class GO,
class NO>
138void NavierStokesAssFE<SC,LO,GO,NO>::assembleConstantMatrices()
const{
141 std::cout <<
"-- Assembly constant matrices Navier-Stokes ... " << std::flush;
143 double viscosity = this->parameterList_->sublist(
"Parameter").get(
"Viscosity",1.);
144 double density = this->parameterList_->sublist(
"Parameter").get(
"Density",1.);
149 A_.reset(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
151 MapConstPtr_Type pressureMap;
152 if ( this->getDomain(1)->getFEType() ==
"P0" )
153 pressureMap = this->getDomain(1)->getElementMap();
155 pressureMap = this->getDomain(1)->getMapUnique();
157 if (this->system_.is_null())
158 this->system_.reset(
new BlockMatrix_Type(2));
160 if (this->residualVec_.is_null())
161 this->residualVec_.reset(
new BlockMultiVector_Type(2));
163 MatrixPtr_Type B(
new Matrix_Type( pressureMap, this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
164 MatrixPtr_Type BT(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(1)->getDimension() * this->getDomain(1)->getApproxEntriesPerRow() ) );
167 this->system_->addBlock(A_,0,0);
168 this->system_->addBlock(BT,0,1);
169 this->system_->addBlock(B,1,0);
171 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);
173 if ( !this->getFEType(0).compare(
"P1") ) {
174 MatrixPtr_Type C(
new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
175 this->feFactory_->assemblyBDStabilization( this->dim_,
"P1", C,
true);
177 C->scale( -1. / ( viscosity * density ) );
178 C->fillComplete( pressureMap, pressureMap );
180 this->system_->addBlock( C, 1, 1 );
189 if(this->parameterList_->sublist(
"Parameter").get(
"Use Pressure Projection",
false) && (!this->getFEType(0).compare(
"P2") || (!this->getFEType(0).compare(
"Q2") && !this->getFEType(1).compare(
"Q1"))) && !this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic").compare(
"Monolithic")){
191 BlockMultiVectorPtr_Type projection(
new BlockMultiVector_Type (2));
193 MultiVectorPtr_Type P(
new MultiVector_Type( this->getDomain(1)->getMapUnique(), 1 ) );
195 this->feFactory_->assemblyPressureMeanValue( this->dim_,
"P1",P) ;
197 MultiVectorPtr_Type vel0(
new MultiVector_Type( this->getDomain(0)->getMapVecFieldUnique(), 1 ) );
201 projection->addBlock(vel0,0);
202 projection->addBlock(P,1);
205 this->getPreconditionerConst()->setPressureProjection( projection );
208 std::cout <<
"\n 'Use pressure correction' was set to 'true'. This requieres a version of Trilinos of that includes pressure correction in the FROSch_OverlappingOperator!!" << std::endl;
214 if ( !this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic").compare(
"Teko") ) {
215 if (!this->parameterList_->sublist(
"General").get(
"Assemble Velocity Mass",
false)) {
216 MatrixPtr_Type Mvelocity(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getApproxEntriesPerRow() ) );
218 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(0),
"Vector", Mvelocity,
true );
220 this->getPreconditionerConst()->setVelocityMassMatrix( Mvelocity );
222 std::cout <<
"\nVelocity mass matrix for LSC block preconditioner is assembled." << std::endl;
225 std::cout <<
"\nVelocity mass matrix for LSC block preconditioner not assembled." << std::endl;
229 std::string precType = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
230 if ( precType ==
"Diagonal" || precType ==
"Triangular" ) {
231 MatrixPtr_Type Mpressure(
new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
233 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(1),
"Scalar", Mpressure,
true );
234 SC kinVisco = this->parameterList_->sublist(
"Parameter").get(
"Viscosity",1.);
235 Mpressure->scale(-1./kinVisco);
236 this->getPreconditionerConst()->setPressureMassMatrix( Mpressure );
239 std::cout <<
"done -- " << std::endl;
243template<
class SC,
class LO,
class GO,
class NO>
244void NavierStokesAssFE<SC,LO,GO,NO>::reAssemble( MatrixPtr_Type& massmatrix, std::string type )
const
251template<
class SC,
class LO,
class GO,
class NO>
252void NavierStokesAssFE<SC,LO,GO,NO>::reAssemble(std::string type)
const {
256 std::cout <<
"-- Reassembly Navier-Stokes ("<< type <<
") ... " << std::flush;
258 double density = this->parameterList_->sublist(
"Parameter").get(
"Density",1.);
260 MatrixPtr_Type ANW = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
262 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
263 u_rep_->importFromVector(u,
true);
265 MultiVectorConstPtr_Type p = this->solution_->getBlock(1);
266 p_rep_->importFromVector(p,
true);
271 this->system_->addBlock(ANW,0,0);
275 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);
278 else if (type==
"FixedPoint" ) {
280 this->system_->addBlock(ANW,0,0);
281 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);
283 else if(type==
"Newton"){
285 this->system_->addBlock(ANW,0,0);
286 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);
290 this->system_->addBlock(ANW,0,0);
293 std::cout <<
"done -- " << std::endl;
299template<
class SC,
class LO,
class GO,
class NO>
303 this->reAssemble(
"Rhs");
306 if(this->getDomain(0)->getFEType() ==
"P1"){
308 MultiVectorPtr_Type residualPressureTmp = Teuchos::rcp(
new MultiVector_Type( this->getDomain(1)->getMapUnique() ));
310 this->system_->getBlock(1,1)->apply( *(this->solution_->getBlock(1)), *residualPressureTmp);
312 this->residualVec_->getBlockNonConst(1)->update(1.,*residualPressureTmp,1.);
324 if (!type.compare(
"standard")){
325 this->residualVec_->update(-1.,*this->rhs_,1.);
329 this->bcFactory_->setVectorMinusBC( this->residualVec_, this->solution_, time );
332 else if(!type.compare(
"reverse")){
333 this->residualVec_->update(1.,*this->rhs_,-1.);
337 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );
343template<
class SC,
class LO,
class GO,
class NO>
344void NavierStokesAssFE<SC,LO,GO,NO>::calculateNonLinResidualVecWithMeshVelo(std::string type,
double time, MultiVectorPtr_Type u_minus_w, MatrixPtr_Type P)
const{
352 this->system_->apply( *this->solution_, *this->residualVec_ );
355 if (!type.compare(
"standard")){
356 this->residualVec_->update(-1.,*this->rhs_,1.);
357 if ( !this->sourceTerm_.is_null() )
358 this->residualVec_->update(-1.,*this->sourceTerm_,1.);
360 else if(!type.compare(
"reverse")){
361 this->residualVec_->update(1.,*this->rhs_,-1.);
362 if ( !this->sourceTerm_.is_null() )
363 this->residualVec_->update(1.,*this->sourceTerm_,1.);
367 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );
410template<
class SC,
class LO,
class GO,
class NO>
411void NavierStokesAssFE<SC,LO,GO,NO>::reAssembleExtrapolation(BlockMultiVectorPtrArray_Type previousSolutions){
414 std::cout <<
"-- Reassembly Navier-Stokes (Extrapolation) ... " << std::flush;
417 double density = this->parameterList_->sublist(
"Parameter").get(
"Density",1.);
419 if (previousSolutions.size()>=2) {
421 MultiVectorPtr_Type extrapolatedVector = Teuchos::rcp(
new MultiVector_Type( previousSolutions[0]->getBlock(0) ) );
423 extrapolatedVector->update( -1., *previousSolutions[1]->getBlock(0), 2. );
425 u_rep_->importFromVector(extrapolatedVector,
true);
427 else if(previousSolutions.size()==1){
428 MultiVectorConstPtr_Type u = previousSolutions[0]->getBlock(0);
429 u_rep_->importFromVector(u,
true);
431 else if (previousSolutions.size()==0){
432 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
433 u_rep_->importFromVector(u,
true);
436 MatrixPtr_Type ANW = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
438 MatrixPtr_Type N = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
439 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_rep_,
true );
443 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
445 A_->addMatrix(1.,ANW,0.);
446 N->addMatrix(1.,ANW,1.);
448 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
450 this->system_->addBlock( ANW, 0, 0 );
453 std::cout <<
"done -- " << std::endl;
462template<
class SC,
class LO,
class GO,
class NO>
463void NavierStokesAssFE<SC,LO,GO,NO>::computeSteadyPostprocessingViscosity_Solution() {
466 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
467 u_rep_->importFromVector(u,
true);
469 MultiVectorConstPtr_Type p = this->solution_->getBlock(1);
470 p_rep_->importFromVector(p,
true);
475 viscosity_element_ = Teuchos::rcp(
new MultiVector_Type( this->getDomain(0)->getElementMap() ) );
476 this->feFactory_->computeSteadyViscosityFE_CM(this->dim_, this->getDomain(0)->getFEType(), this->getDomain(1)->getFEType(), this->dim_,1,u_rep_,p_rep_,this->parameterList_);
478 Teuchos::RCP<const MultiVector<SC,LO,GO,NO>> exportSolutionViscosityAssFE = this->feFactory_->const_output_fields->getBlock(0);
479 viscosity_element_->importFromVector(exportSolutionViscosityAssFE,
true);
virtual void assemble(std::string type="") const
assemble of type exectuted by the derived specific non-linear problem classes
Definition NavierStokesAssFE_def.hpp:121
virtual void calculateNonLinResidualVec(std::string type="standard", double time=0.) const
Virtual function which is implemented in the specific non-linear problem classes to calculate the non...
Definition NavierStokesAssFE_def.hpp:300
Definition NonLinearProblem_decl.hpp:28
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36