1#ifndef TIMEPROBLEM_DEF_hpp
2#define TIMEPROBLEM_DEF_hpp
3#include "TimeProblem_decl.hpp"
15template<
class SC,
class LO,
class GO,
class NO>
16TimeProblem<SC,LO,GO,NO>::TimeProblem(Problem_Type& problem, CommConstPtr_Type comm):
24dimension_(problem.getDomain(0)->getDimension()),
25verbose_(comm->getRank()==0),
26parameterList_(problem.getParameterList()),
27bcFactory_(problem.getBCFactory()),
29solutionPreviousTimesteps_(0),
30velocityPreviousTimesteps_(0),
31accelerationPreviousTimesteps_(0),
32systemMassPreviousTimeSteps_(0),
34#ifdef TIMEPROBLEM_TIMER
35,TimeSolveTimer_ (Teuchos::TimeMonitor::getNewCounter(
"TT Problem: Solve"))
39 problem_ = Teuchos::rcpFromRef(problem);
40 BCConstPtr_Type bcFaCSI;
41 if( problem_->preconditioner_->hasFaCSIBCFactory() )
42 bcFaCSI = problem_->preconditioner_->getFaCSIBCFactory();
44 problem_->preconditioner_ = Teuchos::rcp(
new Preconditioner_Type(
this ) );
46 if( !bcFaCSI.is_null() )
47 problem_->preconditioner_->setFaCSIBCFactory( bcFaCSI );
48 FEFacConstPtr_Type facConst = problem.getFEFactory();
49 feFactory_ = Teuchos::rcp_const_cast<FEFac_Type>(facConst);
51 systemMass_.reset(
new BlockMatrix_Type(1));
52 systemCombined_.reset(
new BlockMatrix_Type( 1 ) );
56template<
class SC,
class LO,
class GO,
class NO>
57void TimeProblem<SC,LO,GO,NO>::setTimeDef( SmallMatrix<int>& def ){
61template<
class SC,
class LO,
class GO,
class NO>
62void TimeProblem<SC,LO,GO,NO>::assemble( std::string type )
const{
64 std::string timestepping = parameterList_->sublist(
"Timestepping Parameter").get(
"Class",
"Singlestep");
66 if (type ==
"MassSystem"){
70 initializeCombinedSystems();
71 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
72 if (!nonLinProb.is_null()){
75 if (timestepping==
"External" )
76 this->systemCombined_ = problem_->getSystem();
78 this->combineSystems();
83 problem_->assemble(type);
85 if (timestepping==
"External")
86 this->systemCombined_ = problem_->getSystem();
88 this->combineSystems();
93template<
class SC,
class LO,
class GO,
class NO>
94void TimeProblem<SC,LO,GO,NO>::reAssembleAndFill( BlockMatrixPtr_Type bMat, std::string type ){
96 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
97 nonLinProb->reAssembleAndFill( bMat, type );
100template<
class SC,
class LO,
class GO,
class NO>
101void TimeProblem<SC,LO,GO,NO>::combineSystems()
const{
103 BlockMatrixPtr_Type tmpSystem = problem_->getSystem();
104 int size = tmpSystem->size();
105 systemCombined_.reset(
new BlockMatrix_Type ( size ) );
107 for (
int i=0; i<size; i++) {
108 DomainConstPtr_Type dom = this->getDomain(i);
109 for (
int j=0; j<size; j++) {
110 if ( tmpSystem->blockExists(i,j) ) {
111 LO maxNumEntriesPerRow = tmpSystem->getBlock(i,j)->getGlobalMaxNumRowEntries();
112 MatrixPtr_Type matrix = Teuchos::rcp(
new Matrix_Type( tmpSystem->getBlock(i,j)->getMap(), maxNumEntriesPerRow ) );
114 systemCombined_->addBlock( matrix, i, j );
117 else if (systemMass_->blockExists(i,j)) {
118 LO maxNumEntriesPerRow = systemMass_->getBlock(i,j)->getGlobalMaxNumRowEntries();
119 MatrixPtr_Type matrix = Teuchos::rcp(
new Matrix_Type( systemMass_->getBlock(i,j)->getMap(), maxNumEntriesPerRow) );
120 systemCombined_->addBlock( matrix, i, j );
124 SmallMatrix<SC> ones( size , Teuchos::ScalarTraits<SC>::one());
125 SmallMatrix<SC> zeros( size , Teuchos::ScalarTraits<SC>::zero());
126 systemMass_->addMatrix( massParameters_, systemCombined_, zeros );
127 tmpSystem->addMatrix( timeParameters_, systemCombined_, ones );
129 for (
int i=0; i<size; i++) {
130 for (
int j=0; j<size; j++) {
131 if ( systemCombined_->blockExists(i,j) ) {
132 if ( tmpSystem->blockExists(i,j) ) {
133 MatrixPtr_Type matrix = tmpSystem->getBlock(i,j);
134 MatrixConstPtr_Type matrixConstComb = systemCombined_->getBlock(i,j);
135 MatrixPtr_Type matrixComb = Teuchos::rcp_const_cast<Matrix_Type>(matrixConstComb);
136 matrixComb->fillComplete( matrix->getMap(
"domain"), matrix->getMap(
"range") );
138 else if ( systemMass_->blockExists(i,j) ) {
139 MatrixPtr_Type matrix = systemMass_->getBlock(i,j);
140 MatrixConstPtr_Type matrixConstComb = systemCombined_->getBlock(i,j);
141 MatrixPtr_Type matrixComb = Teuchos::rcp_const_cast<Matrix_Type>(matrixConstComb);
142 matrixComb->fillComplete( matrix->getMap(
"domain"), matrix->getMap(
"range") );
145 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"TimeProblem: Combined systems possess a block which does not exist in partial systems.");
151template<
class SC,
class LO,
class GO,
class NO>
152void TimeProblem<SC,LO,GO,NO>::updateRhs(){
154 systemMass_->apply( *solutionPreviousTimesteps_[0], *problem_->getRhs(), massParameters_ );
157template<
class SC,
class LO,
class GO,
class NO>
158void TimeProblem<SC,LO,GO,NO>::updateMultistepRhs(vec_dbl_Type& coeff,
int nmbToUse){
160 problem_->getRhs()->putScalar(0.);
162 int size = massParameters_.size();
164 for (
int i=0; i<nmbToUse; i++) {
165 SmallMatrix<SC> tmpMassParameter(size);
166 for (
int r=0; r<size; r++) {
167 for (
int s=0; s<size; s++) {
168 if (massParameters_[r][s]!=0.)
169 tmpMassParameter[r][s] = coeff[i];
172 BlockMultiVectorPtr_Type tmpVector
173 = Teuchos::rcp(
new BlockMultiVector_Type( problem_->getRhs() ) );
174 BlockMultiVectorPtr_Type tmpBlockVector = solutionPreviousTimesteps_[i];
175 systemMass_->apply( *tmpBlockVector, *tmpVector, tmpMassParameter );
176 problem_->getRhs()->update( 1., tmpVector, 1. );
182template<
class SC,
class LO,
class GO,
class NO>
183void TimeProblem<SC,LO,GO,NO>::updateMultistepRhsFSI(vec_dbl_Type& coeff,
int nmbToUse){
185 problem_->getRhs()->putScalar(0.);
187 int size = massParameters_.size();
189 for (
int i=0; i<nmbToUse; i++) {
190 SmallMatrix<SC> tmpMassParameter(size);
191 for (
int r=0; r<size; r++) {
192 for (
int s=0; s<size; s++) {
193 if (massParameters_[r][s]!=0.) {
194 tmpMassParameter[r][s] = coeff[i];
199 BlockMultiVectorPtr_Type tmpVector
200 = Teuchos::rcp(
new BlockMultiVector_Type( problem_->getRhs() ) );
201 BlockMultiVectorPtr_Type tmpBlockVector = solutionPreviousTimesteps_[i];
202 systemMassPreviousTimeSteps_[i]->apply( *tmpBlockVector, *tmpVector, tmpMassParameter );
203 problem_->getRhs()->update( 1., tmpVector, 1. );
213template<
class SC,
class LO,
class GO,
class NO>
214void TimeProblem<SC,LO,GO,NO>::updateNewmarkRhs(
double dt,
double beta,
double gamma, vec_dbl_Type coeff)
227 BlockMultiVectorPtrArray_Type tempVector1(1);
229 tempVector1.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(0)));
232 tempVector1.at(0)->scale(1.0/(dt*dt*beta));
235 tempVector1.at(0)->update(1.0/(dt*beta), *(velocityPreviousTimesteps_[0]), (0.5 - beta)/beta, *(accelerationPreviousTimesteps_[0]), 1.0);
240 BlockMultiVectorPtrArray_Type tempVector2(1);
241 tempVector2.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(0)));
245 int size = massParameters_.size();
246 SmallMatrix<double> tmpMassParameter(size);
247 for(
int r = 0; r < size; r++)
249 for(
int s = 0; s < size; s++)
251 if(massParameters_[r][s] != 0.0)
253 tmpMassParameter[r][s] = coeff.at(0);
260 systemMass_->apply(*(tempVector1.at(0)), *(tempVector2.at(0)), tmpMassParameter);
263 problem_->getRhs()->update(1.0, *(tempVector2.at(0)), .0);
268template<
class SC,
class LO,
class GO,
class NO>
269typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getSolution(){
271 return problem_->getSolution();
274template<
class SC,
class LO,
class GO,
class NO>
275typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorConstPtr_Type TimeProblem<SC,LO,GO,NO>::getSolutionConst()
const {
276 return problem_->getSolution();
279template<
class SC,
class LO,
class GO,
class NO>
280typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getResidual(){
282 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
283 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
284 return nonLinProb->getResidualVector ();
287template<
class SC,
class LO,
class GO,
class NO>
288typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorConstPtr_Type TimeProblem<SC,LO,GO,NO>::getResidualConst()
const{
290 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
291 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
292 return nonLinProb->getResidualVector ();
295template<
class SC,
class LO,
class GO,
class NO>
296typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getSolutionPreviousTimestep(){
298 return solutionPreviousTimesteps_[0];
301template<
class SC,
class LO,
class GO,
class NO>
302typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtrArray_Type TimeProblem<SC,LO,GO,NO>::getSolutionAllPreviousTimestep(){
304 return solutionPreviousTimesteps_;
307template<
class SC,
class LO,
class GO,
class NO>
308void TimeProblem<SC,LO,GO,NO>::initializeCombinedSystems()
const{
310 BlockMatrixConstPtr_Type blockMatrixProblem = problem_->getSystem();
312 int size = blockMatrixProblem->size();
314 for (
int i=0; i<size; i++) {
315 for (
int j=0; j<size; j++) {
316 MatrixPtr_Type matrix;
317 bool foundMatrix =
false;
318 if ( blockMatrixProblem->blockExists(i,j) ) {
319 MatrixConstPtr_Type matrixProblem = blockMatrixProblem->getBlockConst(i,j);
320 MapConstPtr_Type map = matrixProblem->getMap();
321 MapPtr_Type mapNonConst = Teuchos::rcp_const_cast<Map_Type> (map);
322 matrix = Teuchos::rcp(
new Matrix_Type( mapNonConst, matrixProblem->getGlobalMaxNumRowEntries() ) );
325 else if( systemMass_->blockExists(i,j) && !foundMatrix ){
326 MatrixConstPtr_Type matrixMass = systemMass_->getBlockConst(i,j);
327 MapConstPtr_Type map = matrixMass->getMap();
328 MapPtr_Type mapNonConst = Teuchos::rcp_const_cast<Map_Type> (map);
329 matrix = Teuchos::rcp(
new Matrix_Type( mapNonConst, matrixMass->getGlobalMaxNumRowEntries() ) );
333 systemCombined_->addBlock( matrix, i, j );
339template<
class SC,
class LO,
class GO,
class NO>
340void TimeProblem<SC,LO,GO,NO>::assembleMassSystem( )
const {
343 ProblemPtr_Type tmpProblem;
344 SC eps100 = 100.*Teuchos::ScalarTraits<SC>::eps();
347 double density = parameterList_->sublist(
"Parameter").get(
"Density",1.);
349 int size = problem_->getSystem()->size();
350 systemMass_->resize( size );
352 for (
int i=0; i<size; i++ ) {
353 dofsPerNode = problem_->getDofsPerNode(i);
355 if ( timeStepDef_[i][i]>0 ) {
357 M = Teuchos::rcp(
new Matrix_Type( this->getDomain(i)->getMapVecFieldUnique(), dimension_*this->getDomain(i)->getApproxEntriesPerRow() ) );
358 feFactory_->assemblyMass(dimension_, problem_->getFEType(i),
"Vector", M,
true);
362 M->fillComplete( this->getDomain(i)->getMapVecFieldUnique(), this->getDomain(i)->getMapVecFieldUnique());
364 systemMass_->addBlock(M, i, i);
367 M = Teuchos::rcp(
new Matrix_Type( this->getDomain(i)->getMapUnique(), this->getDomain(i)->getApproxEntriesPerRow() ) );
368 feFactory_->assemblyMass(dimension_, problem_->getFEType(i),
"Scalar", M,
true);
372 M->fillComplete( this->getDomain(i)->getMapUnique(), this->getDomain(i)->getMapUnique());
374 systemMass_->addBlock(M, i, i);
378 for (
int j=0; j<size; j++) {
379 if (timeStepDef_[i][j]==2) {
381 M = Teuchos::rcp(
new Matrix_Type( this->getDomain(i)->getMapVecFieldUnique(), this->getDomain(i)->getApproxEntriesPerRow() ) );
382 feFactory_->assemblyMass(dimension_, problem_->getFEType(i),
"Vector", M,
true);
386 M->fillComplete( this->getDomain(i)->getMapVecFieldUnique(), this->getDomain(i)->getMapVecFieldUnique());
388 systemMass_->addBlock(M, i, j);
391 M = Teuchos::rcp(
new Matrix_Type( this->getDomain(i)->getMapUnique(), this->getDomain(i)->getApproxEntriesPerRow() ) );
392 feFactory_->assemblyMass(dimension_, problem_->getFEType(i),
"Scalar", M,
true);
396 M->fillComplete( this->getDomain(i)->getMapUnique(), this->getDomain(i)->getMapUnique());
398 systemMass_->addBlock(M, i, j);
406template<
class SC,
class LO,
class GO,
class NO>
407void TimeProblem<SC,LO,GO,NO>::setTimeParameters(SmallMatrix<double> &massParameters, SmallMatrix<double> &timeParameters){
409 timeParameters_ = timeParameters;
411 massParameters_ = massParameters;
415template<
class SC,
class LO,
class GO,
class NO>
416bool TimeProblem<SC,LO,GO,NO>::getVerbose(){
421template<
class SC,
class LO,
class GO,
class NO>
422double TimeProblem<SC,LO,GO,NO>::calculateResidualNorm(){
424 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
425 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
426 Teuchos::Array<SC> res(1);
427 nonLinProb->getResidualVector()->norm2(res);
431template<
class SC,
class LO,
class GO,
class NO>
432void TimeProblem<SC,LO,GO,NO>::calculateNonLinResidualVec( std::string type,
double time )
const{
434 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
435 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
437 if (type ==
"external") {
438 nonLinProb->calculateNonLinResidualVec(
"external" );
443 nonLinProb->calculateNonLinResidualVec( timeParameters_ ,type, time );
446 if (this->parameterList_->sublist(
"Parameter").get(
"FSI",
false) ){
447 bool geometryExplicit = this->parameterList_->sublist(
"Parameter").get(
"Geometry Explicit",
true);
448 if( !geometryExplicit ) {
449 typedef FSI<SC,LO,GO,NO> FSI_Type;
450 typedef Teuchos::RCP<FSI_Type> FSIPtr_Type;
452 MatrixPtr_Type massmatrix;
453 FSIPtr_Type fsi = Teuchos::rcp_dynamic_cast<FSI_Type>( this->problem_ );
454 fsi->setFluidMassmatrix( massmatrix );
455 this->systemMass_->addBlock( massmatrix, 0, 0 );
460 BlockMultiVectorPtr_Type tmpMV = Teuchos::rcp(
new BlockMultiVector_Type( nonLinProb->getSolution() ) );
461 tmpMV->putScalar(0.);
463 systemMass_->apply( *nonLinProb->getSolution(), *tmpMV, massParameters_ );
466 nonLinProb->getResidualVector()->update(-1,*tmpMV,1.);
467 else if(type==
"standard")
468 nonLinProb->getResidualVector()->update(1,*tmpMV,1.);
470 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"Unkown type to compute the residual for a time problem.");
473 this->bcFactory_->setBCMinusVector( nonLinProb->getResidualVector(), nonLinProb->getSolution(), time );
474 else if(type==
"standard")
475 this->bcFactory_->setVectorMinusBC( nonLinProb->getResidualVector(), nonLinProb->getSolution(), time );
482template<
class SC,
class LO,
class GO,
class NO>
483void TimeProblem<SC,LO,GO,NO>::setBoundaries(
double time){
485 BlockMultiVectorPtr_Type tmpRhs = problem_->getRhs();
487 bcFactory_->set( systemCombined_, tmpRhs, time );
490template<
class SC,
class LO,
class GO,
class NO>
491void TimeProblem<SC,LO,GO,NO>::setBoundariesRHS(
double time){
493 BlockMultiVectorPtr_Type tmpRhs = problem_->getRhs();
495 bcFactory_->setRHS( tmpRhs, time );
498template<
class SC,
class LO,
class GO,
class NO>
499void TimeProblem<SC,LO,GO,NO>::setBoundariesSystem()
const{
501 bcFactory_->setSystem(systemCombined_);
505template<
class SC,
class LO,
class GO,
class NO>
506int TimeProblem<SC,LO,GO,NO>::solveUpdate( ){
508 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
509 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
511 *nonLinProb->previousSolution_ = *nonLinProb->getSolution();
512 int its = this->solve( nonLinProb->residualVec_ );
517template<
class SC,
class LO,
class GO,
class NO>
518int TimeProblem<SC,LO,GO,NO>::solveAndUpdate(
const std::string& criterion,
double& criterionValue ){
520 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
521 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
524 int its = solveUpdate( );
526 if (criterion==
"Update") {
527 Teuchos::Array<SC> updateNorm(1);
528 nonLinProb->getSolution()->norm2(updateNorm());
529 criterionValue = updateNorm[0];
533 if (criterion==
"ResidualAceGen") {
534 nonLinProb->getSolution()->update( 1., *nonLinProb->previousSolution_, -1. );
535 nonLinProb->assemble(
"SetSolutionNewton" );
539 nonLinProb->getSolution()->update( 1., *nonLinProb->previousSolution_, 1. );
544template<
class SC,
class LO,
class GO,
class NO>
545int TimeProblem<SC,LO,GO,NO>::solve( BlockMultiVectorPtr_Type rhs ){
549 std::cout <<
"-- Solve System ..." << std::endl;
551 std::string type = parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
552 LinearSolver<SC,LO,GO,NO> linSolver;
553 its = linSolver.solve(
this, rhs, type );
556 std::cout <<
" done. -- " << std::endl;
561template<
class SC,
class LO,
class GO,
class NO>
562void TimeProblem<SC,LO,GO,NO>::updateSolutionPreviousStep(){
564 if (solutionPreviousTimesteps_.size()==0)
565 solutionPreviousTimesteps_.resize(1);
567 solutionPreviousTimesteps_[0] = Teuchos::rcp(
new BlockMultiVector_Type( problem_->getSolution() ) );
571template<
class SC,
class LO,
class GO,
class NO>
572void TimeProblem<SC,LO,GO,NO>::updateSolutionMultiPreviousStep(
int nmbSteps){
574 int size = solutionPreviousTimesteps_.size();
575 if (size<nmbSteps && size > 0) {
576 BlockMultiVectorPtr_Type toAddMVreset = Teuchos::rcp(
new BlockMultiVector_Type( solutionPreviousTimesteps_[size-1] ) );
577 solutionPreviousTimesteps_.push_back( toAddMVreset );
580 solutionPreviousTimesteps_.resize(1);
582 for (
int i=size-1; i>0; i--)
583 solutionPreviousTimesteps_[i] = Teuchos::rcp(
new BlockMultiVector_Type( solutionPreviousTimesteps_[i-1] ) );
586 solutionPreviousTimesteps_[0] = Teuchos::rcp(
new BlockMultiVector_Type( problem_->getSolution() ) );
591template<
class SC,
class LO,
class GO,
class NO>
592void TimeProblem<SC,LO,GO,NO>::updateSystemMassMultiPreviousStep(
int nmbSteps){
594 int size = systemMassPreviousTimeSteps_.size();
595 if (size<nmbSteps && size > 0) {
596 BlockMatrixPtr_Type toAddMatrixreset = Teuchos::rcp(
new BlockMatrix_Type( systemMassPreviousTimeSteps_[size-1] ) );
598 systemMassPreviousTimeSteps_.push_back( toAddMatrixreset );
601 systemMassPreviousTimeSteps_.resize(1);
603 for (
int i=size-1; i>0; i--)
604 systemMassPreviousTimeSteps_[i] = Teuchos::rcp(
new BlockMatrix_Type( systemMassPreviousTimeSteps_[i-1] ) );
607 systemMassPreviousTimeSteps_[0] = Teuchos::rcp(
new BlockMatrix_Type( systemMass_ ) );
613template<
class SC,
class LO,
class GO,
class NO>
614void TimeProblem<SC,LO,GO,NO>::updateSolutionNewmarkPreviousStep(
double dt,
double beta,
double gamma)
622 int size = solutionPreviousTimesteps_.size();
624 if(size < 2 && size > 0)
626 BlockMultiVectorPtr_Type toAddMVreset = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(size-1)));
628 solutionPreviousTimesteps_.push_back(toAddMVreset);
632 solutionPreviousTimesteps_.resize(1);
636 for(
int i = size-1; i > 0; i--)
638 solutionPreviousTimesteps_.at(i) = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(i-1)));
643 solutionPreviousTimesteps_.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(problem_->getSolution()));
652 if(velocityPreviousTimesteps_.size() == 0)
655 velocityPreviousTimesteps_.resize(1);
656 accelerationPreviousTimesteps_.resize(1);
661 velocityPreviousTimesteps_.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(problem_->getSolution()));
662 accelerationPreviousTimesteps_.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(problem_->getSolution()));
663 velocityPreviousTimesteps_.at(0)->putScalar(0.0);
664 accelerationPreviousTimesteps_.at(0)->putScalar(0.0);
674 BlockMultiVectorPtrArray_Type velocityOld;
675 velocityOld.resize(1);
676 velocityOld.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(velocityPreviousTimesteps_.at(0)));
683 BlockMultiVectorPtrArray_Type tmpVector1;
684 tmpVector1.resize(1);
686 tmpVector1.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(0)));
689 tmpVector1.at(0)->update(-gamma/(dt*beta), *(solutionPreviousTimesteps_.at(1)), gamma/(dt*beta));
692 velocityPreviousTimesteps_.at(0)->scale(1.0 - (gamma/beta));
696 velocityPreviousTimesteps_.at(0)->update(1.0, *(tmpVector1.at(0)), dt*((beta - 0.5*gamma)/(beta)), *(accelerationPreviousTimesteps_.at(0)), 1.0);
705 BlockMultiVectorPtrArray_Type tmpVector2;
706 tmpVector2.resize(1);
708 tmpVector2.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(0)));
711 tmpVector2.at(0)->update(-1.0/(dt*dt*beta), *(solutionPreviousTimesteps_.at(1)), 1.0/(dt*dt*beta));
714 accelerationPreviousTimesteps_.at(0)->scale(-(0.5 - beta)/beta);
718 accelerationPreviousTimesteps_.at(0)->update(1.0, *(tmpVector2.at(0)), -1.0/(dt*beta), *(velocityOld.at(0)), 1.0);
721template<
class SC,
class LO,
class GO,
class NO>
722void TimeProblem<SC,LO,GO,NO>::assembleSourceTerm(
double time ){
724 problem_->assembleSourceTerm(time);
728template<
class SC,
class LO,
class GO,
class NO>
729typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getSourceTerm( ) {
731 return problem_->getSourceTerm();
735template<
class SC,
class LO,
class GO,
class NO>
736bool TimeProblem<SC,LO,GO,NO>::hasSourceTerm( )
const{
738 return problem_->hasSourceTerm();
742template<
class SC,
class LO,
class GO,
class NO>
743typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getRhs(){
745 return problem_->getRhs();
748template<
class SC,
class LO,
class GO,
class NO>
749typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getRhs()
const{
751 return problem_->getRhs();
754template<
class SC,
class LO,
class GO,
class NO>
755typename TimeProblem<SC,LO,GO,NO>::DomainConstPtr_Type TimeProblem<SC,LO,GO,NO>::getDomain(
int i)
const {
757 return problem_->getDomain(i);
760template<
class SC,
class LO,
class GO,
class NO>
761std::string TimeProblem<SC,LO,GO,NO>::getFEType(
int i){
763 return problem_->getFEType(i);
766template<
class SC,
class LO,
class GO,
class NO>
767int TimeProblem<SC,LO,GO,NO>::getDofsPerNode(
int i){
769 return problem_->getDofsPerNode(i);
772template<
class SC,
class LO,
class GO,
class NO>
773std::string TimeProblem<SC,LO,GO,NO>::getVariableName(
int i){
775 return problem_->getVariableName(i);
778template<
class SC,
class LO,
class GO,
class NO>
779typename TimeProblem<SC,LO,GO,NO>::BlockMatrixPtr_Type TimeProblem<SC,LO,GO,NO>::getSystem(){
781 return problem_->getSystem();
784template<
class SC,
class LO,
class GO,
class NO>
785typename TimeProblem<SC,LO,GO,NO>::BlockMatrixPtr_Type TimeProblem<SC,LO,GO,NO>::getSystemCombined(){
787 TEUCHOS_TEST_FOR_EXCEPTION(systemCombined_.is_null(), std::logic_error,
"system combined of TimeProblem is null.");
789 return systemCombined_;
792template<
class SC,
class LO,
class GO,
class NO>
793typename TimeProblem<SC,LO,GO,NO>::BlockMatrixPtr_Type TimeProblem<SC,LO,GO,NO>::getSystemCombined()
const{
795 TEUCHOS_TEST_FOR_EXCEPTION(systemCombined_.is_null(), std::logic_error,
"system combined of TimeProblem is null.");
797 return systemCombined_;
800template<
class SC,
class LO,
class GO,
class NO>
801typename TimeProblem<SC,LO,GO,NO>::ProblemPtr_Type TimeProblem<SC,LO,GO,NO>::getUnderlyingProblem(){
806template<
class SC,
class LO,
class GO,
class NO>
807void TimeProblem<SC,LO,GO,NO>::addToRhs(BlockMultiVectorPtr_Type x){
809 problem_->addToRhs(x);
812template<
class SC,
class LO,
class GO,
class NO>
813typename TimeProblem<SC,LO,GO,NO>::BlockMatrixPtr_Type TimeProblem<SC,LO,GO,NO>::getMassSystem(){
818template<
class SC,
class LO,
class GO,
class NO>
819ParameterListPtr_Type TimeProblem<SC,LO,GO,NO>::getParameterList(){
821 return parameterList_;
824template<
class SC,
class LO,
class GO,
class NO>
825typename TimeProblem<SC,LO,GO,NO>::LinSolverBuilderPtr_Type TimeProblem<SC,LO,GO,NO>::getLinearSolverBuilder()
const{
827 return problem_->getLinearSolverBuilder();
830template<
class SC,
class LO,
class GO,
class NO>
831void TimeProblem<SC,LO,GO,NO>::getValuesOfInterest( vec_dbl_Type& values ){
833 problem_->getValuesOfInterest( values );
836template<
class SC,
class LO,
class GO,
class NO>
837void TimeProblem<SC,LO,GO,NO>::computeValuesOfInterestAndExport( ){
839 problem_->computeValuesOfInterestAndExport( );
843template<
class SC,
class LO,
class GO,
class NO>
844Thyra::ModelEvaluatorBase::InArgs<SC> TimeProblem<SC,LO,GO,NO>::getNominalValues()
const
846 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
847 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
849 return nonLinProb->getNominalValues();
852template<
class SC,
class LO,
class GO,
class NO>
853Teuchos::RCP<const ::Thyra::VectorSpaceBase<SC> > TimeProblem<SC,LO,GO,NO>::get_x_space()
const{
854 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
855 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
857 return nonLinProb->get_x_space();
860template<
class SC,
class LO,
class GO,
class NO>
861Teuchos::RCP<const ::Thyra::VectorSpaceBase<SC> > TimeProblem<SC,LO,GO,NO>::get_f_space()
const{
862 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
863 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
864 return nonLinProb->get_f_space();
867template<
class SC,
class LO,
class GO,
class NO>
868Thyra::ModelEvaluatorBase::InArgs<SC> TimeProblem<SC,LO,GO,NO>::createInArgs()
const
870 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
871 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
872 return nonLinProb->createInArgs();
876template<
class SC,
class LO,
class GO,
class NO>
877Thyra::ModelEvaluatorBase::OutArgs<SC> TimeProblem<SC,LO,GO,NO>::createOutArgsImpl()
const
879 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
880 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
881 return nonLinProb->createOutArgsImpl();
884template<
class SC,
class LO,
class GO,
class NO>
885Teuchos::RCP<Thyra::LinearOpBase<SC> > TimeProblem<SC,LO,GO,NO>::create_W_op()
888 this->calculateNonLinResidualVec(
"standard", time_ );
889 this->assemble(
"Newton");
893 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
894 if ( type ==
"Monolithic" )
895 return create_W_op_Monolithic( );
897 return create_W_op_Block( );
900template<
class SC,
class LO,
class GO,
class NO>
901Teuchos::RCP<Thyra::LinearOpBase<SC> > TimeProblem<SC,LO,GO,NO>::create_W_op_Monolithic()
903 Teuchos::RCP<const Thyra::LinearOpBase<SC> > W_opConst = this->getSystemCombined()->getThyraLinOp();
904 Teuchos::RCP<Thyra::LinearOpBase<SC> > W_op = Teuchos::rcp_const_cast<Thyra::LinearOpBase<SC> >(W_opConst);
908template<
class SC,
class LO,
class GO,
class NO>
909Teuchos::RCP<Thyra::LinearOpBase<SC> > TimeProblem<SC,LO,GO,NO>::create_W_op_Block()
912 BlockMatrixPtr_Type system = this->getSystemCombined();
914 Teuchos::RCP<const ThyraBlockOp_Type> W_opBlocksConst = system->getThyraLinBlockOp();
915 Teuchos::RCP<ThyraBlockOp_Type> W_opBlocks = Teuchos::rcp_const_cast<ThyraBlockOp_Type >(W_opBlocksConst);
916 Teuchos::RCP<ThyraOp_Type> W_op = Teuchos::rcp_dynamic_cast<ThyraOp_Type >(W_opBlocks);
921template<
class SC,
class LO,
class GO,
class NO>
922Teuchos::RCP<Thyra::PreconditionerBase<SC> > TimeProblem<SC,LO,GO,NO>::create_W_prec()
925 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
926 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
928 if (!nonLinProb->getPreconditionerConst()->isPreconditionerComputed()) {
929 nonLinProb->initializeSolverBuilder();
931 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
932 this->setBoundariesSystem();
934 if ( type ==
"Teko" || type ==
"FaCSI-Teko" || type ==
"Diagonal" ) {
935 nonLinProb->setupPreconditioner( type );
936 precInitOnly_ =
false;
939 nonLinProb->setupPreconditioner( type );
943 Teuchos::RCP<const Thyra::PreconditionerBase<SC> > thyraPrec = nonLinProb->getPreconditionerConst()->getThyraPrecConst();
944 Teuchos::RCP<Thyra::PreconditionerBase<SC> > thyraPrecNonConst = Teuchos::rcp_const_cast<Thyra::PreconditionerBase<SC> >(thyraPrec);
946 return thyraPrecNonConst;
950template<
class SC,
class LO,
class GO,
class NO>
951void TimeProblem<SC,LO,GO,NO>::evalModelImpl(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
952 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs
955 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
956 if ( !type.compare(
"Monolithic"))
957 evalModelImplMonolithic( inArgs, outArgs );
959 evalModelImplBlock( inArgs, outArgs );
962template<
class SC,
class LO,
class GO,
class NO>
963void TimeProblem<SC,LO,GO,NO>::evalModelImplMonolithic(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
964 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs )
const
970 using Teuchos::rcp_dynamic_cast;
971 using Teuchos::rcp_const_cast;
972 using Teuchos::ArrayView;
973 using Teuchos::Array;
975 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
977 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
979 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
981 BlockMultiVectorConstPtr_Type solConst = this->getSolutionConst();
982 BlockMultiVectorPtr_Type sol = rcp_const_cast<BlockMultiVector_Type >(solConst);
983 sol->fromThyraMultiVector(vecThyraNonConst);
985 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
986 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
987 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
989 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
990 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
991 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
992 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
994 const bool fill_f = nonnull(f_out);
995 const bool fill_W = nonnull(W_out);
996 const bool fill_W_prec = nonnull(W_prec_out);
998 if ( fill_f || fill_W || fill_W_prec ) {
1005 this->calculateNonLinResidualVec(
"standard", time_ );
1007 BlockMultiVectorConstPtr_Type resConst = this->getResidualConst();
1008 BlockMultiVectorPtr_Type res = rcp_const_cast<BlockMultiVector_Type >(resConst);
1010 Teuchos::RCP<Thyra::MultiVectorBase<SC> > f_thyra = res->getThyraMultiVector();
1011 f_out->assign(*f_thyra);
1014 TpetraMatrixPtr_Type W;
1017 this->assemble(
"Newton");
1019 this->setBoundariesSystem();
1021 Teuchos::RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator(W_out);
1022 Teuchos::RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
1024 TpetraMatrixConstPtr_Type W_systemTpetra = this->getSystemCombined()->getMergedMatrix()->getTpetraMatrix();
1025 TpetraMatrixPtr_Type W_systemTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_systemTpetra);
1030 Teuchos::RCP<TpetraMatrix_Type> tpetraMatTpetra = W_systemTpetraNonConst;
1032 W_tpetraMat->resumeFill();
1034 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
1035 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
1036 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
1037 tpetraMatTpetra->getLocalRowView( i, indices, values);
1038 W_tpetraMat->replaceLocalValues( i, indices, values);
1040 W_tpetraMat->fillComplete();
1045 this->problem_->setupPreconditioner(
"Monolithic" );
1050 std::string levelCombination = this->parameterList_->sublist(
"ThyraPreconditioner").sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"Level Combination",
"Additive");
1051 if (!levelCombination.compare(
"Multiplicative")) {
1052 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Multiplicative Level Combination is not supported for NOX.");
1060template<
class SC,
class LO,
class GO,
class NO>
1061void TimeProblem<SC,LO,GO,NO>::evalModelImplBlock(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
1062 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs )
const
1068 using Teuchos::rcp_dynamic_cast;
1069 using Teuchos::rcp_const_cast;
1070 using Teuchos::ArrayView;
1071 using Teuchos::Array;
1073 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
1075 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
1077 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
1079 RCP< Thyra::ProductVectorBase< SC > > vecThyraBlock = rcp_dynamic_cast<Thyra::ProductVectorBase< SC > > (vecThyraNonConst);
1080 BlockMultiVectorConstPtr_Type solConst = this->getSolutionConst();
1081 BlockMultiVectorPtr_Type sol = rcp_const_cast<BlockMultiVector_Type >(solConst);
1082 for (
int i=0; i<sol->size(); i++)
1083 sol->getBlockNonConst(i)->fromThyraMultiVector( vecThyraBlock->getNonconstVectorBlock(i) );
1085 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
1086 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
1087 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
1089 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
1090 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
1091 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
1092 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
1094 const bool fill_f = nonnull(f_out);
1095 const bool fill_W = nonnull(W_out);
1096 const bool fill_W_prec = nonnull(W_prec_out);
1098 if ( fill_f || fill_W || fill_W_prec ) {
1105 this->calculateNonLinResidualVec(
"standard" , time_);
1107 RCP< Thyra::ProductMultiVectorBase<SC> > f_outBlocks
1108 = rcp_dynamic_cast< Thyra::ProductMultiVectorBase<SC> > ( f_out );
1110 BlockMultiVectorConstPtr_Type resConst = this->getResidualConst();
1111 BlockMultiVectorPtr_Type res = rcp_const_cast<BlockMultiVector_Type >(resConst);
1113 for (
int i=0; i<res->size(); i++) {
1114 RCP< Thyra::MultiVectorBase< SC > > res_i =
1115 res->getBlockNonConst(i)->getThyraMultiVector();
1117 RCP< Thyra::MultiVectorBase< SC > > f_i = f_outBlocks->getNonconstMultiVectorBlock(i);
1118 f_i->assign(*res_i);
1122 TpetraMatrixPtr_Type W;
1125 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraCrsMatrix;
1127 this->assemble(
"Newton");
1129 this->setBoundariesSystem();
1131 RCP<ThyraBlockOp_Type> W_blocks = rcp_dynamic_cast<ThyraBlockOp_Type>(W_out);
1133 BlockMatrixPtr_Type system = this->getSystemCombined();
1135 for (
int i=0; i<system->size(); i++) {
1136 for (
int j=0; j<system->size(); j++) {
1137 if ( system->blockExists(i,j) ) {
1138 RCP<const ThyraOp_Type> W = W_blocks->getBlock(i,j);
1139 RCP<ThyraOp_Type> W_NonConst = rcp_const_cast<ThyraOp_Type>( W );
1140 RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator( W_NonConst );
1141 RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
1143 TpetraMatrixConstPtr_Type W_matrixTpetra = system->getBlock(i,j)->getTpetraMatrix();
1144 TpetraMatrixPtr_Type W_matrixTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_matrixTpetra);
1149 RCP<TpetraMatrix_Type> tpetraMatTpetra = W_matrixTpetraNonConst;
1151 W_tpetraMat->resumeFill();
1153 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
1154 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
1155 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
1156 tpetraMatTpetra->getLocalRowView( i, indices, values);
1157 W_tpetraMat->replaceLocalValues( i, indices, values);
1159 W_tpetraMat->fillComplete( W_tpetraMat->getDomainMap(), W_tpetraMat->getRangeMap() );
1166 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
1168 this->problem_->setupPreconditioner( type );
1170 precInitOnly_ =
true;
1175template<
class SC,
class LO,
class GO,
class NO>
1176std::string TimeProblem<SC,LO,GO,NO>::description()
const{
1177 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
1178 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
1179 return nonLinProb->description();
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5