1#ifndef NonLinElasAssFE_def_hpp
2#define NonLinElasAssFE_def_hpp
3#include "NonLinElasAssFE_decl.hpp"
15template<
class SC,
class LO,
class GO,
class NO>
16NonLinElasAssFE<SC,LO,GO,NO>::NonLinElasAssFE(
const DomainConstPtr_Type &domain, std::string FEType, ParameterListPtr_Type parameterList):
20 this->nonLinearTolerance_ = this->parameterList_->sublist(
"Parameter").get(
"relNonLinTol",1.0e-6);
21 this->initNOXParameters();
22 this->addVariable( domain , FEType ,
"u" , domain->getDimension());
23 this->dim_ = this->getDomain(0)->getDimension();
25 C_ = this->parameterList_->sublist(
"Parameter").get(
"C",1.);
27 double density = this->parameterList_->sublist(
"Parameter").get(
"Density",1.);
29 loadStepping_ = !(parameterList->sublist(
"Timestepping Parameter").get(
"Class",
"Singlestep")).compare(
"Loadstepping");
30 externalForce_ = parameterList->sublist(
"Parameter").get(
"External Force",
false);
31 nonlinearExternalForce_ = parameterList->sublist(
"Parameter").get(
"Nonlinear External Force",
false);
33 timeSteppingTool_ = Teuchos::rcp(
new TimeSteppingTools(sublist(this->parameterList_,
"Timestepping Parameter") , this->comm_));
37template<
class SC,
class LO,
class GO,
class NO>
38NonLinElasAssFE<SC,LO,GO,NO>::~NonLinElasAssFE(){
42template<
class SC,
class LO,
class GO,
class NO>
43void NonLinElasAssFE<SC,LO,GO,NO>::info(){
45 this->infoNonlinProblem();
48template<
class SC,
class LO,
class GO,
class NO>
49void NonLinElasAssFE<SC,LO,GO,NO>::assemble(std::string type)
const{
53 std::cout <<
"-- Assembly nonlinear elasticity ... " << std::flush;
55 MatrixPtr_Type A(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
57 this->feFactory_->assemblyEmptyMatrix(A);
59 this->system_.reset(
new BlockMatrix_Type(1));
60 this->system_->addBlock( A, 0, 0 );
62 double density = this->parameterList_->sublist(
"Parameter").get(
"Density",1000.);
63 std::string sourceType = this->parameterList_->sublist(
"Parameter").get(
"Source Type",
"volume");
65 this->assembleSourceTerm( 0. );
66 if(sourceType ==
"volume")
67 this->sourceTerm_->scale(density);
69 this->addToRhs( this->sourceTerm_ );
71 this->setBoundariesRHS();
73 this->solution_->putScalar(0.);
75 u_rep_ = Teuchos::rcp(
new MultiVector_Type( this->getDomain(0)->getMapVecFieldRepeated() ));
76 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
77 u_rep_->importFromVector(u,
true);
80 std::cout <<
"done -- " << std::endl;
82 this->reAssemble(
"Newton-Residual");
84 else if(type ==
"UpdateTime")
87 std::cout <<
"-- Reassembly (UpdateTime)" <<
'\n';
93 this->reAssemble(type);
97template<
class SC,
class LO,
class GO,
class NO>
98void NonLinElasAssFE<SC,LO,GO,NO>::updateTime()
const
100 timeSteppingTool_->t_ = timeSteppingTool_->t_ + timeSteppingTool_->dt_prev_;
103template<
class SC,
class LO,
class GO,
class NO>
104void NonLinElasAssFE<SC,LO,GO,NO>::reAssemble(std::string type)
const {
106 std::string material_model = this->parameterList_->sublist(
"Parameter").get(
"Structure Model",
"Neo-Hooke");
109 std::cout <<
"-- Reassembly nonlinear elasticity with structure material model " << material_model <<
" ("<<type <<
") ... " << std::flush;
111 if (type==
"Newton-Residual") {
112 MultiVectorConstPtr_Type u = this->solution_->getBlock(0);
113 u_rep_->importFromVector(u,
true);
114 MatrixPtr_Type W = Teuchos::rcp(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
115 this->system_->addBlock( W, 0, 0 );
117 MultiVectorPtr_Type fRep = Teuchos::rcp(
new MultiVector_Type( this->getDomain(0)->getMapVecFieldRepeated(), 1 ) );
119 this->residualVec_->addBlock( fRep, 0 );
121 if(this->parameterList_->sublist(
"Parameter").get(
"SCI",
false) ==
true || this->parameterList_->sublist(
"Parameter").get(
"FSCI",
false) ==
true )
122 this->feFactory_->assemblyAceDeformDiffuBlock(this->dim_, this->getDomain(0)->getFEType(), this->getDomain(0)->getFEType(), 2, 1,this->dim_,concentration_,u_rep_,this->system_,0,0,this->residualVec_,0, this->parameterList_,
"Jacobian",
true);
124 this->feFactory_->assemblyNonLinearElasticity(this->dim_, this->getDomain(0)->getFEType(),2, this->dim_, u_rep_, this->system_, this->residualVec_, this->parameterList_,
true);
127 MultiVectorPtr_Type fUnique = Teuchos::rcp(
new MultiVector_Type( this->getDomain(0)->getMapVecFieldUnique(), 1 ) );
128 fUnique->putScalar(0.);
129 fUnique->exportFromVector( fRep,
true,
"Add" );
131 this->residualVec_->addBlock( fUnique, 0 );
134 assembleSourceTermLoadstepping();
138 else if(type==
"Newton"){
142 std::cout <<
"done -- " << std::endl;
145template<
class SC,
class LO,
class GO,
class NO>
146void NonLinElasAssFE<SC,LO,GO,NO>::reAssemble( MatrixPtr_Type& massmatrix, std::string type )
const
151template<
class SC,
class LO,
class GO,
class NO>
152void NonLinElasAssFE<SC,LO,GO,NO>::reAssembleExtrapolation(BlockMultiVectorPtrArray_Type previousSolutions){
155 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Only Newton/NOX implemented for nonlinear material models!");
158template<
class SC,
class LO,
class GO,
class NO>
159void NonLinElasAssFE<SC,LO,GO,NO>::evalModelImpl(
const Thyra::ModelEvaluatorBase::InArgs<SC> &inArgs,
160 const Thyra::ModelEvaluatorBase::OutArgs<SC> &outArgs
165 using Teuchos::rcp_dynamic_cast;
166 using Teuchos::rcp_const_cast;
167 using Teuchos::ArrayView;
168 using Teuchos::Array;
170 TEUCHOS_TEST_FOR_EXCEPTION( this->solution_->getBlock(0)->getMap()->getUnderlyingLib() !=
"Tpetra", std::runtime_error,
"Use of NOX only supports Tpetra. Epetra support must be implemented.");
171 RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
172 TEUCHOS_TEST_FOR_EXCEPTION( inArgs.get_x().is_null(), std::logic_error,
"inArgs.get_x() is null.");
174 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
175 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
177 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
179 this->solution_->fromThyraMultiVector(vecThyraNonConst);
181 const RCP<Thyra::MultiVectorBase<SC> > f_out = outArgs.get_f();
182 const RCP<Thyra::LinearOpBase<SC> > W_out = outArgs.get_W_op();
183 const RCP<Thyra::PreconditionerBase<SC> > W_prec_out = outArgs.get_W_prec();
185 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> tpetra_extract;
186 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraMatrix_Type;
187 typedef RCP<TpetraMatrix_Type> TpetraMatrixPtr_Type;
188 typedef RCP<const TpetraMatrix_Type> TpetraMatrixConstPtr_Type;
190 const bool fill_f = nonnull(f_out);
191 const bool fill_W = nonnull(W_out);
192 const bool fill_W_prec = nonnull(W_prec_out);
194 if ( fill_f || fill_W || fill_W_prec ) {
201 this->calculateNonLinResidualVec(
"standard");
203 RCP<Thyra::MultiVectorBase<SC> > f_thyra = this->getResidualVector()->getThyraMultiVector();
204 f_out->assign(*f_thyra);
207 TpetraMatrixPtr_Type W;
210 this->reAssemble(
"Newton");
211 this->setBoundariesSystem();
213 Teuchos::RCP<TpetraOp_Type> W_tpetra = tpetra_extract::getTpetraOperator(W_out);
214 Teuchos::RCP<TpetraMatrix_Type> W_tpetraMat = Teuchos::rcp_dynamic_cast<TpetraMatrix_Type>(W_tpetra);
216 TpetraMatrixConstPtr_Type W_systemTpetra = this->getSystem()->getBlock( 0, 0 )->getTpetraMatrix();
217 TpetraMatrixPtr_Type W_systemTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_systemTpetra);
222 Teuchos::RCP<TpetraMatrix_Type> tpetraMatTpetra = W_systemTpetraNonConst;
225 W_tpetraMat->resumeFill();
227 for (
auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
228 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices;
229 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::values_host_view_type values;
230 tpetraMatTpetra->getLocalRowView( i, indices, values);
231 W_tpetraMat->replaceLocalValues( i, indices, values);
233 W_tpetraMat->fillComplete();
238 this->setupPreconditioner(
"Monolithic" );
243 std::string levelCombination = this->parameterList_->sublist(
"ThyraPreconditioner").sublist(
"Preconditioner Types").sublist(
"FROSch").get(
"Level Combination",
"Additive");
244 if (!levelCombination.compare(
"Multiplicative")) {
245 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Multiplicative Level Combination is not supported for NOX. In general we need to pre-apply the coarse problem. This must be implemented here.");
252template<
class SC,
class LO,
class GO,
class NO>
253void NonLinElasAssFE<SC,LO,GO,NO>::assembleSourceTermLoadstepping(
double time)
const
255 double dt = timeSteppingTool_->get_dt();
256 double beta = timeSteppingTool_->get_beta();
257 double gamma = timeSteppingTool_->get_gamma();
260 if( loadStepping_ ==
true){
262 this->getRhs()->scale(0.0);
266 if (this->hasSourceTerm())
270 MultiVectorPtr_Type FERhs = Teuchos::rcp(
new MultiVector_Type( this->getDomain(0)->getMapVecFieldRepeated() ));
271 vec_dbl_Type funcParameter(4,0.);
272 funcParameter[0] = timeSteppingTool_->t_;
274 funcParameter[1] =this->parameterList_->sublist(
"Parameter").get(
"Volume force",0.00211);
276 funcParameter[3] =this->parameterList_->sublist(
"Parameter").get(
"Final time force",1.0);
277 funcParameter[4] =this->parameterList_->sublist(
"Parameter").get(
"dt",0.1);
280 if(nonlinearExternalForce_){
281 MatrixPtr_Type A(
new Matrix_Type (this->system_->getBlock(0,0)));
283 MatrixPtr_Type AKext(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
284 MatrixPtr_Type Kext(
new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow()*2 ) );
285 MultiVectorPtr_Type Kext_vec;
286 this->feFactory_->assemblyNonlinearSurfaceIntegralExternal(this->dim_, this->getDomain(0)->getFEType(),FERhs, u_rep_,Kext, funcParameter, this->rhsFuncVec_[0],this->parameterList_);
288 A->addMatrix(1.,AKext,0.);
289 Kext->addMatrix(1.,AKext,1.);
291 AKext->fillComplete(this->getDomain(0)->getMapVecFieldUnique(),this->getDomain(0)->getMapVecFieldUnique());
293 this->system_->addBlock(AKext,0,0);
297 this->feFactory_->assemblySurfaceIntegralExternal(this->dim_, this->getDomain(0)->getFEType(),FERhs, u_rep_, funcParameter, this->rhsFuncVec_[0],this->parameterList_);
300 this->sourceTerm_->getBlockNonConst(0)->exportFromVector( FERhs,
false,
"Add" );
303 this->assembleSourceTerm( timeSteppingTool_->t_ );
309 double coeffSourceTermStructure = 1.0;
310 BlockMultiVectorPtr_Type tmpPtr= this->sourceTerm_;
312 this->getRhs()->update(coeffSourceTermStructure, *tmpPtr, 1.);
313 this->rhs_->addBlock( this->getRhs()->getBlockNonConst(0), 0 );
318template<
class SC,
class LO,
class GO,
class NO>
319Teuchos::RCP<Thyra::LinearOpBase<SC> > NonLinElasAssFE<SC,LO,GO,NO>::create_W_op()
const
322 Teuchos::RCP<const Thyra::LinearOpBase<SC> > W_opConst = this->system_->getThyraLinOp();
323 Teuchos::RCP<Thyra::LinearOpBase<SC> > W_op = Teuchos::rcp_const_cast<Thyra::LinearOpBase<SC> >(W_opConst);
327template<
class SC,
class LO,
class GO,
class NO>
328Teuchos::RCP<Thyra::PreconditionerBase<SC> > NonLinElasAssFE<SC,LO,GO,NO>::create_W_prec()
const
330 this->initializeSolverBuilder();
331 this->initializePreconditioner();
333 Teuchos::RCP<const Thyra::PreconditionerBase<SC> > thyraPrec = this->getPreconditionerConst()->getThyraPrecConst();
334 Teuchos::RCP<Thyra::PreconditionerBase<SC> > thyraPrecNonConst= Teuchos::rcp_const_cast<Thyra::PreconditionerBase<SC> >(thyraPrec);
336 return thyraPrecNonConst;
339template<
class SC,
class LO,
class GO,
class NO>
340void NonLinElasAssFE<SC,LO,GO,NO>::calculateNonLinResidualVec(std::string type,
double time)
const{
343 this->reAssemble(
"Newton-Residual");
345 if(this->parameterList_->sublist(
"Parameter").get(
"SCI",
false) ==
true || this->parameterList_->sublist(
"Parameter").get(
"FSCI",
false) ==
true ){
347 this->feFactory_->assemblyAceDeformDiffuBlock(this->dim_, this->getDomain(0)->getFEType(), this->getDomain(0)->getFEType(), 2, 1,this->dim_,concentration_,u_rep_,this->system_,0,0,this->residualVec_,0, this->parameterList_,
"Rhs",
true);
350 if (!type.compare(
"standard")){
351 this->residualVec_->update(-1.,*this->rhs_,1.);
355 else if(!type.compare(
"reverse")){
356 this->residualVec_->update(1.,*this->rhs_,-1.);
361 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"Unknown type for residual computation.");
365 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );
Definition NonLinearProblem_decl.hpp:24
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5