LifeV
lifev/fsi/testsuite/fsi_segregated/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
30 
31  * The time discretization is carried out using BDF methods of order 2. At the moment, even is the Newmark method is available
32  * for the temporal discretization of the single problems( e.g. in test_structuralsolver), it cannot be used in the FSI framework
33  * since the class TimeAdvanceNewmark is not registered as one of the possible instances of the abstrac class TimeAdvance.
34  @author
35  @date 00-00-0000
36 */
37 
38 
39 #ifdef TWODIM
40 #error test_fsi cannot be compiled in 2D
41 #endif
42 
43 #include <boost/timer.hpp>
44 
45 #include <cassert>
46 #include <iomanip>
47 #include <cmath>
48 
49 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
50 #include <lifev/core/algorithm/PreconditionerML.hpp>
51 #include <lifev/core/LifeV.hpp>
52 #include <lifev/core/util/LifeChrono.hpp>
53 
54 #include <lifev/fsi/solver/FSISolver.hpp>
55 #include <lifev/fsi/solver/FSIOperator.hpp>
56 #include <lifev/fsi/solver/FSIExactJacobian.hpp>
57 #include <lifev/fsi/solver/FSIFixedPoint.hpp>
58 #include <lifev/fsi/solver/FSIData.hpp>
59 #include <lifev/structure/solver/StructuralOperator.hpp>
60 #include <lifev/structure/solver/StructuralConstitutiveLaw.hpp>
61 #include <lifev/structure/solver/isotropic/VenantKirchhoffMaterialNonLinear.hpp>
62 #include <lifev/structure/solver/isotropic/VenantKirchhoffMaterialLinear.hpp>
63 
64 #include <lifev/core/filter/ExporterHDF5.hpp>
65 #include <lifev/core/filter/ExporterEnsight.hpp>
66 
67 
68 #include <Epetra_ConfigDefs.h>
69 #ifdef EPETRA_MPI
70 #include <mpi.h>
71 #include <Epetra_MpiComm.h>
72 #else
73 #include <Epetra_SerialComm.h>
74 #endif
75 
76 
77 #include "ud_functions.hpp"
79 
80 
81 namespace LifeV
82 {
83 namespace
84 {
85 static bool regIF = PRECFactory::instance().registerProduct ( "Ifpack", &createIfpack );
86 static bool regML = PRECFactory::instance().registerProduct ( "ML", &createML );
87 static bool regFP = FSIOperator::FSIFactory_Type::instance().registerProduct ( "fixedPoint", &createFP );
88 static bool regEJ = FSIOperator::FSIFactory_Type::instance().registerProduct ( "exactJacobian", &createEJ );
89 }
90 }
91 
92 
93 namespace LifeV
94 {
95 namespace
96 {
97 
98 //LifeV::VenantKirchhoffSolver< LifeV::FSIOperator::mesh_Type, LifeV::SolverAztecOO >* createLinearStructure() { return new VenantKirchhoffSolverLinear< LifeV::FSIOperator::mesh_Type, LifeV::SolverAztecOO >(); }
99 
100 
101 
102 //LifeV::StructuralMaterial< LifeV::FSIOperator::mesh_Type >* createVenantKirchhoffLinear() { return new VenantKirchhoffMaterialLinear< LifeV::FSIOperator::mesh_Type >(); }
103 
104 
105 
106 
107 //LifeV::StructuralMaterial< LifeV::FSIOperator::mesh_Type >* createVenantKirchhoffLinear() { return new VenantKirchhoffMaterialLinear< LifeV::FSIOperator::mesh_Type >(); }
108 
109 
110 //LifeV::VenantKirchhoffSolver< LifeV::FSIOperator::mesh_Type, LifeV::SolverAztecOO >* createLinearStructure() {
111 //return new VenantKirchhoffSolverLinear< LifeV::FSIOperator::mesh_Type, LifeV::SolverAztecOO >();
112 //}
113 
114 
115 //NOTE: the nonlinear structure solver is still in development in the FSI framework
116 //LifeV::VenantKirchhofSolver< LifeV::FSI::mesh_Type, LifeV::SolverAztecOO >* createNonLinearStructure(){ return new NonLinearVenantKirchhofSolver< LifeV::FSI::mesh_Type, LifeV::SolverAztecOO >(); }
117 }
118 }
119 
120 using namespace LifeV;
121 
122 int returnValue = EXIT_SUCCESS; // For the final check
123 
124 
125 
126 #define PI 3.141592653589793
128 {
129 public:
130 
131  bc_adaptor ( FSIOperator& Operator ) :
132  M_oper ( Operator )
133  {
134  Real area0 = 0.7854;
135  //Real area0 = M_oper.fluid().area(3);
136  Real area = area0;
137  UInt flag = M_oper.dataSolid()->vectorFlags() [0];
138 
139  Real beta = M_oper.solid().thickness() * M_oper.solid().young ( flag ) /
140  (1 - M_oper.solid().poisson ( flag ) * M_oper.solid().poisson ( flag ) ) * PI / area0;
141 
142  Real qn = M_oper.fluid().flux (3);
143 
144  M_outflow = std::pow (std::sqrt (M_oper.solid().rho() ) / (2 * std::sqrt (2.) ) * qn / area + std::sqrt (beta * std::sqrt (area0) ), 2) - beta * std::sqrt (area0);
145 
146  std::cout << "--------------- Absorbing boundary condition ---------------" << std::endl;
147  std::cout << " Outflow BC : density = " << M_oper.solid().rho() << std::endl;
148  std::cout << " Outflow BC : thickness = " << M_oper.solid().thickness() << std::endl;
149  std::cout << " Outflow BC : young = " << M_oper.solid().young ( flag ) << std::endl;
150  std::cout << " Outflow BC : poisson = " << M_oper.solid().poisson ( flag ) << std::endl;
151  std::cout << " Outflow BC : area0 = " << area0 << std::endl;
152  std::cout << " Outflow BC : area = " << M_oper.fluid().area (3) << std::endl;
153  std::cout << " Outflow BC : radius = " << std::sqrt (area0 / PI) << std::endl;
154  std::cout << " Outflow BC : beta = " << beta << std::endl;
155  std::cout << " Outflow BC : Flow rate = " << qn << std::endl;
156  std::cout << " Outflow BC : outflow = " << M_outflow << std::endl;
157  std::cout << "------------------------------------------------------------" << std::endl;
158  }
159 
160  Real operator() ( Real /*t*/, Real /*x*/, Real /*y*/, Real /*z*/, ID id)
161  {
162  switch ( id )
163  {
164  case 0:
165  return 0.;
166  break;
167 
168  case 1:
169  return 0.;
170  break;
171 
172  case 2:
173  //return 0.;
174  return -M_outflow;
175  break;
176 
177  default:
178  ERROR_MSG ("This entrie is not allowed: disp_adatptor");
179  break;
180  }
181 
182  return 0.;
183  }
184 
185 private:
186 
187  FSIOperator& M_oper;
189 };
190 
192 {
193 public:
194 
195  bc_adaptorFace ( FSIOperator& Operator ) :
196  M_oper ( Operator )
197  {
198  Real area0 = 0.147439938;
199  //Real area = area0;
200  UInt flag = 1;
201 
202  //Real beta = M_oper.solid().thickness()*M_oper.solid().young() / (1 - M_oper.solid().poisson()*M_oper.solid().poisson()) * PI/area0;
203  //Alexandra's Abc
204  Real exp = 5 / 4;
205  Real beta = ( std::sqrt (PI) * M_oper.solid().thickness() * M_oper.solid().young ( flag ) ) / (1 - M_oper.solid().poisson ( flag ) * M_oper.solid().poisson ( flag ) );
206  Real R = ( std::sqrt (M_oper.solid().rho( ) * beta ) ) / ( std::sqrt (2.0) * std::pow (area0, exp) );
207 
208  Real qn = M_oper.fluid().flux (3);
209 
210  M_outflowFace = R * qn;
211  //M_outflowFace = std::pow(std::sqrt(M_oper.solid().rho())/(2*std::sqrt(2.))*qn/area + std::sqrt(beta*std::sqrt(area0)), 2)- beta*std::sqrt(area0);
212 
213  std::cout << "--------------- Absorbing boundary condition for Face-------" << std::endl;
214  std::cout << " Outflow BC : density = " << M_oper.solid().rho() << std::endl;
215  std::cout << " Outflow BC : thickness = " << M_oper.solid().thickness() << std::endl;
216  std::cout << " Outflow BC : young = " << M_oper.solid().young ( flag ) << std::endl;
217  std::cout << " Outflow BC : poisson = " << M_oper.solid().poisson ( flag ) << std::endl;
218  std::cout << " Outflow BC : area0 = " << area0 << std::endl;
219  std::cout << " Outflow BC : area = " << M_oper.fluid().area (3) << std::endl;
220  std::cout << " Outflow BC : radius = " << std::sqrt (area0 / PI) << std::endl;
221  std::cout << " Outflow BC : beta = " << beta << std::endl;
222  std::cout << " Outflow BC : Flow rate = " << qn << std::endl;
223  std::cout << " Outflow BC : outflow = " << M_outflowFace << std::endl;
224  std::cout << "------------------------------------------------------------" << std::endl;
225 
226  }
227 
228  Real operator() ( Real /*t*/, Real /*x*/, Real /*y*/, Real /*z*/, ID id)
229  {
230  switch ( id )
231  {
232  case 0:
233  return 0.155851 * M_outflowFace;
234  break;
235 
236  case 1:
237  return -0.987781 * M_outflowFace;
238  break;
239 
240  case 2:
241  //return 0.;
242  return 9.02676e-06 * M_outflowFace;
243  break;
244 
245  default:
246  ERROR_MSG ("This entrie is not allowed: disp_adatptor");
247  break;
248  }
249 
250  return 0.;
251  }
252 
253 private:
254 
255  FSIOperator& M_oper;
257 };
258 
259 
261 {
262 public:
263 
264  bc_adaptorBrain ( FSIOperator& Operator ) :
265  M_oper ( Operator )
266  {
267  Real area0 = 0.191155176;
268  //Real area = area0;
269  UInt flag = 1 ;
270 
271  //Real beta = M_oper.solid().thickness()*M_oper.solid().young() / (1 - M_oper.solid().poisson()*M_oper.solid().poisson()) * PI/area0;
272 
273  //Alexandra's Abc
274  Real exp = 5 / 4;
275  Real beta = ( std::sqrt (PI) * M_oper.solid().thickness() * M_oper.solid().young ( flag ) ) / (1 - M_oper.solid().poisson ( flag ) * M_oper.solid().poisson ( flag ) );
276  Real R = ( std::sqrt (M_oper.solid().rho( ) * beta ) ) / ( std::sqrt (2.0) * std::pow (area0, exp) );
277 
278  Real qn = M_oper.fluid().flux (4);
279 
280  M_outflowBrain = R * qn;
281  //M_outflowBrain = std::pow(std::sqrt(M_oper.solid().rho())/(2*std::sqrt(2.))*qn/area + std::sqrt(beta*std::sqrt(area0)), 2) - beta*std::sqrt(area0);
282 
283 
284  std::cout << "--------------- Absorbing boundary condition for Brain-------" << std::endl;
285  std::cout << " Outflow BC : density = " << M_oper.solid().rho() << std::endl;
286  std::cout << " Outflow BC : thickness = " << M_oper.solid().thickness() << std::endl;
287  std::cout << " Outflow BC : young = " << M_oper.solid().young ( flag ) << std::endl;
288  std::cout << " Outflow BC : poisson = " << M_oper.solid().poisson ( flag ) << std::endl;
289  std::cout << " Outflow BC : area0 = " << area0 << std::endl;
290  std::cout << " Outflow BC : area = " << M_oper.fluid().area (4) << std::endl;
291  std::cout << " Outflow BC : radius = " << std::sqrt (area0 / PI) << std::endl;
292  std::cout << " Outflow BC : beta = " << beta << std::endl;
293  std::cout << " Outflow BC : Flow rate = " << qn << std::endl;
294  std::cout << " Outflow BC : outflow = " << M_outflowBrain << std::endl;
295  std::cout << "------------------------------------------------------------" << std::endl;
296  }
297 
298  Real operator() ( Real /*t*/, Real /*x*/, Real /*y*/, Real /*z*/, ID id)
299  {
300  switch ( id )
301  {
302  case 0:
303  return -0.0979856 * M_outflowBrain;
304  break;
305 
306  case 1:
307  return -0.995188 * M_outflowBrain;
308  break;
309 
310  case 2:
311  return -3.13375e-05 * M_outflowBrain;
312  break;
313 
314  default:
315  ERROR_MSG ("This entrie is not allowed: disp_adatptor");
316  break;
317  }
318 
319  return 0.;
320  }
321 
322 private:
323 
324  FSIOperator& M_oper;
326 };
327 
328 
329 
330 
331 class Problem
332 {
333 public:
334 
336  typedef FSIOperator::data_Type data_Type;
337  typedef FSIOperator::dataPtr_Type dataPtr_Type;
338 
339  typedef FSIOperator::vector_Type vector_Type;
340  typedef FSIOperator::vectorPtr_Type vectorPtr_Type;
341  typedef FSIOperator::mesh_Type mesh_Type;
342 
343  typedef Exporter<FSIOperator::mesh_Type> filter_type;
345 
346  typedef FESpace<FSIOperator::mesh_Type, MapEpetra> feSpace_Type;
348 
349  /*!
350  This routine sets up the problem:
351 
352  -# create the standard boundary conditions for the fluid and
353  structure problems.
354 
355  -# initialize and setup the FSIsolver
356  */
357  Problem ( const std::string& dataFileName, std::string method = "" )
358  {
359 
360  //VenantKirchhoffSolver< FSIOperator::mesh_Type, SolverAztecOO >::StructureSolverFactory::instance().registerProduct( "linearVenantKirchhoff", &createLinearStructure );
361 
362 
363  //StructuralSolver< FSIOperator::mesh_Type, SolverAztecOO >::material_Type::StructureMaterialFactory::instance().registerProduct( "linearVenantKirchhoff", &createVenantKirchhoffLinear );
364 
365  StructuralOperator< FSIOperator::mesh_Type>();
366 
367  //StructuralSolver< FSIOperator::mesh_Type, SolverAztecOO >::material_Type::StructureMaterialFactory::instance().registerProduct( "linearVenantKirchhoff", &createVenantKirchhoffLinear );
368 
369  // VenantKirchhofSolver< FSIOperator::mesh_Type, SolverAztecOO >::StructureSolverFactory::instance().registerProduct( "nonLinearVenantKirchhoff", &createNonLinearStructure );
370 
371  debugStream ( 10000 ) << "Setting up data from GetPot \n";
372  GetPot dataFile ( dataFileName );
373  M_data = dataPtr_Type ( new data_Type() );
374  M_data->setup ( dataFile );
375  M_data->dataSolid()->setTimeData ( M_data->dataFluid()->dataTime() ); //Same TimeData for fluid & solid
376  M_data->showMe();
377  // M_data->dataSolid()->showMe();
378  MPI_Barrier ( MPI_COMM_WORLD );
379 
380  debugStream ( 10000 ) << "creating FSISolver with operator : " << method << "\n";
381  M_fsi = fsi_solver_ptr ( new FSISolver( ) );
382  M_fsi->setData ( M_data );
383  M_fsi->FSIOper()->setDataFile ( dataFile ); //TO BE REMOVED!
384  MPI_Barrier ( MPI_COMM_WORLD );
385 
386  // Setting FESpace and DOF
387  debugStream ( 10000 ) << "Setting up the FESpace and DOF \n";
388  M_fsi->FSIOper( )->partitionMeshes( );
389  M_fsi->FSIOper()->setupFEspace();
390  M_fsi->FSIOper()->setupDOF();
391  MPI_Barrier ( MPI_COMM_WORLD );
392 
393  debugStream ( 10000 ) << "Setting up the BC \n";
394  M_fsi->setFluidBC (BCh_fluid (*M_fsi->FSIOper() ) );
395  M_fsi->setHarmonicExtensionBC ( BCh_harmonicExtension (*M_fsi->FSIOper() ) );
396  M_fsi->setSolidBC (BCh_solid (*M_fsi->FSIOper() ) );
397  M_fsi->setLinFluidBC (BCh_fluidLin (*M_fsi->FSIOper() ) );
398  M_fsi->setLinSolidBC (BCh_solidLin (*M_fsi->FSIOper() ) );
399 
400  M_absorbingBC = dataFile ("fluid/absorbing_bc", false);
401  std::cout << " absorbing BC = " << M_absorbingBC << std::endl;
402 
403  MPI_Barrier ( MPI_COMM_WORLD );
404 
405  debugStream ( 10000 ) << "Setting up the problem \n";
406  M_fsi->setup( );
407 
408  //M_fsi->resetFSISolvers();
409 
410  MPI_Barrier ( MPI_COMM_WORLD );
411 
412  std::string const exporterType = dataFile ( "exporter/type", "hdf5");
413  std::string const exporterName = dataFile ( "exporter/name", "fixedPt");
414 
415  debugStream ( 10000 ) << "Setting up ExporterEnsight \n";
416  if ( M_fsi->isFluid() )
417  {
418 #ifdef HAVE_HDF5
419  if (exporterType.compare ("hdf5") == 0)
420  {
421  M_exporterFluid.reset ( new ExporterHDF5<mesh_Type > ( dataFile, exporterName + "Fluid" ) );
422  }
423  else
424 #endif
425  M_exporterFluid.reset ( new ExporterEnsight<mesh_Type > ( dataFile, exporterName + "Fluid" ) );
426 
427  M_exporterFluid->setMeshProcId (M_fsi->FSIOper()->uFESpace().mesh(), M_fsi->FSIOper()->uFESpace().map().comm().MyPID() );
428 
429  M_velAndPressure.reset ( new vector_Type ( M_fsi->FSIOper()->fluid().getMap(), M_exporterFluid->mapType() ) );
430  M_fluidDisp.reset ( new vector_Type ( M_fsi->FSIOper()->meshMotion().getMap(), M_exporterFluid->mapType() ) );
431 
432  M_exporterFluid->addVariable ( ExporterData<mesh_Type>::VectorField, "f-velocity",
433  M_fsi->FSIOper()->uFESpacePtr(), M_velAndPressure, UInt (0) );
434 
435  M_exporterFluid->addVariable ( ExporterData<mesh_Type>::ScalarField, "f-pressure",
436  M_fsi->FSIOper()->pFESpacePtr(), M_velAndPressure,
437  UInt (3 * M_fsi->FSIOper()->uFESpace().dof().numTotalDof() ) );
438 
439  M_exporterFluid->addVariable ( ExporterData<mesh_Type>::VectorField, "f-displacement",
440  M_fsi->FSIOper()->mmFESpacePtr(), M_fluidDisp, UInt (0) );
441  }
442  if ( M_fsi->isSolid() )
443  {
444 #ifdef HAVE_HDF5
445  if (exporterType.compare ("hdf5") == 0)
446  {
447  M_exporterSolid.reset ( new ExporterHDF5<mesh_Type > ( dataFile, exporterName + "Solid" ) );
448  }
449  else
450 #endif
451  M_exporterSolid.reset ( new ExporterEnsight<mesh_Type > ( dataFile, exporterName + "Solid" ) );
452 
453  M_exporterSolid->setMeshProcId (M_fsi->FSIOper()->dFESpace().mesh(), M_fsi->FSIOper()->dFESpace().map().comm().MyPID() );
454  M_solidDisp.reset ( new vector_Type ( M_fsi->FSIOper()->solid().map(), M_exporterSolid->mapType() ) );
455  M_solidVel.reset ( new vector_Type ( M_fsi->FSIOper()->solid().map(), M_exporterSolid->mapType() ) );
456 
457  M_exporterSolid->addVariable ( ExporterData<mesh_Type>::VectorField, "s-displacement",
458  M_fsi->FSIOper()->dFESpacePtr(), M_solidDisp, UInt (0) );
459  M_exporterSolid->addVariable ( ExporterData<mesh_Type>::VectorField, "s-velocity",
460  M_fsi->FSIOper()->dFESpacePtr(), M_solidVel, UInt (0) );
461 
462  }
463 
464  std::cout << "XXX10" << std::endl;
465 
466  bool restart = dataFile ("problem/restart", false);
467  M_Tstart = 0.;
468  if ( restart )
469  {
470  std::string velFName = dataFile ("fluid/miscellaneous/velname" , "vel");
471  std::string pressName = dataFile ("fluid/miscellaneous/pressname", "press");
472  std::string velwName = dataFile ("fluid/miscellaneous/velwname", "velw");
473  std::string depName = dataFile ("solid/miscellaneous/depname" , "dep");
474  std::string velSName = dataFile ("solid/miscellaneous/velname" , "velw");
475  M_Tstart = dataFile ("problem/initialtime" , 0.);
476  std::cout << "Starting time = " << M_Tstart << std::endl;
477 
478  //M_fsi->initialize(velFName, pressName, velwName, depName, velSName, M_Tstart);
479 
480  if ( M_fsi->isFluid() )
481  {
482  M_exporterFluid->import (M_Tstart, M_data->dataFluid()->dataTime()->timeStep() );
483  M_fsi->FSIOper()->initializeFluid ( *M_velAndPressure, *M_fluidDisp );
484  }
485  if ( M_fsi->isSolid() )
486  {
487  M_exporterSolid->import (M_Tstart, M_data->dataSolid()->dataTime()->timeStep() );
488  M_fsi->FSIOper()->initializeSolid ( M_solidDisp, M_solidVel );
489  }
490  }
491  else
492  {
493  M_fsi->initialize();
494  }
495  std::cout << "XXX11" << std::endl;
496  M_data->dataFluid()->dataTime()->setInitialTime ( M_Tstart ); //+ M_data->dataFluid()->dataTime()->timeStep()
497  M_data->dataFluid()->dataTime()->setTime ( M_Tstart );
498  //std::cout << "in problem" << std::endl;
499  //M_fsi->FSIOper()->fluid().postProcess();
500  std::cout << "XXX12" << std::endl;
501  }
502 
504  {
505  return M_fsi;
506  }
507 
508  dataPtr_Type fsiData()
509  {
510  return M_data;
511  }
512 
513  /*!
514  This routine runs the temporal loop
515  */
516  void run()
517  {
518  std::cout << "XXX15" << std::endl;
519  std::ofstream ofile;
520 
521  bool const isFluidLeader ( M_fsi->FSIOper()->isFluid() && M_fsi->FSIOper()->isLeader() );
522  if ( isFluidLeader )
523  {
524  ofile.open ( "fluxes.res" );
525  }
526 
527  boost::timer _overall_timer;
528 
529  Real flux;
530  int _i = 1;
531  std::cout << "XXX16" << std::endl;
532 
533  for ( ; M_data->dataFluid()->dataTime()->canAdvance(); M_data->dataFluid()->dataTime()->updateTime(), ++_i )
534  {
535  boost::timer _timer;
536 
537  if ( M_absorbingBC && M_fsi->isFluid() )
538  {
539  std::cout << "XXX17" << std::endl;
540 
541  BCFunctionBase outFlow;
542  outFlow.setFunction (bc_adaptor (*M_fsi->FSIOper() ) );
543  std::cout << "XXX18" << std::endl;
544  //M_fsi->FSIOper()->BCh_fluid()->modifyBC (3, outFlow);
545  std::cout << "XXX19" << std::endl;
546 
547  /*
548  BCFunctionBase outFlowFace;
549  BCFunctionBase outFlowBrain;
550 
551  outFlowFace.setFunction(bc_adaptorFace(*M_fsi->FSIOper()));
552  M_fsi->FSIOper()->BCh_fluid()->modifyBC(3, outFlowFace);
553 
554  outFlowBrain.setFunction(bc_adaptorBrain(*M_fsi->FSIOper()));
555  M_fsi->FSIOper()->BCh_fluid()->modifyBC(4, outFlowBrain);
556  */
557  //std::cout << " F- Pressure = " << outFlow(0., 0., 0., 0., 3) << std::endl;
558  }
559 
560  M_fsi->iterate();
561  std::cout << "XXX20" << std::endl;
562 
563  if ( M_fsi->isFluid() )
564  {
565  if ( isFluidLeader )
566  {
567  ofile << M_data->dataFluid()->dataTime()->time() << " ";
568  }
569 
570  flux = M_fsi->FSIOper()->fluid().flux (2);
571  if ( isFluidLeader )
572  {
573  ofile << flux << " ";
574  }
575 
576  flux = M_fsi->FSIOper()->fluid().flux (3);
577  if ( isFluidLeader )
578  {
579  ofile << flux << " ";
580  }
581 
582  flux = M_fsi->FSIOper()->fluid().pressure (2);
583  if ( isFluidLeader )
584  {
585  ofile << flux << " ";
586  }
587 
588  flux = M_fsi->FSIOper()->fluid().pressure (3);
589  if ( isFluidLeader )
590  {
591  ofile << flux << " " << std::endl;
592  }
593 
594  *M_velAndPressure = *M_fsi->FSIOper()->fluid().solution();
595  *M_fluidDisp = M_fsi->FSIOper()->meshMotion().disp();
596  M_exporterFluid->postProcess ( M_data->dataFluid()->dataTime()->time() );
597  }
598 
599  if ( M_fsi->isSolid() )
600  {
601  *M_solidDisp = M_fsi->FSIOper()->solid().displacement();
602  // *M_solidVel = M_fsi->FSIOper()->solid().velocity();
603  *M_solidVel = M_fsi->FSIOper()->solidTimeAdvance()->firstDerivative();
604 
605  M_exporterSolid->postProcess ( M_data->dataFluid()->dataTime()->time() );
606  }
607 
608  std::cout << "[fsi_run] Iteration " << _i << " was done in : " << _timer.elapsed() << "\n";
609 
610  // CHECKING THE RESULTS OF THE TEST AT EVERY TIMESTEP
611  checkResult ( M_data->dataFluid()->dataTime()->time() );
612  }
613  std::cout << "Total computation time = " << _overall_timer.elapsed() << "s" << "\n";
614  ofile.close();
615  }
616 
617 private:
618 
619  void checkResult (const LifeV::Real& time)
620  {
621  /*
622  assert (M_data->dataFluid()->dataTime()->timeStep() == 0.001);
623  double dispNorm (M_fsi->displacement().norm2() );
624 
625  std::cout << "Displ Norm: " << dispNorm << std::endl;
626 
627  const LifeV::Real relTol (5e-3);
628 
629  if ( sameAs (time, 0) && sameAs (dispNorm, 0.0474091, relTol) )
630  {
631  return;
632  }
633  if ( sameAs (time, 0.001) && sameAs (dispNorm, 0.0564487, relTol) )
634  {
635  return;
636  }
637  if ( sameAs (time, 0.002) && sameAs (dispNorm, 0.0618011, relTol) )
638  {
639  return;
640  }
641 
642  throw RESULT_CHANGED_EXCEPTION (time);
643  */
644  }
645 
646  bool sameAs (const LifeV::Real& a, const LifeV::Real& b, const LifeV::Real& relTol = 1e-6)
647  {
648  const LifeV::Real maxAbs (std::max (std::fabs (a), std::fabs (b) ) );
649  if (maxAbs < relTol * relTol)
650  {
651  return true;
652  }
653 
654  return std::fabs (a - b) < relTol * maxAbs;
655  }
656 
658  dataPtr_Type M_data;
660 
662 
665 
666  vectorPtr_Type M_velAndPressure;
667  vectorPtr_Type M_fluidDisp;
668  vectorPtr_Type M_solidDisp;
669  vectorPtr_Type M_solidVel;
670 
671  struct RESULT_CHANGED_EXCEPTION
672  {
673  public:
674  RESULT_CHANGED_EXCEPTION (LifeV::Real time)
675  {
676  std::cout << "Some modifications led to changes in the l2 norm of the solution at time " << time << std::endl;
677  returnValue = EXIT_FAILURE;
678  }
679  };
680 };
681 
682 
683 
684 
685 
686 struct FSIChecker
687 {
688  FSIChecker ( const std::string& dataFileName ) :
690  M_method ()
691  {
692  GetPot dataFile ( dataFileName );
693  M_method = dataFile ( "problem/method", "exactJacobian" );
694  }
695 
696  FSIChecker ( const std::string& dataFileName,
697  const std::string& method ) :
699  M_method ( method )
700  {}
701 
702  void operator() ()
703  {
704  std::shared_ptr<Problem> FSIproblem;
705 
706  try
707  {
708  FSIproblem = std::shared_ptr<Problem> ( new Problem ( M_dataFileName, M_method ) );
709  std::cout << "XXX13" << std::endl;
710  FSIproblem->run();
711  std::cout << "XXX14" << std::endl;
712  }
713  catch ( const std::exception& _ex )
714  {
715  std::cout << "caught exception : " << _ex.what() << "\n";
716  }
717  }
718 
721 };
722 
723 int main ( int argc, char** argv )
724 {
725 #ifdef HAVE_MPI
726  std::cout << "MPI Initialization" << std::endl;
727  MPI_Init ( &argc, &argv );
728 #else
729  std::cout << "Serial Version" << std::endl;
730 #endif
731 
732  LifeChrono chrono;
733  chrono.start();
734 
735  GetPot command_line ( argc, argv );
736  std::string dataFileName = command_line.follow ( "data", 2, "-f", "--file" );
737 
738  /*
739  const bool check = command_line.search(2, "-c", "--check");
740  if (check)
741  {
742  debugStream( 10000 ) << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
743  FSIChecker _ej_check( dataFile, "exactJacobian" );
744 
745  _ej_check();
746 
747  debugStream( 10000 ) << "_ej_disp size : " << static_cast<Real> (_ej_check.disp.size()) << "\n";
748  debugStream( 10000 ) << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
749  debugStream( 10000 ) << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
750  FSIChecker _sp_check( dataFile, "steklovPoincare" );
751 
752  _sp_check();
753 
754  debugStream( 10000 ) << "_fp_disp size : " << static_cast<Real> (_sp_check.disp.size()) << "\n";
755  debugStream( 10000 ) << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
756 
757  Real norm1 = norm_2( _ej_check.disp - _sp_check.disp );
758 
759  std::cout << "norm_2(EJ displacement) = " << norm_2( _ej_check.disp ) << " \n"
760  << "norm_2(SP displacement) = " << norm_2( _sp_check.disp ) << " \n"
761  << "norm_2(displacement error EJ/SP) = " << norm1 << "\n";
762 
763  if (norm1 < 1e-04)
764  returnValue = EXIT_SUCCESS;
765  else
766  returnValue = EXIT_FAILURE;
767  }
768  else
769  {
770 
771  FSIChecker _sp_check( dataFile );
772  _sp_check();
773 
774  returnValue = EXIT_SUCCESS;
775  }
776  */
777 
778  FSIChecker FSIProblem ( dataFileName );
779  std::cout << "XXX2" << std::endl;
780  FSIProblem();
781  std::cout << "XXX3" << std::endl;
782 
783  std::cout << "Total sum up " << chrono.diffCumul() << " s." << std::endl;
784 
785 #ifdef HAVE_MPI
786  std::cout << "MPI Finalization" << std::endl;
787  MPI_Finalize();
788 #endif
789 
790  return returnValue;
791 }
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
double operator()(const char *VarName, const double &Default) const
Definition: GetPot.hpp:2033
LifeV::FactorySingleton< LifeV::Factory< LifeV::FSIOperator, std::string > > FSIFactory_Type
void start()
Start the timer.
Definition: LifeChrono.hpp:93
#define PI
FESpace - Short description here please!
Definition: FESpace.hpp:78
int main(int argc, char **argv)
Real operator()(Real, Real, Real, Real, ID id)
GetPot(const int argc_, char **argv_, const char *FieldSeparator=0x0)
Definition: GetPot.hpp:507
#define debugStream
Definition: LifeDebug.hpp:182
Real operator()(Real, Real, Real, Real, ID id)
std::shared_ptr< FSISolver > fsi_solver_ptr
FSIChecker(const std::string &dataFileName)
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
Problem(const std::string &dataFileName, std::string method="")
Exporter< FSIOperator::mesh_Type > filter_type
uint32_type ID
IDs.
Definition: LifeV.hpp:194
void checkResult(const LifeV::Real &time)
std::shared_ptr< filter_type > filter_ptrtype
bool sameAs(const LifeV::Real &a, const LifeV::Real &b, const LifeV::Real &relTol=1e-6)
FESpace< FSIOperator::mesh_Type, MapEpetra > feSpace_Type
double Real
Generic real data.
Definition: LifeV.hpp:175
Real operator()(Real, Real, Real, Real, ID id)
NdebugStream noDebugStream(int=0, NdebugStream::stprintf=&printf)
Definition: LifeDebug.hpp:183
bool operator()(const char *VarName, bool Default) const
Definition: GetPot.hpp:2008
FSIChecker(const std::string &dataFileName, const std::string &method)
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
std::shared_ptr< feSpace_Type > feSpacePtr_Type