LifeV
lifev/fsi/examples/application_aortaFSI/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  * @include fluidstructure.dox
29  * @file
30  * @brief for testing the benchmark contained in the
31  *
32  * @date 2009-04-09
33  * @author Paolo Crosetto <crosetto@iacspc70.epfl.ch>
34  *
35  * @maintainer Paolo Crosetto <crosetto@iacspc70.epfl.ch>
36  *
37  * Monolithic problem. Features:
38  * - fullMonolithic (CE):
39  * -# solution with exact Newton (semiImplicit = false, useShapeDerivatives = true, domainVelImplicit = false, convectiveTermDer = false)
40  * -# solution with quasi Newton (semiImplicit = false, useShapeDerivatives = false, domainVelImplicit = false, convectiveTermDer = false)
41  * -# preconditioner choice: see the classes Monolithic and fullMonolithic
42  * - Monolithic (GCE):
43  * -# solution extrapolating the fluid domain (semiImplicit = true, useShapeDerivatives = false, domainVelImplicit = false, convectiveTermDer = false)
44  * -# preconditioner choice: see the classes Monolithic and fullMonolithic
45  * - boundary conditions:
46  * -# Neumann
47  * -# Dirichlet
48  * -# Robin
49  * -# Fluxes (defective)
50  * -# absorbing \cite BadiaNobileVergara2008 :
51  * through the class flowConditions.
52  * - optional: computation of wall shear stress (not properly tested in parallel)
53  * - optional: computation of the largest singular values of the preconditioned matrix
54  *
55  * \b Features:
56  * This test by default solves the FSI probem discretized in time using the GCE or CE methods, implemented respectively
57  * in the files monolithicGE.hpp and monolithicGI.hpp . The geometry is that of a tube (benchmark test introduced in \cite Gerbeau2003).
58  * In this test the boundary conditions assigned are of type:
59  * - flux (defective b.c.) at the inlet
60  * - absorbing (see \cite BadiaNobileVergara2008) at the outlet
61  * - Robin b.c. on the solid external wall
62  * - Dirichlet homogeneous at the solid rings on the inlet-outlet (clamped tube).
63  *
64  * The output is written at every timestep, in HDF5 (if available) or ensight format.
65  * This test implements an inlet flux bundary condition for the first three time steps, then at the fourth time step
66  * the inlet boundary condition is replaced by a Neumann one (this mechanism is useful to implement rudimental valves).
67  * The outflow boundary condition is of absorbing type. At the outer wall for the structure a Robin condition is imposed.
68  */
69 
70 #define BL 1
71 #define HAVE_NS_PREC 1
72 #undef HAVE_NS_PREC
73 #include <cassert>
74 #include <cstdlib>
75 
76 #include <boost/timer.hpp>
77 
78 #include <Epetra_ConfigDefs.h>
79 #ifdef EPETRA_MPI
80 #include <mpi.h>
81 #include <Epetra_MpiComm.h>
82 #else
83 #include <Epetra_SerialComm.h>
84 #endif
85 
86 
87 #include "ud_functions.hpp"
88 // LifeV includes
89 #include <lifev/core/fem/FESpace.hpp>
90 #include <lifev/core/array/MapEpetra.hpp>
91 #include <lifev/core/fem/BCHandler.hpp>
92 #include <lifev/core/LifeV.hpp>
93 
94 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
95 #include <lifev/core/algorithm/PreconditionerML.hpp>
96 #ifdef HAVE_NS_PREC
97 #include <lifev/core/algorithm/PreconditionerPCD.hpp>
98 #endif
99 
100 #include <lifev/fsi/solver/FSISolver.hpp>
101 #include <lifev/structure/solver/StructuralOperator.hpp>
102 #include <lifev/fsi/solver/FSIMonolithicGI.hpp>
103 
104 #include <lifev/core/filter/ExporterEnsight.hpp>
105 #include <lifev/core/filter/ExporterEmpty.hpp>
106 #ifdef HAVE_HDF5
107 #include <lifev/core/filter/ExporterHDF5.hpp>
108 #endif
109 
110 #include "ud_functions.hpp"
112 
113 class Problem
114 {
115 public:
116 
117  typedef std::shared_ptr<LifeV::FSISolver> FSISolverPtr_Type;
118 
119  typedef LifeV::FSIOperator::data_Type data_Type;
120  typedef LifeV::FSIOperator::dataPtr_Type dataPtr_Type;
121 
122  typedef LifeV::FSIOperator::vector_Type vector_Type;
123  typedef LifeV::FSIOperator::vectorPtr_Type vectorPtr_Type;
124 
125  typedef std::shared_ptr< LifeV::Exporter<LifeV::RegionMesh<LifeV::LinearTetra> > > filterPtr_Type;
126 
127  typedef LifeV::ExporterEnsight<LifeV::FSIOperator::mesh_Type> ensightFilter_Type;
128  typedef std::shared_ptr<ensightFilter_Type> ensightFilterPtr_Type;
129 #ifdef HAVE_HDF5
130  typedef LifeV::ExporterHDF5<LifeV::FSIOperator::mesh_Type> hdf5Filter_Type;
131  typedef std::shared_ptr<hdf5Filter_Type> hdf5FilterPtr_Type;
132 #endif
133  typedef LifeV::FactorySingleton<LifeV::Factory<LifeV::FSIOperator, std::string> > FSIFactory_Type;
134  typedef LifeV::RegionMesh<LifeV::LinearTetra> mesh_Type;
135  typedef LifeV::MapEpetra map_Type;
136  typedef LifeV::FESpace<mesh_Type, map_Type> fespace_Type;
137  /*!
138  This routine sets up the problem:
139 
140  -# create the standard boundary conditions for the fluid and
141  structure problems.
142 
143  -# initialize and setup the FSIsolver
144  */
145 
146  Problem ( GetPot const& data_file ) :
147  M_Tstart (0.),
148  M_saveEvery (1),
149  M_tol (1)
150  {
151  using namespace LifeV;
152 
153  FSIOperator::solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct ( "linearVenantKirchhoff", &FSIOperator::createVenantKirchhoffLinear );
154  FSIOperator::solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct ( "exponential", &FSIOperator::createExponentialMaterialNonLinear );
155  FSIOperator::solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct ( "neoHookean", &FSIOperator::createNeoHookeanMaterialNonLinear );
156  FSIOperator::solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct ( "nonLinearVenantKirchhoff", &FSIOperator::createVenantKirchhoffNonLinear );
157 
158  std::cout << "register MonolithicGE : " << FSIMonolithicGE::S_register << std::endl;
159  std::cout << "register MonolithicGI : " << FSIMonolithicGI::S_register << std::endl;
160 #ifdef HAVE_NS_PREC
161  std::cout << "register PCD : " << PreconditionerPCD::S_register << std::endl;
162 #endif
163 
164  //bool reg=FSIMonolithicGI::S_register&&FSIMonolithicGE::S_register;
165 
166  M_data = dataPtr_Type ( new data_Type() );
167  M_data->setup ( data_file );
168 
169  M_fsi = FSISolverPtr_Type ( new FSISolver( ) );
170  MPI_Barrier ( MPI_COMM_WORLD );
171 
172  M_fsi->setData ( M_data );
173  M_fsi->FSIOper()->setDataFile ( data_file ); //TO BE REMOVED!
174 
175  // Setting FESpace and DOF
176 
177  std::string fluidMeshPartitioned = data_file ( "problem/fluidMeshPartitioned", "none" );
178  std::string solidMeshPartitioned = data_file ( "problem/solidMeshPartitioned", "none" );
179 #ifdef HAVE_HDF5
180  if ( fluidMeshPartitioned.compare ( "none" ) )
181  {
182  FSIOperator::meshFilter_Type fluidMeshFilter ( data_file, fluidMeshPartitioned );
183  fluidMeshFilter.setComm ( M_fsi->FSIOper()->worldComm() );
184  FSIOperator::meshFilter_Type solidMeshFilter ( data_file, solidMeshPartitioned );
185  solidMeshFilter.setComm ( M_fsi->FSIOper( )->worldComm( ) );
186  M_fsi->FSIOper( )->partitionMeshes ( fluidMeshFilter, solidMeshFilter );
187  M_fsi->FSIOper( )->setupFEspace( );
188  M_fsi->FSIOper( )->setupDOF ( fluidMeshFilter );
189  fluidMeshFilter.closeFile( );
190  solidMeshFilter.closeFile( );
191  }
192  else
193 #endif
194  {
195  M_fsi->FSIOper( )->partitionMeshes( );
196  M_fsi->FSIOper( )->setupFEspace( );
197  M_fsi->FSIOper( )->setupDOF( );
198  }
199 
200  MPI_Barrier ( MPI_COMM_WORLD );
201 
202  M_fsi->setFluidBC ( BCh_monolithicFlux( ) );
203  M_fsi->setSolidBC ( BCh_monolithicSolid ( *M_fsi->FSIOper( ) ) );
204 
205  M_fsi->setup();
206 
207  M_fsi->setFluidBC ( BCh_monolithicFluid ( *M_fsi->FSIOper( ) ) );
208  M_fsi->setHarmonicExtensionBC ( BCh_harmonicExtension ( *M_fsi->FSIOper( ) ) );
209 
210  dynamic_cast<LifeV::FSIMonolithic*> (M_fsi->FSIOper().get() )->mergeBCHandlers();
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  M_tol = data_file ("exporter/tolSave", 1);
241 
242  // load using ensight/hdf5
243  std::string restartType (data_file ("importer/restartType", "newSimulation") );
244  std::cout << "The load state is: " << restartType << std::endl;
245 
246  if (!restartType.compare ("Stokes") )
247  {
248  initializeStokes (data_file);
249  }
250  else if (!restartType.compare ("restartFSI") )
251  {
252  restartFSI (data_file);
253  }
254  else
255  {
256  M_fsi->initialize();
257 
258  M_velAndPressure.reset ( new vector_Type ( M_fsi->FSIOper()->fluid().getMap(), M_exporterFluid->mapType() ) );
259 
260  M_fluidDisp.reset ( new vector_Type ( M_fsi->FSIOper()->mmFESpace().map(), M_exporterFluid->mapType() ) );
261 
262  M_solidDisp.reset ( new vector_Type ( M_fsi->FSIOper()->dFESpace().map(), M_exporterSolid->mapType() ) );
263  }
264 
265 
266  M_exporterFluid->setMeshProcId (M_fsi->FSIOper()->uFESpace().mesh(), M_fsi->FSIOper()->uFESpace().map().comm().MyPID() );
267  M_exporterSolid->setMeshProcId (M_fsi->FSIOper()->dFESpace().mesh(), M_fsi->FSIOper()->dFESpace().map().comm().MyPID() );
268  M_exporterFluid->addVariable ( ExporterData<FSIOperator::mesh_Type>::VectorField, "f-velocity",
269  M_fsi->FSIOper()->uFESpacePtr(), M_velAndPressure, UInt (0) );
270  M_exporterFluid->addVariable ( ExporterData<FSIOperator::mesh_Type>::ScalarField, "f-pressure",
271  M_fsi->FSIOper()->pFESpacePtr(), M_velAndPressure,
272  UInt (3 * M_fsi->FSIOper()->uFESpace().dof().numTotalDof() ) );
273 
274  M_exporterFluid->addVariable ( ExporterData<FSIOperator::mesh_Type>::VectorField, "f-displacement",
275  M_fsi->FSIOper()->mmFESpacePtr(), M_fluidDisp, UInt (0) );
276 
277 
278 
279  // M_solidVel.reset ( new vector_Type( M_fsi->FSIOper()->dFESpace().map(), M_exporterSolid->mapType() ));
280  // M_WS.reset ( new vector_Type( M_fsi->FSIOper()->dFESpace().map(), M_exporterSolid->mapType() ));
281 
282  M_exporterSolid->addVariable ( ExporterData<FSIOperator::mesh_Type>::VectorField, "s-displacement",
283  M_fsi->FSIOper()->dFESpacePtr(), M_solidDisp, UInt (0) );
284  // M_exporterSolid->addVariable( ExporterData<FSIOperator::mesh_Type>::VectorField, "s-velocity",
285  // M_fsi->FSIOper()->dFESpacePtr(), M_solidVel, UInt(0) );
286  // M_exporterSolid->addVariable( ExporterData<FSIOperator::mesh_Type>::VectorField, "s-ws",
287  // M_fsi->FSIOper()->dFESpacePtr(), M_WS, UInt(0) );
288 
289 
290 
291  // M_data->dataFluid()->dataTime()->setInitialTime( M_Tstart );
292  M_data->dataFluid()->dataTime()->setInitialTime ( M_data->dataFluid()->dataTime()->initialTime() );
293  M_data->dataFluid()->dataTime()->setTime ( M_data->dataFluid()->dataTime()->initialTime() );
294  // M_data->dataSolid()->dataTime()->setInitialTime( M_Tstart );
295  M_data->dataSolid()->dataTime()->setTime ( M_data->dataFluid()->dataTime()->initialTime() );
296  M_data->dataSolid()->dataTime()->setInitialTime ( M_data->dataFluid()->dataTime()->initialTime() );
297  // M_data->dataALE()->setInitialTime( M_Tstart );
298  M_data->timeDataALE()->setInitialTime ( M_data->dataFluid()->dataTime()->initialTime() );
299  M_data->timeDataALE()->setTime ( M_data->dataFluid()->dataTime()->initialTime() );
300  }
301 
302  /*!
303  This routine runs the temporal loop
304  */
305  void
306  run()
307  {
308  boost::timer _overall_timer;
309 
310  LifeV::UInt iter = 1;
311  LifeV::UInt offset = dynamic_cast<LifeV::FSIMonolithic*> (M_fsi->FSIOper().get() )->offset();
312 
313  //This part is to have the pillow saving Paolo T.
314  LifeV::UInt r (0);
315  LifeV::UInt d (0);
316  //This is the size of the TimeAdvaces classes. It uses the size of the solid.
317  //It could be changed and it's better to set it up as the highest size of TA
318  LifeV::UInt sizeTA (M_fsi->FSIOper()->solidTimeAdvance()->size() );
319  LifeV::UInt tol (sizeTA + M_tol);
320 
321 
322  dynamic_cast<LifeV::FSIMonolithic*> (M_fsi->FSIOper().get() )->enableStressComputation (1);
323 
324  // #ifdef HAVE_HDF5
325  // if (M_exporterFluid->mapType() == LifeV::Unique)
326  // {
327  // M_exporterFluid->postProcess( M_Tstart-M_data->dataFluid()->dataTime()->getTimeStep() );//ugly way to avoid that hdf5 starts with a deformed mesh
328  // M_exporterSolid->postProcess( M_Tstart-M_data->dataSolid()->dataTime()->getTimeStep() );//ugly way to avoid that hdf5 starts with a deformed mesh
329  // }
330  // #endif
331 
332  for ( ; M_data->dataFluid()->dataTime()->canAdvance(); M_data->dataFluid()->dataTime()->updateTime(), M_data->dataSolid()->dataTime()->updateTime(), ++iter)
333  {
334  boost::timer _timer;
335 
336  // if(iter%M_saveEvery==0)
337  // {
338  // M_fsi->FSIOper()->exportSolidDisplacement(*M_solidDisp);// displacement(), M_offset);
339  // //M_fsi->FSIOper()->exportSolidVelocity(*M_solidVel);// displacement(), M_offset);
340 
341  // M_fsi->FSIOper()->exportFluidVelocityAndPressure(*M_velAndPressure);
342  // M_exporterSolid->postProcess( M_data->dataFluid()->dataTime()->time() );
343 
344  // //*M_WS= *(dynamic_cast<LifeV::FSIMonolithic*>(M_fsi->FSIOper().get())->/*WS());//*/computeStress());
345 
346  // *M_fluidDisp = M_fsi->FSIOper()->meshDisp();
347  // M_exporterFluid->postProcess( M_data->dataFluid()->dataTime()->time() );
348  // }
349 
350  r = iter % M_saveEvery;
351  d = iter - r;
352 
353  if ( (iter - d) <= tol || ( (std::floor (d / M_saveEvery) + 1) *M_saveEvery - iter ) <= tol )
354  {
355  *M_fluidDisp = M_fsi->FSIOper()->meshDisp();
356  M_fsi->FSIOper()->exportSolidDisplacement (*M_solidDisp); // displacement(), M_offset);
357  //M_fsi->FSIOper()->exportSolidVelocity(*M_solidVel);// displacement(), M_offset);
358  M_fsi->FSIOper()->exportFluidVelocityAndPressure (*M_velAndPressure);
359 
360  M_exporterSolid->postProcess ( M_data->dataFluid()->dataTime()->time() );
361  M_exporterFluid->postProcess ( M_data->dataFluid()->dataTime()->time() );
362  }
363 
364  M_fsi->iterate();
365 
366 
367  M_fsi->FSIOper()->displayer().leaderPrintMax ("[fsi_run] Iteration ", iter);
368  M_fsi->FSIOper()->displayer().leaderPrintMax (" was done in : ", _timer.elapsed() );
369 
370  // std::cout << "solution norm " << iter << " : "
371  // << M_fsi->displacement().norm2() << "\n";
372 
373  }
374  if (M_data->method().compare ("monolithicGI") )
375  {
376  vectorPtr_Type solution ( new vector_Type ( (*M_fsi->FSIOper()->couplingVariableMap() ) ) );
377  M_fsi->FSIOper()->extrapolation ( *solution );
378  M_fsi->FSIOper()->iterateMesh (*solution);
379 
380  M_solidDisp->subset (*solution, offset);
381  // M_solidVel->subset(M_fsi->FSIOper()->solid().velocity(), offset);
382  // *M_solidDisp *= 1/(M_fsi->FSIOper()->solid().rescaleFactor()*M_data->dataFluid()->dataTime()->getTimeStep());
383  // *M_solidVel *= 1/(M_fsi->FSIOper()->solid().rescaleFactor()*M_data->dataFluid()->dataTime()->getTimeStep());
384 
385  *M_velAndPressure = *solution;
386  M_exporterSolid->postProcess ( M_data->dataFluid()->dataTime()->time() );
387  *M_fluidDisp = M_fsi->FSIOper()->meshMotion().disp();
388  M_exporterFluid->postProcess ( M_data->dataFluid()->dataTime()->time() );
389  }
390 
391  std::cout << "Total computation time = "
392  << _overall_timer.elapsed() << "s" << "\n";
393  }
394 
395 private:
396 
397  void initializeStokes ( GetPot const& data_file);
398  void restartFSI ( GetPot const& data_file);
399 
400  FSISolverPtr_Type M_fsi;
401  dataPtr_Type M_data;
402 
403  filterPtr_Type M_exporterSolid;
404  filterPtr_Type M_exporterFluid;
405  filterPtr_Type M_importerSolid;
406  filterPtr_Type M_importerFluid;
407  vectorPtr_Type M_velAndPressure;
408  vectorPtr_Type M_fluidDisp;
409  vectorPtr_Type M_solidDisp;
410 
411  std::vector<vectorPtr_Type> M_solidStencil;
412  std::vector<vectorPtr_Type> M_fluidStencil;
413  std::vector<vectorPtr_Type> M_ALEStencil;
414 
415  //vectorPtr_Type M_solidVel;
416  LifeV::Real M_Tstart;
417  // vectorPtr_Type M_WS;
418  LifeV::UInt M_saveEvery;
419  LifeV::UInt M_tol;
420 
421  struct RESULT_CHANGED_EXCEPTION
422  {
423  public:
424  RESULT_CHANGED_EXCEPTION (LifeV::Real time)
425  {
426  std::cout << "Some modifications led to changes in the l2 norm of the solution at time" << time << std::endl;
427  }
428  };
429 };
430 
432 {
433  FSIChecker ( GetPot const& _data_file ) :
435  {}
436 
437  void operator() ()
438  {
439  std::shared_ptr<Problem> fsip;
440 
441  try
442  {
443  fsip = std::shared_ptr<Problem> ( new Problem ( data_file ) );
444 
445  fsip->run();
446  }
447  catch ( std::exception const& _ex )
448  {
449  std::cout << "caught exception : " << _ex.what() << "\n";
450  }
451 
452  }
453 
455  LifeV::Vector disp;
456 };
457 
458 
459 
460 namespace LifeV
461 {
462 namespace
463 {
464 static bool regIF = (PRECFactory::instance().registerProduct ( "Ifpack", &createIfpack ) );
465 static bool regML = (PRECFactory::instance().registerProduct ( "ML", &createML ) );
466 }
467 }
468 
469 
470 int main (int argc, char** argv)
471 {
472 #ifdef HAVE_MPI
473  MPI_Init (&argc, &argv);
474 #else
475  std::cout << "% using serial Version" << std::endl;
476 #endif
477 
478  GetPot command_line (argc, argv);
479  const bool check = command_line.search (2, "-c", "--check");
480 
481  if (check)
482  {
483  GetPot data_fileGCE ("dataGCE");
484  FSIChecker _GCE_check ( data_fileGCE );
485  _GCE_check();
486 
487  GetPot data_fileCE ("dataCE");
488  FSIChecker _CE_check (data_fileCE);
489  _CE_check();
490 
491 #ifdef HAVE_MPI
492  MPI_Finalize();
493 #endif
494  return 0;
495  }
496  else
497  {
498  const std::string data_file_name = command_line.follow ("data", 2, "-f", "--file");
499  GetPot data_file (data_file_name);
500  FSIChecker _sp_check ( data_file );
501  _sp_check();
502  }
503 #ifdef HAVE_MPI
504  MPI_Finalize();
505 #endif
506 
507  return 0;
508 
509 }
510 
511 void Problem::restartFSI ( GetPot const& data_file)
512 {
513 
514  using namespace LifeV;
515 
516  typedef FSIOperator::mesh_Type mesh_Type;
517 
518  //Creating the pointer to the filter
519  std::string const importerType = data_file ( "importer/type", "ensight");
520  std::string const fluidName = data_file ( "importer/fluid/filename", "fluid");
521  std::string const solidName = data_file ( "importer/solid/filename", "solid");
522 
523  std::string const loadInitSol = data_file ( "importer/initSol", "00000");
524  std::string const loadInitSolFD = data_file ("importer/initSolFD", "-1");
525  std::string iterationString;
526 
527  M_Tstart = data_file ( "fluid/time_discretization/initialtime", 0.);
528 
529  std::cout << "The file for fluid is : " << fluidName << std::endl;
530  std::cout << "The file for solid is : " << solidName << std::endl;
531  std::cout << "The importerType is : " << importerType << std::endl;
532  std::cout << "The iteration is : " << loadInitSol << std::endl;
533  std::cout << "For the fluid disp is : " << loadInitSolFD << std::endl;
534  std::cout << "Starting time : " << M_Tstart << std::endl;
535 
536 #ifdef HAVE_HDF5
537  if (importerType.compare ("hdf5") == 0)
538  {
539  M_importerFluid.reset ( new hdf5Filter_Type ( data_file, fluidName) );
540  M_importerSolid.reset ( new hdf5Filter_Type ( data_file, solidName) );
541  }
542  else
543 #endif
544  {
545  if (importerType.compare ("none") == 0)
546  {
547  M_importerFluid.reset ( new ExporterEmpty<mesh_Type > ( data_file, M_fsi->FSIOper()->uFESpace().mesh(), "fluid", M_fsi->FSIOper()->uFESpace().map().comm().MyPID() ) );
548  M_importerSolid.reset ( new ExporterEmpty<mesh_Type > ( data_file, M_fsi->FSIOper()->dFESpace().mesh(), "solid", M_fsi->FSIOper()->uFESpace().map().comm().MyPID() ) );
549  }
550  else
551  {
552  M_importerFluid.reset ( new ensightFilter_Type ( data_file, fluidName) );
553  M_importerSolid.reset ( new ensightFilter_Type ( data_file, solidName) );
554  }
555  }
556 
557  M_importerFluid->setMeshProcId (M_fsi->FSIOper()->uFESpace().mesh(), M_fsi->FSIOper()->uFESpace().map().comm().MyPID() );
558  M_importerSolid->setMeshProcId (M_fsi->FSIOper()->dFESpace().mesh(), M_fsi->FSIOper()->dFESpace().map().comm().MyPID() );
559 
560  //Each of the vectors of the stencils has the dimension of the big vector
561  //Performing a cycle of the size of the timeAdvance classes for each problem
562  //The size of TimeAdvanceClass depends on the order of the BDF (data file)
563 
564  //It should work just initializing the timeAdvance classes
565  //Three stencils are needed (Fluid-Structure-Geometric)
566 
567 
568  vectorPtr_Type fluidSol (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique) );
569  vectorPtr_Type initFluid (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique, Zero) );
570  vectorPtr_Type HarmonicSol (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique, Zero) );
571  vectorPtr_Type structureSol (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique, Zero) );
572  vectorPtr_Type temporarySol (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique, Zero) );
573 
574  vectorPtr_Type vel (new vector_Type (M_fsi->FSIOper()->uFESpace().map(), M_importerFluid->mapType() ) );
575  vectorPtr_Type pressure (new vector_Type (M_fsi->FSIOper()->pFESpace().map(), M_importerFluid->mapType() ) );
576  vectorPtr_Type solidDisp (new vector_Type (M_fsi->FSIOper()->dFESpace().map(), M_importerSolid->mapType() ) );
577  vectorPtr_Type fluidDisp (new vector_Type (M_fsi->FSIOper()->mmFESpace().map(), M_importerFluid->mapType() ) );
578 
579  vectorPtr_Type firstFluidDisp (new vector_Type (M_fsi->FSIOper()->mmFESpace().map(), M_importerFluid->mapType() ) );
580 
581  UInt offset = dynamic_cast<LifeV::FSIMonolithic*> (M_fsi->FSIOper().get() )->offset();
582 
583  iterationString = loadInitSol;
584  std::cout << "Fluid size TimeAdvance:" << M_fsi->FSIOper()->fluidTimeAdvance()->size() << std::endl;
585  for (UInt iterInit = 0; iterInit < M_fsi->FSIOper()->fluidTimeAdvance()->size(); iterInit++ )
586  {
587 
588  /*!
589  definition of the vector to fill with the initialization.
590  */
591  temporarySol.reset (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique, Zero) );
592  fluidSol.reset (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique) );
593  initFluid.reset (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique, Zero) );
594 
595 
596  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 );
597  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 );
598 
599  /*!load of the solutions*/
600  M_importerFluid->readVariable (initSolFluidVel);
601  M_importerFluid->readVariable (initSolFluidPress);
602 
603  fluidSol.reset ( new vector_Type (*pressure, Unique, Zero) );
604  initFluid->subset (*fluidSol, fluidSol->map(), UInt (0), (UInt) 3 * M_fsi->FSIOper()->uFESpace().dof().numTotalDof() );
605  vector_Type tmpVec (*initFluid);
606  //temporarySol->subset(*fluidSol, fluidSol->map(), UInt(0), (UInt)3*M_fsi->FSIOper()->uFESpace().dof().numTotalDof());
607  fluidSol.reset ( new vector_Type (*vel, Unique, Zero) );
608  tmpVec = *fluidSol;
609  *initFluid += tmpVec;
610 
611  // std::string firstFl="firstFluid";
612  // initFluid->spy(firstFl);
613 
614  std::cout << "Norm of first Fluid sol: " << initFluid->norm2() << std::endl;
615  *temporarySol = *initFluid;
616 
617  // if(!iterInit)
618  // {
619  // *un += *temporarySol;
620  // }
621 
622  M_fluidStencil.push_back (temporarySol);
623  //Updating string name
624  int iterations = std::atoi (iterationString.c_str() );
625  iterations--;
626 
627  std::ostringstream iter;
628  iter.fill ( '0' );
629  iter << std::setw (5) << ( iterations );
630  iterationString = iter.str();
631 
632  }
633 
634  iterationString = loadInitSol;
635  for (UInt iterInit = 0; iterInit < M_fsi->FSIOper()->solidTimeAdvance()->size(); iterInit++ )
636  {
637  /*!
638  definition of the vector to fill with the initialization.
639  */
640  temporarySol.reset (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique, Zero) );
641  structureSol.reset (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique, Zero) );
642 
643 
644  /*!Definition of the ExporterData, used to load the solution inside the previously defined vectors*/
645  LifeV::ExporterData<mesh_Type> initSolSolidDisp (LifeV::ExporterData<mesh_Type>::VectorField, "s-displacement." + iterationString, M_fsi->FSIOper()->dFESpacePtr(), solidDisp, UInt (0) /*offset*/, LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
646 
647  /*!load of the solutions*/
648  M_importerSolid->readVariable (initSolSolidDisp);
649 
650  structureSol->subset (*solidDisp, solidDisp->map(), (UInt) 0, offset);
651 
652  *temporarySol = *structureSol / (M_fsi->FSIOper()->solid().rescaleFactor() );
653 
654  M_solidStencil.push_back (temporarySol);
655 
656  //Updating the string name for the next iteration
657  UInt iterations = std::atoi (iterationString.c_str() );
658  iterations--;
659 
660  std::ostringstream iter;
661  iter.fill ( '0' );
662  iter << std::setw (5) << ( iterations );
663  iterationString = iter.str();
664 
665  }
666 
667  Int convectiveTerm = 0; //loadInitSol;
668  if (!M_data->dataFluid()->domainVelImplicit() )
669  {
670  convectiveTerm = 1;
671  }
672  HarmonicSol.reset (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique, Zero) );
673 
674  iterationString = loadInitSolFD;
675 
676  for (UInt iterInit = 0; iterInit < M_fsi->FSIOper()->ALETimeAdvance()->size() + convectiveTerm + 1; iterInit++ )
677  {
678  temporarySol.reset (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV:: Unique, Zero) );
679  /*!
680  definition of the vector to fill with the initialization.
681  */
682 
683  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 );
684 
685  /*!load of the solutions*/
686  M_importerFluid->readVariable (initSolFluidDisp);
687 
688  std::cout << "Reloaded Harmonic sol norm: " << fluidDisp->norm2() << std::endl;
689  if (iterInit == 0)
690  {
691  HarmonicSol->subset (*fluidDisp, fluidDisp->map(), (UInt) 0, dynamic_cast<LifeV::FSIMonolithicGI*> (M_fsi->FSIOper().get() )->mapWithoutMesh().map (Unique)->NumGlobalElements() );
692  if (!convectiveTerm)
693  {
694  *firstFluidDisp = *fluidDisp;
695  }
696  }
697  else if (convectiveTerm && iterInit == 1)
698  {
699  *firstFluidDisp = *fluidDisp;
700  }
701  else
702  {
703  M_ALEStencil.push_back (/*temporarySol*/fluidDisp);
704  }
705  //Updating the iteration String name
706  int iterations = std::atoi (iterationString.c_str() );
707  iterations--;
708 
709  std::ostringstream iter;
710  iter.fill ( '0' );
711  iter << std::setw (5) << ( iterations );
712  iterationString = iter.str();
713  }
714 
715  *M_fluidStencil[0] += *M_solidStencil[0];
716  *M_fluidStencil[0] += *HarmonicSol;
717  //this is going to be the global solutions returned by the method solution()
718 
719  M_fsi->initialize (M_fluidStencil, M_solidStencil, M_ALEStencil);
720 
721  if (!M_data->dataFluid()->domainVelImplicit() )
722  {
723  //The following is needed because (and if) of the extrapolation of the fluid domain velocity is used, i.e. M_domainVelImplicit
724  M_fsi->FSIOper()->ALETimeAdvance()->updateRHSFirstDerivative ( M_data->dataSolid()->dataTime()->timeStep() );
725  M_fsi->FSIOper()->ALETimeAdvance()->shiftRight (*firstFluidDisp);
726  }
727 
728  M_velAndPressure.reset ( new vector_Type ( M_fsi->FSIOper()->fluid().getMap(), M_importerFluid->mapType() ) );
729  M_velAndPressure->subset (*pressure, pressure->map(), UInt (0), (UInt) 3 * M_fsi->FSIOper()->uFESpace().dof().numTotalDof() );
730  *M_velAndPressure += *vel;
731 
732  M_fluidDisp.reset ( new vector_Type ( *fluidDisp, M_importerFluid->mapType() ) );
733 
734  M_solidDisp.reset ( new vector_Type ( *solidDisp, M_importerSolid->mapType() ) );
735 
736  M_data->dataFluid()->dataTime()->updateTime(), M_data->dataSolid()->dataTime()->updateTime();
737 }
738 
739 
740 void Problem::initializeStokes ( GetPot const& data_file)
741 {
742 
743  using namespace LifeV;
744 
745  typedef FSIOperator::mesh_Type mesh_Type;
746 
747 
748  //Creating the pointer to the filter
749  filterPtr_Type importer;
750  std::string const importerType = data_file ( "importer/type", "hdf5");
751  std::string const filename = data_file ( "importer/fluid/filename", "fluid");
752 
753  std::string const loadInitSol = data_file ( "importer/initSol", "00000");
754  std::string const loadInitSolFD = data_file ("importer/initSolFD", "-1");
755  std::string iterationString;
756 
757  std::cout << "The filename is : " << filename << std::endl;
758  std::cout << "The importerType is: " << importerType << std::endl;
759 
760 #ifdef HAVE_HDF5
761  if (importerType.compare ("hdf5") == 0)
762  {
763  importer.reset ( new hdf5Filter_Type ( data_file, filename) );
764  }
765  else
766 #endif
767  {
768  if (importerType.compare ("none") == 0)
769  {
770  importer.reset ( new ExporterEmpty<RegionMesh<LinearTetra> > ( data_file, M_fsi->FSIOper()->uFESpace().mesh(), "fluid", M_fsi->FSIOper()->uFESpace().map().comm().MyPID() ) );
771  }
772  else
773  {
774  importer.reset ( new ensightFilter_Type ( data_file, filename) );
775  }
776  }
777 
778  importer->setMeshProcId (M_fsi->FSIOper()->uFESpace().mesh(), M_fsi->FSIOper()->uFESpace().map().comm().MyPID() );
779 
780 
781  std::vector<vectorPtr_Type> fluidStencil;;
782 
783  vectorPtr_Type temporarySol (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), LifeV::Unique) );
784 
785  //UInt offset=dynamic_cast<LifeV::FSIMonolithic*>(M_fsi->FSIOper().get())->offset();
786 
787  iterationString = loadInitSol;
788  for (UInt iterInit = 0; iterInit < M_fsi->FSIOper()->fluidTimeAdvance()->size(); ++iterInit )
789  {
790 
791  /*!
792  definition of the vector to fill with the initialization.
793  */
794  temporarySol.reset (new vector_Type (*M_fsi->FSIOper()->couplingVariableMap(), Unique) );
795 
796  vectorPtr_Type vel (new vector_Type (M_fsi->FSIOper()->uFESpace().map(), M_importerFluid->mapType() ) );
797  vectorPtr_Type pressure (new vector_Type (M_fsi->FSIOper()->pFESpace().map(), M_importerFluid->mapType() ) );
798 
799  *vel *= 0.0;
800  *pressure *= 0.0;
801 
802  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 );
803  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 );
804 
805  /*!load of the solutions*/
806  importer->readVariable (initSolFluidVel);
807  importer->readVariable (initSolFluidPress);
808 
809  int iterations = std::atoi (iterationString.c_str() );
810  iterations--;
811 
812  std::ostringstream iter;
813  iter.fill ( '0' );
814  iter << std::setw (5) << ( iterations );
815  iterationString = iter.str();
816 
817  *temporarySol = *vel + *pressure;
818  fluidStencil.push_back (temporarySol);
819  }
820 
821  // M_fsi->initialize(fluidStencil);
822 
823 }
int main(int argc, char **argv)
GetPot(const int argc_, char **argv_, const char *FieldSeparator=0x0)
Definition: GetPot.hpp:507
FSIChecker(GetPot const &_data_file)
GetPot(const char *FileName, const char *CommentStart=0x0, const char *CommentEnd=0x0, const char *FieldSeparator=0x0)
Definition: GetPot.hpp:541
bool search(unsigned No, const char *P,...)
Definition: GetPot.hpp:1217
GetPot(const STRING_VECTOR &FileNameList)
Definition: GetPot.hpp:645
const std::string follow(const char *Default, unsigned No, const char *Option,...)
Definition: GetPot.hpp:1510