LifeV
lifev/fsi/testsuite/fsi_restart/main.cpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  * @file
29  * @brief File containing the Monolithic Test
30  *
31  * @date 2009-04-09
32  * @author Paolo Crosetto <crosetto@iacspc70.epfl.ch>
33  *
34  * @maintainer Paolo Crosetto <crosetto@iacspc70.epfl.ch>
35  *
36  * Monolithic problem. Features:
37  * - fullMonolithic (CE):
38  * -# solution with exact Newton (semiImplicit = false, useShapeDerivatives = true, conservativeFormulation = false)
39  * -# solution with quasi Newton (semiImplicit = false, useShapeDerivatives = false, conservativeFormulation = false)
40  * -# preconditioner choice: see the classes Monolithic and fullMonolithic
41  * - Monolithic (GCE):
42  * -# solution extrapolating the fluid domain (semiImplicit = true, useShapeDerivatives = false, conservativeFormulation = false)
43  * -# preconditioner choice: see the classes Monolithic and fullMonolithic
44  * - boundary conditions:
45  * -# Neumann
46  * -# Dirichlet
47  * -# Robin
48  * -# Fluxes (defective)
49  * -# absorbing \cite BadiaNobileVergara2008 :
50  * through the class flowConditions.
51  * - optional: computation of wall shear stress (not properly tested in parallel)
52  * - optional: computation of the largest singular values of the preconditioned matrix
53  *
54  * \b Features:
55  * This test by default solves the FSI probem discretized in time using the GCE or CE methods, implemented respectively
56  * in the files monolithicGE.hpp and monolithicGI.hpp . The geometry is that of a tube (benchmark test introduced in \cite Gerbeau2003).
57  * In this test the boundary conditions assigned are of type:
58  * - flux (defective b.c.) at the inlet
59  * - absorbing (see \cite BadiaNobileVergara2008) at the outlet
60  * - Robin b.c. on the solid external wall
61  * - Dirichlet homogeneous at the solid rings on the inlet-outlet (clamped tube).
62  *
63  * The output is written at every timestep, in HDF5 (if available) or ensight format.
64  * This test implements an inlet flux bundary condition for the first three time steps, then at the fourth time step
65  * the inlet boundary condition is replaced by a Neumann one (this mechanism is useful to implement rudimental valves).
66  * The outflow boundary condition is of absorbing type. At the outer wall for the structure a Robin condition is imposed.
67  * The time discretization is carried out using BDF methods of order 2. At the moment, even is the Newmark method is available
68  * for the temporal discretization of the single problems( e.g. in test_structuralsolver), it cannot be used in the FSI framework
69  * since the class TimeAdvanceNewmark is not registered as one of the possible instances of the abstrac class TimeAdvance.
70  *
71  * This test loads an FSI simulation (done using the FSIMonolithic) and it restarts it.
72  */
73 
74 
75 #include <cassert>
76 #include <cstdlib>
77 
78 #include <boost/timer.hpp>
79 
80 #include <Epetra_ConfigDefs.h>
81 #ifdef EPETRA_MPI
82 #include <mpi.h>
83 #include <Epetra_MpiComm.h>
84 #else
85 #include <Epetra_SerialComm.h>
86 #endif
87 
88 
89 // LifeV includes
90 #include <lifev/core/LifeV.hpp>
91 
92 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
93 #include <lifev/core/algorithm/PreconditionerML.hpp>
94 
95 #include <lifev/fsi/solver/FSISolver.hpp>
96 #include <lifev/structure/solver/StructuralOperator.hpp>
97 #include <lifev/fsi/solver/FSIMonolithicGI.hpp>
98 
99 #include <lifev/core/filter/ExporterEnsight.hpp>
100 #include <lifev/core/filter/ExporterEmpty.hpp>
101 #ifdef HAVE_HDF5
102 #include <lifev/core/filter/ExporterHDF5.hpp>
103 #endif
104 
105 #include "ud_functions.hpp"
107 #include "flowConditions.hpp"
108 
109 class Problem
110 {
111 public:
112 
114 
115  typedef LifeV::FSIOperator::data_Type data_Type;
116  typedef LifeV::FSIOperator::dataPtr_Type dataPtr_Type;
117 
118  typedef LifeV::FSIOperator::vector_Type vector_Type;
119  typedef LifeV::FSIOperator::vectorPtr_Type vectorPtr_Type;
120 
122 
123  typedef LifeV::ExporterEnsight<LifeV::FSIOperator::mesh_Type> ensightFilter_Type;
125 #ifdef HAVE_HDF5
128 #endif
130  /*!
131  This routine sets up the problem:
132 
133  -# create the standard boundary conditions for the fluid and
134  structure problems.
135 
136  -# initialize and setup the FSIsolver
137  */
138 
139  Problem ( GetPot const& data_file ) :
140  M_Tstart (0.),
141  M_saveEvery (1),
142  M_returnValue (EXIT_FAILURE)
143  {
144  using namespace LifeV;
145 
146  FSIOperator::solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct ( "linearVenantKirchhoff", &FSIOperator::createVenantKirchhoffLinear );
147  FSIOperator::solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct ( "exponential", &FSIOperator::createExponentialMaterialNonLinear );
148  FSIOperator::solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct ( "neoHookean", &FSIOperator::createNeoHookeanMaterialNonLinear );
149  FSIOperator::solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct ( "nonLinearVenantKirchhoff", &FSIOperator::createVenantKirchhoffNonLinear );
150 
151  std::cout << "register MonolithicGE : " << FSIMonolithicGE::S_register << std::endl;
152  std::cout << "register MonolithicGI : " << FSIMonolithicGI::S_register << std::endl;
153 
154  M_data = dataPtr_Type ( new data_Type() );
155  M_data->setup ( data_file );
156  //M_data->dataSolid()->setTimeData( M_data->dataFluid()->dataTime() ); //Same TimeData for fluid & solid
157  //M_data->showMe();
158 
159  M_fsi = fsi_solver_ptr ( new FSISolver( ) );
160  MPI_Barrier ( MPI_COMM_WORLD );
161 
162  M_fsi->setData ( M_data );
163  M_fsi->FSIOper()->setDataFile ( data_file ); //TO BE REMOVED!
164 
165  // Setting FESpace and DOF
166 
167  std::string fluidMeshPartitioned = data_file ( "problem/fluidMeshPartitioned", "none" );
168  std::string solidMeshPartitioned = data_file ( "problem/solidMeshPartitioned", "none" );
169 #ifdef HAVE_HDF5
170  if ( fluidMeshPartitioned.compare ( "none" ) )
171  {
172  FSIOperator::meshFilter_Type fluidMeshFilter ( data_file, fluidMeshPartitioned );
173  fluidMeshFilter.setComm ( M_fsi->FSIOper()->worldComm() );
174  FSIOperator::meshFilter_Type solidMeshFilter ( data_file, solidMeshPartitioned );
175  solidMeshFilter.setComm ( M_fsi->FSIOper( )->worldComm( ) );
176  M_fsi->FSIOper( )->partitionMeshes ( fluidMeshFilter, solidMeshFilter );
177  M_fsi->FSIOper( )->setupFEspace( );
178  M_fsi->FSIOper( )->setupDOF ( fluidMeshFilter );
179  fluidMeshFilter.closeFile( );
180  solidMeshFilter.closeFile( );
181  }
182  else
183 #endif
184  {
185  M_fsi->FSIOper( )->partitionMeshes( );
186  M_fsi->FSIOper( )->setupFEspace( );
187  M_fsi->FSIOper( )->setupDOF( );
188  }
189 
190 #ifdef DEBUG
191  debugStream ( 10000 ) << "Setting up the FESpace and DOF \n";
192 #endif
193  MPI_Barrier ( MPI_COMM_WORLD );
194 
195 #ifdef DEBUG
196  debugStream ( 10000 ) << "Setting up the BC \n";
197 #endif
198  M_fsi->setFluidBC ( BCh_monolithicFlux ( true ) );
199  M_fsi->setSolidBC ( BCh_monolithicSolid ( *M_fsi->FSIOper( ) ) );
200 
201  M_fsi->setup();
202 
203  M_fsi->setFluidBC ( BCh_monolithicFluid ( *M_fsi->FSIOper( ), true ) );
204  M_fsi->setHarmonicExtensionBC ( BCh_harmonicExtension ( *M_fsi->FSIOper( ) ) );
205 
206  dynamic_cast<LifeV::FSIMonolithic*> (M_fsi->FSIOper().get() )->mergeBCHandlers();
207 
208 #ifdef DEBUG
209  debugStream ( 10000 ) << "BC set\n";
210 #endif
211 
212  std::string const exporterType = data_file ( "exporter/type", "ensight" );
213  std::string const fluidName = data_file ( "exporter/fluid/filename", "fluid" );
214  std::string const solidName = data_file ( "exporter/solid/filename", "solid" );
215 
216 #ifdef HAVE_HDF5
217  if (exporterType.compare ("hdf5") == 0)
218  {
219  M_exporterFluid.reset ( new hdf5Filter_Type ( data_file, fluidName) );
220  M_exporterSolid.reset ( new hdf5Filter_Type ( data_file, solidName) );
221  }
222  else
223 #endif
224  {
225  if (exporterType.compare ("none") == 0)
226  {
227  M_exporterFluid.reset ( new ExporterEmpty<RegionMesh<LinearTetra> > ( data_file, M_fsi->FSIOper()->uFESpace().mesh(), fluidName, M_fsi->FSIOper()->uFESpace().map().comm().MyPID() ) );
228  M_exporterSolid.reset ( new ExporterEmpty<RegionMesh<LinearTetra> > ( data_file, M_fsi->FSIOper()->dFESpace().mesh(), solidName, M_fsi->FSIOper()->uFESpace().map().comm().MyPID() ) );
229  }
230  else
231  {
232  M_exporterFluid.reset ( new ensightFilter_Type ( data_file, fluidName) );
233  M_exporterSolid.reset ( new ensightFilter_Type ( data_file, solidName) );
234  }
235  }
236 
237 
238  // load using ensight/hdf5
239  M_saveEvery = data_file ("exporter/saveEvery", 1);
240 
241  // load using ensight/hdf5
242  std::string restartType (data_file ("importer/restartFSI", "false" ) );
243  std::cout << "The load state is: " << restartType << std::endl;
244 
245  if ( !restartType.compare ("true") )
246  {
247  restartFSI (data_file);
248  }
249  else
250  {
251  M_fsi->initialize();
252 
253  M_velAndPressure.reset ( new vector_Type ( M_fsi->FSIOper()->fluid().getMap(), M_exporterFluid->mapType() ) );
254 
255  M_fluidDisp.reset ( new vector_Type ( M_fsi->FSIOper()->mmFESpace().map(), M_exporterFluid->mapType() ) );
256 
257  M_solidDisp.reset ( new vector_Type ( M_fsi->FSIOper()->dFESpace().map(), M_exporterSolid->mapType() ) );
258  }
259 
260 
261  M_exporterFluid->setMeshProcId (M_fsi->FSIOper()->uFESpace().mesh(), M_fsi->FSIOper()->uFESpace().map().comm().MyPID() );
262  M_exporterSolid->setMeshProcId (M_fsi->FSIOper()->dFESpace().mesh(), M_fsi->FSIOper()->dFESpace().map().comm().MyPID() );
263  M_exporterFluid->addVariable ( ExporterData<FSIOperator::mesh_Type>::VectorField, "f-velocity",
264  M_fsi->FSIOper()->uFESpacePtr(), M_velAndPressure, UInt (0) );
265  M_exporterFluid->addVariable ( ExporterData<FSIOperator::mesh_Type>::ScalarField, "f-pressure",
266  M_fsi->FSIOper()->pFESpacePtr(), M_velAndPressure,
267  UInt (3 * M_fsi->FSIOper()->uFESpace().dof().numTotalDof() ) );
268 
269  M_exporterFluid->addVariable ( ExporterData<FSIOperator::mesh_Type>::VectorField, "f-displacement",
270  M_fsi->FSIOper()->mmFESpacePtr(), M_fluidDisp, UInt (0) );
271 
272 
273 
274 
275  M_exporterSolid->addVariable ( ExporterData<FSIOperator::mesh_Type>::VectorField, "s-displacement",
276  M_fsi->FSIOper()->dFESpacePtr(), M_solidDisp, UInt (0) );
277 
278  //M_fsi->FSIOper()->fluid().setupPostProc(); //this has to be called if we want to initialize the postProcess
279 
280  FC0.initParameters ( *M_fsi->FSIOper(), 3);
281 
282  M_data->dataFluid()->dataTime()->setInitialTime ( M_data->dataFluid()->dataTime()->initialTime() );
283  M_data->dataFluid()->dataTime()->setTime ( M_data->dataFluid()->dataTime()->initialTime() );
284  M_data->dataSolid()->dataTime()->setInitialTime ( M_data->dataFluid()->dataTime()->initialTime() );
285  M_data->dataSolid()->dataTime()->setTime ( M_data->dataFluid()->dataTime()->initialTime() );
286  M_data->timeDataALE()->setInitialTime ( M_data->dataFluid()->dataTime()->initialTime() );
287  M_data->timeDataALE()->setTime ( M_data->dataFluid()->dataTime()->initialTime() );
288  }
289 
290  /*!
291  This routine runs the temporal loop
292  */
293  int
294  run()
295  {
296  boost::timer _overall_timer;
297 
298  LifeV::UInt iter = 1;
299 
300  dynamic_cast<LifeV::FSIMonolithic*> (M_fsi->FSIOper().get() )->enableStressComputation (0);
301 
302  vectorPtr_Type solution ( new vector_Type ( (*M_fsi->FSIOper()->couplingVariableMap() ) ) );
303 
304  M_fsi->FSIOper()->extrapolation ( *solution );
305 
306  //Initialize the exporters
307  M_fsi->FSIOper()->exportSolidDisplacement (*M_solidDisp); // displacement(), M_offset);
308  M_fsi->FSIOper()->exportFluidVelocityAndPressure (*M_velAndPressure);
309  *M_fluidDisp = M_fsi->FSIOper()->meshDisp();
310  M_exporterFluid->postProcess ( M_data->dataFluid()->dataTime()->time() );
311  M_exporterSolid->postProcess ( M_data->dataFluid()->dataTime()->time() );
312 
313  for ( ; M_data->dataFluid()->dataTime()->canAdvance(); ++iter)
314  {
315  M_returnValue = EXIT_FAILURE;
316  M_data->dataFluid()->dataTime()->updateTime();
317  M_data->dataSolid()->dataTime()->updateTime();
318  M_data->timeDataALE()->updateTime();
319 
320 
321  boost::timer _timer;
322  FC0.renewParameters ( *M_fsi, 3 );
323 
324  M_fsi->FSIOper()->extrapolation ( *solution );
325 
326  M_fsi->iterate ( solution );
327 
328  // Saving the solution
329  M_fsi->FSIOper()->updateSolution ( *solution );
330 
331  if (iter % M_saveEvery == 0)
332  {
333  M_fsi->FSIOper()->exportSolidDisplacement (*M_solidDisp);
334  M_fsi->FSIOper()->exportFluidVelocityAndPressure (*M_velAndPressure);
335  *M_fluidDisp = M_fsi->FSIOper()->meshDisp();
336 
337  M_exporterSolid->postProcess ( M_data->dataFluid()->dataTime()->time() );
338  M_exporterFluid->postProcess ( M_data->dataFluid()->dataTime()->time() );
339  }
340 
341  std::cout << "solution norm at time: " << M_data->dataFluid()->dataTime()->time() << "(iter" << iter << ") : "
342  << M_fsi->displacement().norm2() << "\n";
343 
344 
345  if ( M_data->method().compare ("monolithicGI") == 0 )
346  {
347  checkResultGI (M_data->dataFluid()->dataTime()->time() );
348  }
349  else
350  {
351  checkResultGCE (M_data->dataFluid()->dataTime()->time() );
352  }
353 
354 
355  }
356 
357  std::cout << "Total computation time = "
358  << _overall_timer.elapsed() << "s" << "\n";
359 
360  return M_returnValue;
361 
362  }
363 
364 private:
365 
366  void restartFSI ( GetPot const& data_file);
367  //Methods to conclude the reading for restart
368  void readLastVectorSolidTimeAdvance ( vectorPtr_Type fluidDisp, const LifeV::UInt iterInit, std::string iterationString);
369  void readLastVectorALETimeAdvance ( vectorPtr_Type fluidDisp, const std::string loadInitSol);
370  void checkResultGI (const LifeV::Real& time);
371  void checkResultGCE (const LifeV::Real& time);
372 
374  dataPtr_Type M_data;
375 
378  filterPtr_Type M_importerSolid;
379  filterPtr_Type M_importerFluid;
380  vectorPtr_Type M_velAndPressure;
381  vectorPtr_Type M_fluidDisp;
382  vectorPtr_Type M_solidDisp;
383 
384  std::vector<vectorPtr_Type> M_solidStencil;
385  std::vector<vectorPtr_Type> M_fluidStencil;
386  std::vector<vectorPtr_Type> M_ALEStencil;
387 
389 
391  LifeV::UInt M_saveEvery;
393 public:
394  void resultCorrect (LifeV::Real time)
395  {
396  std::cout << "Result correct at time: " << time << std::endl;
397  M_returnValue = EXIT_SUCCESS;
398  }
399 
400 };
401 
402 struct FSIChecker
403 {
404  FSIChecker ( GetPot const& _data_file ) :
406  {}
407 
408  int operator() ()
409  {
410  std::shared_ptr<Problem> fsip;
411  int returnVariable;
412  returnVariable = EXIT_FAILURE;
413  try
414  {
415  fsip = std::shared_ptr<Problem> ( new Problem ( data_file ) );
416  returnVariable = fsip->run();
417 
418  }
419  catch ( std::exception const& _ex )
420  {
421  std::cout << "caught exception : " << _ex.what() << "\n";
422  }
423 
424  return returnVariable;
425  }
426 
427  GetPot data_file;
428  LifeV::Vector disp;
429 };
430 
431 
432 namespace LifeV
433 {
434 
435 namespace
436 {
437 static bool regIF = (PRECFactory::instance().registerProduct ( "Ifpack", &createIfpack ) );
438 static bool regML = (PRECFactory::instance().registerProduct ( "ML", &createML ) );
439 }
440 }
441 
442 
443 int main (int argc, char** argv)
444 {
445 #ifdef HAVE_MPI
446  MPI_Init (&argc, &argv);
447 #else
448  std::cout << "% using serial Version" << std::endl;
449 #endif
450 
451  GetPot command_line (argc, argv);
452  const std::string data_file_name = command_line.follow ("data", 2, "-f", "--file");
453  GetPot data_file (data_file_name);
454  FSIChecker _sp_check ( data_file );
455  int returnValue = _sp_check();
456 
457 #ifdef HAVE_MPI
458  MPI_Finalize();
459 #endif
460 
461  return returnValue;
462 
463 }
464 
465 void Problem::restartFSI ( GetPot const& data_file)
466 {
467 
468  using namespace LifeV;
469 
470  typedef FSIOperator::mesh_Type mesh_Type;
471 
472  //Creating the pointer to the filter
473  std::string const importerType = data_file ( "importer/type", "ensight");
474  std::string const fluidName = data_file ( "importer/fluid/filename", "fluid");
475  std::string const solidName = data_file ( "importer/solid/filename", "solid");
476 
477  std::string const loadInitSol = data_file ( "importer/initSol", "00000");
478  std::string const loadInitSolFD = data_file ("importer/initSolFD", "-1");
479  std::string iterationString;
480 
481  M_Tstart = data_file ( "fluid/time_discretization/initialtime", 0.);
482 
483  std::cout << "The file for fluid is : " << fluidName << std::endl;
484  std::cout << "The file for solid is : " << solidName << std::endl;
485  std::cout << "The importerType is : " << importerType << std::endl;
486  std::cout << "The iteration is : " << loadInitSol << std::endl;
487  std::cout << "For the fluid disp is : " << loadInitSolFD << std::endl;
488  std::cout << "Starting time : " << M_Tstart << std::endl;
489 
490  //At the moment the restart works only if BDF methods are used in time.
491  // For Newmark method a almost new implementation is needed
492 
493  std::string methodFluid = data_file ( "fluid/time_discretization/method", "Newmark");
494  std::string methodSolid = data_file ( "solid/time_discretization/method", "Newmark");
495  std::string methodALE = data_file ( "mesh_motion/time_discretization/method", "Newmark");
496 
497 #ifdef HAVE_HDF5
498  if (importerType.compare ("hdf5") == 0)
499  {
500  M_importerFluid.reset ( new hdf5Filter_Type ( data_file, fluidName) );
501  M_importerSolid.reset ( new hdf5Filter_Type ( data_file, solidName) );
502  }
503  else
504 #endif
505  {
506  if (importerType.compare ("none") == 0)
507  {
508  M_importerFluid.reset ( new ExporterEmpty<mesh_Type > ( data_file, M_fsi->FSIOper()->uFESpace().mesh(), "fluid", M_fsi->FSIOper()->uFESpace().map().comm().MyPID() ) );
509  M_importerSolid.reset ( new ExporterEmpty<mesh_Type > ( data_file, M_fsi->FSIOper()->dFESpace().mesh(), "solid", M_fsi->FSIOper()->uFESpace().map().comm().MyPID() ) );
510  }
511  else
512  {
513  M_importerFluid.reset ( new ensightFilter_Type ( data_file, fluidName) );
514  M_importerSolid.reset ( new ensightFilter_Type ( data_file, solidName) );
515  }
516  }
517 
518  M_importerFluid->setMeshProcId (M_fsi->FSIOper()->uFESpace().mesh(), M_fsi->FSIOper()->uFESpace().map().comm().MyPID() );
519  M_importerSolid->setMeshProcId (M_fsi->FSIOper()->dFESpace().mesh(), M_fsi->FSIOper()->dFESpace().map().comm().MyPID() );
520 
521  //Each of the vectors of the stencils has the dimension of the big vector
522  //Performing a cycle of the size of the timeAdvance classes for each problem
523  //The size of TimeAdvanceClass depends on the order of the BDF (data file)
524 
525  //The hypothesis used for this method is that the three TimeAdvance classes have the same size
526  iterationString = loadInitSol;
527 
528  UInt iterInit;
529 
530  vectorPtr_Type vel;
531  vectorPtr_Type pressure;
532  vectorPtr_Type solidDisp;
533  vectorPtr_Type fluidDisp;
534 
535  for (iterInit = 0; iterInit < M_fsi->FSIOper()->fluidTimeAdvance()->size(); iterInit++ )
536  {
537 
538  //It should work just initializing the timeAdvance classes
539  //Three stencils are needed (Fluid-Structure-Geometric)
540  vel.reset (new vector_Type (M_fsi->FSIOper()->uFESpace().map(), LifeV::Unique) );
541  pressure.reset (new vector_Type (M_fsi->FSIOper()->pFESpace().map(), LifeV::Unique) );
542  solidDisp.reset (new vector_Type (M_fsi->FSIOper()->dFESpace().map(), LifeV::Unique) );
543 
544  //First the three fields are read at the same time
545  //Creating the exporter data for the fields
546  //Fluid
547  LifeV::ExporterData<mesh_Type> initSolFluidVel (LifeV::ExporterData<mesh_Type>::VectorField, std::string ("f-velocity." + iterationString), M_fsi->FSIOper()->uFESpacePtr(), vel, UInt (0), LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
548  LifeV::ExporterData<mesh_Type> initSolFluidPress (LifeV::ExporterData<mesh_Type>::ScalarField, std::string ("f-pressure." + iterationString), M_fsi->FSIOper()->pFESpacePtr(), pressure, UInt (0), LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
549 
550  //Structure
551  LifeV::ExporterData<mesh_Type> initSolSolidDisp (LifeV::ExporterData<mesh_Type>::VectorField, "s-displacement." + iterationString, M_fsi->FSIOper()->dFESpacePtr(), solidDisp, UInt (0), LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
552 
553  //Initialization of the vectors used to read
554  *vel *= 0.0;
555  *pressure *= 0.0;
556  *solidDisp *= 0.0;
557 
558  //load of the solutions
559  M_importerFluid->readVariable (initSolFluidVel); //Fluid u
560  M_importerFluid->readVariable (initSolFluidPress); //Fluid p
561  M_importerSolid->readVariable (initSolSolidDisp); //Solid d
562 
563  std::cout << "Norm of the vel " << vel->norm2() << std::endl;
564  std::cout << "Norm of the pressure " << pressure->norm2() << std::endl;
565  std::cout << "Norm of the solid " << solidDisp->norm2() << std::endl;
566 
567  //We send the vectors to the FSIMonolithic class using the interface of FSIOper
568  M_fsi->FSIOper()->setVectorInStencils (vel, pressure, solidDisp, iterInit )
569  ;
570  //Updating string name
571  int iterations = std::atoi (iterationString.c_str() );
572  iterations--;
573 
574  std::ostringstream iter;
575  iter.fill ( '0' );
576  iter << std::setw (5) << ( iterations );
577  iterationString = iter.str();
578  }
579 
580  readLastVectorSolidTimeAdvance ( solidDisp, iterInit, iterationString );
581 
582  //For the ALE timeAdvance, one should be careful on the vectors that are used
583  //to compute the RHSFirstDerivative. That is why we first load the stencil using previous
584  //vectors and then we read the last one
585  iterationString = loadInitSol;
586  int iterationStartALE = std::atoi (iterationString.c_str() );
587  iterationStartALE--;
588 
589  std::ostringstream iter;
590  iter.fill ( '0' );
591  iter << std::setw (5) << ( iterationStartALE );
592  iterationString = iter.str();
593 
594  std::cout << "The load init sol is: " << loadInitSol << std::endl;
595  std::cout << "The first read sol is: " << iterationString << std::endl;
596 
597  for (iterInit = 0; iterInit < M_fsi->FSIOper()->ALETimeAdvance()->size(); iterInit++ )
598  {
599  //Reset the pointer
600  fluidDisp.reset (new vector_Type (M_fsi->FSIOper()->mmFESpace().map(), LifeV::Unique) );
601 
602  //Setting the exporterData to read: ALE problem
603  LifeV::ExporterData<mesh_Type> initSolFluidDisp (LifeV::ExporterData<mesh_Type>::VectorField, "f-displacement." + iterationString, M_fsi->FSIOper()->mmFESpacePtr(), fluidDisp, UInt (0), LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
604 
605  //Initializing
606  *fluidDisp *= 0.0;
607 
608  //Reading
609  M_importerFluid->readVariable (initSolFluidDisp); //Fluid df
610 
611  //Output
612  std::cout << "Norm of the df " << fluidDisp->norm2() << std::endl;
613 
614  //Setting the vector in the stencil
615  M_fsi->FSIOper()->setALEVectorInStencil ( fluidDisp, iterInit, false );
616 
617  //Updating string name
618  int iterations = std::atoi (iterationString.c_str() );
619  iterations--;
620 
621  std::ostringstream iter;
622  iter.fill ( '0' );
623  iter << std::setw (5) << ( iterations );
624  iterationString = iter.str();
625  }
626 
627  //Initializing the vector for the RHS terms of the formulas
628  M_fsi->FSIOper()->finalizeRestart();
629 
630  //Need to read still one vector and shiftright it.
631  readLastVectorALETimeAdvance ( fluidDisp, loadInitSol );
632 
633  //This are used to export the loaded solution to check it is correct.
634  vel.reset (new vector_Type (M_fsi->FSIOper()->uFESpace().map(), LifeV::Unique) );
635  pressure.reset (new vector_Type (M_fsi->FSIOper()->pFESpace().map(), LifeV::Unique) );
636  fluidDisp.reset (new vector_Type (M_fsi->FSIOper()->mmFESpace().map(), LifeV::Unique) );
637  M_velAndPressure.reset ( new vector_Type ( M_fsi->FSIOper()->fluid().getMap(), M_importerFluid->mapType() ) );
638  M_velAndPressure->subset (*pressure, pressure->map(), UInt (0), (UInt) 3 * M_fsi->FSIOper()->uFESpace().dof().numTotalDof() );
639  *M_velAndPressure += *vel;
640 
641  M_fluidDisp.reset ( new vector_Type ( *fluidDisp, M_importerFluid->mapType() ) );
642 
643  M_solidDisp.reset ( new vector_Type ( *solidDisp, M_importerSolid->mapType() ) );
644 
645 
646 }
647 
648 void Problem::readLastVectorSolidTimeAdvance ( vectorPtr_Type solidDisp,
649  LifeV::UInt iterInit,
650  std::string iterationString)
651 {
652  using namespace LifeV;
653 
654  typedef FSIOperator::mesh_Type mesh_Type;
655 
656  //Reading another vector for the solidTimeAdvance since its BDF has the same order
657  //as the other ones but since the orderDerivative = 2, the size of the stencil is
658  //orderBDF + 1
659 
660  solidDisp.reset (new vector_Type (M_fsi->FSIOper()->dFESpace().map(), LifeV::Unique) );
661  *solidDisp *= 0.0;
662  LifeV::ExporterData<mesh_Type> initSolSolidDisp (LifeV::ExporterData<mesh_Type>::VectorField, "s-displacement." + iterationString, M_fsi->FSIOper()->dFESpacePtr(), solidDisp, UInt (0), LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
663 
664  M_importerSolid->readVariable (initSolSolidDisp); //Solid d
665 
666  M_fsi->FSIOper()->setSolidVectorInStencil ( solidDisp, iterInit );
667 }
668 
669 
670 void Problem::readLastVectorALETimeAdvance ( vectorPtr_Type fluidDisp,
671  const std::string loadInitSol)
672 {
673  using namespace LifeV;
674 
675  typedef FSIOperator::mesh_Type mesh_Type;
676 
677  //We still need to load the last vector for ALE
678  std::string iterationString = loadInitSol;
679  fluidDisp.reset (new vector_Type (M_fsi->FSIOper()->mmFESpace().map(), LifeV::Unique) );
680 
681  //Setting the exporterData to read: ALE problem
682  LifeV::ExporterData<mesh_Type> initSolFluidDisp (LifeV::ExporterData<mesh_Type>::VectorField, "f-displacement." + iterationString, M_fsi->FSIOper()->mmFESpacePtr(), fluidDisp, UInt (0), LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
683 
684  //Initializing
685  *fluidDisp *= 0.0;
686 
687  //Reading
688  M_importerFluid->readVariable (initSolFluidDisp); //Fluid df
689 
690  //Output
691  std::cout << "Norm of the df " << fluidDisp->norm2() << std::endl;
692 
693  //This is ugly but it's the only way I have figured out at the moment
694  if ( M_data->method().compare ("monolithicGI") == 0 )
695  {
696  //Don't be scared by the ten. The goal of 10 is just to make the first if fail
697  M_fsi->FSIOper()->setALEVectorInStencil ( fluidDisp, 10, true );
698  }
699 
700  //Setting the vector in the stencil
701  M_fsi->FSIOper()->ALETimeAdvance()->shiftRight ( *fluidDisp );
702 }
703 
704 void Problem::checkResultGI (const LifeV::Real& time)
705 {
706 
707  //Extract the previous solution
708  LifeV::Real dispNorm = M_fsi->displacement().norm2();
709  if (time == 0.006 && ( (dispNorm - 104264) / dispNorm * (dispNorm - 104264) / dispNorm < 1e-5 ) )
710  {
711  resultCorrect (time);
712  }
713  else if (time == 0.007 && ( (dispNorm - 101014) / dispNorm * (dispNorm - 101014) / dispNorm < 1e-5 ) )
714  {
715  resultCorrect (time);
716  }
717  else if (time == 0.008 && ( (dispNorm - 98183.7) / dispNorm * (dispNorm - 98183.7) / dispNorm < 1e-5 ) )
718  {
719  resultCorrect (time);
720  }
721 }
722 
723 void Problem::checkResultGCE (const LifeV::Real& time)
724 {
725 
726  //Extract the previous solution
727  LifeV::Real dispNorm = M_fsi->displacement().norm2();
728  if (time == 0.006 && (dispNorm - 89122.6) / dispNorm * (dispNorm - 89122.6) / dispNorm < 1e-5)
729  {
730  resultCorrect (time);
731  }
732  else if (time == 0.007 && (dispNorm - 83260.4) / dispNorm * (dispNorm - 83260.4) / dispNorm < 1e-5)
733  {
734  resultCorrect (time);
735  }
736  else if (time == 0.008 && (dispNorm - 79342.5) / dispNorm * (dispNorm - 79342.5) / dispNorm < 1e-5)
737  {
738  resultCorrect (time);
739  }
740 }
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
LifeV::FactorySingleton< LifeV::Factory< LifeV::FSIOperator, std::string > > FSIFactory_Type
int main(int argc, char **argv)
GetPot(const int argc_, char **argv_, const char *FieldSeparator=0x0)
Definition: GetPot.hpp:507
std::shared_ptr< FSISolver > fsi_solver_ptr
void resultCorrect(LifeV::Real time)
FSIChecker(GetPot const &_data_file)
void readLastVectorALETimeAdvance(vectorPtr_Type fluidDisp, const std::string loadInitSol)
void readLastVectorSolidTimeAdvance(vectorPtr_Type fluidDisp, const LifeV::UInt iterInit, std::string iterationString)
void checkResultGI(const LifeV::Real &time)
void restartFSI(GetPot const &data_file)
Problem(GetPot const &data_file)
void checkResultGCE(const LifeV::Real &time)
std::shared_ptr< ensightFilter_Type > ensightFilterPtr_Type
LifeV::ExporterEnsight< LifeV::FSIOperator::mesh_Type > ensightFilter_Type
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191