90 if (it != vectmpPointsPressure->end()) {
91 back = distance(vectmpPointsPressure->begin(),it);
93 pressureIDsLoc->at(0) = front;
94 pressureIDsLoc->at(1) = back;
96 else if(domainPressure->getDimension() == 3){
97#ifdef ASSERTS_WARNINGS
98 MYASSERT(
false,
"Not implemented to calc coefficients in 3D!");
105template<
class SC,
class LO,
class GO,
class NO>
106void NavierStokes<SC,LO,GO,NO>::info(){
108 this->infoNonlinProblem();
111template<
class SC,
class LO,
class GO,
class NO>
112void NavierStokes<SC,LO,GO,NO>::assemble( std::string type )
const{
116 std::cout <<
"-- Assembly Navier-Stokes ... " << std::endl;
118 assembleConstantMatrices();
121 std::cout <<
"done -- " << std::endl;
128template<
class SC,
class LO,
class GO,
class NO>
129void NavierStokes<SC,LO,GO,NO>::assembleConstantMatrices()
const{
132 std::cout <<
"-- Assembly constant matrices Navier-Stokes ... " << std::flush;
134 double viscosity = this->parameterList_->sublist(
"Parameter").get(
"Viscosity",1.);
135 double density = this->parameterList_->sublist(
"Parameter").get(
"Density",1.);
140 A_.reset(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
142 if ( this->parameterList_->sublist(
"Parameter").get(
"Symmetric gradient",
false) )
143 this->feFactory_->assemblyStress(this->dim_, this->domain_FEType_vec_.at(0), A_, OneFunction, dummy,
true);
145 this->feFactory_->assemblyLaplaceVecField(this->dim_, this->domain_FEType_vec_.at(0), 2, A_,
true);
149 A_->scale(viscosity);
152 A_->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
154 if (this->system_.is_null())
155 this->system_.reset(
new BlockMatrix_Type(2));
157 this->system_->addBlock( A_, 0, 0 );
158 assembleDivAndStab();
161 if ( !this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic").compare(
"Teko") ) {
162 if (!this->parameterList_->sublist(
"General").get(
"Assemble Velocity Mass",
false)) {
163 MatrixPtr_Type Mvelocity(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getApproxEntriesPerRow() ) );
165 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(0),
"Vector", Mvelocity,
true );
167 this->getPreconditionerConst()->setVelocityMassMatrix( Mvelocity );
169 std::cout <<
"\nVelocity mass matrix for LSC block preconditioner is assembled." << std::endl;
172 std::cout <<
"\nVelocity mass matrix for LSC block preconditioner not assembled." << std::endl;
176 std::string precType = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
177 if ( precType ==
"Diagonal" || precType ==
"Triangular" ) {
178 MatrixPtr_Type Mpressure(
new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
180 this->feFactory_->assemblyMass( this->dim_, this->domain_FEType_vec_.at(1),
"Scalar", Mpressure,
true );
181 SC kinVisco = this->parameterList_->sublist(
"Parameter").get(
"Viscosity",1.);
182 Mpressure->scale(-1./kinVisco);
183 this->getPreconditionerConst()->setPressureMassMatrix( Mpressure );
187 std::cout <<
" Call Reassemble FixedPoint and Newton to allocate the Matrix pattern " << std::endl;
191 this->reAssemble(
"FixedPoint");
192 this->reAssemble(
"Newton");
195 std::cout <<
"done -- " << std::endl;
199template<
class SC,
class LO,
class GO,
class NO>
200void NavierStokes<SC,LO,GO,NO>::assembleDivAndStab()
const{
202 double viscosity = this->parameterList_->sublist(
"Parameter").get(
"Viscosity",1.);
203 double density = this->parameterList_->sublist(
"Parameter").get(
"Density",1.);
207 MatrixPtr_Type BT(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(1)->getDimension() * this->getDomain(1)->getApproxEntriesPerRow() ) );
209 MapConstPtr_Type pressureMap;
210 if ( this->getDomain(1)->getFEType() ==
"P0" )
211 pressureMap = this->getDomain(1)->getElementMap();
213 pressureMap = this->getDomain(1)->getMapUnique();
215 MatrixPtr_Type B(
new Matrix_Type( pressureMap, this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
219 this->feFactory_->assemblyDivAndDivTFast(this->dim_, this->getFEType(0), this->getFEType(1), 2, B, BT, this->getDomain(0)->getMapVecFieldUnique(), pressureMap,
true );
227 B->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), pressureMap );
228 BT->fillComplete( pressureMap, this->getDomain(0)->getMapVecFieldUnique() );
230 this->system_->addBlock( BT, 0, 1 );
231 this->system_->addBlock( B, 1, 0 );
233 if ( !this->getFEType(0).compare(
"P1") ) {
234 C.reset(
new Matrix_Type( this->getDomain(1)->getMapUnique(), this->getDomain(1)->getApproxEntriesPerRow() ) );
235 this->feFactory_->assemblyBDStabilization( this->dim_,
"P1", C,
true);
237 C->scale( -1. / ( viscosity * density ) );
238 C->fillComplete( pressureMap, pressureMap );
240 this->system_->addBlock( C, 1, 1 );
250template<
class SC,
class LO,
class GO,
class NO>
251void NavierStokes<SC,LO,GO,NO>::reAssemble( MatrixPtr_Type& massmatrix, std::string type )
const
256template<
class SC,
class LO,
class GO,
class NO>
257void NavierStokes<SC,LO,GO,NO>::reAssembleFSI(std::string type, MultiVectorPtr_Type u_minus_w, MatrixPtr_Type P)
const {
260 std::cout <<
"-- Reassembly Navier-Stokes ("<< type <<
") for FSI ... " << std::flush;
262 double density = this->parameterList_->sublist(
"Parameter").get(
"Density",1.);
264 MatrixPtr_Type ANW = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
265 if (type==
"FixedPoint") {
267 MatrixPtr_Type N = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
268 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_minus_w,
true );
272 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
273 A_->addMatrix(1.,ANW,0.);
275 N->addMatrix(1.,ANW,1.);
277 P->addMatrix(1.,ANW,1.);
281 else if(type==
"Newton"){
282 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"reAssembleFSI should only be called for FPI-System.");
284 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
286 this->system_->addBlock( ANW, 0, 0 );
289 std::cout <<
"done -- " << std::endl;
293template<
class SC,
class LO,
class GO,
class NO>
294void NavierStokes<SC,LO,GO,NO>::reAssemble(std::string type)
const {
298 std::cout <<
"-- Reassembly Navier-Stokes ("<< type <<
") ... " << std::flush;
300 double density = this->parameterList_->sublist(
"Parameter").get(
"Density",1.);
302 MatrixPtr_Type ANW = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
303 if (type==
"FixedPoint") {
305 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
306 u_rep_->importFromVector(u,
true);
308 MatrixPtr_Type N = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
309 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_rep_,
true );
313 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
315 A_->addMatrix(1.,ANW,0.);
316 N->addMatrix(1.,ANW,1.);
318 else if(type==
"Newton"){
319 MatrixPtr_Type W = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
320 this->feFactory_->assemblyAdvectionInUVecField( this->dim_, this->domain_FEType_vec_.at(0), W, u_rep_,
true );
323 W->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
324 this->system_->getBlock( 0, 0 )->addMatrix(1.,ANW,0.);
325 W->addMatrix(1.,ANW,1.);
327 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
329 this->system_->addBlock( ANW, 0, 0 );
332 std::cout <<
"done -- " << std::endl;
335template<
class SC,
class LO,
class GO,
class NO>
336void NavierStokes<SC,LO,GO,NO>::reAssembleExtrapolation(BlockMultiVectorPtrArray_Type previousSolutions){
339 std::cout <<
"-- Reassembly Navier-Stokes (Extrapolation) ... " << std::flush;
342 double density = this->parameterList_->sublist(
"Parameter").get(
"Density",1.);
344 if (previousSolutions.size()>=2) {
346 MultiVectorPtr_Type extrapolatedVector = Teuchos::rcp(
new MultiVector_Type( previousSolutions[0]->getBlock(0) ) );
348 extrapolatedVector->update( -1., *previousSolutions[1]->getBlock(0), 2. );
350 u_rep_->importFromVector(extrapolatedVector,
true);
352 else if(previousSolutions.size()==1){
353 MultiVectorConstPtr_Type u = previousSolutions[0]->getBlock(0);
354 u_rep_->importFromVector(u,
true);
356 else if (previousSolutions.size()==0){
357 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
358 u_rep_->importFromVector(u,
true);
361 MatrixPtr_Type ANW = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
363 MatrixPtr_Type N = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
364 this->feFactory_->assemblyAdvectionVecField( this->dim_, this->domain_FEType_vec_.at(0), N, u_rep_,
true );
368 N->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique());
370 A_->addMatrix(1.,ANW,0.);
371 N->addMatrix(1.,ANW,1.);
373 ANW->fillComplete( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getMapVecFieldUnique() );
375 this->system_->addBlock( ANW, 0, 0 );
378 std::cout <<
"done -- " << std::endl;
484template<
class SC,
class LO,
class GO,
class NO>
485void NavierStokes<SC,LO,GO,NO>::evalModelImpl(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
486 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs
489 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
490 if ( !type.compare(
"Monolithic"))
491 evalModelImplMonolithic( inArgs, outArgs );
492 else if ( !type.compare(
"Teko")){
494 evalModelImplBlock( inArgs, outArgs );
496 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Teko not found! Build Trilinos with Teko.");
500 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unkown preconditioner/solver type.");
507template<
class SC,
class LO,
class GO,
class NO>
508void NavierStokes<SC,LO,GO,NO>::evalModelImplMonolithic(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
509 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs )
const
515 using Teuchos::rcp_dynamic_cast;
516 using Teuchos::rcp_const_cast;
517 using Teuchos::ArrayView;
518 using Teuchos::Array;
519 RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
520 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
522 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
523 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
525 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
527 this->solution_->fromThyraMultiVector(vecThyraNonConst);
529 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
530 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
531 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
533 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
534 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
535 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
536 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
538 const bool fill_f = nonnull(f_out);
539 const bool fill_W = nonnull(W_out);
540 const bool fill_W_prec = nonnull(W_prec_out);
543 if ( fill_f || fill_W || fill_W_prec ) {
550 this->calculateNonLinResidualVec(
"standard");
554 Teuchos::RCP<Thyra::MultiVectorBase<SC> > f_thyra = this->getResidualVector()->getThyraMultiVector();
555 f_out->assign(*f_thyra);
558 TpetraMatrixPtr_Type W;
560 this->reAssemble(
"Newton");
562 this->setBoundariesSystem();
564 Teuchos::RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator(W_out);
565 Teuchos::RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
567 TpetraMatrixConstPtr_Type W_systemTpetra = this->getSystem()->getMergedMatrix()->getTpetraMatrix();
568 TpetraMatrixPtr_Type W_systemTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_systemTpetra);
573 Teuchos::RCP<TpetraMatrix_Type> tpetraMatTpetra = W_systemTpetraNonConst;
575 W_tpetraMat->resumeFill();
577 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
578 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
579 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
580 tpetraMatTpetra->getLocalRowView( i, indices, values);
581 W_tpetraMat->replaceLocalValues( i, indices, values);
583 W_tpetraMat->fillComplete();
588 this->setupPreconditioner(
"Monolithic" );
593 std::string levelCombination = this->parameterList_->sublist(
"ThyraPreconditioner").sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"Level Combination",
"Additive");
594 if (!levelCombination.compare(
"Multiplicative")) {
595 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Multiplicative Level Combination is not supported for NOX.");
619template<
class SC,
class LO,
class GO,
class NO>
620void NavierStokes<SC,LO,GO,NO>::evalModelImplBlock(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
621 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs )
const
627 using Teuchos::rcp_dynamic_cast;
628 using Teuchos::rcp_const_cast;
629 using Teuchos::ArrayView;
630 using Teuchos::Array;
632 RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
633 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
635 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
636 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
638 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
640 RCP< Thyra::ProductVectorBase< SC > > vecThyraBlock = rcp_dynamic_cast<Thyra::ProductVectorBase< SC > > (vecThyraNonConst);
642 this->solution_->getBlockNonConst(0)->fromThyraMultiVector( vecThyraBlock->getNonconstVectorBlock(0) );
643 this->solution_->getBlockNonConst(1)->fromThyraMultiVector( vecThyraBlock->getNonconstVectorBlock(1) );
645 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
646 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
647 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
649 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
650 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
651 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
652 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
654 const bool fill_f = nonnull(f_out);
655 const bool fill_W = nonnull(W_out);
656 const bool fill_W_prec = nonnull(W_prec_out);
658 if ( fill_f || fill_W || fill_W_prec ) {
665 this->calculateNonLinResidualVec(
"standard");
667 Teko::MultiVector f0;
668 Teko::MultiVector f1;
669 f0 = this->getResidualVector()->getBlockNonConst(0)->getThyraMultiVector();
670 f1 = this->getResidualVector()->getBlockNonConst(1)->getThyraMultiVector();
672 std::vector<Teko::MultiVector> f_vec; f_vec.push_back(f0); f_vec.push_back(f1);
674 Teko::MultiVector f = Teko::buildBlockedMultiVector(f_vec);
679 TpetraMatrixPtr_Type W;
682 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraCrsMatrix;
684 this->reAssemble(
"Newton");
686 this->setBoundariesSystem();
688 RCP<ThyraBlockOp_Type> W_blocks = rcp_dynamic_cast<ThyraBlockOp_Type>(W_out);
689 RCP<const ThyraOp_Type> W_block00 = W_blocks->getBlock(0,0);
690 RCP<ThyraOp_Type> W_block00NonConst = rcp_const_cast<ThyraOp_Type>( W_block00 );
691 RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator( W_block00NonConst );
693 RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
695 TpetraMatrixConstPtr_Type W_matrixTpetra = this->getSystem()->getBlock(0,0)->getTpetraMatrix();
696 TpetraMatrixPtr_Type W_matrixTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_matrixTpetra);
697 RCP<TpetraMatrix_Type> tpetraMatTpetra = W_matrixTpetraNonConst;
699 W_tpetraMat->resumeFill();
701 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
702 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
703 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
704 tpetraMatTpetra->getLocalRowView( i, indices, values);
705 W_tpetraMat->replaceLocalValues( i, indices, values);
707 W_tpetraMat->fillComplete();
712 if (stokesTekoPrecUsed_){
713 this->setupPreconditioner(
"Teko" );
716 stokesTekoPrecUsed_ =
true;
721 ParameterListPtr_Type tmpSubList = sublist( sublist( sublist( sublist( this->parameterList_,
"Teko Parameters" ) ,
"Preconditioner Types" ) ,
"Teko" ) ,
"Inverse Factory Library" );
723 std::string levelCombination1 = tmpSubList->sublist(
"FROSch-Velocity" ).get(
"Level Combination",
"Additive");
724 std::string levelCombination2 = tmpSubList->sublist(
"FROSch-Pressure" ).get(
"Level Combination",
"Additive");
726 if ( !levelCombination1.compare(
"Multiplicative") || !levelCombination2.compare(
"Multiplicative") ) {
728 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Multiplicative Level Combination is not supported for NOX.");
729 ParameterListPtr_Type solverPList = this->getLinearSolverBuilder()->getNonconstParameterList();
744template<
class SC,
class LO,
class GO,
class NO>
746 this->reAssemble(
"FixedPoint");
750 if (this->coeff_.size() == 0)
751 this->system_->apply( *this->solution_, *this->residualVec_ );
753 this->system_->apply( *this->solution_, *this->residualVec_, this->coeff_ );
755 if (!type.compare(
"standard")){
756 this->residualVec_->update(-1.,*this->rhs_,1.);
760 this->bcFactory_->setVectorMinusBC( this->residualVec_, this->solution_, time );
763 else if(!type.compare(
"reverse")){
764 this->residualVec_->update(1.,*this->rhs_,-1.);
768 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );