Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
NonLinElasAssFE_def.hpp
1#ifndef NonLinElasAssFE_def_hpp
2#define NonLinElasAssFE_def_hpp
3#include "NonLinElasAssFE_decl.hpp"
12
13
14namespace FEDD {
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):
17NonLinearProblem<SC,LO,GO,NO>( parameterList, domain->getComm() ),
18u_rep_()
19{
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();
24
25 C_ = this->parameterList_->sublist("Parameter").get("C",1.);
26
27 double density = this->parameterList_->sublist("Parameter").get("Density",1.);
28
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);
32
33 timeSteppingTool_ = Teuchos::rcp(new TimeSteppingTools(sublist(this->parameterList_,"Timestepping Parameter") , this->comm_));
34
35}
36
37template<class SC,class LO,class GO,class NO>
38NonLinElasAssFE<SC,LO,GO,NO>::~NonLinElasAssFE(){
39
40}
41
42template<class SC,class LO,class GO,class NO>
43void NonLinElasAssFE<SC,LO,GO,NO>::info(){
44 this->infoProblem();
45 this->infoNonlinProblem();
46}
47
48template<class SC,class LO,class GO,class NO>
49void NonLinElasAssFE<SC,LO,GO,NO>::assemble(std::string type) const{
50
51 if (type == ""){
52 if (this->verbose_)
53 std::cout << "-- Assembly nonlinear elasticity ... " << std::flush;
54
55 MatrixPtr_Type A(new Matrix_Type( this->getDomain(0)->getMapVecFieldUnique(), this->getDomain(0)->getDimension() * this->getDomain(0)->getApproxEntriesPerRow() ) );
56
57 this->feFactory_->assemblyEmptyMatrix(A);
58
59 this->system_.reset(new BlockMatrix_Type(1));
60 this->system_->addBlock( A, 0, 0 );
61
62 double density = this->parameterList_->sublist("Parameter").get("Density",1000.);
63 std::string sourceType = this->parameterList_->sublist("Parameter").get("Source Type","volume");
64
65 this->assembleSourceTerm( 0. );
66 if(sourceType == "volume")
67 this->sourceTerm_->scale(density);
68
69 this->addToRhs( this->sourceTerm_ );
70
71 this->setBoundariesRHS();
72
73 this->solution_->putScalar(0.);
74
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);
78
79 if (this->verbose_)
80 std::cout << "done -- " << std::endl;
81
82 this->reAssemble("Newton-Residual");
83 }
84 else if(type == "UpdateTime")
85 {
86 if(this->verbose_)
87 std::cout << "-- Reassembly (UpdateTime)" << '\n';
88
89 updateTime();
90 return;
91 }
92 else
93 this->reAssemble(type);
94}
95
96// Damit die richtige timeSteppingTool_->currentTime() genommen wird.
97template<class SC,class LO,class GO,class NO>
98void NonLinElasAssFE<SC,LO,GO,NO>::updateTime() const
99{
100 timeSteppingTool_->t_ = timeSteppingTool_->t_ + timeSteppingTool_->dt_prev_;
101}
102
103template<class SC,class LO,class GO,class NO>
104void NonLinElasAssFE<SC,LO,GO,NO>::reAssemble(std::string type) const {
105
106 std::string material_model = this->parameterList_->sublist("Parameter").get("Structure Model","Neo-Hooke");
107
108 if (this->verbose_)
109 std::cout << "-- Reassembly nonlinear elasticity with structure material model " << material_model <<" ("<<type <<") ... " << std::flush;
110
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 );
116
117 MultiVectorPtr_Type fRep = Teuchos::rcp( new MultiVector_Type( this->getDomain(0)->getMapVecFieldRepeated(), 1 ) );
118 fRep->putScalar(0.);
119 this->residualVec_->addBlock( fRep, 0 );
120
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/*call fillComplete*/);
123 else
124 this->feFactory_->assemblyNonLinearElasticity(this->dim_, this->getDomain(0)->getFEType(),2, this->dim_, u_rep_, this->system_, this->residualVec_, this->parameterList_,true);
125 //fRep->scale(-1.);
126
127 MultiVectorPtr_Type fUnique = Teuchos::rcp( new MultiVector_Type( this->getDomain(0)->getMapVecFieldUnique(), 1 ) );
128 fUnique->putScalar(0.);
129 fUnique->exportFromVector( fRep, true, "Add" );
130
131 this->residualVec_->addBlock( fUnique, 0 );
132
133 if(loadStepping_)
134 assembleSourceTermLoadstepping();
135
136
137 }
138 else if(type=="Newton"){ //we already assemble the new tangent when we calculate the stresses above
139
140 }
141 if (this->verbose_)
142 std::cout << "done -- " << std::endl;
143}
144
145template<class SC,class LO,class GO,class NO>
146void NonLinElasAssFE<SC,LO,GO,NO>::reAssemble( MatrixPtr_Type& massmatrix, std::string type ) const
147{
148
149}
150
151template<class SC,class LO,class GO,class NO>
152void NonLinElasAssFE<SC,LO,GO,NO>::reAssembleExtrapolation(BlockMultiVectorPtrArray_Type previousSolutions){
153
154
155 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Only Newton/NOX implemented for nonlinear material models!");
156
157}
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
161 ) const
162{
163 using Teuchos::RCP;
164 using Teuchos::rcp;
165 using Teuchos::rcp_dynamic_cast;
166 using Teuchos::rcp_const_cast;
167 using Teuchos::ArrayView;
168 using Teuchos::Array;
169
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.");
173
174 RCP< const Thyra::VectorBase< SC > > vecThyra = inArgs.get_x();
175 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
176
177 RCP< Thyra::VectorBase< SC > > vecThyraNonConst = rcp_const_cast<Thyra::VectorBase< SC > >(vecThyra);
178
179 this->solution_->fromThyraMultiVector(vecThyraNonConst);
180
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();
184
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;
189
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);
193
194 if ( fill_f || fill_W || fill_W_prec ) {
195
196 // ****************
197 // Get the underlying xpetra objects
198 // ****************
199 if (fill_f) {
200
201 this->calculateNonLinResidualVec("standard");
202
203 RCP<Thyra::MultiVectorBase<SC> > f_thyra = this->getResidualVector()->getThyraMultiVector();
204 f_out->assign(*f_thyra);
205 }
206
207 TpetraMatrixPtr_Type W;
208 if (fill_W) {
209
210 this->reAssemble("Newton");
211 this->setBoundariesSystem();
212
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);
215
216 TpetraMatrixConstPtr_Type W_systemTpetra = this->getSystem()->getBlock( 0, 0 )->getTpetraMatrix();
217 TpetraMatrixPtr_Type W_systemTpetraNonConst = rcp_const_cast<TpetraMatrix_Type>(W_systemTpetra);
218
219 //Tpetra::CrsMatrixWrap<SC,LO,GO,NO>& crsOp = dynamic_cast<Xpetra::CrsMatrixWrap<SC,LO,GO,NO>&>(*W_systemXpetraNonConst);
220 //Xpetra::TpetraCrsMatrix<SC,LO,GO,NO>& xTpetraMat = dynamic_cast<Xpetra::TpetraCrsMatrix<SC,LO,GO,NO>&>(*crsOp.getCrsMatrix());
221
222 Teuchos::RCP<TpetraMatrix_Type> tpetraMatTpetra = W_systemTpetraNonConst; //xTpetraMat.getTpetra_CrsMatrixNonConst();
223
224
225 W_tpetraMat->resumeFill();
226
227 for (auto i=0; i<tpetraMatTpetra->getMap()->getLocalNumElements(); i++) {
228 typename Tpetra::CrsMatrix<SC,LO,GO,NO>::local_inds_host_view_type indices; //ArrayView< const LO > 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);
232 }
233 W_tpetraMat->fillComplete();
234
235 }
236
237 if (fill_W_prec) {
238 this->setupPreconditioner( "Monolithic" );
239
240 // ch 26.04.19: After each setup of the preconditioner we check if we use a two-level precondtioner with multiplicative combination between the levels.
241 // If this is the case, we need to pre apply the coarse level to the residual(f_out).
242
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.");
246 }
247
248 }
249 }
250}
251
252template<class SC,class LO,class GO,class NO>
253void NonLinElasAssFE<SC,LO,GO,NO>::assembleSourceTermLoadstepping(double time) const
254{
255 double dt = timeSteppingTool_->get_dt();
256 double beta = timeSteppingTool_->get_beta();
257 double gamma = timeSteppingTool_->get_gamma();
258
259
260 if( loadStepping_ == true){
261 // The if condition resets the rhs. If we skip it when we attemp loadstepping, the rhs will be updated continously and wrongly increase with each timestep
262 this->getRhs()->scale(0.0);
263 }
264
265
266 if (this->hasSourceTerm())
267 {
268 if(externalForce_){
269
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_;
273 // how can we use different parameters for different blocks here?
274 funcParameter[1] =this->parameterList_->sublist("Parameter").get("Volume force",0.00211);
275
276 funcParameter[3] =this->parameterList_->sublist("Parameter").get("Final time force",1.0);
277 funcParameter[4] =this->parameterList_->sublist("Parameter").get("dt",0.1);
278
279
280 if(nonlinearExternalForce_){
281 MatrixPtr_Type A( new Matrix_Type (this->system_->getBlock(0,0)));
282 //A->print();
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_);
287
288 A->addMatrix(1.,AKext,0.);
289 Kext->addMatrix(1.,AKext,1.);
290
291 AKext->fillComplete(this->getDomain(0)->getMapVecFieldUnique(),this->getDomain(0)->getMapVecFieldUnique());
292
293 this->system_->addBlock(AKext,0,0);
294
295 }
296 else
297 this->feFactory_->assemblySurfaceIntegralExternal(this->dim_, this->getDomain(0)->getFEType(),FERhs, u_rep_, funcParameter, this->rhsFuncVec_[0],this->parameterList_);
298
299
300 this->sourceTerm_->getBlockNonConst(0)->exportFromVector( FERhs, false, "Add" );
301 }
302 else
303 this->assembleSourceTerm( timeSteppingTool_->t_ );
304 //this->problemTimeStructure_->getSourceTerm()->scale(density);
305 // Fuege die rechte Seite der DGL (f bzw. f_{n+1}) der rechten Seite hinzu (skaliert mit coeffSourceTerm)
306 // Die Skalierung mit der Dichte erfolgt schon in der Assemblierungsfunktion!
307
308 // addSourceTermToRHS() aus DAESolverInTime
309 double coeffSourceTermStructure = 1.0;
310 BlockMultiVectorPtr_Type tmpPtr= this->sourceTerm_;
311
312 this->getRhs()->update(coeffSourceTermStructure, *tmpPtr, 1.);
313 this->rhs_->addBlock( this->getRhs()->getBlockNonConst(0), 0 );
314
315 }
316}
317
318template<class SC,class LO,class GO,class NO>
319Teuchos::RCP<Thyra::LinearOpBase<SC> > NonLinElasAssFE<SC,LO,GO,NO>::create_W_op() const
320{
321
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);
324 return W_op;
325}
326
327template<class SC,class LO,class GO,class NO>
328Teuchos::RCP<Thyra::PreconditionerBase<SC> > NonLinElasAssFE<SC,LO,GO,NO>::create_W_prec() const
329{
330 this->initializeSolverBuilder();
331 this->initializePreconditioner();
332
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);
335
336 return thyraPrecNonConst;
337}
338
339template<class SC,class LO,class GO,class NO>
340void NonLinElasAssFE<SC,LO,GO,NO>::calculateNonLinResidualVec(std::string type, double time) const{
341
342
343 this->reAssemble("Newton-Residual");
344
345 if(this->parameterList_->sublist("Parameter").get("SCI",false) == true || this->parameterList_->sublist("Parameter").get("FSCI",false) == true ){
346 //this->feFactory_->assemblyNonLinearElasticity(this->dim_, this->getDomain(0)->getFEType(),2, this->dim_, u_rep_, this->system_, this->residualVec_, this->parameterList_,this->getDomain(0), this->eModVec_,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/*call fillComplete*/);
348 }
349 else{
350 if (!type.compare("standard")){
351 this->residualVec_->update(-1.,*this->rhs_,1.);
352 //if ( !this->sourceTerm_.is_null() )
353 // this->residualVec_->update(-1.,*this->sourceTerm_,1.);
354 }
355 else if(!type.compare("reverse")){
356 this->residualVec_->update(1.,*this->rhs_,-1.); // this = -1*this + 1*rhs
357 //if ( !this->sourceTerm_.is_null() )
358 // this->residualVec_->update(1.,*this->sourceTerm_,1.);
359 }
360 else{
361 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Unknown type for residual computation.");
362 }
363
364 // this might be set again by the TimeProblem after adding of M*u
365 this->bcFactory_->setBCMinusVector( this->residualVec_, this->solution_, time );
366 }
367
368}
369}
370#endif
Definition NonLinearProblem_decl.hpp:24
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5