Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
DAESolverInTime_def.hpp
1#ifndef DAESOLVERINTIME_DEF_hpp
2#define DAESOLVERINTIME_DEF_hpp
3
4
5#include "feddlib/problems/specific/FSI.hpp"
6#include "feddlib/core/Mesh/MeshUnstructured.hpp"
7#include "feddlib/core/FE/Domain.hpp"
8#include "feddlib/core/FE/FE.hpp"
9
18
19namespace FEDD {
20
21
22template<class SC,class LO,class GO,class NO>
23DAESolverInTime<SC,LO,GO,NO>::DAESolverInTime( CommConstPtr_Type comm ):
24comm_(comm),
25verbose_(comm->getRank()==0),
26parameterList_(),
27isTimeSteppingDefined_(false),
28problem_(),
29problemTime_(),
30timeStepDef_(),
31timeSteppingTool_(),
32exporter_vector_(),
33export_solution_vector_(),
34boolExporterSetup_(false)
35#ifdef FEDD_TIMER
36,solveProblemTimer_ (Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime - Solve Problem"))
37#endif
38#ifdef FEDD_DETAIL_TIMER
39,reassmbleAddInterfaceRHSTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Interface RHS"))
40,reassmbleUpdateMeshDisplacementTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Update Mesh Displ."))
41,reassmbleSolveGeometryTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Solve Geometry"))
42,reassmbleMoveMeshTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Move Mesh"))
43,reassmbleSolidMassAndRHSTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Assemble Solid Massmatrix and RHS"))
44,reassmbleForTimeTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Assemble Fluid Problem (steady Navier-Stokes)"))
45,reassmbleUpdateFluidInTimeTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Update Fluid Solution"))
46#endif
47{
48
49
50}
51
52template<class SC,class LO,class GO,class NO>
53DAESolverInTime<SC,LO,GO,NO>::DAESolverInTime( ParameterListPtr_Type &parameterList, CommConstPtr_Type comm):
54comm_(comm),
55verbose_(comm->getRank()==0),
56parameterList_(parameterList),
57isTimeSteppingDefined_(false),
58problem_(),
59problemTime_(),
60timeStepDef_(),
61timeSteppingTool_(),
62exporter_vector_(),
63export_solution_vector_(),
64boolExporterSetup_(false)
65#ifdef FEDD_TIMER
66,solveProblemTimer_ (Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime - Solve Problem"))
67#endif
68#ifdef FEDD_DETAIL_TIMER
69,reassmbleAddInterfaceRHSTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Interface RHS"))
70,reassmbleUpdateMeshDisplacementTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Update Mesh Displ."))
71,reassmbleSolveGeometryTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Solve Geometry"))
72,reassmbleMoveMeshTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Move Mesh"))
73,reassmbleSolidMassAndRHSTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Assemble Solid Massmatrix and RHS"))
74,reassmbleForTimeTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Assemble Fluid Problem (steady Navier-Stokes)"))
75,reassmbleUpdateFluidInTimeTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Update Fluid Solution"))
76#endif
77
78{
79
80}
81
82template<class SC,class LO,class GO,class NO>
83DAESolverInTime<SC,LO,GO,NO>::DAESolverInTime( SmallMatrix<int> &timeStepDef, ParameterListPtr_Type &parameterList, CommConstPtr_Type comm):
84comm_(comm),
85verbose_(comm->getRank()==0),
86parameterList_(parameterList),
87isTimeSteppingDefined_(false),
88problem_(),
89problemTime_(),
90timeStepDef_(),
91timeSteppingTool_(),
92exporter_vector_(),
93export_solution_vector_(),
94boolExporterSetup_(false)
95#ifdef FEDD_TIMER
96,solveProblemTimer_ (Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime - Solve Problem"))
97#endif
98#ifdef FEDD_DETAIL_TIMER
99,reassmbleAddInterfaceRHSTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Interface RHS"))
100,reassmbleUpdateMeshDisplacementTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Update Mesh Displ."))
101,reassmbleSolveGeometryTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Solve Geometry"))
102,reassmbleMoveMeshTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Move Mesh"))
103,reassmbleSolidMassAndRHSTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Assemble Solid Massmatrix and RHS"))
104,reassmbleForTimeTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Assemble Fluid Problem (steady Navier-Stokes)"))
105,reassmbleUpdateFluidInTimeTimer_(Teuchos::TimeMonitor::getNewCounter("FEDD - DAETime Detail - FSI Update Fluid Solution"))
106#endif
107
108{
109 this->defineTimeStepping(timeStepDef);
110}
111
112template<class SC,class LO,class GO,class NO>
113DAESolverInTime<SC,LO,GO,NO>::~DAESolverInTime(){
114
115}
116
117
118template<class SC,class LO,class GO,class NO>
119void DAESolverInTime<SC,LO,GO,NO>::setProblem(Problem_Type& problem){
120
121 problem_ = Teuchos::rcpFromRef(problem); /*now a NON-OWNING TEUCHOS::RCP to the object which was probably constructed in main function */
122
123}
124
125template<class SC,class LO,class GO,class NO>
126void DAESolverInTime<SC,LO,GO,NO>::defineTimeStepping(SmallMatrix<int> &timeStepDef){
127
128 timeStepDef_ = timeStepDef;
129 timeSteppingTool_.reset(new TimeSteppingTools(sublist(parameterList_,"Timestepping Parameter") , comm_));
130 isTimeSteppingDefined_ = true;
131
132
133}
134
135template<class SC,class LO,class GO,class NO>
136void DAESolverInTime<SC,LO,GO,NO>::advanceInTime(){
137
138 TEUCHOS_TEST_FOR_EXCEPTION(problemTime_.is_null(), std::logic_error, "Mass system is null.");
139
140 checkTimeSteppingDef();
141
142 if(this->parameterList_->sublist("Parameter").get("FSI",false))
143 {
144 advanceInTimeFSI();
145 }
146 else{
147 if (!parameterList_->sublist("Timestepping Parameter").get("Class","Singlestep").compare("Loadstepping")) {
148 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
149 if (nonLinProb.is_null()){
150 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Loadstepping only available to nonlinear Problems. (It is a tool to increase Nonlinear Solver convergence.)");
151 }
152 else{
153 advanceWithLoadStepping();
154 }
155 }
156 if (!parameterList_->sublist("Timestepping Parameter").get("Class","Singlestep").compare("Singlestep")) {
157 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
158 if (nonLinProb.is_null()) {
159 advanceInTimeLinear();
160 }
161 else{
162 advanceInTimeNonLinear();
163 }
164 }
165 else if(!parameterList_->sublist("Timestepping Parameter").get("Class","Singlestep").compare("Newmark"))
166 {
167 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
168 if (nonLinProb.is_null()) {
169 advanceInTimeLinearNewmark();
170 }
171 else
172 {
173 advanceInTimeNonLinearNewmark();
174 }
175 }
176 else if( !parameterList_->sublist("Timestepping Parameter").get("Class","Singlestep").compare("Multistep") ){
177 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
178 if (nonLinProb.is_null()) {
179 advanceInTimeLinearMultistep();
180 }
181 else{
182 advanceInTimeNonLinearMultistep();
183 }
184 }
185 else if( !parameterList_->sublist("Timestepping Parameter").get("Class","Singlestep").compare("External") ){
186 NonLinProbPtr_Type nonLinProb = Teuchos::rcp_dynamic_cast<NonLinProb_Type>(problem_);
187 if (nonLinProb.is_null()) {
188 advanceInTimeLinearExternal();
189 }
190 else{
191 advanceInTimeNonLinearExternal();
192 }
193 }
194 else{
195 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Unknown time discretization type.");
196 }
197 }
198
199}
200
201template<class SC,class LO,class GO,class NO>
202void DAESolverInTime<SC,LO,GO,NO>::advanceInTimeLinear(){
203
204
205 bool print = parameterList_->sublist("General").get("ParaViewExport",false);
206 if (print)
207 exportTimestep();
208 bool fullImplicitPressure = false;
209 int size = timeStepDef_.size();
210 double dt = 0.0;
211 while (timeSteppingTool_->continueTimeStepping()) {
212 problemTime_->updateTime ( timeSteppingTool_->currentTime() );
213 dt = timeSteppingTool_->get_dt();
214 problemTime_->updateSolutionPreviousStep();
215
216 Teuchos::Array<BlockMatrixPtr_Type> bMatNonLin_vec_allstages;
217 BlockMultiVectorPtrArray_Type solutionRK_stages;
218 BlockMultiVectorPtrArray_Type sourceTermRK_stages;
219
220 for (int s=0; s<timeSteppingTool_->getNmbStages(); s++) {
221 double time = timeSteppingTool_->currentTime() + dt * timeSteppingTool_->getButcherTableC(s);
222 if (verbose_)
223 std::cout << "Currently in stage " << s+1 << " of "<< timeSteppingTool_->getNmbStages() << std::endl;
224
225 problemTime_->updateRhs();/*apply (mass matrix / dt) to u_t*/
226 if ( problemTime_->hasSourceTerm() ){
227 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Fix source term.");
228 problemTime_->assembleSourceTerm( time );
229 }
230
231 if (s==0 && timeSteppingTool_->getButcherTableCoefficient(s , s) == 0.0) {
232 /* solution of last time step is later added to rk solution vector */
233 }
234 else if (s==0 && timeSteppingTool_->getButcherTableCoefficient(s , s) != 0.0) {
235 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented butcher table!");
236 }
237 else{
238 for (int s_prior=0; s_prior<s; s_prior++) {
239 SmallMatrix<double> coeff(size);
240 for (int i=0; i<size; i++) {
241 for (int j=0; j<size; j++) {
242 if (timeStepDef_[i][j]>0) {
243 if (i==0 && j==1 && fullImplicitPressure) {
244 coeff[i][j] = 0;
245 }
246 else{
247 coeff[i][j] = - timeSteppingTool_->getButcherTableCoefficient(s , s_prior);
248 }
249 }
250 }
251 }
252 if (problemTime_->hasSourceTerm())
253 this->addRhsDAE(coeff, sourceTermRK_stages[s_prior] );
254
255 this->addRhsDAE( coeff, problemTime_->getSystem(), solutionRK_stages[s_prior] );
256
257 }
258
259 SmallMatrix<double> massCoeff(size);
260 SmallMatrix<double> problemCoeff(size);
261 double coeffSourceTerm = 0.;
262 for (int i=0; i<size; i++) {
263 for (int j=0; j<size; j++) {
264 if (timeStepDef_[i][j]>0 && i==j) {
265 massCoeff[i][j] = 1. / dt;
266 }
267 else if (timeStepDef_[i][j]==2) /*force off-diagnonal mass matrix*/
268 massCoeff[i][j] = 1. / dt;
269 else{
270 massCoeff[i][j] = 0.;
271 }
272 }
273 }
274 for (int i=0; i<size; i++) {
275 for (int j=0; j<size; j++){
276 if (timeStepDef_[i][j]>0){
277 if (i==0 && j==1 && fullImplicitPressure) {
278 problemCoeff[i][j] = 1.;
279 coeffSourceTerm = timeSteppingTool_->getButcherTableCoefficient(s , s); // ACHTUNG FUER SOURCE TERM, DER NICHT IN DER ZEIT
280 }
281 else{
282 problemCoeff[i][j] = timeSteppingTool_->getButcherTableCoefficient(s , s);
283 coeffSourceTerm = timeSteppingTool_->getButcherTableCoefficient(s , s); // ACHTUNG FUER SOURCE TERM, DER NICHT IN DER ZEIT DISKRETISIERT WIRD!
284 }
285 }
286 else{
287 problemCoeff[i][j] = 1.;
288 }
289 }
290 }
291
292 if (problemTime_->hasSourceTerm())
293 addSourceTermToRHS(coeffSourceTerm);
294
295 problemTime_->setTimeParameters(massCoeff, problemCoeff);
296 problemTime_->combineSystems();
297 problemTime_->setBoundaries(time);
298
299 problemTime_->solve();
300
301 }
302
303 if (s+1 == timeSteppingTool_->getNmbStages()) {
304 BlockMultiVectorPtr_Type tmpSolution = Teuchos::rcp( new BlockMultiVector_Type ( problemTime_->getSolution() ) );
305 solutionRK_stages.push_back(tmpSolution);
306 BlockMultiVectorPtr_Type tmpSolutionPtr = problemTime_->getSolution();
307 BlockMatrixPtr_Type tmpMassSystem = problemTime_->getMassSystem();
308 timeSteppingTool_->calculateSolution( tmpSolutionPtr, solutionRK_stages, tmpMassSystem);
309 }
310 else{
311 solutionRK_stages.push_back( problemTime_->getSolution() );
312 if ( problemTime_->hasSourceTerm() )
313 sourceTermRK_stages.push_back( problemTime_->getSourceTerm() );
314 }
315 }
316
317 timeSteppingTool_->advanceTime(true/*output info*/);
318
319 if (print)
320 exportTimestep();
321 }
322
323 if (print) {
324 closeExporter();
325 }
326 if (parameterList_->sublist("NSParameter").get("Calculate Coefficients",false)) {
327 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "close txt exporters here.");
328 }
329
330}
331template<class SC,class LO,class GO,class NO>
332void DAESolverInTime<SC,LO,GO,NO>::getMassCoefficients(SmallMatrix<double> &massCoeff){
333 int size = timeStepDef_.size();
334 massCoeff.resize(size);
335
336 for (int i=0; i<size; i++) {
337 for (int j=0; j<size; j++) {
338 if (timeStepDef_[i][j]>0 && i==j)
339 massCoeff[i][j] = 1.;
340 else
341 massCoeff[i][j] = 0.;
342 }
343 }
344}
345
346template<class SC,class LO,class GO,class NO>
347void DAESolverInTime<SC,LO,GO,NO>::getMultiStageCoefficients(SmallMatrix<double> &problemCoeff, int stage, int stagePrior, bool forRhs){
348 int size = timeStepDef_.size();
349 problemCoeff.resize(size);
350
351 for (int i=0; i<size; i++) {
352 for (int j=0; j<size; j++) {
353 if (timeStepDef_[i][j]>0)
354 problemCoeff[i][j] = timeSteppingTool_->get_dt()* timeSteppingTool_->getButcherTableCoefficient(stage , stagePrior);
355 else{
356 if (forRhs)
357 problemCoeff[i][j] = 0.;
358 else
359 problemCoeff[i][j] = 1.;
360 }
361 }
362 }
363}
364
365template<class SC,class LO,class GO,class NO>
366void DAESolverInTime<SC,LO,GO,NO>::buildMultiStageRhs( int stage, Teuchos::Array<BlockMatrixPtr_Type>& matrixPrevStages, BlockMultiVectorPtrArray_Type& solutionPrevStages ){
367
368 int size = timeStepDef_.size();
369 SmallMatrix<double> massCoeff(size);
370 SmallMatrix<double> problemCoeff(size);
371
372 getMassCoefficients(massCoeff);
373
374 problemTime_->setTimeParameters(massCoeff, problemCoeff);//problemCoeff not needed here
375 problemTime_->updateRhs();/*apply (mass matrix / dt) to u_t*/
376
377 bool fullImplicitPressure = parameterList_->sublist("Timestepping Parameter").get("Full implicit pressure",false);
378 for (int prevStage=0; prevStage<stage; prevStage++) {
379
380 getMultiStageCoefficients(problemCoeff, stage, prevStage, true);
381 if (fullImplicitPressure && size>1 )
382 problemCoeff[0][1] = 0.;
383
384 problemCoeff.scale(-1.);
385
386 TEUCHOS_TEST_FOR_EXCEPTION(problemTime_->hasSourceTerm(), std::logic_error, "Using source term must be implemented for single-step methods.");
387// addRhsDAE(coeff,beNL_vec_allstages.at(s_prior), solutionRK_stages.at(s_prior), sourceTermRK_stages.at(s_prior));
388 addRhsDAE( problemCoeff, matrixPrevStages[prevStage], solutionPrevStages[prevStage] );
389
390 }
391}
392
393
394
395template<class SC,class LO,class GO,class NO>
396void DAESolverInTime<SC,LO,GO,NO>::advanceInTimeNonLinear(){
397
398 bool print = parameterList_->sublist("General").get("ParaViewExport",false);
399 BlockMultiVectorPtr_Type solShort;
400 if (print){
401 if (parameterList_->sublist("Timestepping Parameter").get("Print Solution Short",false)) {
402 solShort = Teuchos::rcp(new BlockMultiVector_Type (problemTime_->getSolution()) );
403 exportTimestep(solShort);
404 }
405 else{
406 exportTimestep();
407 }
408 }
409
410 // Navier-Stokes treatment of pressure
411 bool fullImplicitPressure = parameterList_->sublist("Timestepping Parameter").get("Full implicit pressure",false);
412 bool semiImplicitPressure = parameterList_->sublist("Timestepping Parameter").get("Semi implicit pressure",false);
413 bool correctPressure = parameterList_->sublist("Timestepping Parameter").get("Correct pressure",false);
414 int size = timeStepDef_.size();
415 SmallMatrix<double> massCoeff(size);
416 SmallMatrix<double> problemCoeff(size);
417 double dt = 0.0;
418 int timeit = 0;
419 while (timeSteppingTool_->continueTimeStepping()) {
420
421 dt = timeSteppingTool_->get_dt();
422 // Which values should we use for extrapolation? u_m and u_m-1 (current implementation) or should we use most recent U_i-1 of multi stages
423 if(!parameterList_->sublist("General").get("Linearization","FixedPoint").compare("Extrapolation")) {
424 if (timeSteppingTool_->currentTime()!=0.)
425 problemTime_->updateSolutionMultiPreviousStep(2); //2nd order
426 else
427 problemTime_->updateSolutionMultiPreviousStep(1);
428 }
429 else{
430 problemTime_->updateSolutionPreviousStep();
431 }
432
433
434// BlockMultiVectorPtrArray_Type sourceTermRK_stages;
435
436 TEUCHOS_TEST_FOR_EXCEPTION(timeSteppingTool_->getButcherTableCoefficient(0 , 0) != 0.0, std::logic_error, "Not implemented butchertable! First stage should have 0 diagonal value");
437 if (verbose_)
438 std::cout << "Currently in stage " << 1 << " of "<< timeSteppingTool_->getNmbStages() <<" (dummy stage)"<< std::endl;
439 // Multistage stepping, in general we use at least 2 stages (implicit Euler and Crank-Nicolson)
440 Teuchos::Array<BlockMatrixPtr_Type> matrixPrevStages;
441 BlockMultiVectorPtrArray_Type solutionPrevStages;
442
443 BlockMatrixPtr_Type blockMatrix = Teuchos::rcp( new BlockMatrix_Type( problemTime_->getSystem()->size() ) );
444 problemTime_->reAssembleAndFill( blockMatrix ); // Reassemble FixedPoint
445
446 matrixPrevStages.push_back( blockMatrix );
447
448 BlockMultiVectorPtr_Type sol =
449 Teuchos::rcp( new BlockMultiVector_Type( problemTime_->getSolution() ) );
450 solutionPrevStages.push_back( sol );
451
452 for (int stage=1; stage<timeSteppingTool_->getNmbStages(); stage++) {
453 double time = timeSteppingTool_->currentTime() + dt * timeSteppingTool_->getButcherTableC(stage);
454 problemTime_->updateTime( time );
455 if (verbose_)
456 std::cout << "Currently in stage " << stage+1 << " of "<< timeSteppingTool_->getNmbStages() << std::endl;
457
458 buildMultiStageRhs( stage, matrixPrevStages, solutionPrevStages );
459
460 TEUCHOS_TEST_FOR_EXCEPTION(problemTime_->hasSourceTerm(), std::logic_error, "Using source term must be implemented for single-step methods.");
461// problemTime_->AssembleSourceTerm(time);
462
463
464 SmallMatrix<double> massCoeff(size);
465 SmallMatrix<double> problemCoeff(size);
466
467 getMassCoefficients(massCoeff);
468 getMultiStageCoefficients(problemCoeff, stage, stage, false);
469 if (fullImplicitPressure && size>1 )
470 problemCoeff[0][1] = timeSteppingTool_->get_dt();
471
472 problemTime_->setTimeParameters(massCoeff, problemCoeff);
473
474 NonLinearSolver<SC, LO, GO, NO> nlSolver(parameterList_->sublist("General").get("Linearization","FixedPoint"));
475 nlSolver.solve(*problemTime_,time);
476
477 if (correctPressure) {
478 TEUCHOS_TEST_FOR_EXCEPTION( !fullImplicitPressure && !semiImplicitPressure, std::logic_error,"There is no pressure that can be corrected." );
479
480 MultiVectorPtr_Type sol = problemTime_->getSolution()->getBlockNonConst(1);
481 MultiVectorConstPtr_Type solLast = problemTime_->getSolutionPreviousTimestep()->getBlock(1);
482 timeSteppingTool_->correctPressure( sol, solLast );
483 if (verbose_)
484 std::cout << "Pressure corrected." << std::endl;
485 }
486
487 if (stage+1 == timeSteppingTool_->getNmbStages()) {
488 // save last solution
489 BlockMultiVectorPtr_Type tmpSolution = Teuchos::rcp( new BlockMultiVector_Type ( problemTime_->getSolution() ) );
490
491 solutionPrevStages.push_back( tmpSolution );
492 BlockMultiVectorPtr_Type tmpSolutionPtr = problemTime_->getSolution();
493 BlockMatrixPtr_Type tmpMassSystem = problemTime_->getMassSystem();
494 timeSteppingTool_->calculateSolution( tmpSolutionPtr, solutionPrevStages, tmpMassSystem, solShort);
495 }
496 else{
497 BlockMatrixPtr_Type blockMatrix = Teuchos::rcp( new BlockMatrix_Type( problemTime_->getSystem()->size() ) );
498 problemTime_->reAssembleAndFill( blockMatrix );
499 matrixPrevStages.push_back( blockMatrix );
500
501 BlockMultiVectorPtr_Type sol =
502 Teuchos::rcp( new BlockMultiVector_Type( problemTime_->getSolution() ) );
503 solutionPrevStages.push_back( sol );
504
505 TEUCHOS_TEST_FOR_EXCEPTION(problemTime_->hasSourceTerm(), std::logic_error, "Using source term must be implemented for single-step methods.");
506// sourceTermRK_stages.push_back(*problemTime_->GetSourceTerm());
507 }
508 }
509 timeSteppingTool_->advanceTime(true/*output info*/);
510 timeit++;
511 if (print) {
512 exportTimestep();
513 }
514 if (parameterList_->sublist("NSParameter").get("Calculate Coefficients",false)) {
515 vec_dbl_ptr_Type values(new vec_dbl_Type(4));
516 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Drag and Lift are not implemented.");
517// nonLinearProblem_->ComputeDragLift(values);
518 }
519 }
520
521 if (print) {
522 closeExporter();
523 }
524 if (parameterList_->sublist("NSParameter").get("Calculate Coefficients",false)) {
525 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "close txt exporters here.");
526 }
527
528}
529
530// TODO: Irgendwann einmal fuer St. Venant-Kirchoff oder so programmieren.
531// Erstmal nicht wichtig
532template<class SC,class LO,class GO,class NO>
533void DAESolverInTime<SC,LO,GO,NO>::advanceWithLoadStepping()
534{
535
536 bool print = parameterList_->sublist("General").get("ParaViewExport",false);
537 bool printExtraData = parameterList_->sublist("General").get("Export Extra Data",false);
538 bool printData = parameterList_->sublist("General").get("Export Data",false);
539 if (print)
540 {
541 exportTimestep();
542 }
543
544 vec_dbl_ptr_Type its = Teuchos::rcp(new vec_dbl_Type ( 2, 0. ) ); //0:linear iterations, 1: nonlinear iterations
545 ExporterTxtPtr_Type exporterTimeTxt;
546 ExporterTxtPtr_Type exporterIterations;
547 ExporterTxtPtr_Type exporterNewtonIterations;
548 if (printData) {
549 std::string suffix = parameterList_->sublist("General").get("Export Suffix","");
550
551 exporterTimeTxt = Teuchos::rcp(new ExporterTxt());
552 exporterTimeTxt->setup( "time" + suffix, this->comm_ );
553
554 exporterNewtonIterations = Teuchos::rcp(new ExporterTxt());
555 exporterNewtonIterations->setup( "newtonIterations" + suffix, this->comm_ );
556
557 exporterIterations = Teuchos::rcp(new ExporterTxt());
558 exporterIterations->setup( "linearIterations" + suffix, this->comm_ );
559 }
560 // Groesse des Problems, Zeitschrittweite und Newmark-Parameter
561 int size = timeStepDef_.size();
562 TEUCHOS_TEST_FOR_EXCEPTION( size>1, std::runtime_error, "Loadstepping only implemented or sensible for 1x1 Systems.");
563 double dt = timeSteppingTool_->get_dt();
564
565
566 // Koeffizienten vor der Massematrix und vor der Systemmatrix des steady-Problems
567 SmallMatrix<double> massCoeff(size);
568 SmallMatrix<double> problemCoeff(size);
569 double coeffSourceTerm = 0.0; // Koeffizient fuer den Source-Term (= rechte Seite der DGL); mit Null initialisieren
570
571 // Koeffizient vor der Massematrix
572 massCoeff[0][0] = 0.;
573 problemCoeff[0][0] = 1.0;
574 // Der Source Term ist schon nach der Assemblierung mit der Dichte \rho skaliert worden
575 coeffSourceTerm = 1.0; // ACHTUNG FUER SOURCE TERM, DER NICHT IN DER ZEIT DISKRETISIERT WIRD!
576
577 // Temporaerer Koeffizienten fuer die Skalierung der Massematrix in der rechten Seite des Systems in UpdateNewmarkRhs()
578 vec_dbl_Type coeffTemp(1);
579 coeffTemp.at(0) = 1.0;
580
581 // Uebergebe die Parameter fuer Masse- und steady-Problemmatrix an TimeProblem
582 // Wegen moeglicher Zeitschrittweitensteuerung, rufe CombineSystems()
583 // in jedem Zeitschritt auf, um LHS neu aufzustellen.
584 // Bei AdvanceInTimeNonLinear... wird das in ReAssemble() gemacht!!!
585 problemTime_->setTimeParameters(massCoeff, problemCoeff);
586 // Der Source Term ist schon nach der Assemblierung mit der Dichte \rho skaliert worden
587
588 // ######################
589 // "Time" loop
590 // ######################
591 while(timeSteppingTool_->continueTimeStepping())
592 {
593 // Stelle (massCoeff*M + problemCoeff*A) auf
594 //problemTime_->combineSystems();
595
596
597 double time = timeSteppingTool_->currentTime() + dt;
598 problemTime_->updateTime ( time );
599
600 NonLinearSolver<SC, LO, GO, NO> nlSolver(parameterList_->sublist("General").get("Linearization","Newton"));
601 nlSolver.solve( *problemTime_, time, its );
602
603 timeSteppingTool_->advanceTime(true/*output info*/);
604 if (printData) {
605 exporterTimeTxt->exportData( timeSteppingTool_->currentTime() );
606 exporterIterations->exportData( (*its)[0] );
607 exporterNewtonIterations->exportData( (*its)[1] );
608 }
609 if (print) {
610 exportTimestep();
611 }
612 this->problemTime_->assemble("UpdateTime"); // Updates to next timestep
613
614 }
615
616 comm_->barrier();
617 if (print)
618 {
619 closeExporter();
620 }
621}
622
623
624template<class SC,class LO,class GO,class NO>
625void DAESolverInTime<SC,LO,GO,NO>::advanceInTimeLinearNewmark()
626{
627 // problemCoeff vor A (= kompletes steady-System)
628 // massCoeff vor M (= Massematrix)
629 // coeffSourceTerm vor f (= rechte Seite der DGL)
630
631 bool print = parameterList_->sublist("General").get("ParaViewExport",false);
632 if (print)
633 {
634 exportTimestep();
635 }
636
637 // Groesse des Problems, Zeitschrittweite und Newmark-Parameter
638 int size = timeStepDef_.size();
639 TEUCHOS_TEST_FOR_EXCEPTION( size>1, std::runtime_error, "Newmark only implemented for systems of size 1x1.");
640 double dt = timeSteppingTool_->get_dt();
641 double beta = timeSteppingTool_->get_beta();
642 double gamma = timeSteppingTool_->get_gamma();
643
644 // Koeffizienten vor der Massematrix und vor der Systemmatrix des steady-Problems
645 SmallMatrix<double> massCoeff(size);
646 SmallMatrix<double> problemCoeff(size);
647 double coeffSourceTerm = 0.0; // Koeffizient fuer den Source-Term (= rechte Seite der DGL); mit Null initialisieren
648
649 // Koeffizient vor der Massematrix
650 massCoeff[0][0] = 1.0/(dt*dt*beta);
651 problemCoeff[0][0] = 1.0;
652 // Der Source Term ist schon nach der Assemblierung mit der Dichte \rho skaliert worden
653 coeffSourceTerm = 1.0; // ACHTUNG FUER SOURCE TERM, DER NICHT IN DER ZEIT DISKRETISIERT WIRD!
654
655 // Temporaerer Koeffizienten fuer die Skalierung der Massematrix in der rechten Seite des Systems in UpdateNewmarkRhs()
656 vec_dbl_Type coeffTemp(1);
657 coeffTemp.at(0) = 1.0;
658
659 // Uebergebe die Parameter fuer Masse- und steady-Problemmatrix an TimeProblem
660 // Wegen moeglicher Zeitschrittweitensteuerung, rufe CombineSystems()
661 // in jedem Zeitschritt auf, um LHS neu aufzustellen.
662 // Bei AdvanceInTimeNonLinear... wird das in ReAssemble() gemacht!!!
663 problemTime_->setTimeParameters(massCoeff, problemCoeff);
664
665 // ######################
666 // Time loop
667 // ######################
668 while(timeSteppingTool_->continueTimeStepping())
669 {
670 // Stelle (massCoeff*M + problemCoeff*A) auf
671 problemTime_->combineSystems();
672
673 // Update u und berechne u' und u'' mit Hilfe der Newmark-Vorschrift
674 problemTime_->updateSolutionNewmarkPreviousStep(dt, beta, gamma);
675
676 double time = timeSteppingTool_->currentTime() + dt;
677 problemTime_->updateTime ( timeSteppingTool_->currentTime() );
678 // Stelle die rechte Seite des zeitdiskretisierten Systems auf (ohne f_{n+1}).
679 // Bei Newmark lautet dies:
680 // M*[\frac{1}{dt^2*beta}*u_n + \frac{1}{dt*beta}*u'_n + \frac{0.5 - beta}{beta}*u''_n],
681 // wobei u' = v (velocity) und u'' = w (acceleration).
682 problemTime_->updateNewmarkRhs(dt, beta, gamma, coeffTemp);
683
684 // TODO: SourceTerm wird in jedem Zeitschritt neu berechnet; auch wenn konstant!!!
685 // if(time == 0){nur dann konstanten SourceTerm berechnen}
686 if ( problemTime_->hasSourceTerm() )
687 {
688// TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Fix source term.");
689 problemTime_->assembleSourceTerm(time);
690
691 // Fuege die rechte Seite der DGL (f bzw. f_{n+1}) der rechten Seite hinzu (skaliert mit coeffSourceTerm)
692 // Die Skalierung mit der Dichte erfolgt schon in der Assemblierungsfunktion!
693 addSourceTermToRHS(coeffSourceTerm);
694 }
695
696 // Uebergabeparameter fuer BC noch hinzu nehmen!
697 problemTime_->setBoundaries(time);
698 problemTime_->solve();
699
700 timeSteppingTool_->advanceTime(true/*output info*/);
701
702 if (print) {
703 exportTimestep();
704 }
705
706 }
707
708 comm_->barrier();
709 if (print)
710 {
711 closeExporter();
712 }
713}
714
715
716// TODO: Irgendwann einmal fuer St. Venant-Kirchoff oder so programmieren.
717// Erstmal nicht wichtig
718template<class SC,class LO,class GO,class NO>
719void DAESolverInTime<SC,LO,GO,NO>::advanceInTimeNonLinearNewmark()
720{
721
722 bool print = parameterList_->sublist("General").get("ParaViewExport",false);
723 bool printExtraData = parameterList_->sublist("General").get("Export Extra Data",false);
724 bool printData = parameterList_->sublist("General").get("Export Data",false);
725 if (print)
726 {
727 exportTimestep();
728 }
729
730 vec_dbl_ptr_Type its = Teuchos::rcp(new vec_dbl_Type ( 2, 0. ) ); //0:linear iterations, 1: nonlinear iterations
731 ExporterTxtPtr_Type exporterTimeTxt;
732 ExporterTxtPtr_Type exporterIterations;
733 ExporterTxtPtr_Type exporterNewtonIterations;
734 if (printData) {
735 std::string suffix = parameterList_->sublist("General").get("Export Suffix","");
736
737 exporterTimeTxt = Teuchos::rcp(new ExporterTxt());
738 exporterTimeTxt->setup( "time" + suffix, this->comm_ );
739
740 exporterNewtonIterations = Teuchos::rcp(new ExporterTxt());
741 exporterNewtonIterations->setup( "newtonIterations" + suffix, this->comm_ );
742
743 exporterIterations = Teuchos::rcp(new ExporterTxt());
744 exporterIterations->setup( "linearIterations" + suffix, this->comm_ );
745 }
746 // Groesse des Problems, Zeitschrittweite und Newmark-Parameter
747 int size = timeStepDef_.size();
748 TEUCHOS_TEST_FOR_EXCEPTION( size>1, std::runtime_error, "Newmark only implemented for systems of size 1x1.");
749 double dt = timeSteppingTool_->get_dt();
750 double beta = timeSteppingTool_->get_beta();
751 double gamma = timeSteppingTool_->get_gamma();
752
753 // Koeffizienten vor der Massematrix und vor der Systemmatrix des steady-Problems
754 SmallMatrix<double> massCoeff(size);
755 SmallMatrix<double> problemCoeff(size);
756 double coeffSourceTerm = 0.0; // Koeffizient fuer den Source-Term (= rechte Seite der DGL); mit Null initialisieren
757
758 // Koeffizient vor der Massematrix
759 massCoeff[0][0] = 1.0/(dt*dt*beta);
760 problemCoeff[0][0] = 1.0;
761 // Der Source Term ist schon nach der Assemblierung mit der Dichte \rho skaliert worden
762 coeffSourceTerm = 1.0; // ACHTUNG FUER SOURCE TERM, DER NICHT IN DER ZEIT DISKRETISIERT WIRD!
763
764 // Temporaerer Koeffizienten fuer die Skalierung der Massematrix in der rechten Seite des Systems in UpdateNewmarkRhs()
765 vec_dbl_Type coeffTemp(1);
766 coeffTemp.at(0) = 1.0;
767
768 // Uebergebe die Parameter fuer Masse- und steady-Problemmatrix an TimeProblem
769 // Wegen moeglicher Zeitschrittweitensteuerung, rufe CombineSystems()
770 // in jedem Zeitschritt auf, um LHS neu aufzustellen.
771 problemTime_->setTimeParameters(massCoeff, problemCoeff);
772
773 // ######################
774 // Time loop
775 // ######################
776 while(timeSteppingTool_->continueTimeStepping())
777 {
778 // Stelle (massCoeff*M + problemCoeff*A) auf
779 problemTime_->combineSystems();
780
781 // Update u und berechne u' und u'' mit Hilfe der Newmark-Vorschrift
782 problemTime_->updateSolutionNewmarkPreviousStep(dt, beta, gamma);
783
784 double time = timeSteppingTool_->currentTime() + dt;
785 problemTime_->updateTime ( time );
786 // Stelle die rechte Seite des zeitdiskretisierten Systems auf (ohne f_{n+1}).
787 // Bei Newmark lautet dies:
788 // M*[\frac{1}{dt^2*beta}*u_n + \frac{1}{dt*beta}*u'_n + \frac{0.5 - beta}{beta}*u''_n],
789 // wobei u' = v (velocity) und u'' = w (acceleration).
790 problemTime_->updateNewmarkRhs(dt, beta, gamma, coeffTemp);
791
792 // TODO: SourceTerm wird in jedem Zeitschritt neu berechnet; auch wenn konstant!!!
793 // if(time == 0){nur dann konstanten SourceTerm berechnen}
794 if (problemTime_->hasSourceTerm())
795 {
796// TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Fix source term.");
797 problemTime_->assembleSourceTerm(time);
798
799 // Fuege die rechte Seite der DGL (f bzw. f_{n+1}) der rechten Seite hinzu (skaliert mit coeffSourceTerm)
800 // Die Skalierung mit der Dichte erfolgt schon in der Assemblierungsfunktion!
801 // This is done in calculateNonLinResidualVec for this nonlinear problem
802 addSourceTermToRHS(coeffSourceTerm);
803 }
804
805 // Uebergabeparameter fuer BC noch hinzu nehmen!
806// problemTime_->setBoundaries(time);
807
808 NonLinearSolver<SC, LO, GO, NO> nlSolver(parameterList_->sublist("General").get("Linearization","Newton"));
809 nlSolver.solve( *problemTime_, time, its );
810
811 timeSteppingTool_->advanceTime(true/*output info*/);
812 if (printData) {
813 exporterTimeTxt->exportData( timeSteppingTool_->currentTime() );
814 exporterIterations->exportData( (*its)[0] );
815 exporterNewtonIterations->exportData( (*its)[1] );
816 }
817 if (print) {
818 exportTimestep();
819 }
820
821 }
822
823 comm_->barrier();
824 if (print)
825 {
826 closeExporter();
827 }
828}
829
830template<class SC,class LO,class GO,class NO>
831void DAESolverInTime<SC,LO,GO,NO>::advanceInTimeFSI()
832{
833 // problemCoeff vor A (= komplettes steady-System)
834 // massCoeff vor M (= Massematrix)
835 // coeffSourceTerm vor f (= rechte Seite der DGL)
836
837
838 FSIProblemPtr_Type fsi = Teuchos::rcp_dynamic_cast<FSIProblem_Type>( this->problemTime_->getUnderlyingProblem() );
839
840 bool print = parameterList_->sublist("General").get("ParaViewExport",false);
841 bool printData = parameterList_->sublist("General").get("Export Data",false);
842 bool printExtraData = parameterList_->sublist("General").get("Export Extra Data",false);
843 bool printFlowRate = parameterList_->sublist("General").get("Export Flow Rate",true);
844
845 if (print)
846 {
847 exportTimestep();
848 }
849
850
851 vec_dbl_ptr_Type its = Teuchos::rcp(new vec_dbl_Type ( 2, 0. ) ); //0:linear iterations, 1: nonlinear iterations
852 ExporterTxtPtr_Type exporterTimeTxt;
853 ExporterTxtPtr_Type exporterDisplXTxt;
854 ExporterTxtPtr_Type exporterDisplYTxt;
855 ExporterTxtPtr_Type exporterIterations;
856 ExporterTxtPtr_Type exporterNewtonIterations;
857 ExporterTxtPtr_Type exporterFlowRateInlet;
858 ExporterTxtPtr_Type exporterFlowRateOutlet;
859 ExporterTxtPtr_Type exporterAreaInlet;
860 ExporterTxtPtr_Type exporterAreaOutlet;
861 ExporterTxtPtr_Type exporterPressureOutlet;
862 if (printData) {
863 exporterTimeTxt = Teuchos::rcp(new ExporterTxt());
864 exporterDisplXTxt = Teuchos::rcp(new ExporterTxt());
865 exporterDisplYTxt = Teuchos::rcp(new ExporterTxt());
866 exporterTimeTxt->setup( "time", this->comm_ );
867
868 std::string suffix = parameterList_->sublist("General").get("Export Suffix","");
869
870 exporterNewtonIterations = Teuchos::rcp(new ExporterTxt());
871 exporterNewtonIterations->setup( "newtonIterations" + suffix, this->comm_ );
872
873 exporterIterations = Teuchos::rcp(new ExporterTxt());
874 exporterIterations->setup( "linearIterations" + suffix, this->comm_ );
875 }
876 if (printExtraData) {
877
878 vec_dbl_Type v(3,-9999.);
879 this->problemTime_->getValuesOfInterest(v);
880 vec_dbl_Type vGathered(this->comm_->getSize());
881 Teuchos::gatherAll<int,double>( *this->comm_, 1, &v[0], vGathered.size(), &vGathered[0] );
882 int targetRank=0;
883 while (vGathered[targetRank] < 0){
884 targetRank++;
885 TEUCHOS_TEST_FOR_EXCEPTION( targetRank == vGathered.size(), std::runtime_error, "No targetRank for export of displacements was found!" );
886 }
887
888 std::string suffix = parameterList_->sublist("General").get("Export Suffix","");
889
890 exporterDisplXTxt->setup( "displ_x" + suffix, this->comm_ , targetRank);
891 exporterDisplYTxt->setup( "displ_y" + suffix, this->comm_ , targetRank);
892
893 }
894 if (printFlowRate) {
895 std::string suffix = parameterList_->sublist("General").get("Export Suffix","");
896
897 exporterFlowRateInlet = Teuchos::rcp(new ExporterTxt());
898 exporterFlowRateInlet->setup( "flowRateInlet" + suffix, this->comm_ );
899
900 exporterFlowRateOutlet = Teuchos::rcp(new ExporterTxt());
901 exporterFlowRateOutlet->setup( "flowRateOutlet" + suffix, this->comm_ );
902
903 exporterPressureOutlet = Teuchos::rcp(new ExporterTxt());
904 exporterPressureOutlet->setup( "pressureOutlet" + suffix, this->comm_ );
905
906 exporterAreaInlet = Teuchos::rcp(new ExporterTxt());
907 exporterAreaInlet->setup( "areaInlet" + suffix, this->comm_ );
908
909 exporterAreaOutlet = Teuchos::rcp(new ExporterTxt());
910 exporterAreaOutlet->setup( "areaOutlet" + suffix, this->comm_ );
911
912
913 }
914
915 // Notwendige Parameter
916 bool geometryExplicit = this->parameterList_->sublist("Parameter").get("Geometry Explicit",true);
917 int sizeFSI = timeStepDef_.size();
918
919 // ACHTUNG
920 int sizeFluid = 2; // u_f + p
921 int sizeStructure = 1; // d_s
922
923 double dt = timeSteppingTool_->get_dt();
924 double beta = timeSteppingTool_->get_beta();
925 double gamma = timeSteppingTool_->get_gamma();
926 int nmbBDF = timeSteppingTool_->getBDFNumber();
927 // ######################
928 // Fluid: Mass-, Problem, SourceTerm Koeffizienten
929 // ######################
930 SmallMatrix<double> massCoeffFluid(sizeFluid);
931 SmallMatrix<double> problemCoeffFluid(sizeFluid);
932 double coeffSourceTermFluid = 0.0;
933
934 for (int i=0; i<sizeFluid; i++) {
935 for (int j=0; j<sizeFluid; j++) {
936 if (timeStepDef_[i][j]>0 && i==j) {
937 massCoeffFluid[i][j] = timeSteppingTool_->getInformationBDF(0) / dt;
938 }
939 else{
940 massCoeffFluid[i][j] = 0.0;
941 }
942 }
943 }
944 for (int i=0; i<sizeFluid; i++) {
945 for (int j=0; j<sizeFluid; j++){
946 if (timeStepDef_[i][j]>0){
947 problemCoeffFluid[i][j] = timeSteppingTool_->getInformationBDF(1);
948 coeffSourceTermFluid = timeSteppingTool_->getInformationBDF(1);
949 }
950 else{
951 problemCoeffFluid[i][j] = 1.;
952 }
953 }
954 }
955
956
957 // ######################
958 // Struktur: Mass-, Problem, SourceTerm Koeffizienten
959 // ######################
960 // Koeffizienten vor der Massematrix und vor der Systemmatrix des steady-Problems
961 SmallMatrix<double> massCoeffStructure(sizeStructure);
962 SmallMatrix<double> problemCoeffStructure(sizeStructure);
963 double coeffSourceTermStructure = 0.0; // Koeffizient fuer den Source-Term (= rechte Seite der DGL); mit Null initialisieren
964
965 // Koeffizient vor der Massematrix
966 for(int i = 0; i < sizeStructure; i++)
967 {
968 for(int j = 0; j < sizeStructure; j++)
969 {
970 // Falls in dem Block von timeStepDef_ zeitintegriert werden soll.
971 // i == j, da vektorwertige Massematrix blockdiagonal ist
972 if(timeStepDef_[i + sizeFluid][j + sizeFluid] > 0 && i == j) // Weil: (u_f, p, d_s,...) und timeStepDef_ von FSI
973 {
974 // Vorfaktor der Massematrix in der LHS
975 massCoeffStructure[i][j] = 1.0/(dt*dt*beta);
976 }
977 else
978 {
979 massCoeffStructure[i][j] = 0.;
980 }
981 }
982 }
983
984
985 // Die anderen beiden Koeffizienten
986 for(int i = 0; i < sizeStructure; i++)
987 {
988 for(int j = 0; j < sizeStructure; j++)
989 {
990 if(timeStepDef_[i + sizeFluid][j + sizeFluid] > 0 )
991 {
992 problemCoeffStructure[i][j] = 1.0;
993 // Der Source Term ist schon nach der Assemblierung mit der Dichte \rho skaliert worden
994 coeffSourceTermStructure = 1.0; // ACHTUNG FUER SOURCE TERM, DER NICHT IN DER ZEIT DISKRETISIERT WIRD!
995 }
996 else // Die steady-Systemmatrix ist nicht zwingend blockdiagonal
997 {
998 problemCoeffStructure[i][j] = 1.0;
999 }
1000 }
1001 }
1002
1003
1004 // ######################
1005 // FSI: Mass-, Problem-Koeffizienten
1006 // ######################
1007 SmallMatrix<double> massCoeffFSI(sizeFSI);
1008 SmallMatrix<double> problemCoeffFSI(sizeFSI);
1009 for (int i = 0; i < sizeFluid; i++)
1010 {
1011 for (int j = 0; j < sizeFluid; j++)
1012 {
1013 massCoeffFSI[i][j] = massCoeffFluid[i][j];
1014 problemCoeffFSI[i][j] = problemCoeffFluid[i][j];
1015 }
1016 }
1017
1018 for (int i = 0; i < sizeStructure; i++)
1019 {
1020 for (int j = 0; j < sizeStructure; j++)
1021 {
1022 massCoeffFSI[i + sizeFluid][j + sizeFluid] = massCoeffStructure[i][j];
1023 problemCoeffFSI[i + sizeFluid][j + sizeFluid] = problemCoeffStructure[i][j];
1024 }
1025 }
1026
1027 // Setze noch Einsen an die Stellen, wo Eintraege (Kopplungsbloecke) vorhanden sind.
1028 problemCoeffFSI[0][3] = 1.0; // C1_T
1029 problemCoeffFSI[2][3] = 1.0; // C3_T
1030 problemCoeffFSI[3][0] = 1.0; // C1
1031 problemCoeffFSI[3][2] = 1.0; // C2
1032 if(!geometryExplicit)
1033 {
1034 problemCoeffFSI[4][2] = 1.0; // C4
1035 problemCoeffFSI[4][4] = 1.0; // H (Geometrie)
1036 std::string linearization = this->parameterList_->sublist("General").get("Linearization","Extrapolation");
1037 if(linearization == "Newton" || linearization == "NOX")
1038 {
1039 problemCoeffFSI[0][4] = 1.0; // Shape-Derivatives Velocity
1040 problemCoeffFSI[1][4] = 1.0; // Shape-Derivatives Div-Nebenbedingung
1041 }
1042 }
1043
1044 this->problemTime_->setTimeParameters(massCoeffFSI, problemCoeffFSI);
1045
1046 if (printExtraData) {
1047 exporterTimeTxt->exportData( timeSteppingTool_->currentTime() );
1048 vec_dbl_Type v(3,0.);
1049 this->problemTime_->getValuesOfInterest( v );
1050
1051 exporterDisplXTxt->exportData( v[0] );
1052 exporterDisplYTxt->exportData( v[1] );
1053 }
1054
1055// {
1056// // Initialize mass matrix for fluid problem
1057// MatrixPtr_Type massmatrix;
1058// TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Fix reassembly of mass matrix for FSI.");
1059// MatrixPtr_Type massmatrix;
1060// fsi->setSolidMassmatrix( massmatrix );
1062// }
1063 // ######################
1064 // Time loop
1065 // ######################
1066#ifdef FEDD_TIMER
1067 TimeMonitor_Type solveTM(*solveProblemTimer_);
1068#endif
1069 while(timeSteppingTool_->continueTimeStepping())
1070 {
1071 problemTime_->updateTime ( timeSteppingTool_->currentTime() );
1072
1073 std::string linearization = this->parameterList_->sublist("General").get("Linearization","Extrapolation");
1074
1075 // Ist noetig, falls wir extrapolieren, damit wir
1076 // immer die korrekten previousSolution_ haben.
1077 // TODO: Vermutlich reicht lediglich (da erstmal nur BDF2):
1078 // this->problemTime_->updateSolutionMultiPreviousStep(nmbBDF);
1079 if(nmbBDF<2 && !parameterList_->sublist("General").get("Linearization","FixedPoint").compare("Extrapolation"))
1080 {// we need the last two solution for a second order extrapolation.
1081 if (timeSteppingTool_->currentTime() != 0.0)
1082 {
1083 this->problemTime_->updateSolutionMultiPreviousStep(2);
1084 }
1085 else
1086 {
1087 this->problemTime_->updateSolutionMultiPreviousStep(1);
1088 }
1089 }
1090 else
1091 {
1092 this->problemTime_->updateSolutionMultiPreviousStep(nmbBDF);
1093 }
1094 {
1095#ifdef FEDD_DETAIL_TIMER
1096 TimeMonitor_Type reassmbleTM(*reassmbleAddInterfaceRHSTimer_);
1097#endif
1098 // Den Block C2*d_s^n in der RHS im Interface-Block setzen.
1099 this->problemTime_->assemble("AddInterfaceBlockRHS");
1100 }
1101 {
1102#ifdef FEDD_DETAIL_TIMER
1103 TimeMonitor_Type reassmbleTM(*reassmbleUpdateMeshDisplacementTimer_);
1104#endif
1105 // Alte Gitterbewegung mit der Geometrieloesung ueberschreiben.
1106 this->problemTime_->assemble("UpdateMeshDisplacement");
1107 }
1108 // Das Geometry-Problem separat loesen, falls GE.
1109 if(geometryExplicit)
1110 {
1111 {
1112#ifdef FEDD_DETAIL_TIMER
1113 TimeMonitor_Type reassmbleTM(*reassmbleSolveGeometryTimer_);
1114#endif
1115 this->problemTime_->assemble("SolveGeometryProblem");
1116 }
1117#ifdef FEDD_DETAIL_TIMER
1118 TimeMonitor_Type reassmbleTM(*reassmbleMoveMeshTimer_);
1119#endif
1120 this->problemTime_->assemble("MoveMesh");
1121 }
1122
1123
1124 // ######################
1125 // Struktur Zeitsystem
1126 // ######################
1127 // In jedem Zeitschritt die RHS der Struktur holen.
1128 // Die Massematrix wird in FSI jedoch nur fuer t = 0 berechnet, da Referenzkonfiguration
1129 // in der Struktur.
1130 {
1131
1132
1133#ifdef FEDD_DETAIL_TIMER
1134 TimeMonitor_Type reassmbleTM(*reassmbleSolidMassAndRHSTimer_);
1135#endif
1136 // Hier wird auch direkt ein Update der Loesung bei der Struktur gemacht.
1137 // Aehnlich zu "UpdateFluidInTime".
1138
1139 if(timeSteppingTool_->currentTime() == 0.0)
1140 {
1141 // We extract the underlying FSI problem
1142 MatrixPtr_Type massmatrix;
1143 fsi->setSolidMassmatrix( massmatrix );
1144 this->problemTime_->systemMass_->addBlock( massmatrix, 2, 2 );
1145 }
1146 // this should be done automatically rhs will not be used here
1147// this->problemTime_->getRhs()->addBlock( Teuchos::rcp_const_cast<MultiVector_Type>(rhs->getBlock(0)), 2 );
1148 this->problemTime_->assemble("ComputeSolidRHSInTime");
1149 }
1150
1151
1152 if(geometryExplicit) // && linearization != "Extrapolation"
1153 {
1154#ifdef FEDD_DETAIL_TIMER
1155 TimeMonitor_Type reassmbleTM(*reassmbleForTimeTimer_);
1156#endif
1157 this->problemTime_->assemble("ForTime");
1158 }
1159
1160 // ######################
1161 // Fluid Zeitsystem
1162 // ######################
1163 // Fluid-Loesung aktualisieren fuer die naechste(n) BDF2-Zeitintegration(en)
1164 // in diesem Zeitschritt.
1165 {
1166#ifdef FEDD_DETAIL_TIMER
1167 TimeMonitor_Type reassmbleTM(*reassmbleUpdateFluidInTimeTimer_);
1168#endif
1169 //Do we need this, if BDF for FSI is used correctly? We still need it to save the mass matrices
1170 this->problemTime_->assemble("UpdateFluidInTime");
1171
1172 // We add the pressure influence on the boundary condition. This is done in each time step since it depends on the
1173 // current flow rate and area of outlet
1174 this->problemTime_->assemble("ComputePressureRHSInTime");
1175
1176 }
1177 // Aktuelle Massematrix auf dem Gitter fuer BDF2-Integration und
1178 // fuer das FSI-System (bei GI wird die Massematrix weiterhin in TimeProblem.reAssemble() assembliert).
1179 // In der ersten nichtlinearen Iteration wird bei GI also die Massematrix zweimal assembliert.
1180 // Massematrix fuer FSI holen und fuer timeProblemFluid setzen (fuer BDF2)
1181 MatrixPtr_Type massmatrix;
1182 fsi->setFluidMassmatrix( massmatrix );
1183 this->problemTime_->systemMass_->addBlock( massmatrix, 0, 0 );
1184
1185
1186 // RHS nach BDF2
1187 this->problemTime_->assemble( "ComputeFluidRHSInTime" ); // hier ist massmatrix nicht relevant
1188// this->problemTime_->getRhs()->addBlock( Teuchos::rcp_const_cast<MultiVector_Type>(rhs->getBlock(0)), 0 );
1189
1190
1191 // ######################
1192 // System loesen
1193 // ######################
1194 // Use BDF1 Parameters for first system
1195 if (timeSteppingTool_->currentTime() == 0.) {
1196 SmallMatrix<double> massCoeffFluidTmp(sizeFluid);
1197
1198 for (int i = 0; i < sizeFluid; i++)
1199 {
1200 for (int j = 0; j < sizeFluid; j++){
1201 if (massCoeffFSI[i][j] != 0.){
1202 massCoeffFSI[i][j] = 1./dt ;
1203 massCoeffFluidTmp[i][j] = 1./dt;
1204 }
1205 }
1206 }
1207 this->problemTime_->setTimeParameters(massCoeffFSI, problemCoeffFSI);
1208 fsi->problemTimeFluid_->setTimeParameters(massCoeffFluidTmp, problemCoeffFluid);
1209
1210 }
1211
1212
1213 double time = timeSteppingTool_->currentTime() + dt;
1214 problemTime_->updateTime ( time );
1215 NonLinearSolver<SC, LO, GO, NO> nlSolver(parameterList_->sublist("General").get("Linearization","FixedPoint"));
1216
1217 nlSolver.solve(*this->problemTime_, time, its);
1218
1219 if (timeSteppingTool_->currentTime() <= dt+1.e-10) {
1220 for (int i = 0; i < sizeFluid; i++)
1221 {
1222 for (int j = 0; j < sizeFluid; j++){
1223 massCoeffFSI[i][j] = massCoeffFluid[i][j];
1224 }
1225 }
1226 this->problemTime_->setTimeParameters(massCoeffFSI, problemCoeffFSI);
1227 fsi->problemTimeFluid_->setTimeParameters(massCoeffFluid, problemCoeffFluid);
1228
1229 }
1230
1231 this->problemTime_->computeValuesOfInterestAndExport();
1232
1233 timeSteppingTool_->advanceTime(true/*output info*/);
1234 this->problemTime_->assemble("UpdateTime"); // Zeit in FSI inkrementieren
1235 if (printData) {
1236 exporterTimeTxt->exportData( timeSteppingTool_->currentTime() );
1237 exporterIterations->exportData( (*its)[0] );
1238 exporterNewtonIterations->exportData( (*its)[1] );
1239 }
1240 if (printExtraData) {
1241 vec_dbl_Type v(3,-9999.);
1242 this->problemTime_->getValuesOfInterest(v);
1243
1244 exporterDisplXTxt->exportData( v[0] );
1245 exporterDisplYTxt->exportData( v[1] );
1246 }
1247 if (print)
1248 {
1249 exportTimestep();
1250 }
1251 if(printFlowRate){
1252 FE<SC,LO,GO,NO> fe;
1253 fe.addFE(problemTime_->getDomain(0));
1254 double flowRateInlet;
1255 double flowRateOutlet;
1256
1257 int flagInlet = this->parameterList_->sublist("General").get("Flag Inlet Fluid", 4);
1258 int flagOutlet = this->parameterList_->sublist("General").get("Flag Outlet Fluid", 5);
1259
1260 MultiVectorPtr_Type u_rep = Teuchos::rcp(new MultiVector_Type ( problemTime_->getDomain(0)->getMapVecFieldRepeated() ) );
1261 u_rep->importFromVector(problemTime_->getSolution()->getBlock(0),false,"Insert");
1262 fe.assemblyFlowRate(problemTime_->getDomain(0)->getDimension(), flowRateInlet, problemTime_->getDomain(0)->getFEType() , problemTime_->getDomain(0)->getDimension(), flagInlet , u_rep);
1263 fe.assemblyFlowRate(problemTime_->getDomain(0)->getDimension(), flowRateOutlet, problemTime_->getDomain(0)->getFEType() , problemTime_->getDomain(0)->getDimension(), flagOutlet , u_rep);
1264
1265 exporterFlowRateInlet->exportData( timeSteppingTool_->currentTime() , flowRateInlet );
1266 exporterFlowRateOutlet->exportData( timeSteppingTool_->currentTime() ,flowRateOutlet );
1267
1268 exporterPressureOutlet->exportData( timeSteppingTool_->currentTime() , fsi->getPressureOutlet() );
1269
1270 double areaInlet=0.;
1271 fe.assemblyArea(problemTime_->getDomain(0)->getDimension(), areaInlet, flagInlet);
1272
1273 double areaOutlet=0.;
1274 fe.assemblyArea(problemTime_->getDomain(0)->getDimension(), areaOutlet, flagOutlet);
1275
1276 exporterAreaInlet->exportData( timeSteppingTool_->currentTime() , areaInlet);
1277 exporterAreaOutlet->exportData( timeSteppingTool_->currentTime() ,areaOutlet );
1278 }
1279
1280 }
1281
1282 comm_->barrier();
1283 if (printExtraData) {
1284 exporterTimeTxt->closeExporter();
1285 exporterIterations->closeExporter();
1286 exporterNewtonIterations->closeExporter();
1287 }
1288
1289 if (printExtraData) {
1290 exporterDisplXTxt->closeExporter();
1291 exporterDisplYTxt->closeExporter();
1292 }
1293 if (print)
1294 {
1295 closeExporter();
1296 }
1297}
1298
1299
1300/* UEBERARBEITEN!!!!!!!!!!!!!!!!! */
1301template<class SC,class LO,class GO,class NO>
1302void DAESolverInTime<SC,LO,GO,NO>::advanceInTimeLinearMultistep(){
1303
1304 //TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "advanceInTimeLinearMultistep rework.");
1305 bool print = parameterList_->sublist("General").get("ParaViewExport",false);
1306 if (print) {
1307 exportTimestep();
1308 }
1309 int size = timeStepDef_.size();
1310 double dt = timeSteppingTool_->get_dt();
1311 int nmbBDF = timeSteppingTool_->getBDFNumber();
1312 vec_dbl_Type coeffPrevSteps(nmbBDF);
1313 for (int i=0; i<coeffPrevSteps.size(); i++) {
1314 coeffPrevSteps.at(i) = timeSteppingTool_->getInformationBDF(i+2) / dt;
1315 }
1316
1317 SmallMatrix<double> massCoeff(size);
1318 SmallMatrix<double> problemCoeff(size);
1319 double coeffSourceTerm = 0.;
1320
1321 for (int i=0; i<size; i++) {
1322 for (int j=0; j<size; j++) {
1323 if (timeStepDef_[i][j]==1 && i==j) {
1324 massCoeff[i][j] = timeSteppingTool_->getInformationBDF(0) / dt;
1325 }
1326 else{
1327 massCoeff[i][j] = 0.;
1328 }
1329 }
1330 }
1331 for (int i=0; i<size; i++) {
1332 for (int j=0; j<size; j++){
1333 if (timeStepDef_[i][j]==1){
1334 problemCoeff[i][j] = timeSteppingTool_->getInformationBDF(1);
1335 coeffSourceTerm = timeSteppingTool_->getInformationBDF(1); // ACHTUNG FUER SOURCE TERM, DER NICHT IN DER ZEIT DISKRETISIERT WIRD!
1336 }
1337 else{
1338 problemCoeff[i][j] = 1.;
1339 }
1340 }
1341 }
1342 problemTime_->setTimeParameters(massCoeff, problemCoeff);
1343
1344 //#########
1345 //time loop
1346 //#########
1347 while (timeSteppingTool_->continueTimeStepping()) {
1348
1349 problemTime_->updateSolutionMultiPreviousStep(nmbBDF);
1350
1351 double time = timeSteppingTool_->currentTime() + dt;
1352 problemTime_->updateMultistepRhs(coeffPrevSteps,nmbBDF);/*apply mass matrix to u_t*/
1353 if (problemTime_->hasSourceTerm()) {
1354 problemTime_->assembleSourceTerm(time);
1355 addSourceTermToRHS(coeffSourceTerm);
1356 }
1357
1358 problemTime_->combineSystems();
1359 // Uebergabeparameter fuer BC noch hinzunehmen!
1360 problemTime_->setBoundaries(time);
1361 problemTime_->solve();
1362
1363 timeSteppingTool_->advanceTime(true/*output info*/);
1364
1365 if (print) {
1366 exportTimestep();
1367 }
1368
1369 }
1370 comm_->barrier();
1371 if (print) {
1372 closeExporter();
1373 }
1374
1375}
1376
1377template<class SC,class LO,class GO,class NO>
1378void DAESolverInTime<SC,LO,GO,NO>::advanceInTimeNonLinearMultistep(){
1379
1380 bool print = parameterList_->sublist("General").get("ParaViewExport",false);
1381 bool printData = parameterList_->sublist("General").get("Export Data",false);
1382
1383 if (print) {
1384 exportTimestep();
1385 }
1386
1387 ExporterTxtPtr_Type exporterIterations;
1388 ExporterTxtPtr_Type exporterNewtonIterations;
1389 ExporterTxtPtr_Type exporterTimeTxt;
1390 vec_dbl_ptr_Type its = Teuchos::rcp(new vec_dbl_Type ( 2, 0. ) ); //0:linear iterations, 1: nonlinear iterations
1391
1392 if (printData) {
1393 exporterTimeTxt = Teuchos::rcp(new ExporterTxt());
1394 exporterTimeTxt->setup( "time", this->comm_ );
1395
1396 std::string suffix = parameterList_->sublist("General").get("Export Suffix","");
1397
1398 exporterNewtonIterations = Teuchos::rcp(new ExporterTxt());
1399 exporterNewtonIterations->setup( "newtonIterations" + suffix, this->comm_ );
1400
1401 exporterIterations = Teuchos::rcp(new ExporterTxt());
1402 exporterIterations->setup( "linearIterations" + suffix, this->comm_ );
1403 }
1404
1405 int size = timeStepDef_.size();
1406 double dt = timeSteppingTool_->get_dt();
1407 int nmbBDF = timeSteppingTool_->getBDFNumber();
1408
1409 vec_dbl_Type coeffPrevSteps(nmbBDF);
1410 for (int i=0; i<coeffPrevSteps.size(); i++) {
1411 coeffPrevSteps.at(i) = timeSteppingTool_->getInformationBDF(i+2) / dt;
1412 }
1413
1414 SmallMatrix<double> massCoeff(size);
1415 SmallMatrix<double> problemCoeff(size);
1416 double coeffSourceTerm = 0.;
1417
1418 for (int i=0; i<size; i++) {
1419 for (int j=0; j<size; j++) {
1420 if (timeStepDef_[i][j]>0 && i==j) {
1421 massCoeff[i][j] = timeSteppingTool_->getInformationBDF(0) / dt;
1422 }
1423 else{
1424 massCoeff[i][j] = 0.;
1425 }
1426 }
1427 }
1428 for (int i=0; i<size; i++) {
1429 for (int j=0; j<size; j++){
1430 if (timeStepDef_[i][j]>0){
1431 problemCoeff[i][j] = timeSteppingTool_->getInformationBDF(1);
1432 coeffSourceTerm = timeSteppingTool_->getInformationBDF(1);
1433 }
1434 else{
1435 problemCoeff[i][j] = 1.;
1436 }
1437 }
1438 }
1439 problemTime_->setTimeParameters(massCoeff, problemCoeff);
1440
1441 //#########
1442 //time loop
1443 //#########
1444 vec_dbl_Type linearIterations(0);
1445 vec_dbl_Type newtonIterations(0);
1446 NonLinearSolver<SC, LO, GO, NO> nlSolver(parameterList_->sublist("General").get("Linearization","FixedPoint"));
1447
1448 while (timeSteppingTool_->continueTimeStepping()) {
1449
1450 // For the first time step we use BDF1
1451 if (timeSteppingTool_->currentTime()==0.) {
1452 SmallMatrix<double> tmpmassCoeff(size);
1453 SmallMatrix<double> tmpproblemCoeff(size);
1454 for (int i=0; i<size; i++) {
1455 for (int j=0; j<size; j++) {
1456 if (timeStepDef_[i][j]>0 && i==j) {
1457 tmpmassCoeff[i][j] = 1. / dt;
1458 }
1459 else{
1460 tmpmassCoeff[i][j] = 0.;
1461 }
1462 }
1463 }
1464 for (int i=0; i<size; i++) {
1465 for (int j=0; j<size; j++){
1466 if (timeStepDef_[i][j]>0){
1467 tmpproblemCoeff[i][j] = 1.; // ist das richtig? Vermutlich schon, da BDF so geschrieben ist, dass zu berechnende Lsg den Koeffizienten 1 hat
1468 }
1469 else{
1470 tmpproblemCoeff[i][j] = 1.;
1471 }
1472 }
1473 }
1474 problemTime_->setTimeParameters(tmpmassCoeff, tmpproblemCoeff);
1475 }
1476 if(nmbBDF<2 && !parameterList_->sublist("General").get("Linearization","FixedPoint").compare("Extrapolation")) {
1477 if (timeSteppingTool_->currentTime()!=0.){
1478 problemTime_->updateSolutionMultiPreviousStep(2);
1479 }
1480 else{
1481 problemTime_->updateSolutionMultiPreviousStep(1);
1482 }
1483 }
1484 else{
1485 problemTime_->updateSolutionMultiPreviousStep(nmbBDF);
1486 }
1487 double time = timeSteppingTool_->currentTime() + dt;
1488 problemTime_->updateTime ( time );
1489
1490 if (timeSteppingTool_->currentTime()==0.) {
1491 vec_dbl_Type tmpcoeffPrevSteps(1, 1. / dt);
1492 problemTime_->updateMultistepRhs(tmpcoeffPrevSteps,1);/*apply (mass matrix / dt) to u_t*/
1493 }
1494 else{
1495 problemTime_->updateMultistepRhs(coeffPrevSteps,nmbBDF);/*apply (mass matrix / dt) to u_t*/
1496 }
1497 if (problemTime_->hasSourceTerm()) {
1498 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Check sourceterm.");
1499// problemTime_->AssembleSourceTerm(time);
1500// if (timeSteppingTool_->CurrentTime()==0.) {
1501// AddSourceTermToRHS(1.);
1502// }
1503// else{
1504// AddSourceTermToRHS(coeffSourceTerm); //ACHTUNG
1505// }
1506 }
1507
1508 nlSolver.solve(*problemTime_,time,its);
1509 problemTime_->assemble("UpdateTime");
1510 // After the first time step we can use the desired BDF Parameters
1511 if (timeSteppingTool_->currentTime()==0.) {
1512 problemTime_->setTimeParameters(massCoeff, problemCoeff);
1513 }
1514
1515 timeSteppingTool_->advanceTime(true/*output info*/);
1516 if (printData) {
1517 exporterTimeTxt->exportData( timeSteppingTool_->currentTime() );
1518 exporterIterations->exportData( (*its)[0] );
1519 linearIterations.push_back((*its)[0]);
1520 exporterNewtonIterations->exportData( (*its)[1] );
1521 newtonIterations.push_back((*its)[1]);
1522
1523 }
1524 if (print) {
1525 exportTimestep();
1526 }
1527 }
1528 if (printData) {
1529 exporterTimeTxt->closeExporter();
1530 exporterIterations->closeExporter();
1531 exporterNewtonIterations->closeExporter();
1532
1533 double sumLinear=0., sumNewton=0.;
1534 for(int i=0; i < linearIterations.size(); i++){
1535 sumLinear += linearIterations[i];
1536 sumNewton += newtonIterations[i];
1537 }
1538 sumLinear = sumLinear / linearIterations.size();
1539 sumNewton = sumNewton / newtonIterations.size();
1540
1541 if (verbose_) {
1542 std::cout << " ######################################################## "<< std::endl;
1543 std::cout << " Average linear iteration count over all time steps: " << sumLinear << std::endl;
1544 std::cout << " Average Newton iteration count over all time steps: " << sumNewton << std::endl;
1545 std::cout << " ######################################################## \n"<< std::endl;
1546 }
1547
1548 }
1549 if (print) {
1550 closeExporter();
1551 }
1552
1553}
1554
1555template<class SC,class LO,class GO,class NO>
1556void DAESolverInTime<SC,LO,GO,NO>::advanceInTimeLinearExternal(){
1557 bool print = parameterList_->sublist("General").get("ParaViewExport",false);
1558 if (print) {
1559 exportTimestep();
1560 }
1561
1562 double dt = timeSteppingTool_->get_dt();
1563 int counter=0;
1564 //#########
1565 //time loop
1566 //#########
1567 while (timeSteppingTool_->continueTimeStepping()) {
1568
1569 double time = timeSteppingTool_->currentTime() + dt;
1570 problemTime_->updateTime ( time );
1571
1572 problemTime_->assemble( "Assemble" );
1573
1574 if (problemTime_->hasSourceTerm()){
1575 problemTime_->assembleSourceTerm(time); // assemble source term and add to rhs
1576 problemTime_->addToRhs( problemTime_->getSourceTerm() );
1577 }
1578
1579 problemTime_->setBoundaries( time );
1580
1581 BlockMultiVectorPtr_Type tmpSol = Teuchos::rcp(new BlockMultiVector_Type(problemTime_->getSolution()) );
1582
1583 //problemTime_->getSystemCombined()->print();
1584 //problemTime_->getRhs()->print();
1585
1586 problemTime_->solve();
1587
1588 //AceGen systems and solutions are always for a Newton method, i.e., we solve for an update even in the linear case.
1589 // ?? Alpha a + beta this?
1590 problemTime_->getSolution()->update( 1., tmpSol, -1. );
1591
1592 problemTime_->assemble( "SetSolutionNewton" ); // Newton solution is actually the solution at t+1 and time solution is still at time t
1593
1594 problemTime_->assemble( "OnlyUpdate" ); // updates AceGEN history
1595
1596 problemTime_->assemble( "SetSolutionInTime" ); // Here, we update the time solution with the Newton solution, which basically means that we can go to the next timestep
1597
1598 timeSteppingTool_->advanceTime(true/*output info*/);
1599 counter++;
1600 if (print)
1601 exportTimestep();
1602 }
1603
1604 if (print) {
1605 closeExporter();
1606 }
1607}
1608
1609template<class SC,class LO,class GO,class NO>
1610void DAESolverInTime<SC,LO,GO,NO>::advanceInTimeNonLinearExternal(){
1611
1612 bool print = parameterList_->sublist("General").get("ParaViewExport",false);
1613 if (print) {
1614 exportTimestep();
1615 }
1616
1617 double dt = timeSteppingTool_->get_dt();
1618 int counter=0;
1619 //#########
1620 //time loop
1621 //#########
1622 while (timeSteppingTool_->continueTimeStepping()) {
1623
1624 double time = timeSteppingTool_->currentTime() + dt;
1625 problemTime_->updateTime ( time );
1626
1627 if (problemTime_->hasSourceTerm()){
1628 problemTime_->assembleSourceTerm(time); // assemble source term; added to residual vector in calculateNonLinResidualVec()
1629 }
1630 NonLinearSolver<SC, LO, GO, NO> nlSolver(parameterList_->sublist("General").get("Linearization","Newton"));
1631 nlSolver.solve(*problemTime_,time);
1632 problemTime_->assemble( "OnlyUpdate" ); // updates AceGEN history
1633
1634 problemTime_->assemble( "SetSolutionInTime" ); // Here, we update the time solution with the Newton solution, which basically means that we can go to the next timestep
1635
1636 timeSteppingTool_->advanceTime(true/*output info*/);
1637 counter++;
1638 if (print) {
1639 exportTimestep();
1640 }
1641 }
1642
1643 if (print) {
1644 closeExporter();
1645 }
1646}
1647
1648template<class SC,class LO,class GO,class NO>
1649void DAESolverInTime<SC,LO,GO,NO>::addRhsDAE(SmallMatrix<double> coeff, BlockMatrixPtr_Type bMat, BlockMultiVectorPtr_Type vec){
1650
1651 BlockMultiVectorPtr_Type mv = Teuchos::rcp( new BlockMultiVector_Type( vec ) );
1652 bMat->apply( *vec, *mv , coeff );
1653 problemTime_->getRhs()->update( 1., *mv, 1. );
1654}
1655
1656template<class SC,class LO,class GO,class NO>
1657void DAESolverInTime<SC,LO,GO,NO>::addRhsDAE(SmallMatrix<double> coeff, BlockMultiVectorPtr_Type vec){
1658 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Is this correct? addRhsDAE!");
1659 for (int i=0; i<vec->size(); i++)
1660 problemTime_->getRhs()->getBlockNonConst(i)->update( coeff[i][i], vec->getBlock(i), 1. );
1661}
1662
1663template<class SC,class LO,class GO,class NO>
1664void DAESolverInTime<SC,LO,GO,NO>::addSourceTermToRHS(double coeff)
1665{
1666 BlockMultiVectorPtr_Type tmpMV = problemTime_->getSourceTerm();
1667
1668 problemTime_->getRhs()->update(coeff, *tmpMV, 1.);
1669}
1670
1671template<class SC,class LO,class GO,class NO>
1672void DAESolverInTime<SC,LO,GO,NO>::exportTimestep(){
1673
1674 if (!boolExporterSetup_) {
1675 setupExporter();
1676 }
1677 if (verbose_) {
1678 std::cout << "-- Exporting..."<< std::flush;
1679 }
1680 for (int i=0; i<exporter_vector_.size(); i++) {
1681
1682 exporter_vector_[i]->save( timeSteppingTool_->currentTime() );
1683
1684 }
1685
1686 if (verbose_) {
1687 std::cout << "done! --"<< std::endl;
1688 }
1689
1690}
1691
1692template<class SC,class LO,class GO,class NO>
1693void DAESolverInTime<SC,LO,GO,NO>::exportTimestep(BlockMultiVectorPtr_Type& solShort){
1694
1695 if (!boolExporterSetup_) {
1696 setupExporter(solShort);
1697 }
1698 if (verbose_) {
1699 std::cout << "-- Exporting..."<< std::flush;
1700 }
1701 for (int i=0; i<exporter_vector_.size(); i++) {
1702
1703 exporter_vector_[i]->save( timeSteppingTool_->currentTime() );
1704
1705 }
1706
1707 if (verbose_) {
1708 std::cout << "done! --"<< std::endl;
1709 }
1710
1711}
1712
1713template<class SC,class LO,class GO,class NO>
1714void DAESolverInTime<SC,LO,GO,NO>::closeExporter(){
1715
1716 if (boolExporterSetup_) {
1717 for (int i=0; i<exporter_vector_.size(); i++)
1718 exporter_vector_[i]->closeExporter();
1719 }
1720}
1721
1722
1723template<class SC,class LO,class GO,class NO>
1724void DAESolverInTime<SC,LO,GO,NO>::setupExporter(){
1725 for (int i=0; i<timeStepDef_.size(); i++) {
1726 // \lambda in FSI, koennen wir nicht exportieren, weil keine Elementliste dafuer vorhanden
1727 bool exportThisBlock = true;
1728 if(this->parameterList_->sublist("Parameter").get("FSI",false) == true )
1729 exportThisBlock = (i != 3);
1730 else if(this->parameterList_->sublist("Parameter").get("FSCI",false) == true)
1731 exportThisBlock = (i != 4);
1732
1733 if(exportThisBlock)
1734 {
1735 ExporterPtr_Type exporterPtr(new Exporter_Type());
1736 MultiVectorConstPtr_Type exportVector = problemTime_->getSolution()->getBlock(i);
1737
1738 DomainConstPtr_Type dom = problemTime_->getDomain(i);
1739
1740 int exportEveryXTimesteps = parameterList_->sublist("Exporter").get( "Export every X timesteps", 1 );
1741 std::string plSuffix = "Suffix variable" + std::to_string(i+1);
1742 std::string suffix = parameterList_->sublist("Exporter").get(plSuffix, "" );
1743 std::string varName = problemTime_->getVariableName(i) + suffix;
1744 MeshPtr_Type meshNonConst = Teuchos::rcp_const_cast<Mesh_Type>(dom->getMesh());
1745 exporterPtr->setup(varName, meshNonConst, dom->getFEType(), parameterList_);
1746
1747// exporterPtr->setup(dom->getDimension(), dom->getNumElementsGlobal(), dom->getElements(), dom->getPointsUnique(), dom->getMapUnique(), dom->getMapRepeated(), dom->getFEType(), varName, exportEveryXTimesteps, comm_ , parameterList_);
1748
1749 UN dofsPerNode = problemTime_->getDofsPerNode(i);
1750
1751 if (dofsPerNode == 1)
1752 exporterPtr->addVariable( exportVector, varName, "Scalar", dofsPerNode, dom->getMapUnique() );
1753 else
1754 exporterPtr->addVariable( exportVector, varName, "Vector", dofsPerNode, dom->getMapUnique() );
1755
1756 exporter_vector_.push_back(exporterPtr);
1757 export_solution_vector_.push_back(exportVector);
1758 }
1759 }
1760 boolExporterSetup_ = true;
1761
1762}
1763
1764template<class SC,class LO,class GO,class NO>
1765void DAESolverInTime<SC,LO,GO,NO>::setupExporter(BlockMultiVectorPtr_Type& solShort){
1766 for (int i=0; i<timeStepDef_.size(); i++) {
1767 // \lambda in FSI, koennen wir nicht exportieren, weil keine Elementliste dafuer vorhanden
1768 bool exportThisBlock = true;
1769 exportThisBlock = !(this->parameterList_->sublist("Parameter").get("FSI",false) && i == 3);
1770 if(exportThisBlock)
1771 {
1772 ExporterPtr_Type exporterPtr(new Exporter_Type());
1773 MultiVectorConstPtr_Type exportVector = problemTime_->getSolution()->getBlock(i);
1774 MultiVectorConstPtr_Type exportVectorShort = solShort->getBlock(i);
1775
1776 DomainConstPtr_Type dom = problemTime_->getDomain(i);
1777
1778 int exportEveryXTimesteps = parameterList_->sublist("Exporter").get( "Export every X timesteps", 1 );
1779 std::string plSuffix = "Suffix variable" + std::to_string(i+1);
1780 std::string suffix = parameterList_->sublist("Exporter").get(plSuffix, "" );
1781 std::string varName = problemTime_->getVariableName(i) + suffix;
1782 std::string varNameShort = problemTime_->getVariableName(i) + "_short_" + suffix;
1783
1784 MeshPtr_Type meshNonConst = Teuchos::rcp_const_cast<Mesh_Type>(dom->getMesh());
1785 exporterPtr->setup(varName, meshNonConst, dom->getFEType(), parameterList_);
1786
1787// exporterPtr->setup(dom->getDimension(), dom->getNumElementsGlobal(), dom->getElements(), dom->getPointsUnique(), dom->getMapUnique(), dom->getMapRepeated(), dom->getFEType(), varName, exportEveryXTimesteps, comm_ , parameterList_);
1788
1789 UN dofsPerNode = problemTime_->getDofsPerNode(i);
1790
1791 if (dofsPerNode == 1){
1792 exporterPtr->addVariable( exportVector, varName, "Scalar", dofsPerNode, dom->getMapUnique() );
1793 exporterPtr->addVariable( exportVectorShort, varNameShort, "Scalar", dofsPerNode, dom->getMapUnique() );
1794 }
1795 else {
1796 exporterPtr->addVariable( exportVector, varName, "Vector", dofsPerNode, dom->getMapUnique() );
1797 exporterPtr->addVariable( exportVectorShort, varNameShort, "Vector", dofsPerNode, dom->getMapUnique() );
1798 }
1799
1800
1801 exporter_vector_.push_back(exporterPtr);
1802 export_solution_vector_.push_back(exportVector);
1803 }
1804 }
1805 boolExporterSetup_ = true;
1806
1807}
1808
1809
1810 //ch 21.03.19: Funktion aendern!
1811template<class SC,class LO,class GO,class NO>
1812void DAESolverInTime<SC,LO,GO,NO>::setupTimeStepping(){
1813
1814 int size = this->problem_->getSystem()->size();
1815
1816 problemTime_.reset(new TimeProblem<SC,LO,GO,NO>(*this->problem_,comm_));
1817
1818 // Fuer FSI
1819 if(this->parameterList_->sublist("Parameter").get("FSI",false) || this->parameterList_->sublist("Parameter").get("SCI",false) || this->parameterList_->sublist("Parameter").get("FSCI",false))
1820 {
1821 // Beachte: Massematrix ist schon vektorwertig!
1822 // Reset auf Massesystem von problemTime_ (=FSI), da auf problemTime_ kein assemble() bzw. assembleMassSystem() aufgerufen wird.
1823 this->problemTime_->systemMass_.reset(new BlockMatrix_Type(this->problemTime_->getSystem()->size()));
1824 this->problemTime_->systemCombined_.reset( new BlockMatrix_Type( this->problemTime_->getSystem()->size() ));
1825 }
1826 else
1827 {
1828 size = timeStepDef_.size();
1829 SmallMatrix<double> massCoeff(size);
1830 SmallMatrix<double> problemCoeff(size); //hier egal, nur Massenmatrix wichtig. Deswegen auf Null belassen
1831
1832 for (int i=0; i<size; i++) {
1833 for (int j=0; j<size; j++) {
1834 if (timeStepDef_[i][j]>1 && i==j) {
1835 massCoeff[i][j] = 1.0;
1836 }
1837 else{
1838 massCoeff[i][j] = 0.;
1839 }
1840 }
1841 }
1842
1843 // Setze massCoeff und problemCoeff in TimeProblem
1844 // ACHTUNG: problemCoeff ist Null. Es wird also nur die Massematrix in systemCombined_ geschrieben.
1845 problemTime_->setTimeParameters(massCoeff,problemCoeff);
1846
1847 // Assembliere Massematrix -> ggf. ReAssemble() falls nichtlinear ->
1848 // -> das linearProblem (bzw. nonlinearProblem) von oben mit der Massematrix verbinden
1849 problemTime_->setTimeDef( timeStepDef_ );
1850 problemTime_->assemble( "MassSystem" );
1851 }
1852
1853
1854}
1855
1856template<class SC,class LO,class GO,class NO>
1857void DAESolverInTime<SC,LO,GO,NO>::setTimeStep(double dt){
1858
1859 checkTimeSteppingDef();
1860
1861
1862}
1863
1864template<class SC,class LO,class GO,class NO>
1865void DAESolverInTime<SC,LO,GO,NO>::setFinalTime(double T){
1866
1867 checkTimeSteppingDef();
1868
1869}
1870
1871template<class SC,class LO,class GO,class NO>
1872void DAESolverInTime<SC,LO,GO,NO>::checkTimeSteppingDef(){
1873#ifdef ASSERTS_WARNINGS
1874 MYASSERT(isTimeSteppingDefined_,"Time stepping not defined!");
1875#endif
1876
1877}
1878}
1879#endif
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36