1#ifndef TIMEPROBLEM_DEF_hpp
2#define TIMEPROBLEM_DEF_hpp
4#include "feddlib/core/FE/Domain.hpp"
5#include "feddlib/core/FE/FE.hpp"
6#include "feddlib/core/General/BCBuilder.hpp"
8#include "NonLinearProblem.hpp"
9#include "feddlib/problems/Solver/Preconditioner.hpp"
10#include "feddlib/problems/Solver/LinearSolver.hpp"
11#include "feddlib/problems/specific/FSI.hpp"
25template<
class SC,
class LO,
class GO,
class NO>
26TimeProblem<SC,LO,GO,NO>::TimeProblem(Problem_Type& problem, CommConstPtr_Type comm):
34dimension_(problem.getDomain(0)->getDimension()),
35verbose_(comm->getRank()==0),
36parameterList_(problem.getParameterList()),
37bcFactory_(problem.getBCFactory()),
39solutionPreviousTimesteps_(0),
40velocityPreviousTimesteps_(0),
41accelerationPreviousTimesteps_(0),
42systemMassPreviousTimeSteps_(0),
44#ifdef TIMEPROBLEM_TIMER
45,TimeSolveTimer_ (Teuchos::TimeMonitor::getNewCounter(
"TT Problem: Solve"))
49 problem_ = Teuchos::rcpFromRef(problem);
50 BCConstPtr_Type bcFaCSI;
51 if( problem_->preconditioner_->hasFaCSIBCFactory() )
52 bcFaCSI = problem_->preconditioner_->getFaCSIBCFactory();
54 problem_->preconditioner_ = Teuchos::rcp(
new Preconditioner_Type(
this ) );
56 if( !bcFaCSI.is_null() )
57 problem_->preconditioner_->setFaCSIBCFactory( bcFaCSI );
58 FEFacConstPtr_Type facConst = problem.getFEFactory();
59 feFactory_ = Teuchos::rcp_const_cast<FEFac_Type>(facConst);
61 systemMass_.reset(
new BlockMatrix_Type(1));
62 systemCombined_.reset(
new BlockMatrix_Type( 1 ) );
66template<
class SC,
class LO,
class GO,
class NO>
67void TimeProblem<SC,LO,GO,NO>::setTimeDef( SmallMatrix<int>& def ){
71template<
class SC,
class LO,
class GO,
class NO>
72void TimeProblem<SC,LO,GO,NO>::assemble( std::string type )
const{
74 std::string timestepping = parameterList_->sublist(
"Timestepping Parameter").get(
"Class",
"Singlestep");
76 if (type ==
"MassSystem"){
80 initializeCombinedSystems();
81 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
82 if (!nonLinProb.is_null()){
85 if (timestepping==
"External" )
86 this->systemCombined_ = problem_->getSystem();
88 this->combineSystems();
93 problem_->assemble(type);
95 if (timestepping==
"External")
96 this->systemCombined_ = problem_->getSystem();
98 this->combineSystems();
103template<
class SC,
class LO,
class GO,
class NO>
104void TimeProblem<SC,LO,GO,NO>::reAssembleAndFill( BlockMatrixPtr_Type bMat, std::string type ){
106 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
107 nonLinProb->reAssembleAndFill( bMat, type );
110template<
class SC,
class LO,
class GO,
class NO>
111void TimeProblem<SC,LO,GO,NO>::combineSystems()
const{
112 BlockMatrixPtr_Type tmpSystem = problem_->getSystem();
113 int size = tmpSystem->size();
114 systemCombined_.reset(
new BlockMatrix_Type ( size ) );
116 for (
int i=0; i<size; i++) {
117 DomainConstPtr_Type dom = this->getDomain(i);
118 for (
int j=0; j<size; j++) {
119 if ( tmpSystem->blockExists(i,j) ) {
120 LO maxNumEntriesPerRow = tmpSystem->getBlock(i,j)->getGlobalMaxNumRowEntries();
121 MatrixPtr_Type matrix = Teuchos::rcp(
new Matrix_Type( tmpSystem->getBlock(i,j)->getMap(), maxNumEntriesPerRow ) );
123 systemCombined_->addBlock( matrix, i, j );
126 else if (systemMass_->blockExists(i,j)) {
127 LO maxNumEntriesPerRow = systemMass_->getBlock(i,j)->getGlobalMaxNumRowEntries();
128 MatrixPtr_Type matrix = Teuchos::rcp(
new Matrix_Type( systemMass_->getBlock(i,j)->getMap(), maxNumEntriesPerRow) );
129 systemCombined_->addBlock( matrix, i, j );
133 SmallMatrix<SC> ones( size , Teuchos::ScalarTraits<SC>::one());
134 SmallMatrix<SC> zeros( size , Teuchos::ScalarTraits<SC>::zero());
135 systemMass_->addMatrix( massParameters_, systemCombined_, zeros );
136 tmpSystem->addMatrix( timeParameters_, systemCombined_, ones );
138 for (
int i=0; i<size; i++) {
139 for (
int j=0; j<size; j++) {
140 if ( systemCombined_->blockExists(i,j) ) {
141 if ( tmpSystem->blockExists(i,j) ) {
142 MatrixPtr_Type matrix = tmpSystem->getBlock(i,j);
143 MatrixConstPtr_Type matrixConstComb = systemCombined_->getBlock(i,j);
144 MatrixPtr_Type matrixComb = Teuchos::rcp_const_cast<Matrix_Type>(matrixConstComb);
145 matrixComb->fillComplete( matrix->getMap(
"domain"), matrix->getMap(
"range") );
147 else if ( systemMass_->blockExists(i,j) ) {
148 MatrixPtr_Type matrix = systemMass_->getBlock(i,j);
149 MatrixConstPtr_Type matrixConstComb = systemCombined_->getBlock(i,j);
150 MatrixPtr_Type matrixComb = Teuchos::rcp_const_cast<Matrix_Type>(matrixConstComb);
151 matrixComb->fillComplete( matrix->getMap(
"domain"), matrix->getMap(
"range") );
154 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"TimeProblem: Combined systems possess a block which does not exist in partial systems.");
160template<
class SC,
class LO,
class GO,
class NO>
161void TimeProblem<SC,LO,GO,NO>::updateRhs(){
163 systemMass_->apply( *solutionPreviousTimesteps_[0], *problem_->getRhs(), massParameters_ );
166template<
class SC,
class LO,
class GO,
class NO>
167void TimeProblem<SC,LO,GO,NO>::updateMultistepRhs(vec_dbl_Type& coeff,
int nmbToUse){
169 problem_->getRhs()->putScalar(0.);
171 int size = massParameters_.size();
173 for (
int i=0; i<nmbToUse; i++) {
174 SmallMatrix<SC> tmpMassParameter(size);
175 for (
int r=0; r<size; r++) {
176 for (
int s=0; s<size; s++) {
177 if (massParameters_[r][s]!=0.)
178 tmpMassParameter[r][s] = coeff[i];
181 BlockMultiVectorPtr_Type tmpVector
182 = Teuchos::rcp(
new BlockMultiVector_Type( problem_->getRhs() ) );
183 BlockMultiVectorPtr_Type tmpBlockVector = solutionPreviousTimesteps_[i];
184 systemMass_->apply( *tmpBlockVector, *tmpVector, tmpMassParameter );
185 problem_->getRhs()->update( 1., tmpVector, 1. );
191template<
class SC,
class LO,
class GO,
class NO>
192void TimeProblem<SC,LO,GO,NO>::updateMultistepRhsFSI(vec_dbl_Type& coeff,
int nmbToUse){
194 problem_->getRhs()->putScalar(0.);
196 int size = massParameters_.size();
198 for (
int i=0; i<nmbToUse; i++) {
199 SmallMatrix<SC> tmpMassParameter(size);
200 for (
int r=0; r<size; r++) {
201 for (
int s=0; s<size; s++) {
202 if (massParameters_[r][s]!=0.) {
203 tmpMassParameter[r][s] = coeff[i];
208 BlockMultiVectorPtr_Type tmpVector
209 = Teuchos::rcp(
new BlockMultiVector_Type( problem_->getRhs() ) );
210 BlockMultiVectorPtr_Type tmpBlockVector = solutionPreviousTimesteps_[i];
211 systemMassPreviousTimeSteps_[i]->apply( *tmpBlockVector, *tmpVector, tmpMassParameter );
212 problem_->getRhs()->update( 1., tmpVector, 1. );
222template<
class SC,
class LO,
class GO,
class NO>
223void TimeProblem<SC,LO,GO,NO>::updateNewmarkRhs(
double dt,
double beta,
double gamma, vec_dbl_Type coeff)
236 BlockMultiVectorPtrArray_Type tempVector1(1);
238 tempVector1.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(0)));
241 tempVector1.at(0)->scale(1.0/(dt*dt*beta));
244 tempVector1.at(0)->update(1.0/(dt*beta), *(velocityPreviousTimesteps_[0]), (0.5 - beta)/beta, *(accelerationPreviousTimesteps_[0]), 1.0);
249 BlockMultiVectorPtrArray_Type tempVector2(1);
250 tempVector2.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(0)));
254 int size = massParameters_.size();
255 SmallMatrix<double> tmpMassParameter(size);
256 for(
int r = 0; r < size; r++)
258 for(
int s = 0; s < size; s++)
260 if(massParameters_[r][s] != 0.0)
262 tmpMassParameter[r][s] = coeff.at(0);
269 systemMass_->apply(*(tempVector1.at(0)), *(tempVector2.at(0)), tmpMassParameter);
272 problem_->getRhs()->update(1.0, *(tempVector2.at(0)), .0);
277template<
class SC,
class LO,
class GO,
class NO>
278typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getSolution(){
280 return problem_->getSolution();
283template<
class SC,
class LO,
class GO,
class NO>
284typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorConstPtr_Type TimeProblem<SC,LO,GO,NO>::getSolutionConst()
const {
285 return problem_->getSolution();
288template<
class SC,
class LO,
class GO,
class NO>
289typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getResidual(){
291 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
292 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
293 return nonLinProb->getResidualVector ();
296template<
class SC,
class LO,
class GO,
class NO>
297typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorConstPtr_Type TimeProblem<SC,LO,GO,NO>::getResidualConst()
const{
299 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
300 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
301 return nonLinProb->getResidualVector ();
304template<
class SC,
class LO,
class GO,
class NO>
305typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getSolutionPreviousTimestep(){
307 return solutionPreviousTimesteps_[0];
310template<
class SC,
class LO,
class GO,
class NO>
311typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtrArray_Type TimeProblem<SC,LO,GO,NO>::getSolutionAllPreviousTimestep(){
313 return solutionPreviousTimesteps_;
316template<
class SC,
class LO,
class GO,
class NO>
317void TimeProblem<SC,LO,GO,NO>::initializeCombinedSystems()
const{
319 BlockMatrixConstPtr_Type blockMatrixProblem = problem_->getSystem();
321 int size = blockMatrixProblem->size();
323 for (
int i=0; i<size; i++) {
324 for (
int j=0; j<size; j++) {
325 MatrixPtr_Type matrix;
326 bool foundMatrix =
false;
327 if ( blockMatrixProblem->blockExists(i,j) ) {
328 MatrixConstPtr_Type matrixProblem = blockMatrixProblem->getBlockConst(i,j);
329 MapConstPtr_Type map = matrixProblem->getMap();
330 MapPtr_Type mapNonConst = Teuchos::rcp_const_cast<Map_Type> (map);
331 matrix = Teuchos::rcp(
new Matrix_Type( mapNonConst, matrixProblem->getGlobalMaxNumRowEntries() ) );
334 else if( systemMass_->blockExists(i,j) && !foundMatrix ){
335 MatrixConstPtr_Type matrixMass = systemMass_->getBlockConst(i,j);
336 MapConstPtr_Type map = matrixMass->getMap();
337 MapPtr_Type mapNonConst = Teuchos::rcp_const_cast<Map_Type> (map);
338 matrix = Teuchos::rcp(
new Matrix_Type( mapNonConst, matrixMass->getGlobalMaxNumRowEntries() ) );
342 systemCombined_->addBlock( matrix, i, j );
348template<
class SC,
class LO,
class GO,
class NO>
349void TimeProblem<SC,LO,GO,NO>::assembleMassSystem( )
const {
352 ProblemPtr_Type tmpProblem;
353 SC eps100 = 100.*Teuchos::ScalarTraits<SC>::eps();
356 double density = parameterList_->sublist(
"Parameter").get(
"Density",1.);
358 int size = problem_->getSystem()->size();
359 systemMass_->resize( size );
361 for (
int i=0; i<size; i++ ) {
362 dofsPerNode = problem_->getDofsPerNode(i);
364 if ( timeStepDef_[i][i]>0 ) {
366 M = Teuchos::rcp(
new Matrix_Type( this->getDomain(i)->getMapVecFieldUnique(), dimension_*this->getDomain(i)->getApproxEntriesPerRow() ) );
367 feFactory_->assemblyMass(dimension_, problem_->getFEType(i),
"Vector", M,
true);
371 M->fillComplete( this->getDomain(i)->getMapVecFieldUnique(), this->getDomain(i)->getMapVecFieldUnique());
373 systemMass_->addBlock(M, i, i);
376 M = Teuchos::rcp(
new Matrix_Type( this->getDomain(i)->getMapUnique(), this->getDomain(i)->getApproxEntriesPerRow() ) );
377 feFactory_->assemblyMass(dimension_, problem_->getFEType(i),
"Scalar", M,
true);
381 M->fillComplete( this->getDomain(i)->getMapUnique(), this->getDomain(i)->getMapUnique());
383 systemMass_->addBlock(M, i, i);
387 for (
int j=0; j<size; j++) {
388 if (timeStepDef_[i][j]==2) {
390 M = Teuchos::rcp(
new Matrix_Type( this->getDomain(i)->getMapVecFieldUnique(), this->getDomain(i)->getApproxEntriesPerRow() ) );
391 feFactory_->assemblyMass(dimension_, problem_->getFEType(i),
"Vector", M,
true);
395 M->fillComplete( this->getDomain(i)->getMapVecFieldUnique(), this->getDomain(i)->getMapVecFieldUnique());
397 systemMass_->addBlock(M, i, j);
400 M = Teuchos::rcp(
new Matrix_Type( this->getDomain(i)->getMapUnique(), this->getDomain(i)->getApproxEntriesPerRow() ) );
401 feFactory_->assemblyMass(dimension_, problem_->getFEType(i),
"Scalar", M,
true);
405 M->fillComplete( this->getDomain(i)->getMapUnique(), this->getDomain(i)->getMapUnique());
407 systemMass_->addBlock(M, i, j);
415template<
class SC,
class LO,
class GO,
class NO>
416void TimeProblem<SC,LO,GO,NO>::setTimeParameters(SmallMatrix<double> &massParameters, SmallMatrix<double> &timeParameters){
418 timeParameters_ = timeParameters;
420 massParameters_ = massParameters;
424template<
class SC,
class LO,
class GO,
class NO>
425bool TimeProblem<SC,LO,GO,NO>::getVerbose(){
430template<
class SC,
class LO,
class GO,
class NO>
431double TimeProblem<SC,LO,GO,NO>::calculateResidualNorm(){
433 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
434 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
435 Teuchos::Array<SC> res(1);
436 nonLinProb->getResidualVector()->norm2(res);
440template<
class SC,
class LO,
class GO,
class NO>
441void TimeProblem<SC,LO,GO,NO>::calculateNonLinResidualVec( std::string type,
double time )
const{
443 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
444 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
446 if (type ==
"external") {
447 nonLinProb->calculateNonLinResidualVec(
"external" );
453 nonLinProb->calculateNonLinResidualVec( timeParameters_ ,type, time, this->systemMass_ );
457 BlockMultiVectorPtr_Type tmpMV = Teuchos::rcp(
new BlockMultiVector_Type( nonLinProb->getSolution() ) );
458 tmpMV->putScalar(0.);
460 systemMass_->apply( *nonLinProb->getSolution(), *tmpMV, massParameters_ );
463 nonLinProb->getResidualVector()->update(-1,*tmpMV,1.);
464 else if(type==
"standard")
465 nonLinProb->getResidualVector()->update(1,*tmpMV,1.);
467 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"Unkown type to compute the residual for a time problem.");
470 this->bcFactory_->setBCMinusVector( nonLinProb->getResidualVector(), nonLinProb->getSolution(), time );
471 else if(type==
"standard")
472 this->bcFactory_->setVectorMinusBC( nonLinProb->getResidualVector(), nonLinProb->getSolution(), time );
479template<
class SC,
class LO,
class GO,
class NO>
480void TimeProblem<SC,LO,GO,NO>::setBoundaries(
double time){
482 BlockMultiVectorPtr_Type tmpRhs = problem_->getRhs();
484 bcFactory_->set( systemCombined_, tmpRhs, time );
487template<
class SC,
class LO,
class GO,
class NO>
488void TimeProblem<SC,LO,GO,NO>::setBoundariesRHS(
double time){
490 BlockMultiVectorPtr_Type tmpRhs = problem_->getRhs();
492 bcFactory_->setRHS( tmpRhs, time );
495template<
class SC,
class LO,
class GO,
class NO>
496void TimeProblem<SC,LO,GO,NO>::setBoundariesSystem()
const{
498 bcFactory_->setSystem(systemCombined_);
502template<
class SC,
class LO,
class GO,
class NO>
503int TimeProblem<SC,LO,GO,NO>::solveUpdate( ){
505 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
506 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
508 *nonLinProb->previousSolution_ = *nonLinProb->getSolution();
509 int its = this->solve( nonLinProb->residualVec_ );
514template<
class SC,
class LO,
class GO,
class NO>
515int TimeProblem<SC,LO,GO,NO>::solveAndUpdate(
const std::string& criterion,
double& criterionValue ){
517 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
518 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
521 int its = solveUpdate( );
523 if (criterion==
"Update") {
524 Teuchos::Array<SC> updateNorm(1);
525 nonLinProb->getSolution()->norm2(updateNorm());
526 criterionValue = updateNorm[0];
530 if (criterion==
"ResidualAceGen") {
531 nonLinProb->getSolution()->update( 1., *nonLinProb->previousSolution_, -1. );
532 nonLinProb->assemble(
"SetSolutionNewton" );
536 nonLinProb->getSolution()->update( 1., *nonLinProb->previousSolution_, 1. );
541template<
class SC,
class LO,
class GO,
class NO>
542int TimeProblem<SC,LO,GO,NO>::solve( BlockMultiVectorPtr_Type rhs ){
546 std::cout <<
"-- Solve System ..." << std::endl;
548 std::string type = parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
549 LinearSolver<SC,LO,GO,NO> linSolver;
550 its = linSolver.solve(
this, rhs, type );
553 std::cout <<
" done. -- " << std::endl;
558template<
class SC,
class LO,
class GO,
class NO>
559void TimeProblem<SC,LO,GO,NO>::updateSolutionPreviousStep(){
561 if (solutionPreviousTimesteps_.size()==0)
562 solutionPreviousTimesteps_.resize(1);
564 solutionPreviousTimesteps_[0] = Teuchos::rcp(
new BlockMultiVector_Type( problem_->getSolution() ) );
568template<
class SC,
class LO,
class GO,
class NO>
569void TimeProblem<SC,LO,GO,NO>::updateSolutionMultiPreviousStep(
int nmbSteps){
571 int size = solutionPreviousTimesteps_.size();
572 if (size<nmbSteps && size > 0) {
573 BlockMultiVectorPtr_Type toAddMVreset = Teuchos::rcp(
new BlockMultiVector_Type( solutionPreviousTimesteps_[size-1] ) );
574 solutionPreviousTimesteps_.push_back( toAddMVreset );
577 solutionPreviousTimesteps_.resize(1);
579 for (
int i=size-1; i>0; i--)
580 solutionPreviousTimesteps_[i] = Teuchos::rcp(
new BlockMultiVector_Type( solutionPreviousTimesteps_[i-1] ) );
583 solutionPreviousTimesteps_[0] = Teuchos::rcp(
new BlockMultiVector_Type( problem_->getSolution() ) );
588template<
class SC,
class LO,
class GO,
class NO>
589void TimeProblem<SC,LO,GO,NO>::updateSystemMassMultiPreviousStep(
int nmbSteps){
591 int size = systemMassPreviousTimeSteps_.size();
592 if (size<nmbSteps && size > 0) {
593 BlockMatrixPtr_Type toAddMatrixreset = Teuchos::rcp(
new BlockMatrix_Type( systemMassPreviousTimeSteps_[size-1] ) );
595 systemMassPreviousTimeSteps_.push_back( toAddMatrixreset );
598 systemMassPreviousTimeSteps_.resize(1);
600 for (
int i=size-1; i>0; i--)
601 systemMassPreviousTimeSteps_[i] = Teuchos::rcp(
new BlockMatrix_Type( systemMassPreviousTimeSteps_[i-1] ) );
604 systemMassPreviousTimeSteps_[0] = Teuchos::rcp(
new BlockMatrix_Type( systemMass_ ) );
610template<
class SC,
class LO,
class GO,
class NO>
611void TimeProblem<SC,LO,GO,NO>::updateSolutionNewmarkPreviousStep(
double dt,
double beta,
double gamma)
619 int size = solutionPreviousTimesteps_.size();
621 if(size < 2 && size > 0)
623 BlockMultiVectorPtr_Type toAddMVreset = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(size-1)));
625 solutionPreviousTimesteps_.push_back(toAddMVreset);
629 solutionPreviousTimesteps_.resize(1);
633 for(
int i = size-1; i > 0; i--)
635 solutionPreviousTimesteps_.at(i) = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(i-1)));
640 solutionPreviousTimesteps_.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(problem_->getSolution()));
649 if(velocityPreviousTimesteps_.size() == 0)
652 velocityPreviousTimesteps_.resize(1);
653 accelerationPreviousTimesteps_.resize(1);
658 velocityPreviousTimesteps_.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(problem_->getSolution()));
659 accelerationPreviousTimesteps_.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(problem_->getSolution()));
660 velocityPreviousTimesteps_.at(0)->putScalar(0.0);
661 accelerationPreviousTimesteps_.at(0)->putScalar(0.0);
671 BlockMultiVectorPtrArray_Type velocityOld;
672 velocityOld.resize(1);
673 velocityOld.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(velocityPreviousTimesteps_.at(0)));
680 BlockMultiVectorPtrArray_Type tmpVector1;
681 tmpVector1.resize(1);
683 tmpVector1.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(0)));
686 tmpVector1.at(0)->update(-gamma/(dt*beta), *(solutionPreviousTimesteps_.at(1)), gamma/(dt*beta));
689 velocityPreviousTimesteps_.at(0)->scale(1.0 - (gamma/beta));
693 velocityPreviousTimesteps_.at(0)->update(1.0, *(tmpVector1.at(0)), dt*((beta - 0.5*gamma)/(beta)), *(accelerationPreviousTimesteps_.at(0)), 1.0);
702 BlockMultiVectorPtrArray_Type tmpVector2;
703 tmpVector2.resize(1);
705 tmpVector2.at(0) = Teuchos::rcp(
new BlockMultiVector_Type(solutionPreviousTimesteps_.at(0)));
708 tmpVector2.at(0)->update(-1.0/(dt*dt*beta), *(solutionPreviousTimesteps_.at(1)), 1.0/(dt*dt*beta));
711 accelerationPreviousTimesteps_.at(0)->scale(-(0.5 - beta)/beta);
715 accelerationPreviousTimesteps_.at(0)->update(1.0, *(tmpVector2.at(0)), -1.0/(dt*beta), *(velocityOld.at(0)), 1.0);
718template<
class SC,
class LO,
class GO,
class NO>
719void TimeProblem<SC,LO,GO,NO>::assembleSourceTerm(
double time ){
721 problem_->assembleSourceTerm(time);
725template<
class SC,
class LO,
class GO,
class NO>
726typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getSourceTerm( ) {
728 return problem_->getSourceTerm();
732template<
class SC,
class LO,
class GO,
class NO>
733bool TimeProblem<SC,LO,GO,NO>::hasSourceTerm( )
const{
735 return problem_->hasSourceTerm();
739template<
class SC,
class LO,
class GO,
class NO>
740typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getRhs(){
742 return problem_->getRhs();
745template<
class SC,
class LO,
class GO,
class NO>
746typename TimeProblem<SC,LO,GO,NO>::BlockMultiVectorPtr_Type TimeProblem<SC,LO,GO,NO>::getRhs()
const{
748 return problem_->getRhs();
751template<
class SC,
class LO,
class GO,
class NO>
752typename TimeProblem<SC,LO,GO,NO>::DomainConstPtr_Type TimeProblem<SC,LO,GO,NO>::getDomain(
int i)
const {
754 return problem_->getDomain(i);
757template<
class SC,
class LO,
class GO,
class NO>
758std::string TimeProblem<SC,LO,GO,NO>::getFEType(
int i){
760 return problem_->getFEType(i);
763template<
class SC,
class LO,
class GO,
class NO>
764int TimeProblem<SC,LO,GO,NO>::getDofsPerNode(
int i){
766 return problem_->getDofsPerNode(i);
769template<
class SC,
class LO,
class GO,
class NO>
770std::string TimeProblem<SC,LO,GO,NO>::getVariableName(
int i){
772 return problem_->getVariableName(i);
775template<
class SC,
class LO,
class GO,
class NO>
776typename TimeProblem<SC,LO,GO,NO>::BlockMatrixPtr_Type TimeProblem<SC,LO,GO,NO>::getSystem(){
778 return problem_->getSystem();
781template<
class SC,
class LO,
class GO,
class NO>
782typename TimeProblem<SC,LO,GO,NO>::BlockMatrixPtr_Type TimeProblem<SC,LO,GO,NO>::getSystemCombined(){
784 TEUCHOS_TEST_FOR_EXCEPTION(systemCombined_.is_null(), std::logic_error,
"system combined of TimeProblem is null.");
786 return systemCombined_;
789template<
class SC,
class LO,
class GO,
class NO>
790typename TimeProblem<SC,LO,GO,NO>::BlockMatrixPtr_Type TimeProblem<SC,LO,GO,NO>::getSystemCombined()
const{
792 TEUCHOS_TEST_FOR_EXCEPTION(systemCombined_.is_null(), std::logic_error,
"system combined of TimeProblem is null.");
794 return systemCombined_;
797template<
class SC,
class LO,
class GO,
class NO>
798typename TimeProblem<SC,LO,GO,NO>::ProblemPtr_Type TimeProblem<SC,LO,GO,NO>::getUnderlyingProblem(){
803template<
class SC,
class LO,
class GO,
class NO>
804void TimeProblem<SC,LO,GO,NO>::addToRhs(BlockMultiVectorPtr_Type x){
806 problem_->addToRhs(x);
809template<
class SC,
class LO,
class GO,
class NO>
810typename TimeProblem<SC,LO,GO,NO>::BlockMatrixPtr_Type TimeProblem<SC,LO,GO,NO>::getMassSystem(){
815template<
class SC,
class LO,
class GO,
class NO>
816ParameterListPtr_Type TimeProblem<SC,LO,GO,NO>::getParameterList(){
818 return parameterList_;
821template<
class SC,
class LO,
class GO,
class NO>
822typename TimeProblem<SC,LO,GO,NO>::LinSolverBuilderPtr_Type TimeProblem<SC,LO,GO,NO>::getLinearSolverBuilder()
const{
824 return problem_->getLinearSolverBuilder();
827template<
class SC,
class LO,
class GO,
class NO>
828void TimeProblem<SC,LO,GO,NO>::getValuesOfInterest( vec_dbl_Type& values ){
830 problem_->getValuesOfInterest( values );
833template<
class SC,
class LO,
class GO,
class NO>
834void TimeProblem<SC,LO,GO,NO>::computeValuesOfInterestAndExport( ){
836 problem_->computeValuesOfInterestAndExport( );
840template<
class SC,
class LO,
class GO,
class NO>
841Thyra::ModelEvaluatorBase::InArgs<SC> TimeProblem<SC,LO,GO,NO>::getNominalValues()
const
843 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
844 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
846 return nonLinProb->getNominalValues();
849template<
class SC,
class LO,
class GO,
class NO>
850Teuchos::RCP<const ::Thyra::VectorSpaceBase<SC> > TimeProblem<SC,LO,GO,NO>::get_x_space()
const{
851 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
852 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
854 return nonLinProb->get_x_space();
857template<
class SC,
class LO,
class GO,
class NO>
858Teuchos::RCP<const ::Thyra::VectorSpaceBase<SC> > TimeProblem<SC,LO,GO,NO>::get_f_space()
const{
859 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
860 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
861 return nonLinProb->get_f_space();
864template<
class SC,
class LO,
class GO,
class NO>
865Thyra::ModelEvaluatorBase::InArgs<SC> TimeProblem<SC,LO,GO,NO>::createInArgs()
const
867 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
868 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
869 return nonLinProb->createInArgs();
873template<
class SC,
class LO,
class GO,
class NO>
874Thyra::ModelEvaluatorBase::OutArgs<SC> TimeProblem<SC,LO,GO,NO>::createOutArgsImpl()
const
876 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
877 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
878 return nonLinProb->createOutArgsImpl();
881template<
class SC,
class LO,
class GO,
class NO>
882Teuchos::RCP<Thyra::LinearOpBase<SC> > TimeProblem<SC,LO,GO,NO>::create_W_op()
885 this->calculateNonLinResidualVec(
"standard", time_ );
886 this->assemble(
"Newton");
890 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
891 if ( type ==
"Monolithic" )
892 return create_W_op_Monolithic( );
894 return create_W_op_Block( );
897template<
class SC,
class LO,
class GO,
class NO>
898Teuchos::RCP<Thyra::LinearOpBase<SC> > TimeProblem<SC,LO,GO,NO>::create_W_op_Monolithic()
900 Teuchos::RCP<const Thyra::LinearOpBase<SC> > W_opConst = this->getSystemCombined()->getThyraLinOp();
901 Teuchos::RCP<Thyra::LinearOpBase<SC> > W_op = Teuchos::rcp_const_cast<Thyra::LinearOpBase<SC> >(W_opConst);
905template<
class SC,
class LO,
class GO,
class NO>
906Teuchos::RCP<Thyra::LinearOpBase<SC> > TimeProblem<SC,LO,GO,NO>::create_W_op_Block()
909 BlockMatrixPtr_Type system = this->getSystemCombined();
911 Teuchos::RCP<const ThyraBlockOp_Type> W_opBlocksConst = system->getThyraLinBlockOp();
912 Teuchos::RCP<ThyraBlockOp_Type> W_opBlocks = Teuchos::rcp_const_cast<ThyraBlockOp_Type >(W_opBlocksConst);
913 Teuchos::RCP<ThyraOp_Type> W_op = Teuchos::rcp_dynamic_cast<ThyraOp_Type >(W_opBlocks);
918template<
class SC,
class LO,
class GO,
class NO>
919Teuchos::RCP<Thyra::PreconditionerBase<SC> > TimeProblem<SC,LO,GO,NO>::create_W_prec()
921 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
922 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
924 if (!nonLinProb->getPreconditionerConst()->isPreconditionerComputed()) {
925 nonLinProb->initializeSolverBuilder();
927 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
928 this->setBoundariesSystem();
935 nonLinProb->setupPreconditioner( type );
936 precInitOnly_ =
false;
940 Teuchos::RCP<const Thyra::PreconditionerBase<SC> > thyraPrec = nonLinProb->getPreconditionerConst()->getThyraPrecConst();
941 Teuchos::RCP<Thyra::PreconditionerBase<SC> > thyraPrecNonConst = Teuchos::rcp_const_cast<Thyra::PreconditionerBase<SC> >(thyraPrec);
943 return thyraPrecNonConst;
947template<
class SC,
class LO,
class GO,
class NO>
948void TimeProblem<SC,LO,GO,NO>::evalModelImpl(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
949 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs
952 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
953 if ( !type.compare(
"Monolithic"))
954 evalModelImplMonolithic( inArgs, outArgs );
956 evalModelImplBlock( inArgs, outArgs );
959template<
class SC,
class LO,
class GO,
class NO>
960void TimeProblem<SC,LO,GO,NO>::evalModelImplMonolithic(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
961 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs )
const
967 using Teuchos::rcp_dynamic_cast;
968 using Teuchos::rcp_const_cast;
969 using Teuchos::ArrayView;
970 using Teuchos::Array;
973 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
975 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
976 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
979 BlockMultiVectorConstPtr_Type solConst = this->getSolutionConst();
980 BlockMultiVectorPtr_Type sol = rcp_const_cast<BlockMultiVector_Type >(solConst);
981 sol->fromThyraMultiVector(vecThyraNonConst);
984 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
985 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
986 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
988 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
989 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
990 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
991 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 ) {
1007 this->calculateNonLinResidualVec(
"standard", time_ );
1009 BlockMultiVectorConstPtr_Type resConst = this->getResidualConst();
1010 BlockMultiVectorPtr_Type res = rcp_const_cast<BlockMultiVector_Type >(resConst);
1013 Teuchos::RCP<Thyra::MultiVectorBase<SC> > f_thyra = res->getThyraMultiVector();
1014 f_out->assign(*f_thyra);
1017 TpetraMatrixPtr_Type W;
1020 this->assemble(
"Newton");
1021 this->setBoundariesSystem();
1024 Teuchos::RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator(W_out);
1025 Teuchos::RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
1027 TpetraMatrixConstPtr_Type W_systemTpetra = this->getSystemCombined()->getMergedMatrix()->getTpetraMatrix();
1028 TpetraMatrixPtr_Type W_systemTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_systemTpetra);
1033 Teuchos::RCP<TpetraMatrix_Type> tpetraMatTpetra = W_systemTpetraNonConst;
1035 W_tpetraMat->resumeFill();
1037 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
1038 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
1039 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
1040 tpetraMatTpetra->getLocalRowView( i, indices, values);
1041 W_tpetraMat->replaceLocalValues( i, indices, values);
1043 W_tpetraMat->fillComplete();
1049 int newtonLimit = this->parameterList_->sublist(
"Parameter").get(
"newtonLimit",2);
1050 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
1054 if(nonLinProb->newtonStep_ < newtonLimit || this->parameterList_->sublist(
"Parameter").get(
"Rebuild Preconditioner every Newton Iteration",
true) )
1056 this->problem_->setupPreconditioner(
"Monolithic" );
1060 std::cout <<
" \t\t TimeProblem<SC,LO,GO,NO>::evalModelImplMonolithic: Skipping preconditioner reconstruction" << std::endl;
1064 precInitOnly_ =
true;
1066 nonLinProb->newtonStep_++;
1076template<
class SC,
class LO,
class GO,
class NO>
1077void TimeProblem<SC,LO,GO,NO>::evalModelImplBlock(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
1078 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs )
const
1083 using Teuchos::rcp_dynamic_cast;
1084 using Teuchos::rcp_const_cast;
1085 using Teuchos::ArrayView;
1086 using Teuchos::Array;
1089 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
1091 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
1093 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
1095 RCP< Thyra::ProductVectorBase< SC > > vecThyraBlock = rcp_dynamic_cast<Thyra::ProductVectorBase< SC > > (vecThyraNonConst);
1096 BlockMultiVectorConstPtr_Type solConst = this->getSolutionConst();
1097 BlockMultiVectorPtr_Type sol = rcp_const_cast<BlockMultiVector_Type >(solConst);
1098 for (
int i=0; i<sol->size(); i++)
1099 sol->getBlockNonConst(i)->fromThyraMultiVector( vecThyraBlock->getNonconstVectorBlock(i) );
1102 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
1103 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
1104 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
1107 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
1108 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
1109 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
1110 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
1112 const bool fill_f = nonnull(f_out);
1113 const bool fill_W = nonnull(W_out);
1114 const bool fill_W_prec = nonnull(W_prec_out);
1116 if ( fill_f || fill_W || fill_W_prec ) {
1124 this->calculateNonLinResidualVec(
"standard" , time_);
1126 RCP< Thyra::ProductMultiVectorBase<SC> > f_outBlocks
1127 = rcp_dynamic_cast< Thyra::ProductMultiVectorBase<SC> > ( f_out );
1129 BlockMultiVectorConstPtr_Type resConst = this->getResidualConst();
1130 BlockMultiVectorPtr_Type res = rcp_const_cast<BlockMultiVector_Type >(resConst);
1132 for (
int i=0; i<res->size(); i++) {
1133 RCP< Thyra::MultiVectorBase< SC > > res_i =
1134 res->getBlockNonConst(i)->getThyraMultiVector();
1136 RCP< Thyra::MultiVectorBase< SC > > f_i = f_outBlocks->getNonconstMultiVectorBlock(i);
1137 f_i->assign(*res_i);
1141 TpetraMatrixPtr_Type W;
1144 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraCrsMatrix;
1146 this->assemble(
"Newton");
1147 this->setBoundariesSystem();
1150 RCP<ThyraBlockOp_Type> W_blocks = rcp_dynamic_cast<ThyraBlockOp_Type>(W_out);
1152 BlockMatrixPtr_Type system = this->getSystemCombined();
1154 for (
int i=0; i<system->size(); i++) {
1155 for (
int j=0; j<system->size(); j++) {
1156 if ( system->blockExists(i,j) ) {
1157 RCP<const ThyraOp_Type> W = W_blocks->getBlock(i,j);
1158 RCP<ThyraOp_Type> W_NonConst = rcp_const_cast<ThyraOp_Type>( W );
1159 RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator( W_NonConst );
1160 RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
1162 TpetraMatrixConstPtr_Type W_matrixTpetra = system->getBlock(i,j)->getTpetraMatrix();
1163 TpetraMatrixPtr_Type W_matrixTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_matrixTpetra);
1168 RCP<TpetraMatrix_Type> tpetraMatTpetra = W_matrixTpetraNonConst;
1170 W_tpetraMat->resumeFill();
1172 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
1173 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
1174 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
1175 tpetraMatTpetra->getLocalRowView( i, indices, values);
1176 W_tpetraMat->replaceLocalValues( i, indices, values);
1178 W_tpetraMat->fillComplete( W_tpetraMat->getDomainMap(), W_tpetraMat->getRangeMap() );
1185 std::string type = this->parameterList_->sublist(
"General").get(
"Preconditioner Method",
"Monolithic");
1186 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
1190 int newtonLimit = this->parameterList_->sublist(
"Parameter").get(
"newtonLimit",2);
1192 if(nonLinProb->newtonStep_ < newtonLimit || this->parameterList_->sublist(
"Parameter").get(
"Rebuild Preconditioner every Newton Iteration",
true) )
1194 this->problem_->setupPreconditioner( type );
1198 std::cout <<
" \t\t TimeProblem<SC,LO,GO,NO>::evalModelImplBlock Skipping preconditioner reconstruction" << std::endl;
1202 precInitOnly_ =
true;
1204 nonLinProb->newtonStep_++;
1208template<
class SC,
class LO,
class GO,
class NO>
1209std::string TimeProblem<SC,LO,GO,NO>::description()
const{
1210 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
1211 TEUCHOS_TEST_FOR_EXCEPTION(nonLinProb.is_null(), std::runtime_error,
"Nonlinear problem is null.");
1212 return nonLinProb->description();
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36