LifeV
FSIHandler.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  @brief Settings - File handling the solution of the FSI problem
29 
30  @author Davide Forti <davide.forti@epfl.ch>
31  @date 28-10-2014
32 
33 @maintainer Simone Deparis <simone.deparis@epfl.ch>
34 */
35 
36 #include <lifev/core/LifeV.hpp>
37 #include <lifev/fsi_blocks/solver/FSIHandler.hpp>
38 
39 namespace LifeV
40 {
41 
42 FSIHandler::FSIHandler( const commPtr_Type& communicator ) :
43 M_comm ( communicator ),
44 M_displayer ( communicator ),
45 M_dt (0.0),
46 M_t_zero (0.0),
47 M_t_end (0.0),
54 M_invOper(),
55 M_useShapeDerivatives( false ),
56 M_printResiduals ( false ),
57 M_printSteps ( false ),
58 M_NewtonIter ( 0 ),
61 M_usePartitionedMeshes ( false ),
63 M_gravity ( 0.0 ),
64 M_considerGravity ( false ),
65 M_moveMesh ( true ),
66 M_nonconforming ( false ),
67 M_lambda_num_structure ( false ),
68 M_precPtrBuilt ( false ),
69 M_linearElasticity ( true ),
70 M_disregardRestart ( false ),
72 M_useBDF ( false )
73 {
74 }
75 
77 {
78 }
79 
80 void
81 FSIHandler::setGravity ( const Real& gravity, const Real& gravity_direction)
82 {
83  M_gravity = gravity;
84  M_gravityDirection = gravity_direction;
85  M_considerGravity = true;
86 }
87 
88 void
89 FSIHandler::setDatafile( const GetPot& dataFile)
90 {
91  M_datafile = dataFile;
93 }
94 
95 void
97 {
98  Teuchos::RCP<Teuchos::ParameterList> solversOptions = Teuchos::getParametersFromXmlFile ("solversOptionsFast.xml");
99  std::string precType = M_datafile ("fluid/preconditionerType", "none");
100  M_prec->setFluidPreconditioner(precType);
101  M_prec->setOptions(*solversOptions);
102  setSolversOptions(*solversOptions);
103 }
104 
105 void
106 FSIHandler::setSolversOptions(const Teuchos::ParameterList& solversOptions)
107 {
108  std::shared_ptr<Teuchos::ParameterList> monolithicOptions;
109  monolithicOptions.reset(new Teuchos::ParameterList(solversOptions.sublist("MonolithicOperator")) );
110  M_pListLinSolver = monolithicOptions;
111 }
112 
113 void
115 {
116  M_fluidMesh.reset ( new mesh_Type ( M_comm ) );
117  M_meshDataFluid.reset( new MeshData ( ) );
118  M_meshDataFluid->setup (M_datafile, "fluid/space_discretization");
119  readMesh (*M_fluidMesh, *M_meshDataFluid);
120  int severityLevelFluid = M_fluidMesh->check(1,true,true);
121 
122  M_displayer.leaderPrintMax ( "\tSeverity Level fluid mesh is: ", severityLevelFluid ) ;
123 
124  M_structureMesh.reset ( new mesh_Type ( M_comm ) );
125  M_meshDataStructure.reset( new MeshData ( ) );
126  M_meshDataStructure->setup (M_datafile, "solid/space_discretization");
127  readMesh (*M_structureMesh, *M_meshDataStructure);
128  int severityLevelSolid = M_structureMesh->check(1,true,true);
129 
130  M_displayer.leaderPrintMax ( "\tSeverity Level solid mesh is: ", severityLevelSolid ) ;
131 
132 }
133 
134 void
136 {
137  M_fluidPartitioner.reset ( new MeshPartitioner< mesh_Type > (M_fluidMesh, M_comm) );
138  M_fluidLocalMesh.reset ( new mesh_Type ( M_comm ) );
139  M_fluidLocalMesh = M_fluidPartitioner->meshPartition();
140 
141  M_structurePartitioner.reset ( new MeshPartitioner< mesh_Type > (M_structureMesh, M_comm) );
142  M_structureLocalMesh.reset ( new mesh_Type ( M_comm ) );
143  M_structureLocalMesh = M_structurePartitioner->meshPartition();
144 }
145 
146 void
148 {
149  const std::string fluidHdf5File (M_datafile ("offlinePartioner/fluidPartitionedMesh", "fluid.h5") );
150  const std::string solidHdf5File (M_datafile ("offlinePartioner/solidPartitionedMesh", "solid.h5") );
151 
152  std::shared_ptr<Epetra_MpiComm> comm = std::dynamic_pointer_cast<Epetra_MpiComm>(M_comm);
153 
154  // Load fluid mesh part from HDF5
155  M_displayer.leaderPrint ( "\tReading the fluid mesh parts\n" ) ;
156  PartitionIO<mesh_Type > partitionIO (fluidHdf5File, comm);
157  partitionIO.read (M_fluidLocalMesh);
158 
159  // Load fluid mesh part from HDF5
160  M_displayer.leaderPrint ( "\tReading the solid mesh parts\n" ) ;
161  PartitionIO<mesh_Type > partitionIOstructure (solidHdf5File, comm);
162  partitionIOstructure.read (M_structureLocalMesh);
163 }
164 
165 void FSIHandler::setup ( )
166 {
167  M_useBDF = M_datafile ( "solid/time_discretization/useBDF", false );
168 
169  M_linearElasticity = M_datafile ( "solid/linear_elasticity", true );
170 
171  M_saveEvery = M_datafile ( "exporter/save_every", 1 );
172 
173  M_disregardRestart = M_datafile ( "exporter/disregardRestart", false );
174 
176 
177  M_usePartitionedMeshes = M_datafile ( "offlinePartioner/readPartitionedMeshes", false );
178 
179  M_restart = M_datafile ( "importer/restart", false );
180 
181  // Fluid
182  M_fluid.reset ( new NavierStokesSolverBlocks ( M_datafile, M_comm ) );
183  M_fluid->setup ( M_fluidLocalMesh );
184 
185  // Temporary fix for Shape derivatives
186  M_fluid->pFESpace()->setQuadRule(M_fluid->uFESpace()->qr());
187 
188  // Structure
189  if ( M_linearElasticity )
190  {
191  M_structure.reset ( new LinearElasticity ( M_comm ) );
192  }
193  else
194  {
195  M_structureNeoHookean.reset ( new NeoHookean ( M_comm ) );
196  }
197 
198  // setup of the structural class
200 
201  // This beacuse the ale solver requires that the FESpace is given from outside
203 
205 
206  M_extrapolateInitialGuess = M_datafile ( "newton/extrapolateInitialGuess", false );
207  M_orderExtrapolationInitialGuess = M_datafile ( "newton/orderExtrapolation", 3 );
208 
209  // Exporters
211 
213 
214  // Setting auxiliary variables for the fluid solver
215  M_fluid->setAlpha(M_fluidTimeAdvance->alpha());
216  M_fluid->setTimeStep(M_dt);
217  M_fluid->buildSystem();
218  M_fluid->setupPostProc();
219 
220  // Ale
221  M_ale.reset( new ALESolver ( *M_aleFESpace, M_comm ) );
222  M_ale->setUp( M_datafile );
223 
224  // Structure
225  if ( M_linearElasticity )
226  {
227  if ( M_useBDF )
228  {
229  M_structure->assemble_matrices(M_dt, M_structureTimeAdvanceBDF->massCoefficient(), M_structureBC, M_useBDF);
230  }
231  else
232  {
233  M_structure->assemble_matrices(M_dt, M_structureTimeAdvance->get_beta(), M_structureBC, M_useBDF);
234  }
235  }
236 
237  // Data needed by the Newton algorithm
238  M_relativeTolerance = M_datafile ( "newton/reltol", 1.e-4);
239  M_absoluteTolerance = M_datafile ( "newton/abstol", 1.e-4);
240  M_etaMax = M_datafile ( "newton/etamax", 1e-4);
241  M_maxiterNonlinear = M_datafile ( "newton/maxiter", 10);
242 
243  M_displayer.leaderPrintMax ( " Maximum Newton iterations = ", M_maxiterNonlinear ) ;
244 
245  M_nonLinearLineSearch = M_datafile ( "newton/NonLinearLineSearch", 0);
246  if (M_comm->MyPID() == 0)
247  {
248  M_out_res.open ("residualsNewton");
249  M_outputLinearIterations.open("linearIterations.dat");
250  M_outputPreconditionerComputation.open("preconditionerComputation.dat");
251  M_outputTimeLinearSolver.open ("solutionLinearSystem.dat");
252  }
253 
254  M_useShapeDerivatives = M_datafile ( "newton/useShapeDerivatives", false);
255  M_subiterateFluidDirichlet = M_datafile ( "fluid/subiterateFluidDirichlet", false);
256 
257  M_printResiduals = M_datafile ( "newton/output_Residuals", false);
258  M_printSteps = M_datafile ( "newton/output_Steps", false);
259 
260  // setting also in the preconditioner if using shape derivatives
261  M_prec->setUseShapeDerivatives(M_useShapeDerivatives);
262 
263  // setting also in the preconditioner if using shape derivatives
264  M_prec->setSubiterateFluidDirichlet(M_subiterateFluidDirichlet);
265 
266  // Solver
267  std::string solverType(M_pListLinSolver->get<std::string>("Linear Solver Type"));
268  M_invOper.reset(Operators::InvertibleOperatorFactory::instance().createObject(solverType));
269  M_invOper->setParameterList(M_pListLinSolver->sublist(solverType));
270 
271  // Preconditioner
272  M_prec->setComm ( M_comm );
273 
274  // Output Files
275  if(M_comm->MyPID()==0)
276  {
277  M_outputTimeStep << std::scientific;
278  M_outputTimeStep.open ("TimeStep.dat" );
279 
280  if (M_printResiduals)
281  M_outputResiduals.open ("Residuals.txt" );
282 
283  if (M_printSteps)
284  M_outputSteps.open ("Steps.txt" );
285  }
286 
287  M_moveMesh = M_datafile ( "fluid/mesh/move_mesh", true);
288 }
289 
291 {
292  // Exporters
293  std::string outputNameFluid = M_datafile ( "exporter/fluid_filename", "fluid");
294  std::string outputNameStructure = M_datafile ( "exporter/structure_filename", "fluid");
295  instantiateExporter(M_exporterFluid, M_fluidLocalMesh, outputNameFluid);
296  instantiateExporter(M_exporterStructure, M_structureLocalMesh, outputNameStructure);
297 
298  M_fluidVelocity.reset ( new VectorEpetra ( M_fluid->uFESpace()->map(), M_exporterFluid->mapType() ) );
299  M_fluidPressure.reset ( new VectorEpetra ( M_fluid->pFESpace()->map(), M_exporterFluid->mapType() ) );
300  M_fluidDisplacement.reset ( new VectorEpetra ( M_aleFESpace->map(), M_exporterFluid->mapType() ) );
301  M_Lagrange.reset ( new VectorEpetra ( M_fluid->uFESpace()->map(), M_exporterFluid->mapType() ) );
302  M_structureDisplacement.reset ( new VectorEpetra ( M_displacementFESpace->map(), M_exporterStructure->mapType() ) );
303  M_structureVelocity.reset ( new VectorEpetra ( M_displacementFESpace->map(), M_exporterStructure->mapType() ) );
304  M_structureAcceleration.reset ( new VectorEpetra ( M_displacementFESpace->map(), M_exporterStructure->mapType() ) );
305 
306  M_fluidVelocity->zero();
307  M_fluidPressure->zero();
308  M_fluidDisplacement->zero();
309  M_Lagrange->zero(); // vector needed for a correct restart of the FSI simulation
310  M_structureDisplacement->zero();
311  M_structureVelocity->zero();
312  M_structureAcceleration->zero();
313 
314  M_exporterFluid->addVariable ( ExporterData<mesh_Type>::VectorField, "f - velocity", M_fluid->uFESpace(), M_fluidVelocity, UInt (0) );
315  M_exporterFluid->addVariable ( ExporterData<mesh_Type>::ScalarField, "f - pressure", M_fluid->pFESpace(), M_fluidPressure, UInt (0) );
316  M_exporterFluid->addVariable ( ExporterData<mesh_Type>::VectorField, "f - displacement", M_aleFESpace, M_fluidDisplacement, UInt (0) );
317  M_exporterFluid->addVariable ( ExporterData<mesh_Type>::VectorField, "f - lagrange", M_fluid->uFESpace(), M_Lagrange, UInt (0) );
318 
319  M_exporterStructure->addVariable ( ExporterData<mesh_Type>::VectorField, "s - displacement", M_displacementFESpace, M_structureDisplacement, UInt (0) );
320  if ( !M_useBDF )
321  {
322  M_exporterStructure->addVariable ( ExporterData<mesh_Type>::VectorField, "s - velocity", M_displacementFESpace, M_structureVelocity, UInt (0) );
323  M_exporterStructure->addVariable ( ExporterData<mesh_Type>::VectorField, "s - acceleration", M_displacementFESpace, M_structureAcceleration, UInt (0) );
324  }
325 }
326 
327 void
328 FSIHandler::instantiateExporter( std::shared_ptr< Exporter<mesh_Type > >& exporter,
329  const meshPtr_Type& localMesh,
330  const std::string& outputName)
331 {
332  std::string const exporterType = M_datafile ( "exporter/type", "ensight");
333 #ifdef HAVE_HDF5
334  if (exporterType.compare ("hdf5") == 0)
335  {
336  exporter.reset ( new ExporterHDF5<mesh_Type > ( M_datafile, outputName ) );
337  exporter->setPostDir ( "./" ); // This is a test to see if M_post_dir is working
338  exporter->setMeshProcId ( localMesh, M_comm->MyPID() );
339  }
340  else if(exporterType.compare ("vtk") == 0)
341 #endif
342  {
343  exporter.reset ( new ExporterVTK<mesh_Type > ( M_datafile, outputName ) );
344  exporter->setPostDir ( "./" ); // This is a test to see if M_post_dir is working
345  exporter->setMeshProcId ( localMesh, M_comm->MyPID() );
346  }
347 }
348 
349 void FSIHandler::setupStructure ( )
350 {
351  const std::string dOrder = M_datafile ( "solid/space_discretization/order", "P2");
352 
353  Real density = M_datafile("solid/physics/density",0.0);
354  Real young = M_datafile("solid/model/young",0.0);
355  Real poisson = M_datafile("solid/model/poisson",0.0);
356 
357  if ( M_linearElasticity )
358  {
359  M_structure->setCoefficients(density, young, poisson);
360 
361  if ( M_datafile("solid/thin_layer/use_thin", false ) && M_datafile("solid/linear_elasticity", true ) )
362  {
363  M_structure->setCoefficientsThinLayer ( M_datafile("solid/thin_layer/density",0.0),
364  M_datafile("solid/thin_layer/young_thin",0.0),
365  M_datafile("solid/thin_layer/poisson_thin",0.0),
366  M_datafile("solid/thin_layer/h_thin",0.0),
367  M_datafile("interface/flag",0.0) );
368  }
369 
370  M_structure->setup(M_structureLocalMesh, dOrder);
371  M_displacementFESpace = M_structure->fespace();
372  M_displacementETFESpace = M_structure->et_fespace();
373  M_displacementFESpaceScalar.reset ( new FESpace_Type (M_structureLocalMesh, dOrder, 1, M_comm) );
374  }
375  else
376  {
377  M_structureNeoHookean->setCoefficients(density, young, poisson);
378  M_structureNeoHookean->setup(M_structureLocalMesh, dOrder);
379  M_displacementFESpace = M_structureNeoHookean->fespace();
380  M_displacementETFESpace = M_structureNeoHookean->et_fespace();
381  M_displacementFESpaceScalar.reset ( new FESpace_Type (M_structureLocalMesh, dOrder, 1, M_comm) );
382  }
383 
384  if ( !M_usePartitionedMeshes )
385  M_displacementFESpaceSerial.reset ( new FESpace_Type (M_structureMesh, dOrder, 3, M_comm) );
386 
387  M_displayer.leaderPrintMax ( " Number of DOFs for the structure = ", M_displacementFESpace->dof().numTotalDof()*3 ) ;
388 
389 }
390 
391 void FSIHandler::createAleFESpace()
392 {
393  const std::string aleOrder = M_datafile ( "ale/space_discretization/order", "P2");
394  M_aleFESpace.reset ( new FESpace_Type (M_fluidLocalMesh, aleOrder, 3, M_comm) );
395  M_displayer.leaderPrintMax ( " Number of DOFs for the ale = ", M_aleFESpace->dof().numTotalDof()*3 ) ;
396 }
397 
398 void FSIHandler::setBoundaryConditions ( const bcPtr_Type& fluidBC,
399  const bcPtr_Type& structureBC,
400  const bcPtr_Type& aleBC )
401 {
402  M_fluidBC.reset ( new BCHandler ( ) );
403  M_fluidBC_residual_natural.reset ( new BCHandler ( ) );
404  M_fluidBC_residual_essential.reset ( new BCHandler ( ) );
405 
406  for ( std::vector<BCBase>::iterator it = fluidBC->begin(); it != fluidBC->end(); it++ )
407  {
408  if ( it->type() > 3 ) // meaning esssential
409  {
410  M_fluidBC->addBC( *it );
411  M_fluidBC_residual_essential->addBC( *it );
412  }
413  else if ( it->type() == 0 ) // meaning natural
414  {
415  M_fluidBC_residual_natural->addBC( *it );
416  }
417  }
418 
419  M_structureBC.reset ( new BCHandler ( ) );
420  M_structureBC_residual_natural.reset ( new BCHandler ( ) );
421  M_structureBC_residual_essential.reset ( new BCHandler ( ) );
422 
423  for ( std::vector<BCBase>::iterator it = structureBC->begin(); it != structureBC->end(); it++ )
424  {
425  if ( it->type() > 3 ) // meaning esssential
426  {
427  M_structureBC->addBC( *it );
428  M_structureBC_residual_essential->addBC( *it );
429  }
430  else if ( it->type() == 0 ) // meaning natural
431  {
432  M_structureBC_residual_natural->addBC( *it );
433  }
434  }
435 
436  M_aleBC.reset ( new BCHandler ( ) );
437  M_aleBC_residual_natural.reset ( new BCHandler ( ) );
438  M_aleBC_residual_essential.reset ( new BCHandler ( ) );
439 
440  for ( std::vector<BCBase>::iterator it = aleBC->begin(); it != aleBC->end(); it++ )
441  {
442  if ( it->type() > 3 ) // meaning esssential
443  {
444  M_aleBC->addBC( *it );
445  M_aleBC_residual_essential->addBC( *it );
446  }
447  else if ( it->type() == 0 ) // meaning natural
448  {
449  M_aleBC_residual_natural->addBC( *it );
450  }
451  }
452 
453  for ( std::vector<BCBase>::iterator it = M_interfaceFluidBC->begin(); it != M_interfaceFluidBC->end(); it++ )
454  {
455  M_aleBC->addBC( *it );
456  }
457 }
458 
459 void FSIHandler::updateBoundaryConditions ( )
460 {
461  M_fluidBC->bcUpdate ( *M_fluid->uFESpace()->mesh(), M_fluid->uFESpace()->feBd(), M_fluid->uFESpace()->dof() );
462  M_structureBC->bcUpdate ( *M_displacementFESpace->mesh(), M_displacementFESpace->feBd(), M_displacementFESpace->dof() );
463  M_aleBC->bcUpdate ( *M_aleFESpace->mesh(), M_aleFESpace->feBd(), M_aleFESpace->dof() );
464  M_aleBC_residual_essential->bcUpdate ( *M_aleFESpace->mesh(), M_aleFESpace->feBd(), M_aleFESpace->dof() );
465  M_aleBC_residual_natural->bcUpdate ( *M_aleFESpace->mesh(), M_aleFESpace->feBd(), M_aleFESpace->dof() );
466 }
467 
468 void FSIHandler::initializeTimeAdvance ( )
469 {
470  // Fluid
471  M_fluidTimeAdvance.reset( new TimeAndExtrapolationHandler ( ) );
472  M_dt = M_datafile("fluid/time_discretization/timestep",0.0);
473  M_t_zero = M_datafile("fluid/time_discretization/initialtime",0.0);
474  M_t_end = M_datafile("fluid/time_discretization/endtime",0.0);
475  M_orderBDF = M_datafile("fluid/time_discretization/BDF_order",2);
476 
477  // Initialize and create objects for the fluid time advance
478  M_fluidTimeAdvance->setBDForder(M_orderBDF);
479  M_fluidTimeAdvance->setMaximumExtrapolationOrder(M_orderBDF);
480  M_fluidTimeAdvance->setTimeStep(M_dt);
481  vector_Type velocityInitial ( M_fluid->uFESpace()->map() );
482  std::vector<vector_Type> initialStateVelocity;
483 
484  // Initialize and create objects for the ALE time advance
485  M_aleTimeAdvance.reset( new TimeAndExtrapolationHandler ( ) );
486  M_aleTimeAdvance->setMaximumExtrapolationOrder(M_orderBDF);
487  M_aleTimeAdvance->setBDForder(M_orderBDF);
488  M_aleTimeAdvance->setTimeStep(M_dt);
489  vector_Type disp_mesh_initial ( M_aleFESpace->map() );
490  std::vector<vector_Type> initialStateALE;
491  std::vector<vector_Type> initialStateSolid;
492 
493  if ( M_useBDF )
494  {
495  M_structureTimeAdvanceBDF.reset ( new BDFSecondOrderDerivative );
496  M_structureTimeAdvanceBDF->setTimeStep(M_dt);
497  M_orderBDFSolid = M_datafile("solid/time_discretization/BDF_order",2);
498  M_structureTimeAdvanceBDF->setBDForder( M_orderBDFSolid );
499  }
500  else
501  {
502  // Structure time advance
503  M_structureTimeAdvance.reset ( new Newmark );
504  M_structureTimeAdvance->set_beta(0.49); // 0.25
505  M_structureTimeAdvance->set_gamma(0.9); // 0.5
506  M_structureTimeAdvance->set_timestep(M_dt);
507  }
508 
509  if ( !M_restart )
510  {
511  // Fluid
512  velocityInitial.zero() ;
513  for ( UInt i = 0; i < M_orderBDF; ++i )
514  initialStateVelocity.push_back(velocityInitial);
515 
516  // ALE
517  disp_mesh_initial.zero() ;
518  for ( UInt i = 0; i < M_orderBDF; ++i )
519  initialStateALE.push_back(disp_mesh_initial);
520 
521  // Solid
522  if ( M_useBDF )
523  {
524  vector_Type ds_initial ( M_displacementFESpace->map() );
525  ds_initial.zero();
526  for ( UInt i = 0; i < (M_orderBDFSolid+1); ++i )
527  initialStateSolid.push_back(ds_initial);
528  }
529  else
530  {
531  vectorPtr_Type ds_initial ( new vector_Type ( M_displacementFESpace->map() ) );
532  vectorPtr_Type vs_initial ( new vector_Type ( M_displacementFESpace->map() ) );
533  vectorPtr_Type as_initial ( new vector_Type ( M_displacementFESpace->map() ) );
534  ds_initial->zero();
535  vs_initial->zero();
536  as_initial->zero();
537  M_structureTimeAdvance->initialize(ds_initial, vs_initial, as_initial);
538  }
539  }
540  else
541  {
542  std::string const importerType = M_datafile ( "importer/type", "hdf5");
543  std::string const fileNameFluid = M_datafile ( "importer/fluid_filename", "SolutionRestarted");
544  std::string const fileNameStructure = M_datafile ( "importer/structure_filename", "SolutionRestarted");
545  std::string const initialLoaded = M_datafile ( "importer/initSol", "NO_DEFAULT_VALUE");
546 
547  M_importerFluid.reset ( new ExporterHDF5<mesh_Type > ( M_datafile, fileNameFluid) );
548  M_importerFluid->setMeshProcId (M_fluid->uFESpace()->mesh(), M_comm->MyPID() );
549 
550  M_importerStructure.reset ( new ExporterHDF5<mesh_Type > ( M_datafile, fileNameStructure) );
551  M_importerStructure->setMeshProcId (M_displacementFESpace->mesh(), M_comm->MyPID() );
552 
553  std::string iterationString;
554  iterationString = initialLoaded;
555 
556  if ( M_useBDF )
557  {
558  for (UInt iterInit = 0; iterInit < (M_orderBDF+1); iterInit++ )
559  {
560  vectorPtr_Type velocityRestart;
561  velocityRestart.reset ( new vector_Type (M_fluid->uFESpace()->map(), Unique ) );
562  velocityRestart->zero();
563 
564  vectorPtr_Type pressureRestart;
565  pressureRestart.reset ( new vector_Type (M_fluid->pFESpace()->map(), Unique ) );
566  pressureRestart->zero();
567 
568  vectorPtr_Type aleRestart;
569  aleRestart.reset ( new vector_Type (M_aleFESpace->map(), Unique ) );
570  aleRestart->zero();
571 
572  vectorPtr_Type lagrangeRestart;
573  lagrangeRestart.reset ( new vector_Type (M_fluid->uFESpace()->map(), Unique ) );
574  lagrangeRestart->zero();
575 
576  vectorPtr_Type structureRestart;
577  structureRestart.reset ( new vector_Type (M_displacementFESpace->map(), Unique ) );
578  structureRestart->zero();
579 
580  LifeV::ExporterData<mesh_Type> velocityReader (LifeV::ExporterData<mesh_Type>::VectorField,
581  std::string ("f - velocity." + iterationString),
582  M_fluid->uFESpace(),
583  velocityRestart,
584  UInt (0),
585  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
586 
587  LifeV::ExporterData<mesh_Type> pressureReader (LifeV::ExporterData<mesh_Type>::ScalarField,
588  std::string ("f - pressure." + iterationString),
589  M_fluid->pFESpace(),
590  pressureRestart,
591  UInt (0),
592  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
593 
594  LifeV::ExporterData<mesh_Type> aleReader (LifeV::ExporterData<mesh_Type>::VectorField,
595  std::string ("f - displacement." + iterationString),
596  M_aleFESpace,
597  aleRestart,
598  UInt (0),
599  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
600 
601  LifeV::ExporterData<mesh_Type> lagrangeReader (LifeV::ExporterData<mesh_Type>::VectorField,
602  std::string ("f - lagrange." + iterationString),
603  M_fluid->uFESpace(),
604  lagrangeRestart,
605  UInt (0),
606  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
607 
608  LifeV::ExporterData<mesh_Type> structureReader(LifeV::ExporterData<mesh_Type>::VectorField,
609  std::string ("s - displacement." + iterationString),
610  M_displacementFESpace,
611  structureRestart,
612  UInt (0),
613  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
614 
615  M_importerFluid->readVariable (velocityReader);
616  M_importerFluid->readVariable (pressureReader);
617  M_importerFluid->readVariable (aleReader);
618  M_importerFluid->readVariable (lagrangeReader);
619  M_importerStructure->readVariable (structureReader);
620 
621  int iterations = std::atoi (iterationString.c_str() );
622 
623  if ( iterInit == 0 )
624  {
625  *M_fluidVelocity = *velocityRestart;
626  *M_fluidPressure = *pressureRestart;
627  *M_fluidDisplacement = *aleRestart;
628  *M_Lagrange = *lagrangeRestart;
629  *M_structureDisplacement = *structureRestart;
630  }
631 
632  if ( M_datafile ( "importer/change_dt", false ) )
633  {
634  Real previousDt = M_datafile ( "importer/previous_dt", 0.0001 );
635  iterations = iterations - M_dt/previousDt;
636  }
637  else
638  {
639  iterations--;
640  }
641 
642  std::ostringstream iter;
643  iter.fill ( '0' );
644  iter << std::setw (5) << ( iterations );
645  iterationString = iter.str();
646 
647  if ( iterInit < M_orderBDFSolid )
648  {
649  initialStateVelocity.push_back(*velocityRestart);
650  initialStateALE.push_back(*aleRestart);
651  }
652  initialStateSolid.push_back(*structureRestart);
653  }
654 
655  std::reverse(initialStateVelocity.begin(),initialStateVelocity.end());
656  std::reverse(initialStateALE.begin(),initialStateALE.end());
657  std::reverse(initialStateSolid.begin(),initialStateSolid.end());
658  }
659  else
660  {
661  for (UInt iterInit = 0; iterInit < M_orderBDF; iterInit++ )
662  {
663  vectorPtr_Type velocityRestart;
664  velocityRestart.reset ( new vector_Type (M_fluid->uFESpace()->map(), Unique ) );
665  velocityRestart->zero();
666 
667  vectorPtr_Type pressureRestart;
668  pressureRestart.reset ( new vector_Type (M_fluid->pFESpace()->map(), Unique ) );
669  pressureRestart->zero();
670 
671  vectorPtr_Type aleRestart;
672  aleRestart.reset ( new vector_Type (M_aleFESpace->map(), Unique ) );
673  aleRestart->zero();
674 
675  vectorPtr_Type lagrangeRestart;
676  lagrangeRestart.reset ( new vector_Type (M_fluid->uFESpace()->map(), Unique ) );
677  lagrangeRestart->zero();
678 
679  vectorPtr_Type structureRestart;
680  structureRestart.reset ( new vector_Type (M_displacementFESpace->map(), Unique ) );
681  structureRestart->zero();
682 
683  vectorPtr_Type structureVelocityRestart;
684  structureVelocityRestart.reset ( new vector_Type (M_displacementFESpace->map(), Unique ) );
685  structureVelocityRestart->zero();
686 
687  vectorPtr_Type structureAccelerationRestart;
688  structureAccelerationRestart.reset ( new vector_Type (M_displacementFESpace->map(), Unique ) );
689  structureAccelerationRestart->zero();
690 
691  LifeV::ExporterData<mesh_Type> velocityReader (LifeV::ExporterData<mesh_Type>::VectorField,
692  std::string ("f - velocity." + iterationString),
693  M_fluid->uFESpace(),
694  velocityRestart,
695  UInt (0),
696  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
697 
698  LifeV::ExporterData<mesh_Type> pressureReader (LifeV::ExporterData<mesh_Type>::ScalarField,
699  std::string ("f - pressure." + iterationString),
700  M_fluid->pFESpace(),
701  pressureRestart,
702  UInt (0),
703  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
704 
705  LifeV::ExporterData<mesh_Type> aleReader (LifeV::ExporterData<mesh_Type>::VectorField,
706  std::string ("f - displacement." + iterationString),
707  M_aleFESpace,
708  aleRestart,
709  UInt (0),
710  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
711 
712  LifeV::ExporterData<mesh_Type> lagrangeReader (LifeV::ExporterData<mesh_Type>::VectorField,
713  std::string ("f - lagrange." + iterationString),
714  M_fluid->uFESpace(),
715  lagrangeRestart,
716  UInt (0),
717  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
718 
719  LifeV::ExporterData<mesh_Type> structureReader(LifeV::ExporterData<mesh_Type>::VectorField,
720  std::string ("s - displacement." + iterationString),
721  M_displacementFESpace,
722  structureRestart,
723  UInt (0),
724  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
725 
726  LifeV::ExporterData<mesh_Type> structureVelocityReader(LifeV::ExporterData<mesh_Type>::VectorField,
727  std::string ("s - velocity." + iterationString),
728  M_displacementFESpace,
729  structureVelocityRestart,
730  UInt (0),
731  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
732 
733  LifeV::ExporterData<mesh_Type> structureAccelerationReader(LifeV::ExporterData<mesh_Type>::VectorField,
734  std::string ("s - acceleration." + iterationString),
735  M_displacementFESpace,
736  structureAccelerationRestart,
737  UInt (0),
738  LifeV::ExporterData<mesh_Type>::UnsteadyRegime );
739 
740 
741  M_importerFluid->readVariable (velocityReader);
742  M_importerFluid->readVariable (pressureReader);
743  M_importerFluid->readVariable (aleReader);
744  M_importerFluid->readVariable (lagrangeReader);
745  M_importerStructure->readVariable (structureReader);
746  M_importerStructure->readVariable (structureVelocityReader);
747  M_importerStructure->readVariable (structureAccelerationReader);
748 
749  int iterations = std::atoi (iterationString.c_str() );
750 
751  if ( iterInit == 0 )
752  {
753  *M_fluidVelocity = *velocityRestart;
754  *M_fluidPressure = *pressureRestart;
755  *M_fluidDisplacement = *aleRestart;
756  *M_Lagrange = *lagrangeRestart;
757  *M_structureDisplacement = *structureRestart;
758  *M_structureVelocity = *structureVelocityRestart;
759  *M_structureAcceleration = *structureAccelerationRestart;
760  }
761 
762  iterations--;
763 
764  std::ostringstream iter;
765  iter.fill ( '0' );
766  iter << std::setw (5) << ( iterations );
767  iterationString = iter.str();
768 
769  initialStateVelocity.push_back(*velocityRestart);
770  initialStateALE.push_back(*aleRestart);
771 
772  if ( iterInit == 0 )
773  {
774  M_structureTimeAdvance->restart(M_structureDisplacement, M_structureVelocity, M_structureAcceleration);
775  }
776  }
777 
778  // For BDF 1 it does not change anything, for BDF2 it is necessary. We do the std::reverse
779  // just to the fluid and ALE stencil because the one of the structure is ordered in the
780  // other way round.
781  std::reverse(initialStateVelocity.begin(),initialStateVelocity.end());
782  std::reverse(initialStateALE.begin(),initialStateALE.end());
783  }
784  }
785 
786  // Fluid
787  M_fluidTimeAdvance->initialize(initialStateVelocity);
788 
789  // ALE
790  M_aleTimeAdvance->initialize(initialStateALE);
791 
792  // Solid - BDF case
793  if ( M_useBDF )
794  {
795  M_structureTimeAdvanceBDF->initialize(initialStateSolid);
796  }
797 
798  // Post-Processing of the initial solution
799  M_exporterFluid->postProcess(M_t_zero);
800  M_exporterStructure->postProcess(M_t_zero);
801 }
802 
803 void FSIHandler::buildInterfaceMaps ()
804 {
805  M_nonconforming = M_datafile("interface/nonconforming", false);
806  M_lambda_num_structure = M_datafile("interface/lambda_num_structure", false);
807  markerID_Type interface = M_datafile("interface/flag", 1);
808  Real tolerance = M_datafile("interface/tolerance", 1.0);
809  Int flag = M_datafile("interface/fluid_vertex_flag", 123);
810  M_useMasses = M_datafile("interface/useMasses", true);
811 
812  M_displayer.leaderPrintMax ( " Flag of the interface = ", interface ) ;
813  M_displayer.leaderPrintMax ( " Tolerance for dofs on the interface = ", tolerance ) ;
814 
815  if ( !M_nonconforming )
816  {
817  if ( !M_usePartitionedMeshes )
818  {
819  M_dofStructureToFluid.reset ( new DOFInterface3Dto3D );
820  M_dofStructureToFluid->setup ( M_fluid->uFESpace()->refFE(), M_fluid->uFESpace()->dof(), M_displacementFESpaceSerial->refFE(), M_displacementFESpaceSerial->dof() );
821  M_dofStructureToFluid->update ( *M_fluid->uFESpace()->mesh(), interface, *M_displacementFESpaceSerial->mesh(), interface, tolerance, &flag);
822  M_localDofMap.reset(new std::map<UInt, UInt> ( M_dofStructureToFluid->localDofMap ( ) ) );
823  M_displacementFESpaceSerial.reset();
824  }
825  else
826  {
827  const std::string interfaceHdf5File (M_datafile ("offlinePartioner/interfacePartitioned", "interface.h5") );
828  std::shared_ptr<Epetra_MpiComm> comm = std::dynamic_pointer_cast<Epetra_MpiComm>(M_comm);
829  DOFInterfaceIO interfaceIO (interfaceHdf5File, comm);
830  interfaceIO.read (M_localDofMap);
831  }
832 
833  createInterfaceMaps ( *M_localDofMap );
834 
835  if ( M_lambda_num_structure )
836  constructInterfaceMap ( *M_localDofMap, M_displacementFESpace->map().map(Unique)->NumGlobalElements()/nDimensions );
837  else
838  constructInterfaceMap ( *M_localDofMap, M_fluid->uFESpace()->map().map(Unique)->NumGlobalElements()/nDimensions );
839 
840  M_displayer.leaderPrintMax ( " Number of DOFs on the interface = ", M_lagrangeMap->mapSize() ) ;
841  }
842  else
843  {
844  M_displayer.leaderPrint ( " Using nonconforming meshes " ) ;
845 
846  // Reading xml parameter file for solver of the interpolation
847  Teuchos::RCP< Teuchos::ParameterList > belosList = Teuchos::rcp ( new Teuchos::ParameterList );
848  belosList = Teuchos::getParametersFromXmlFile ( "SolverParamList_rbf3d.xml" );
849 
850  const std::string uOrder = M_datafile ( "fluid/space_discretization/vel_order", "P1");
851  FESpacePtr_Type fluid_FESpace_whole ( new FESpace_Type ( M_fluidMesh, uOrder, 3, M_comm) );
852 
853  const std::string dOrder = M_datafile ( "solid/space_discretization/order", "P1");
854  FESpacePtr_Type solid_FESpace_whole ( new FESpace_Type ( M_structureMesh, dOrder, 3, M_comm) );
855 
856  vectorPtr_Type fluid_known ( new vector_Type ( M_fluidVelocity->map() ) );
857  vectorPtr_Type structure_known ( new vector_Type ( M_structureDisplacement->map() ) );
858  fluid_known->zero();
859  structure_known->zero();
860 
861  M_FluidToStructureInterpolant.reset( new interpolation_Type);
862  M_FluidToStructureInterpolant->setup(M_datafile, belosList);
863  M_FluidToStructureInterpolant->setMeshSize(MeshUtility::MeshStatistics::computeSize(*M_fluidMesh).maxH);
864  M_FluidToStructureInterpolant->setFlag( M_datafile("interface/flag", 1) );
865  M_FluidToStructureInterpolant->setVectors(fluid_known, structure_known);
866  M_FluidToStructureInterpolant->buildTableDofs_known ( fluid_FESpace_whole );
867  M_FluidToStructureInterpolant->buildTableDofs_unknown ( solid_FESpace_whole );
868  M_FluidToStructureInterpolant->identifyNodes_known ( );
869  M_FluidToStructureInterpolant->identifyNodes_unknown ( );
870  M_FluidToStructureInterpolant->buildKnownInterfaceMap();
871  M_FluidToStructureInterpolant->buildUnknownInterfaceMap();
872  M_FluidToStructureInterpolant->buildOperators();
873  M_FluidToStructureInterpolant->getKnownInterfaceMap(M_fluidInterfaceMap);
874 
875  M_StructureToFluidInterpolant.reset( new interpolation_Type);
876  M_StructureToFluidInterpolant->setup(M_datafile, belosList);
877  M_StructureToFluidInterpolant->setMeshSize(MeshUtility::MeshStatistics::computeSize(*M_structureMesh).maxH);
878  M_StructureToFluidInterpolant->setFlag( M_datafile("interface/flag", 1) );
879  M_StructureToFluidInterpolant->setVectors(structure_known, fluid_known);
880  M_StructureToFluidInterpolant->buildTableDofs_known ( solid_FESpace_whole );
881  M_StructureToFluidInterpolant->buildTableDofs_unknown ( fluid_FESpace_whole );
882  M_StructureToFluidInterpolant->identifyNodes_known ( );
883  M_StructureToFluidInterpolant->identifyNodes_unknown ( );
884  M_StructureToFluidInterpolant->buildKnownInterfaceMap();
885  M_StructureToFluidInterpolant->buildUnknownInterfaceMap();
886  M_StructureToFluidInterpolant->buildOperators();
887  M_StructureToFluidInterpolant->getKnownInterfaceMap(M_structureInterfaceMap);
888 
889  // Getting a scalar map that will be used for the lagrange multipliers
890  M_FluidToStructureInterpolant->getInterpolationOperatorMap( M_lagrangeMapScalar );
891 
892  // Building map for the lagrange multipliers, vectorial
893  M_lagrangeMap.reset ( new MapEpetra ( *M_lagrangeMapScalar ) );
894  *M_lagrangeMap += *M_lagrangeMapScalar;
895  *M_lagrangeMap += *M_lagrangeMapScalar;
896 
897  // Setting the vectors for the numeration of the interface in the fluid and the structure
898  M_FluidToStructureInterpolant->getNumerationInterfaceKnown(M_numerationInterfaceFluid);
899  M_StructureToFluidInterpolant->getNumerationInterfaceKnown(M_numerationInterfaceStructure);
900  }
901 }
902 
903 void FSIHandler::createInterfaceMaps(std::map<ID, ID> const& locDofMap)
904 {
905  std::vector<int> dofInterfaceFluid;
906  dofInterfaceFluid.reserve ( locDofMap.size() );
907 
908  std::map<ID, ID>::const_iterator i;
909 
910  for (UInt dim = 0; dim < nDimensions; ++dim)
911  for ( i = locDofMap.begin(); i != locDofMap.end(); ++i )
912  {
913  dofInterfaceFluid.push_back (i->first + dim * M_fluid->uFESpace()->dof().numTotalDof() );
914  }
915 
916  int* pointerToDofs (0);
917  if (dofInterfaceFluid.size() > 0)
918  {
919  pointerToDofs = &dofInterfaceFluid[0];
920  }
921 
922  M_fluidInterfaceMap.reset ( new MapEpetra ( -1, static_cast<int> (dofInterfaceFluid.size() ), pointerToDofs, M_fluid->uFESpace()->map().commPtr() ) );
923 
924  M_fluid->uFESpace()->map().commPtr()->Barrier();
925 
926  std::vector<int> dofInterfaceSolid;
927  dofInterfaceSolid.reserve ( locDofMap.size() );
928 
929  for (UInt dim = 0; dim < nDimensions; ++dim)
930  for ( i = locDofMap.begin(); i != locDofMap.end(); ++i )
931  {
932  dofInterfaceSolid.push_back (i->second + dim * M_displacementFESpace->dof().numTotalDof() );
933  }
934 
935  pointerToDofs = 0;
936  if (dofInterfaceSolid.size() > 0)
937  {
938  pointerToDofs = &dofInterfaceSolid[0];
939  }
940 
941  M_structureInterfaceMap.reset ( new MapEpetra ( -1, static_cast<int> (dofInterfaceSolid.size() ), pointerToDofs, M_displacementFESpace->map().commPtr() ) );
942 }
943 
944 void FSIHandler::constructInterfaceMap ( const std::map<ID, ID>& locDofMap,
945  const UInt subdomainMaxId )
946 {
947  std::map<ID, ID>::const_iterator ITrow;
948 
949  Int numtasks = M_comm->NumProc();
950  int* numInterfaceDof (new int[numtasks]);
951  int pid = M_comm->MyPID();
952  int numMyElements;
953 
954  if ( M_lambda_num_structure )
955  {
956  numMyElements = M_structureInterfaceMap->map (Unique)->NumMyElements();
957  }
958  else
959  {
960  numMyElements = M_fluidInterfaceMap->map (Unique)->NumMyElements();
961  }
962 
963  numInterfaceDof[pid] = numMyElements;
964 
965  mapPtr_Type subMap;
966 
967  if ( M_lambda_num_structure )
968  {
969  subMap.reset ( new map_Type ( *M_structureInterfaceMap->map (Unique), (UInt) 0, subdomainMaxId) );
970  }
971  else
972  {
973  subMap.reset ( new map_Type (*M_fluidInterfaceMap->map (Unique), (UInt) 0, subdomainMaxId) );
974  }
975 
976  M_numerationInterface.reset (new VectorEpetra (*subMap, Unique) );
977 
978  for (int j = 0; j < numtasks; ++j)
979  {
980  M_comm->Broadcast ( &numInterfaceDof[j], 1, j);
981  }
982 
983  for (int j = numtasks - 1; j > 0 ; --j)
984  {
985  numInterfaceDof[j] = numInterfaceDof[j - 1];
986  }
987  numInterfaceDof[0] = 0;
988  for (int j = 1; j < numtasks ; ++j)
989  {
990  numInterfaceDof[j] += numInterfaceDof[j - 1];
991  }
992 
993  UInt l = 0;
994 
995  if ( M_lambda_num_structure )
996  {
997  Real M_interface = (UInt) M_structureInterfaceMap->map (Unique)->NumGlobalElements() / nDimensions;
998  for (l = 0, ITrow = locDofMap.begin(); ITrow != locDofMap.end() ; ++ITrow)
999  {
1000  if (M_structureInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->second) ) >= 0)
1001  {
1002  (*M_numerationInterface) [ITrow->second ] = l + (int) (numInterfaceDof[pid] / nDimensions);
1003  if ( (int) (*M_numerationInterface) (ITrow->second ) != floor (l + numInterfaceDof[pid] / nDimensions + 0.2) )
1004  {
1005  std::cout << "ERROR! the numeration of the coupling map is not correct" << std::endl;
1006  }
1007  ++l;
1008  }
1009  }
1010 
1011  std::vector<int> couplingVector;
1012  couplingVector.reserve ( (int) (M_structureInterfaceMap->map (Unique)->NumMyElements() ) );
1013 
1014  for (UInt dim = 0; dim < nDimensions; ++dim)
1015  {
1016  for ( ITrow = locDofMap.begin(); ITrow != locDofMap.end() ; ++ITrow)
1017  {
1018  if (M_structureInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->second) ) >= 0)
1019  {
1020  couplingVector.push_back ( (*M_numerationInterface) (ITrow->second ) + dim * M_interface );
1021  }
1022  }
1023  }
1024 
1025  M_lagrangeMap.reset (new MapEpetra (-1, static_cast< Int> ( couplingVector.size() ), &couplingVector[0], M_comm) );
1026  }
1027  else
1028  {
1029  Real M_interface = (UInt) M_fluidInterfaceMap->map (Unique)->NumGlobalElements() / nDimensions;
1030  for (l = 0, ITrow = locDofMap.begin(); ITrow != locDofMap.end() ; ++ITrow)
1031  {
1032  if (M_fluidInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->first) ) >= 0)
1033  {
1034  (*M_numerationInterface) [ITrow->first ] = l + (int) (numInterfaceDof[pid] / nDimensions);
1035  if ( (int) (*M_numerationInterface) (ITrow->first ) != floor (l + numInterfaceDof[pid] / nDimensions + 0.2) )
1036  {
1037  std::cout << "ERROR! the numeration of the coupling map is not correct" << std::endl;
1038  }
1039  ++l;
1040  }
1041  }
1042 
1043  std::vector<int> couplingVector;
1044  couplingVector.reserve ( (int) (M_fluidInterfaceMap->map (Unique)->NumMyElements() ) );
1045 
1046  for (UInt dim = 0; dim < nDimensions; ++dim)
1047  {
1048  for ( ITrow = locDofMap.begin(); ITrow != locDofMap.end() ; ++ITrow)
1049  {
1050  if (M_fluidInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->first) ) >= 0)
1051  {
1052  couplingVector.push_back ( (*M_numerationInterface) (ITrow->first ) + dim * M_interface );
1053  }
1054  }
1055  }
1056 
1057  M_lagrangeMap.reset (new MapEpetra (-1, static_cast< Int> ( couplingVector.size() ), &couplingVector[0], M_comm) );
1058  }
1059 
1060  delete [] numInterfaceDof;
1061 }
1062 
1063 void
1064 FSIHandler::assembleCoupling ( )
1065 {
1066  M_coupling.reset ( new FSIcouplingCE ( M_comm ) );
1067 
1068  if ( M_lambda_num_structure )
1069  {
1070  if ( M_useBDF )
1071  {
1072  M_coupling->setUp ( M_dt, M_structureInterfaceMap->mapSize()/3.0 , M_structureTimeAdvanceBDF->coefficientFirstDerivative(),
1073  M_lagrangeMap, M_fluid->uFESpace(), M_displacementFESpace, M_numerationInterface );
1074  }
1075  else
1076  {
1077  M_coupling->setUp ( M_dt, M_structureInterfaceMap->mapSize()/3.0 , M_structureTimeAdvance->get_beta(), M_structureTimeAdvance->get_gamma(),
1078  M_lagrangeMap, M_fluid->uFESpace(), M_displacementFESpace, M_numerationInterface );
1079  }
1080  }
1081  else
1082  {
1083  if ( M_useBDF )
1084  {
1085  M_coupling->setUp ( M_dt, M_fluidInterfaceMap->mapSize()/3.0 , M_structureTimeAdvanceBDF->coefficientFirstDerivative(),
1086  M_lagrangeMap, M_fluid->uFESpace(), M_displacementFESpace, M_numerationInterface );
1087  }
1088  else
1089  {
1090  M_coupling->setUp ( M_dt, M_fluidInterfaceMap->mapSize()/3.0 , M_structureTimeAdvance->get_beta(), M_structureTimeAdvance->get_gamma(),
1091  M_lagrangeMap, M_fluid->uFESpace(), M_displacementFESpace, M_numerationInterface );
1092  }
1093  }
1094 
1095  M_coupling->buildBlocks ( *M_localDofMap, M_lambda_num_structure, M_useBDF );
1096 }
1097 
1098 void
1099 FSIHandler::buildMonolithicMap ( )
1100 {
1101  // Fluid velocity
1102  M_monolithicMap.reset( new map_Type ( M_fluid->uFESpace()->map() ) );
1103 
1104  // Fluid pressure
1105  *M_monolithicMap += M_fluid->pFESpace()->map();
1106 
1107  // Structure displacement
1108  *M_monolithicMap += M_displacementFESpace->map();
1109 
1110  // Weak stresses
1111  M_displayer.leaderPrintMax ("\nNumber of DOFs of the Lagrange multipliers: ", M_lagrangeMap->map(Unique)->NumGlobalElements());
1112  *M_monolithicMap += *M_lagrangeMap;
1113 
1114  // ALE
1115  *M_monolithicMap += M_aleFESpace->map();
1116 }
1117 
1118 void
1119 FSIHandler::getMatrixStructure ( )
1120 {
1121  M_matrixStructure.reset (new matrix_Type ( M_displacementFESpace->map() ) );
1122 
1123  M_matrixStructure->zero();
1124 
1125  M_interface_mass_structure_robin.reset (new matrix_Type ( M_displacementFESpace->map() ) );
1126  M_interface_mass_structure_robin->zero();
1127 
1128  if ( M_datafile("solid/robin_external_wall", false ) )
1129  {
1130  M_displayer.leaderPrint ("\nUsing Robin BC at the external wall of the structure\n");
1131  Real alpha_robin = M_datafile("solid/robin_elastic", 100000.0 );
1132 
1133  // ASSEMBLE ROBIN BC MATRIX AT THE INTERFACE
1134  QuadratureBoundary myBDQR (buildTetraBDQR (quadRuleTria7pt) );
1135  {
1136  using namespace ExpressionAssembly;
1137  integrate ( boundary (M_displacementETFESpace->mesh(), M_datafile("solid/externalWallFlag", 210 ) ),
1138  myBDQR,
1139  M_displacementETFESpace,
1140  M_displacementETFESpace,
1141  value ( alpha_robin ) * dot(phi_i, phi_j)
1142  )
1143  >>M_interface_mass_structure_robin;
1144  }
1145 
1146  }
1147 
1148  M_interface_mass_structure_robin->globalAssemble();
1149 
1150  *M_matrixStructure += *M_interface_mass_structure_robin;
1151  *M_matrixStructure += *(M_structure->jacobian());
1152 
1153  M_matrixStructure->globalAssemble();
1154 }
1155 
1156 void
1157 FSIHandler::get_structure_coupling_velocities ( )
1158 {
1159  if ( M_useBDF )
1160  {
1161  M_rhsStructureVelocity.reset ( new vector_Type ( M_displacementFESpace->map(), Unique ) );
1162 
1163  M_structureTimeAdvanceBDF->first_der_old_dts( *M_rhsStructureVelocity );
1164 
1165  *M_rhsStructureVelocity *= ( -1.0 / M_dt );
1166 
1167  }
1168  else
1169  {
1170  M_structureTimeAdvance->compute_csi( );
1171 
1172  M_rhsStructureVelocity.reset ( new vector_Type ( M_displacementFESpace->map(), Unique ) );
1173 
1174  M_rhsStructureVelocity->zero();
1175 
1176  *M_rhsStructureVelocity = ( ( M_dt * M_structureTimeAdvance->get_gamma() ) * (*M_structureTimeAdvance->get_csi() ) -
1177  ( M_dt * ( 1.0 - M_structureTimeAdvance->get_gamma() ) ) * ( *M_structureTimeAdvance->old_second_derivative() ) -
1178  *M_structureTimeAdvance->old_first_derivative() );
1179  }
1180 }
1181 
1182 void
1183 FSIHandler::updateRhsCouplingVelocities ( )
1184 {
1185  if ( M_lambda_num_structure )
1186  {
1187  vector_Type lambda (*M_structureInterfaceMap, Unique);
1188  structureToInterface ( lambda, *M_rhsStructureVelocity);
1189  M_rhsCouplingVelocities.reset( new VectorEpetra ( *M_lagrangeMap ) );
1190  M_rhsCouplingVelocities->zero();
1191 
1192  std::map<ID, ID>::const_iterator ITrow;
1193 
1194  UInt interface (M_structureInterfaceMap->mapSize()/3.0 );
1195  UInt totalDofs (M_displacementFESpace->dof().numTotalDof() );
1196 
1197  for (UInt dim = 0; dim < 3; ++dim)
1198  {
1199  for ( ITrow = M_localDofMap->begin(); ITrow != M_localDofMap->end() ; ++ITrow)
1200  {
1201  if (M_structureInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->second ) ) >= 0 )
1202  {
1203  (*M_rhsCouplingVelocities) [ (int) (*M_numerationInterface) [ITrow->second ] + dim * interface ] = lambda ( ITrow->second + dim * totalDofs );
1204  }
1205  }
1206  }
1207  }
1208  else
1209  {
1210  vector_Type lambda (*M_structureInterfaceMap, Unique);
1211  structureToInterface ( lambda, *M_rhsStructureVelocity);
1212  M_rhsCouplingVelocities.reset( new VectorEpetra ( *M_lagrangeMap ) );
1213  M_rhsCouplingVelocities->zero();
1214 
1215  std::map<ID, ID>::const_iterator ITrow;
1216 
1217  UInt interface (M_fluidInterfaceMap->mapSize()/3.0 );
1218  UInt totalDofs (M_displacementFESpace->dof().numTotalDof() );
1219 
1220  for (UInt dim = 0; dim < 3; ++dim)
1221  {
1222  for ( ITrow = M_localDofMap->begin(); ITrow != M_localDofMap->end() ; ++ITrow)
1223  {
1224  if (M_fluidInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->first ) ) >= 0 )
1225  {
1226  (*M_rhsCouplingVelocities) [ (int) (*M_numerationInterface) [ITrow->first ] + dim * interface ] = lambda ( ITrow->second + dim * totalDofs );
1227  }
1228  }
1229  }
1230  }
1231 }
1232 
1233 void
1234 FSIHandler::updateRhsCouplingVelocities_nonconforming ( )
1235 {
1236  // Update known field for the interpolation
1237  M_StructureToFluidInterpolant->updateRhs ( M_rhsStructureVelocity );
1238  M_StructureToFluidInterpolant->interpolate();
1239 
1240  // Get the vector on the fluid interface
1241  M_StructureToFluidInterpolant->getSolutionOnGamma (M_rhsCouplingVelocities);
1242 }
1243 
1244 void
1245 FSIHandler::structureToInterface (vector_Type& VectorOnGamma, const vector_Type& VectorOnStructure)
1246 {
1247  if (VectorOnStructure.mapType() == Repeated)
1248  {
1249  vector_Type const VectorOnStructureUnique (VectorOnStructure, Unique);
1250  structureToInterface (VectorOnGamma, VectorOnStructureUnique);
1251  return;
1252  }
1253  if (VectorOnGamma.mapType() == Repeated)
1254  {
1255  vector_Type VectorOnGammaUn (VectorOnGamma.map(), Unique);
1256  structureToInterface ( VectorOnGammaUn, VectorOnStructure);
1257  VectorOnGamma = VectorOnGammaUn;
1258  return;
1259  }
1260 
1261  MapEpetra subMap (*VectorOnStructure.map().map (Unique), 0, VectorOnStructure.map().map (Unique)->NumGlobalElements() );
1262  vector_Type subVectorOnStructure (subMap, Unique);
1263  subVectorOnStructure.subset (VectorOnStructure, 0);
1264  VectorOnGamma = subVectorOnStructure;
1265 }
1266 
1267 void
1268 FSIHandler::solveFSIproblem ( )
1269 {
1270  LifeChrono iterChrono;
1271  LifeChrono smallThingsChrono;
1272  M_time = M_t_zero + M_dt;
1273 
1274  // Clean unpartitioned mesh
1275  M_fluidMesh.reset();
1276  M_structureMesh.reset();
1277 
1278  // Build monolithic map
1279  buildMonolithicMap ( );
1280 
1281  M_solution.reset ( new VectorEpetra ( *M_monolithicMap ) );
1282  M_solution->zero();
1283 
1284  if ( M_restart )
1285  {
1286  M_solution.reset ( new VectorEpetra ( *M_monolithicMap ) );
1287  M_solution->zero();
1288 
1289  M_solution->subset(*M_fluidVelocity, M_fluid->uFESpace()->map(), 0, 0);
1290  M_solution->subset(*M_fluidPressure, M_fluid->pFESpace()->map(), 0, M_fluid->uFESpace()->map().mapSize());
1291  M_solution->subset(*M_structureDisplacement, M_displacementFESpace->map(), 0, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize());
1292  M_LagrangeRestart.reset( new vector_Type (*M_lagrangeMap, Unique ) );
1293  if ( !M_nonconforming )
1294  {
1295  *M_LagrangeRestart = ( *(M_coupling->fluidVelocityToLambda()) * (*M_Lagrange) );
1296  M_solution->subset(*M_LagrangeRestart, *M_lagrangeMap, 0, M_fluid->uFESpace()->map().mapSize() +
1297  M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize() );
1298  }
1299  else
1300  {
1301  vectorPtr_Type Lagrange ( new vector_Type (*M_lagrangeMap, Unique ) );
1302  M_FluidToStructureInterpolant->restrictOmegaToGamma_Known( M_Lagrange, Lagrange );
1303  *M_LagrangeRestart = *Lagrange;
1304  M_solution->subset(*M_LagrangeRestart, *M_lagrangeMap, 0, M_fluid->uFESpace()->map().mapSize() +
1305  M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize() );
1306  }
1307  M_solution->subset(*M_fluidDisplacement, M_aleFESpace->map(), 0, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize() + M_lagrangeMap->mapSize() );
1308  }
1309 
1310  M_ale->applyBoundaryConditions ( *M_aleBC );
1311 
1312  // Apply boundary conditions for the structure problem (the matrix will not change during the simulation, it is linear elasticity)
1313  if ( M_linearElasticity )
1314  {
1315  getMatrixStructure ( );
1316  M_displayer.leaderPrint ( "\t Set and approximate structure block in the preconditioner.. " ) ;
1317  smallThingsChrono.start();
1318  M_prec->setStructureBlock ( M_matrixStructure );
1319  M_prec->updateApproximatedStructureMomentumOperator ( );
1320  smallThingsChrono.stop();
1321  M_displayer.leaderPrintMax ( "done in ", smallThingsChrono.diff() ) ;
1322  }
1323 
1324  // Set blocks for the preconditioners: geometry
1325  smallThingsChrono.reset();
1326  M_displayer.leaderPrint ( "\t Set and approximate geometry block in the preconditioner... " ) ;
1327  smallThingsChrono.start();
1328  M_prec->setGeometryBlock ( M_ale->matrix() );
1329  M_prec->updateApproximatedGeometryOperator ( );
1330  smallThingsChrono.stop();
1331  M_displayer.leaderPrintMax ( "done in ", smallThingsChrono.diff() ) ;
1332 
1333  if ( M_nonconforming )
1334  {
1335  M_prec->setCouplingOperators_nonconforming(M_FluidToStructureInterpolant, M_StructureToFluidInterpolant, M_lagrangeMap);
1336  if ( M_useMasses)
1337  {
1338  M_displayer.leaderPrint ( "[FSI] - Assemble interface mass of the structure for coupling of stresses\n" ) ;
1339  assembleStructureInterfaceMass ( );
1340  }
1341  }
1342  else
1343  {
1344  // Set the coupling blocks in the preconditioner
1345  M_prec->setCouplingBlocks ( M_coupling->lambdaToFluidMomentum(),
1346  M_coupling->lambdaToStructureMomentum(),
1347  M_coupling->structureDisplacementToLambda(),
1348  M_coupling->fluidVelocityToLambda(),
1349  M_coupling->structureDisplacementToFluidDisplacement() );
1350  }
1351 
1352  M_prec->setMonolithicMap ( M_monolithicMap );
1353 
1354  int time_step_count = 0;
1355 
1356  for ( ; M_time <= M_t_end + M_dt / 2.; M_time += M_dt)
1357  {
1358  if ( M_comm->MyPID()==0 )
1359  {
1360  M_outputLinearIterations << std::endl;
1361  M_outputPreconditionerComputation << std::endl;
1362  M_outputTimeLinearSolver << std::endl;
1363  }
1364 
1365  time_step_count += 1;
1366 
1367  M_displayer.leaderPrint ( "\n-----------------------------------\n" ) ;
1368  M_displayer.leaderPrintMax ( "FSI - solving now for time ", M_time ) ;
1369  M_displayer.leaderPrint ( "\n" ) ;
1370  iterChrono.start();
1371 
1372  updateSystem ( );
1373 
1374  if ( M_extrapolateInitialGuess && M_time == (M_t_zero + M_dt) )
1375  {
1376  M_displayer.leaderPrint ( "FSI - initializing extrapolation of initial guess\n" ) ;
1377  initializeExtrapolation ( );
1378  }
1379 
1380  if ( M_extrapolateInitialGuess )
1381  {
1382  M_displayer.leaderPrint ( "FSI - Extrapolating initial guess for Newton\n" ) ;
1383  M_extrapolationSolution->extrapolate (M_orderExtrapolationInitialGuess, *M_solution);
1384  }
1385 
1386  // Apply current BC to the solution vector
1387  applyBCsolution ( M_solution );
1388 
1389  M_maxiterNonlinear = 10;
1390 
1391  NonLinearRichardson ( *M_solution, *this, M_absoluteTolerance, M_relativeTolerance, M_maxiterNonlinear, M_etaMax, M_nonLinearLineSearch, 0, 2, M_out_res, M_time);
1392 
1393  iterChrono.stop();
1394 
1395  M_displayer.leaderPrint ( "\n" ) ;
1396  M_displayer.leaderPrintMax ( "FSI - timestep solved in ", iterChrono.diff() ) ;
1397  M_displayer.leaderPrint ( "-----------------------------------\n\n" ) ;
1398 
1399  // Writing the norms into a file
1400  if ( M_comm->MyPID()==0 )
1401  {
1402  M_outputTimeStep << M_time << ", " << iterChrono.diff() << std::endl;
1403  }
1404 
1405  iterChrono.reset();
1406 
1407  if ( M_extrapolateInitialGuess )
1408  M_extrapolationSolution->shift(*M_solution);
1409 
1410  // Export the solution obtained at the current timestep
1411  M_fluidVelocity->subset(*M_solution, M_fluid->uFESpace()->map(), 0, 0);
1412  M_fluidPressure->subset(*M_solution, M_fluid->pFESpace()->map(), M_fluid->uFESpace()->map().mapSize(), 0);
1413 
1414  vectorPtr_Type lagrange ( new vector_Type (*M_lagrangeMap, Unique) );
1415  vectorPtr_Type Lagrange;
1416  lagrange->zero();
1417  lagrange->subset(*M_solution, *M_lagrangeMap, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() +
1418  M_displacementFESpace->map().mapSize(), 0);
1419 
1420  if ( !M_nonconforming )
1421  {
1422  *M_Lagrange = ( *(M_coupling->lambdaToFluidMomentum()) * (*lagrange) );
1423  }
1424  else
1425  {
1426 
1427  M_FluidToStructureInterpolant->expandGammaToOmega_Known( lagrange, Lagrange );
1428  *M_Lagrange = *Lagrange;
1429  }
1430 
1431  M_fluidDisplacement->subset(*M_solution, M_aleFESpace->map(), M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize() + M_lagrangeMap->mapSize(), 0);
1432  M_structureDisplacement->subset(*M_solution, M_displacementFESpace->map(), M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize(), 0);
1433 
1434  // Updating all the time-advance objects
1435  M_fluidTimeAdvance->shift(*M_fluidVelocity);
1436 
1437  if ( M_useBDF )
1438  {
1439  M_structureTimeAdvanceBDF->shift(*M_structureDisplacement);
1440  }
1441  else
1442  {
1443  M_structureTimeAdvance->shift(M_structureDisplacement);
1444  }
1445 
1446  M_aleTimeAdvance->shift(*M_fluidDisplacement);
1447 
1448  if ( !M_useBDF )
1449  {
1450  *M_structureVelocity = *M_structureTimeAdvance->old_first_derivative();
1451 
1452  *M_structureAcceleration = *M_structureTimeAdvance->old_second_derivative();
1453  }
1454 
1455  // This part below handles the exporter of the solution.
1456  // In particular, given a number of timesteps at which
1457  // we ask to export the solution (from datafile), here
1458  // the code takes care of exporting the solution also at
1459  // the previous timesteps such that, if later a restart
1460  // of the simulation is performed, it works correctly.
1461 
1462  if ( M_orderBDF == 1 )
1463  {
1464  if ( time_step_count == M_counterSaveEvery )
1465  {
1466  M_exporterFluid->postProcess(M_time);
1467  M_exporterStructure->postProcess(M_time);
1468  M_counterSaveEvery += M_saveEvery;
1469  }
1470  }
1471  else if ( M_orderBDF == 2 )
1472  {
1473  if ( time_step_count == (M_counterSaveEvery-1) && !M_disregardRestart )
1474  {
1475  M_exporterFluid->postProcess(M_time);
1476  M_exporterStructure->postProcess(M_time);
1477  }
1478  else if ( time_step_count == M_counterSaveEvery )
1479  {
1480  M_exporterFluid->postProcess(M_time);
1481  M_exporterStructure->postProcess(M_time);
1482  M_counterSaveEvery += M_saveEvery;
1483  }
1484  }
1485  }
1486 
1487  M_exporterFluid->closeFile();
1488  M_exporterStructure->closeFile();
1489 }
1490 
1491 void
1492 FSIHandler::intializeTimeLoop ( )
1493 {
1494  LifeChrono smallThingsChrono;
1495 
1496  // Clean unpartitioned mesh
1497  M_fluidMesh.reset();
1498  M_structureMesh.reset();
1499 
1500  // Build monolithic map
1501  buildMonolithicMap ( );
1502 
1503  M_solution.reset ( new VectorEpetra ( *M_monolithicMap ) );
1504  M_solution->zero();
1505 
1506  if ( M_restart )
1507  {
1508  M_solution.reset ( new VectorEpetra ( *M_monolithicMap ) );
1509  M_solution->zero();
1510 
1511  M_solution->subset(*M_fluidVelocity, M_fluid->uFESpace()->map(), 0, 0);
1512  M_solution->subset(*M_fluidPressure, M_fluid->pFESpace()->map(), 0, M_fluid->uFESpace()->map().mapSize());
1513  M_solution->subset(*M_structureDisplacement, M_displacementFESpace->map(), 0, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize());
1514  *M_Lagrange = ( *(M_coupling->fluidVelocityToLambda()) * (*M_LagrangeRestart) );
1515  M_solution->subset(*M_fluidDisplacement, M_aleFESpace->map(), 0, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize()+M_displacementFESpace->map().mapSize() + M_lagrangeMap->mapSize() );
1516  }
1517 
1518  // Apply boundary conditions for the ale problem (the matrix will not change during the simulation)
1519  M_ale->applyBoundaryConditions ( *M_aleBC );
1520 
1521  // Apply boundary conditions for the structure problem (the matrix will not change during the simulation, it is linear elasticity)
1522  if ( M_linearElasticity )
1523  {
1524  getMatrixStructure ( );
1525  M_displayer.leaderPrint ( "\t Set and approximate structure block in the preconditioner.. " ) ;
1526  smallThingsChrono.start();
1527  M_prec->setStructureBlock ( M_matrixStructure );
1528  M_prec->updateApproximatedStructureMomentumOperator ( );
1529  smallThingsChrono.stop();
1530  M_displayer.leaderPrintMax ( "done in ", smallThingsChrono.diff() ) ;
1531  }
1532 
1533  // Set blocks for the preconditioners: geometry
1534  smallThingsChrono.reset();
1535  M_displayer.leaderPrint ( "\t Set and approximate geometry block in the preconditioner... " ) ;
1536  smallThingsChrono.start();
1537  M_prec->setGeometryBlock ( M_ale->matrix() );
1538  M_prec->updateApproximatedGeometryOperator ( );
1539  smallThingsChrono.stop();
1540  M_displayer.leaderPrintMax ( "done in ", smallThingsChrono.diff() ) ;
1541 
1542  if ( M_nonconforming )
1543  {
1544  M_prec->setCouplingOperators_nonconforming(M_FluidToStructureInterpolant, M_StructureToFluidInterpolant, M_lagrangeMap);
1545  if ( M_useMasses)
1546  {
1547  M_displayer.leaderPrint ( "[FSI] - Assemble interface mass of the structure for coupling of stresses\n" ) ;
1548  assembleStructureInterfaceMass ( );
1549  }
1550  }
1551  else
1552  {
1553  // Set the coupling blocks in the preconditioner
1554  M_prec->setCouplingBlocks ( M_coupling->lambdaToFluidMomentum(),
1555  M_coupling->lambdaToStructureMomentum(),
1556  M_coupling->structureDisplacementToLambda(),
1557  M_coupling->fluidVelocityToLambda(),
1558  M_coupling->structureDisplacementToFluidDisplacement() );
1559  }
1560 
1561  M_prec->setMonolithicMap ( M_monolithicMap );
1562 }
1563 
1564 void
1565 FSIHandler::solveTimeStep ( )
1566 {
1567  if ( M_comm->MyPID()==0 )
1568  {
1569  M_outputLinearIterations << std::endl;
1570  M_outputPreconditionerComputation << std::endl;
1571  M_outputTimeLinearSolver << std::endl;
1572  }
1573 
1574  M_displayer.leaderPrint ( "\n-----------------------------------\n" ) ;
1575  M_displayer.leaderPrintMax ( "FSI - solving now for time ", M_time ) ;
1576  M_displayer.leaderPrint ( "\n" ) ;
1577  LifeChrono iterChrono;
1578  iterChrono.start();
1579 
1580  updateSystem ( );
1581 
1582  if ( M_extrapolateInitialGuess && M_time == (M_t_zero + M_dt) )
1583  {
1584  M_displayer.leaderPrint ( "FSI - initializing extrapolation of initial guess\n" ) ;
1585  initializeExtrapolation ( );
1586  }
1587 
1588  if ( M_extrapolateInitialGuess )
1589  {
1590  M_displayer.leaderPrint ( "FSI - Extrapolating initial guess for Newton\n" ) ;
1591  M_extrapolationSolution->extrapolate (M_orderExtrapolationInitialGuess, *M_solution);
1592  }
1593 
1594  // Apply current BC to the solution vector
1595  applyBCsolution ( M_solution );
1596 
1597  M_maxiterNonlinear = 10;
1598 
1599  // Using the solution at the previous timestep as initial guess -> TODO: extrapolation
1600  NonLinearRichardson ( *M_solution, *this, M_absoluteTolerance, M_relativeTolerance, M_maxiterNonlinear, M_etaMax,
1601  M_nonLinearLineSearch, 0, 2, M_out_res, M_time);
1602 
1603  iterChrono.stop();
1604  M_displayer.leaderPrint ( "\n" ) ;
1605  M_displayer.leaderPrintMax ( "FSI - timestep solved in ", iterChrono.diff() ) ;
1606  M_displayer.leaderPrint ( "-----------------------------------\n\n" ) ;
1607 
1608  // Writing the norms into a file
1609  if ( M_comm->MyPID()==0 )
1610  {
1611  // M_outputTimeStep << "Time = " << M_time << " solved in " << iterChrono.diff() << " seconds" << std::endl;
1612  M_outputTimeStep << M_time << ", " << iterChrono.diff() << std::endl;
1613  }
1614 
1615  iterChrono.reset();
1616 
1617  if ( M_extrapolateInitialGuess )
1618  M_extrapolationSolution->shift(*M_solution);
1619 
1620  // Export the solution obtained at the current timestep
1621  M_fluidVelocity->subset(*M_solution, M_fluid->uFESpace()->map(), 0, 0);
1622  M_fluidPressure->subset(*M_solution, M_fluid->pFESpace()->map(), M_fluid->uFESpace()->map().mapSize(), 0);
1623  M_Lagrange->subset(*M_solution, *M_lagrangeMap, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() +
1624  M_displacementFESpace->map().mapSize(), 0);
1625  M_fluidDisplacement->subset(*M_solution, M_aleFESpace->map(), M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize() + M_lagrangeMap->mapSize(), 0);
1626  M_structureDisplacement->subset(*M_solution, M_displacementFESpace->map(), M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize(), 0);
1627 
1628  // Updating all the time-advance objects
1629  M_fluidTimeAdvance->shift(*M_fluidVelocity);
1630 
1631  if ( M_useBDF )
1632  {
1633  M_structureTimeAdvanceBDF->shift(*M_structureDisplacement);
1634  }
1635  else
1636  {
1637  M_structureTimeAdvance->shift(M_structureDisplacement);
1638  }
1639 
1640  M_aleTimeAdvance->shift(*M_fluidDisplacement);
1641 
1642  if ( !M_useBDF )
1643  {
1644  *M_structureVelocity = *M_structureTimeAdvance->old_first_derivative();
1645 
1646  *M_structureAcceleration = *M_structureTimeAdvance->old_second_derivative();
1647  }
1648 }
1649 
1650 void
1651 FSIHandler::postprocessResults( const int& time_step_count )
1652 {
1653  if ( M_orderBDF == 1 )
1654  {
1655  if ( time_step_count == M_counterSaveEvery )
1656  {
1657  M_exporterFluid->postProcess(M_time);
1658  M_exporterStructure->postProcess(M_time);
1659  M_counterSaveEvery += M_saveEvery;
1660  }
1661  }
1662  else if ( M_orderBDF == 2 )
1663  {
1664  if ( time_step_count == (M_counterSaveEvery-1) && !M_disregardRestart )
1665  {
1666  M_exporterFluid->postProcess(M_time);
1667  M_exporterStructure->postProcess(M_time);
1668  }
1669  else if ( time_step_count == M_counterSaveEvery )
1670  {
1671  M_exporterFluid->postProcess(M_time);
1672  M_exporterStructure->postProcess(M_time);
1673  M_counterSaveEvery += M_saveEvery;
1674  }
1675  }
1676 }
1677 
1678 void
1679 FSIHandler::finalizeExporters ( )
1680 {
1681  M_exporterFluid->closeFile();
1682  M_exporterStructure->closeFile();
1683 }
1684 
1685 void
1686 FSIHandler::initializeExtrapolation( )
1687 {
1688  // Initialize vector in the extrapolation object for the initial guess of Newton
1689  vector_Type solutionInitial ( *M_monolithicMap );
1690  std::vector<vector_Type> initialStateSolution;
1691  solutionInitial.zero();
1692  for ( UInt i = 0; i < M_orderExtrapolationInitialGuess; ++i )
1693  initialStateSolution.push_back(solutionInitial);
1694 
1695  M_extrapolationSolution.reset( new TimeAndExtrapolationHandler ( ) );
1696  M_extrapolationSolution->setBDForder(M_orderExtrapolationInitialGuess);
1697  M_extrapolationSolution->setMaximumExtrapolationOrder(M_orderExtrapolationInitialGuess);
1698  M_extrapolationSolution->initialize(initialStateSolution);
1699 }
1700 
1701 void
1702 FSIHandler::applyBCsolution(vectorPtr_Type& M_solution)
1703 {
1704  //! Extract each component of the input vector
1705  VectorEpetra velocity(M_fluid->uFESpace()->map(), Unique);
1706  velocity.subset(*M_solution, M_fluid->uFESpace()->map(), 0, 0);
1707 
1708  VectorEpetra displacement(M_displacementFESpace->map(), Unique);
1709  displacement.subset(*M_solution, M_displacementFESpace->map(), M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize(), 0 );
1710 
1711  VectorEpetra geometry(M_aleFESpace->map(), Unique);
1712  geometry.subset(*M_solution, M_aleFESpace->map(), M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() +
1713  M_displacementFESpace->map().mapSize() + M_lagrangeMap->mapSize(), 0 );
1714 
1715  //! Apply BC on each component
1716  if ( !M_fluidBC->bcUpdateDone() )
1717  M_fluidBC->bcUpdate ( *M_fluid->uFESpace()->mesh(), M_fluid->uFESpace()->feBd(), M_fluid->uFESpace()->dof() );
1718 
1719  bcManageRhs ( velocity, *M_fluid->uFESpace()->mesh(), M_fluid->uFESpace()->dof(), *M_fluidBC, M_fluid->uFESpace()->feBd(), 1.0, M_time );
1720 
1721  if ( !M_structureBC->bcUpdateDone() )
1722  M_structureBC->bcUpdate ( *M_displacementFESpace->mesh(), M_displacementFESpace->feBd(), M_displacementFESpace->dof() );
1723 
1724  bcManageRhs ( displacement, *M_displacementFESpace->mesh(), M_displacementFESpace->dof(), *M_structureBC, M_displacementFESpace->feBd(), 1.0, M_time );
1725 
1726  if ( !M_aleBC_residual_essential->bcUpdateDone() )
1727  M_aleBC_residual_essential->bcUpdate ( *M_aleFESpace->mesh(), M_aleFESpace->feBd(), M_aleFESpace->dof() );
1728 
1729  bcManageRhs ( geometry, *M_aleFESpace->mesh(), M_aleFESpace->dof(), *M_aleBC_residual_essential, M_aleFESpace->feBd(), 1.0, M_time );
1730 
1731  //! Push local contributions into the global one
1732  M_solution->subset(velocity, M_fluid->uFESpace()->map(), 0, 0);
1733  M_solution->subset(displacement, M_displacementFESpace->map(), 0, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() );
1734  M_solution->subset(geometry, M_aleFESpace->map(), 0, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() +
1735  M_displacementFESpace->map().mapSize() + M_lagrangeMap->mapSize() );
1736 }
1737 
1738 void
1739 FSIHandler::applyBCresidual(VectorEpetra& r_u, VectorEpetra& r_ds, VectorEpetra& r_df)
1740 {
1741  //! Extract each component of the input vector
1742  VectorEpetra ru_copy(r_u, Unique);
1743  ru_copy *= -1;
1744 
1745  //! Apply BC on each component
1746  if ( !M_fluidBC_residual_natural->bcUpdateDone() )
1747  M_fluidBC_residual_natural->bcUpdate ( *M_fluid->uFESpace()->mesh(), M_fluid->uFESpace()->feBd(), M_fluid->uFESpace()->dof() );
1748 
1749  bcManageRhs ( ru_copy,
1750  *M_fluid->uFESpace()->mesh(),
1751  M_fluid->uFESpace()->dof(),
1752  *M_fluidBC_residual_natural,
1753  M_fluid->uFESpace()->feBd(),
1754  1.0,
1755  M_time );
1756 
1757  ru_copy *= -1;
1758 
1759  if ( !M_fluidBC_residual_essential->bcUpdateDone() )
1760  M_fluidBC_residual_essential->bcUpdate ( *M_fluid->uFESpace()->mesh(), M_fluid->uFESpace()->feBd(), M_fluid->uFESpace()->dof() );
1761 
1762  bcManageRhs ( ru_copy,
1763  *M_fluid->uFESpace()->mesh(),
1764  M_fluid->uFESpace()->dof(),
1765  *M_fluidBC_residual_essential,
1766  M_fluid->uFESpace()->feBd(),
1767  0.0, // Homogeneous condition for Dirichlet type on the residual
1768  M_time );
1769 
1770  r_u.zero();
1771  r_u = ru_copy;
1772 
1773  if ( !M_structureBC_residual_natural->bcUpdateDone() )
1774  M_structureBC_residual_natural->bcUpdate ( *M_displacementFESpace->mesh(), M_displacementFESpace->feBd(), M_displacementFESpace->dof() );
1775 
1776  if ( M_datafile("solid/robin_external_wall", false ) )
1777  {
1778  VectorEpetra rds_robin( M_displacementFESpace->map(), Unique);
1779  rds_robin.zero();
1780  rds_robin = *M_interface_mass_structure_robin * (*M_dsk);
1781  r_ds += rds_robin;
1782  }
1783 
1784  bcManageRhs ( r_ds,
1785  *M_displacementFESpace->mesh(),
1786  M_displacementFESpace->dof(),
1787  *M_structureBC_residual_natural,
1788  M_displacementFESpace->feBd(),
1789  1.0,
1790  M_time );
1791 
1792  if ( !M_structureBC_residual_essential->bcUpdateDone() )
1793  M_structureBC_residual_essential->bcUpdate ( *M_displacementFESpace->mesh(), M_displacementFESpace->feBd(), M_displacementFESpace->dof() );
1794 
1795  bcManageRhs ( r_ds,
1796  *M_displacementFESpace->mesh(),
1797  M_displacementFESpace->dof(),
1798  *M_structureBC_residual_essential,
1799  M_displacementFESpace->feBd(),
1800  0.0, // Homogeneous condition for Dirichlet type on the residual
1801  M_time );
1802 
1803  if ( !M_aleBC_residual_natural->bcUpdateDone() )
1804  M_aleBC_residual_natural->bcUpdate ( *M_aleFESpace->mesh(), M_aleFESpace->feBd(), M_aleFESpace->dof() );
1805 
1806  bcManageRhs ( r_df, *M_aleFESpace->mesh(), M_aleFESpace->dof(), *M_aleBC_residual_natural, M_aleFESpace->feBd(), 1.0, M_time );
1807 
1808  if ( !M_aleBC_residual_essential->bcUpdateDone() )
1809  M_aleBC_residual_essential->bcUpdate ( *M_aleFESpace->mesh(), M_aleFESpace->feBd(), M_aleFESpace->dof() );
1810 
1811  bcManageRhs ( r_df, *M_aleFESpace->mesh(), M_aleFESpace->dof(), *M_aleBC_residual_essential, M_aleFESpace->feBd(), 0.0, M_time );
1812 }
1813 
1814 void
1815 FSIHandler::assembleStructureInterfaceMass()
1816 {
1817  // INITIALIZE MATRIX WITH THE MAP OF THE INTERFACE
1818  matrixPtr_Type structure_interfaceMass( new matrix_Type ( M_displacementFESpace->map(), 50 ) );
1819  structure_interfaceMass->zero();
1820 
1821  // ASSEMBLE MASS MATRIX AT THE INTERFACE
1822  QuadratureBoundary myBDQR (buildTetraBDQR (quadRuleTria7pt) );
1823  {
1824  using namespace ExpressionAssembly;
1825  integrate ( boundary (M_displacementETFESpace->mesh(), M_datafile("interface/flag", 1) ),
1826  myBDQR,
1827  M_displacementETFESpace,
1828  M_displacementETFESpace,
1829  //Boundary Mass
1830  dot(phi_i,phi_j)
1831  )
1832  >> structure_interfaceMass;
1833  }
1834  structure_interfaceMass->globalAssemble();
1835 
1836  mapPtr_Type M_mapStuctureGammaVectorial;
1837  M_StructureToFluidInterpolant->getVectorialInterpolationMap(M_mapStuctureGammaVectorial);
1838 
1839  // RESTRICT MATRIX TO INTERFACE DOFS ONLY
1840  M_interface_mass_structure.reset(new matrix_Type ( *M_mapStuctureGammaVectorial, 50 ) );
1841  structure_interfaceMass->restrict ( M_mapStuctureGammaVectorial, M_numerationInterfaceStructure,
1842  M_structureDisplacement->size()/3, M_interface_mass_structure );
1843 }
1844 
1845 void
1846 FSIHandler::applyInverseFluidMassOnGamma ( const vectorPtr_Type& weakLambda, vectorPtr_Type& strongLambda )
1847 {
1848  Teuchos::RCP< Teuchos::ParameterList > belosList = Teuchos::rcp ( new Teuchos::ParameterList );
1849  belosList = Teuchos::getParametersFromXmlFile ( "SolverParamList_rbf3d.xml" );
1850 
1851  // Preconditioner
1852  if ( !M_precPtrBuilt )
1853  {
1854  prec_Type* precRawPtr;
1855  precRawPtr = new prec_Type;
1856  precRawPtr->setDataFromGetPot ( M_datafile, "prec" );
1857  M_precPtr.reset ( precRawPtr );
1858  M_precPtrBuilt = true;
1859  }
1860 
1861  // Linear Solver
1862  LinearSolver solverOne;
1863  solverOne.setCommunicator ( M_comm );
1864  solverOne.setParameters ( *belosList );
1865  solverOne.setPreconditioner ( M_precPtr );
1866 
1867  // Solution
1868  strongLambda->zero();
1869 
1870  // Solve system
1871  solverOne.setOperator ( M_interface_mass_fluid );
1872  solverOne.setRightHandSide ( weakLambda );
1873  solverOne.solve ( strongLambda );
1874 }
1875 
1876 void
1877 FSIHandler::evalResidual(vector_Type& residual, const vector_Type& solution, const UInt iter_newton)
1878 {
1879  residual.zero();
1880  M_NewtonIter = iter_newton;
1881 
1882  // Create empty vectors to store each component of the FSI residual
1883 
1884  vectorPtr_Type res_u ( new vector_Type ( M_fluid->uFESpace()->map(), Unique ) );
1885  vectorPtr_Type res_p ( new vector_Type ( M_fluid->pFESpace()->map(), Unique ) );
1886  vectorPtr_Type res_ds ( new vector_Type ( M_displacementFESpace->map(), Unique ) );
1887  vectorPtr_Type res_lambda ( new vector_Type ( *M_lagrangeMap, Unique ) );
1888  vectorPtr_Type res_df ( new vector_Type (M_aleFESpace->map(), Unique ) );
1889 
1890  res_u->zero();
1891  res_p->zero();
1892  res_ds->zero();
1893  res_lambda->zero();
1894  res_df->zero();
1895 
1896  // Create empty vectors to store each component of the FSI solution from previous newton step
1897 
1898  vectorPtr_Type u_k ( new vector_Type ( M_fluid->uFESpace()->map() ) );
1899  vectorPtr_Type p_k ( new vector_Type ( M_fluid->pFESpace()->map() ) );
1900  vectorPtr_Type ds_k ( new vector_Type ( M_displacementFESpace->map() ) );
1901  vectorPtr_Type lambda_k ( new vector_Type ( *M_lagrangeMap ) );
1902  vectorPtr_Type df_k ( new vector_Type ( M_aleFESpace->map() ) );
1903 
1904  u_k->zero();
1905  p_k->zero();
1906  ds_k->zero();
1907  lambda_k->zero();
1908  df_k->zero();
1909 
1910  // Copy in the vectors u_k, p_k, ds_k, lambda_k and df_k each component of the solution at the previous newton step k
1911 
1912  u_k->subset (solution, M_fluid->uFESpace()->map(), 0, 0);
1913  p_k->subset (solution, M_fluid->pFESpace()->map(), M_fluid->uFESpace()->map().mapSize(), 0);
1914  ds_k->subset (solution, M_displacementFESpace->map(), M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize(), 0);
1915  lambda_k->subset(solution, *M_lagrangeMap, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize(), 0);
1916  df_k->subset(solution, M_aleFESpace->map(), M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize() + M_lagrangeMap->mapSize(), 0);
1917 
1918  M_dsk.reset( new vector_Type ( *ds_k ) );
1919 
1920  //---------------//
1921  // Move the mesh //
1922  //---------------//
1923 
1924  vectorPtr_Type mmRep ( new vector_Type (*df_k, Repeated ) );
1925  moveMesh ( *mmRep );
1926 
1927  //---------------------------------//
1928  // Compute the fluid mesh velocity //
1929  //---------------------------------//
1930 
1931  vectorPtr_Type meshVelocity ( new vector_Type (M_aleFESpace->map() ) );
1932  meshVelocity->zero();
1933  vector_Type meshVelocity_bdf ( M_aleFESpace->map() ); // velocity from previous timesteps
1934  meshVelocity_bdf.zero();
1935  M_aleTimeAdvance->rhsContribution( meshVelocity_bdf );
1936  *meshVelocity = ( M_aleTimeAdvance->alpha()*(*df_k)/(M_dt) - meshVelocity_bdf );
1937 
1938  //---------------------------------//
1939  // Compute the convective velocity //
1940  //---------------------------------//
1941 
1942  M_beta.reset ( new VectorEpetra ( M_fluid->uFESpace()->map ( ) ) );
1943  M_beta->zero();
1944  *M_beta = ( *u_k - *meshVelocity );
1945 
1946  //--------------------------------------------------------------------//
1947  // Re-assemble the fluid constant blocks since we have moved the mesh //
1948  //--------------------------------------------------------------------//
1949 
1950  M_fluid->buildSystem();
1951  M_fluid->setupPostProc();
1952 
1953  if ( M_nonconforming )
1954  {
1955  //----------------------------------------------//
1956  // Residual, part 1: compute the fluid residual //
1957  //----------------------------------------------//
1958 
1959  M_displayer.leaderPrint ( "[FSI] - Computing residual of the fluid \n" ) ;
1960 
1961  // Evaluate the residual coming from the fluid
1962  M_fluid->evaluateResidual( M_beta, u_k, p_k, M_rhs_velocity, res_u, res_p);
1963 
1964  vectorPtr_Type lambda_km1_omegaF ( new vector_Type ( M_fluid->uFESpace()->map() ) );
1965  M_FluidToStructureInterpolant->expandGammaToOmega_Known(lambda_k, lambda_km1_omegaF);
1966 
1967  *res_u += *lambda_km1_omegaF;
1968 
1969  //--------------------------------------------------//
1970  // Residual, part 2: compute the structure residual //
1971  //--------------------------------------------------//
1972 
1973  M_displayer.leaderPrint ( "[FSI] - Computing residual structure \n" ) ;
1974 
1975  // Vector containing the residual of the structural part
1976  res_ds->zero();
1977 
1978  if ( M_linearElasticity )
1979  {
1980  if ( M_useBDF )
1981  {
1982  vectorPtr_Type old_second_der_terms ( new vector_Type ( M_displacementFESpace->map() ) );
1983  old_second_der_terms->zero();
1984  M_structureTimeAdvanceBDF->second_der_old_dts(*old_second_der_terms);
1985 
1986  *res_ds = ( ( ( 1.0 / ( M_dt * M_dt ) * M_structureTimeAdvanceBDF->massCoefficient() ) * ( (*M_structure->mass_matrix_no_bc() ) * (*ds_k) ) ) +
1987  ( (*M_structure->stiffness_matrix_no_bc() ) * (*ds_k) ) +
1988  ( ( 1.0 / ( M_dt * M_dt ) ) * ( ( *M_structure->mass_matrix_no_bc() ) * ( *old_second_der_terms ) ) ) );
1989  }
1990  else
1991  {
1992  *res_ds = ( ( ( 1.0/ ( M_dt * M_dt * M_structureTimeAdvance->get_beta() ) ) * ( (*M_structure->mass_matrix_no_bc() ) * (*ds_k) ) ) +
1993  ( (*M_structure->stiffness_matrix_no_bc() ) * (*ds_k) ) -
1994  ( (*M_structure->mass_matrix_no_bc() ) * (*M_structureTimeAdvance->get_csi()) ) );
1995  }
1996  }
1997  else
1998  {
1999  if ( M_useBDF )
2000  {
2001  Real coefficient = 1.0/ ( M_dt * M_dt ) * M_structureTimeAdvanceBDF->massCoefficient();
2002  vectorPtr_Type old_second_der_terms ( new vector_Type ( M_displacementFESpace->map() ) );
2003  old_second_der_terms->zero();
2004  M_structureTimeAdvanceBDF->second_der_old_dts(*old_second_der_terms);
2005  *old_second_der_terms *= ( 1.0 / ( M_dt * M_dt ) );
2006  M_structureNeoHookean->evaluate_residual(ds_k, coefficient, old_second_der_terms, res_ds );
2007  }
2008  else
2009  {
2010  Real coefficient = 1.0/ ( M_dt * M_dt * M_structureTimeAdvance->get_beta() );
2011  M_structureNeoHookean->evaluate_residual(ds_k, coefficient, M_structureTimeAdvance->get_csi(), res_ds );
2012  }
2013 
2014  }
2015 
2016  if ( M_useMasses )
2017  {
2018  M_displayer.leaderPrint ( "[FSI] - Assemble interface mass of the fluid \n" ) ;
2019  M_fluid->assembleInterfaceMass ( M_interface_mass_fluid, M_lagrangeMap, M_datafile("interface/flag", 1),
2020  M_numerationInterfaceFluid, M_fluid->uFESpace()->map().mapSize()/3 );
2021 
2022  M_displayer.leaderPrint ( "[FSI] - From weak to strong residual - fluid \n" ) ;
2023  vectorPtr_Type tmp_gamma_f ( new vector_Type ( M_lagrangeMap ) );
2024  tmp_gamma_f->zero();
2025  applyInverseFluidMassOnGamma( lambda_k, tmp_gamma_f );
2026 
2027  M_displayer.leaderPrint ( "[FSI] - Interpolating strong residual \n" ) ;
2028  vectorPtr_Type tmp_omega_f ( new vector_Type ( M_fluid->uFESpace()->map() ) );
2029  tmp_omega_f->zero ( );
2030 
2031  M_FluidToStructureInterpolant->expandGammaToOmega_Known( tmp_gamma_f, tmp_omega_f );
2032 
2033  M_FluidToStructureInterpolant->updateRhs(tmp_omega_f);
2034 
2035  M_FluidToStructureInterpolant->interpolate();
2036 
2037  vectorPtr_Type tmp_omega_s ( new vector_Type ( M_displacementFESpace->map() ) );
2038 
2039  tmp_omega_s->zero();
2040 
2041  M_FluidToStructureInterpolant->solution(tmp_omega_s);
2042 
2043  vectorPtr_Type tmp_gamma_s;
2044 
2045  M_StructureToFluidInterpolant->restrictOmegaToGamma_Known(tmp_omega_s, tmp_gamma_s);
2046 
2047  vectorPtr_Type out_gamma_s ( new vector_Type ( tmp_gamma_s->map( ) ) );
2048  out_gamma_s->zero();
2049 
2050  M_displayer.leaderPrint ( "[FSI] - From strong to weak residual - structure \n" ) ;
2051  *out_gamma_s = (*M_interface_mass_structure) * ( *tmp_gamma_s );
2052 
2053  vectorPtr_Type structure_weak_residual ( new vector_Type ( M_displacementFESpace->map() ) );
2054  structure_weak_residual->zero();
2055 
2056  M_StructureToFluidInterpolant->expandGammaToOmega_Known( out_gamma_s, structure_weak_residual );
2057 
2058  *res_ds -= *structure_weak_residual;
2059  }
2060  else
2061  {
2062  M_FluidToStructureInterpolant->updateRhs(lambda_km1_omegaF);
2063 
2064  M_FluidToStructureInterpolant->interpolate();
2065 
2066  vectorPtr_Type structure_weak_residual ( new vector_Type ( M_displacementFESpace->map() ) );
2067  structure_weak_residual->zero();
2068 
2069  M_FluidToStructureInterpolant->solution(structure_weak_residual);
2070 
2071  *res_ds -= *structure_weak_residual;
2072  }
2073 
2074  //-------------------------------------------------//
2075  // Residual, part 3: compute the coupling residual //
2076  //-------------------------------------------------//
2077 
2078  M_displayer.leaderPrint ( "[FSI] - Computing residual coupling velocities \n" ) ;
2079 
2080  res_lambda->zero();
2081 
2082  vectorPtr_Type velocity_km1_gamma( new vector_Type ( *M_lagrangeMap ) );
2083  velocity_km1_gamma->zero();
2084  M_FluidToStructureInterpolant->restrictOmegaToGamma_Known(u_k, velocity_km1_gamma);
2085 
2086  vectorPtr_Type structure_vel( new vector_Type ( M_displacementFESpace->map() ) );
2087  structure_vel->zero();
2088 
2089  if ( M_useBDF )
2090  {
2091  *structure_vel = ( ( M_structureTimeAdvanceBDF->coefficientFirstDerivative()/ M_dt ) * (*ds_k) );
2092  }
2093  else
2094  {
2095  *structure_vel = ( ( M_structureTimeAdvance->get_gamma()/(M_dt * M_structureTimeAdvance->get_beta() ) ) * (*ds_k) );
2096  }
2097 
2098  vectorPtr_Type res_couplingVel_omega_f ( new vector_Type ( M_fluid->uFESpace()->map() ) );
2099  res_couplingVel_omega_f->zero();
2100 
2101  M_StructureToFluidInterpolant->updateRhs ( structure_vel );
2102  M_StructureToFluidInterpolant->interpolate();
2103  M_StructureToFluidInterpolant->solution(res_couplingVel_omega_f);
2104 
2105  vectorPtr_Type res_couplingVel_gamma_f ( new vector_Type ( *M_lagrangeMap ) );
2106  res_couplingVel_gamma_f->zero();
2107 
2108  M_FluidToStructureInterpolant->restrictOmegaToGamma_Known(res_couplingVel_omega_f, res_couplingVel_gamma_f);
2109 
2110  *res_lambda = (*velocity_km1_gamma - *res_couplingVel_gamma_f + *M_rhsCouplingVelocities );
2111 
2112  //--------------------------------------------//
2113  // Residual, part 4: compute the ALE residual //
2114  //--------------------------------------------//
2115 
2116  M_displayer.leaderPrint ( "[FSI] - Computing residual ALE \n" ) ;
2117 
2118  M_StructureToFluidInterpolant->updateRhs ( ds_k );
2119 
2120  M_StructureToFluidInterpolant->interpolate();
2121 
2122  vectorPtr_Type res_ds_ale ( new vector_Type ( M_fluid->uFESpace()->map() ) );
2123 
2124  res_ds_ale->zero();
2125 
2126  M_StructureToFluidInterpolant->solution(res_ds_ale);
2127 
2128  vectorPtr_Type res_ale_ale ( new vector_Type ( M_aleFESpace->map() ) );
2129 
2130  res_ale_ale->zero();
2131 
2132  *res_ale_ale = ( *M_ale->matrix ( ) ) * ( *df_k );
2133 
2134  res_df->zero();
2135 
2136  *res_df -= *res_ds_ale;
2137 
2138  *res_df += *res_ale_ale;
2139 
2140  //---------------------------------------//
2141  // Residual, part 5: monolithic residual //
2142  //---------------------------------------//
2143 
2144  M_displayer.leaderPrint ( "[FSI] - Gathering all components of the residual \n" ) ;
2145 
2146  }
2147  else
2148  {
2149  //------------------------//
2150  // Residual for the fluid //
2151  //------------------------//
2152 
2153  // Evaluate the residual coming from the fluid ( without coupling for the moment )
2154  M_fluid->evaluateResidual( M_beta, u_k, p_k, M_rhs_velocity, res_u, res_p);
2155 
2156  // Adding the coupling contribution
2157  *res_u += ( *(M_coupling->lambdaToFluidMomentum()) * (*lambda_k) );
2158 
2159  //------------------------//
2160  // Residual for the solid //
2161  //------------------------//
2162 
2163  if ( M_linearElasticity )
2164  {
2165  if ( M_useBDF )
2166  {
2167  vectorPtr_Type old_second_der_terms ( new vector_Type ( M_displacementFESpace->map() ) );
2168  old_second_der_terms->zero();
2169  M_structureTimeAdvanceBDF->second_der_old_dts(*old_second_der_terms);
2170 
2171  *res_ds = ( ( ( 1.0 / ( M_dt * M_dt ) * M_structureTimeAdvanceBDF->massCoefficient() ) * ( (*M_structure->mass_matrix_no_bc() ) * (*ds_k) ) ) +
2172  ( (*M_structure->stiffness_matrix_no_bc() ) * (*ds_k) ) +
2173  ( (*M_coupling->lambdaToStructureMomentum() ) * (*lambda_k) ) +
2174  ( ( 1.0 / ( M_dt * M_dt ) ) * ( ( *M_structure->mass_matrix_no_bc() ) * ( *old_second_der_terms ) ) ) );
2175  }
2176  else
2177  {
2178  *res_ds = ( ( ( 1.0/ ( M_dt * M_dt * M_structureTimeAdvance->get_beta() ) ) * ( (*M_structure->mass_matrix_no_bc() ) * (*ds_k) ) ) +
2179  ( (*M_structure->stiffness_matrix_no_bc() ) * (*ds_k) ) +
2180  ( (*M_coupling->lambdaToStructureMomentum() ) * (*lambda_k) ) -
2181  ( (*M_structure->mass_matrix_no_bc() ) * (*M_structureTimeAdvance->get_csi()) ) );
2182  }
2183  }
2184  else
2185  {
2186  if ( M_useBDF )
2187  {
2188  Real coefficient = 1.0/ ( M_dt * M_dt ) * M_structureTimeAdvanceBDF->massCoefficient();
2189  vectorPtr_Type old_second_der_terms ( new vector_Type ( M_displacementFESpace->map() ) );
2190  old_second_der_terms->zero();
2191  M_structureTimeAdvanceBDF->second_der_old_dts(*old_second_der_terms);
2192  *old_second_der_terms *= ( 1.0 / ( M_dt * M_dt ) );
2193  M_structureNeoHookean->evaluate_residual(ds_k, coefficient, old_second_der_terms, res_ds );
2194  }
2195  else
2196  {
2197  Real coefficient = 1.0/ ( M_dt * M_dt * M_structureTimeAdvance->get_beta() );
2198  M_structureNeoHookean->evaluate_residual(ds_k, coefficient, M_structureTimeAdvance->get_csi(), res_ds );
2199  }
2200  *res_ds += ( (*M_coupling->lambdaToStructureMomentum() ) * (*lambda_k) );
2201  }
2202  //---------------------------------------//
2203  // Residual for the lagrange multipliers //
2204  //---------------------------------------//
2205 
2206  *res_lambda = ( ( (*M_coupling->fluidVelocityToLambda()) * (*u_k) ) +
2207  ( (*M_coupling->structureDisplacementToLambda()) * (*ds_k) ) +
2208  ( *M_rhsCouplingVelocities ) );
2209 
2210  //----------------------//
2211  // Residual for the ALE //
2212  //----------------------//
2213 
2214  *res_df = ( ( (*M_coupling->structureDisplacementToFluidDisplacement()) * (*ds_k) ) +
2215  ( (*M_ale->matrix()) * (*df_k) ) );
2216 
2217  }
2218 
2219  applyBCresidual ( *res_u, *res_ds, *res_df );
2220 
2221  residual.subset(*res_u, M_fluid->uFESpace()->map(), 0, 0 );
2222  residual.subset(*res_p, M_fluid->pFESpace()->map(), 0, M_fluid->uFESpace()->map().mapSize() );
2223  residual.subset(*res_ds, M_displacementFESpace->map(), 0, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() );
2224  residual.subset(*res_lambda, *M_lagrangeMap, 0, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize() );
2225  residual.subset(*res_df, M_aleFESpace->map(), 0, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize() + M_lagrangeMap->mapSize() );
2226 
2227  if (M_printResiduals)
2228  {
2229  // Computing the norms
2230  Real norm_full_residual = residual.normInf();
2231  Real norm_u_residual = res_u->normInf();
2232  Real norm_p_residual = res_p->normInf();
2233  Real norm_ds_residual = res_ds->normInf();
2234  Real norm_lambda_residual = res_lambda->normInf();
2235  Real norm_df_residual = res_df->normInf();
2236 
2237  // Writing the norms into a file
2238  if ( M_comm->MyPID()==0 && iter_newton == 0)
2239  {
2240  M_outputResiduals << "------------------------------------------------------------------------------------" << std::endl;
2241  M_outputResiduals << "# time = " << M_time << std::endl;
2242  M_outputResiduals << "Initial norms: " << std::endl;
2243  M_outputResiduals << "||r|| =" << norm_full_residual << ", ||r_u|| =" << norm_u_residual << ", ||r_p|| =" << norm_p_residual;
2244  M_outputResiduals << ", ||r_ds|| =" << norm_ds_residual << ", ||r_lambda|| =" << norm_lambda_residual << ", ||r_df|| =" << norm_df_residual << std::endl;
2245  M_outputResiduals << "iter ||r|| ||r_u|| ||r_p|| ||r_ds|| ||r_lambda|| ||r_df||" << std::endl;
2246  }
2247  else if ( M_comm->MyPID()==0 && iter_newton > 0 )
2248  {
2249  M_outputResiduals << iter_newton << " " << norm_full_residual << " " << norm_u_residual << " " << norm_p_residual << " " <<
2250  norm_ds_residual << " " << norm_lambda_residual << " " << norm_df_residual << std::endl;
2251  }
2252  }
2253 
2254  //---------------------------------------------//
2255  // Post-step: update the Jacobian of the fluid //
2256  //---------------------------------------------//
2257 
2258  M_displayer.leaderPrint ( "[FSI] - Update Jacobian terms: \n" ) ;
2259  M_fluid->updateConvectiveTerm(M_beta);
2260  M_fluid->updateJacobian(*u_k);
2261  if ( M_fluid->useStabilization() )
2262  M_fluid->updateStabilization(*M_beta, *u_k, *p_k, *M_rhs_velocity);
2263 
2264  M_fluid->applyBoundaryConditionsJacobian ( M_fluidBC );
2265 
2266  if ( !M_linearElasticity )
2267  {
2268  M_displayer.leaderPrint ( "\nAssembly Jacobian structure" ) ;
2269  M_matrixStructure.reset (new matrix_Type ( M_displacementFESpace->map() ) );
2270  M_matrixStructure->zero();
2271 
2272  Real coefficient;
2273  if ( M_useBDF )
2274  {
2275  coefficient = 1.0/ ( M_dt * M_dt ) * M_structureTimeAdvanceBDF->massCoefficient();
2276  }
2277  else
2278  {
2279  coefficient = 1.0/ ( M_dt * M_dt * M_structureTimeAdvance->get_beta() );
2280  }
2281 
2282  M_structureNeoHookean->update_jacobian( ds_k, coefficient, M_matrixStructure);
2283  bcManageMatrix( *M_matrixStructure, *M_displacementFESpace->mesh(), M_displacementFESpace->dof(), *M_structureBC_residual_essential,
2284  M_displacementFESpace->feBd(), 1.0, M_time);
2285  }
2286 
2287  //----------------------------------------------------//
2288  // Post-step bis: Compute the shape derivatives block //
2289  //----------------------------------------------------//
2290 
2291  if (M_useShapeDerivatives)
2292  {
2293 
2294  Real alpha = M_fluidTimeAdvance->alpha() / M_dt;
2295  Real density = M_fluid->density();
2296  Real viscosity = M_fluid->viscosity();
2297 
2298  vector_Type un (M_fluid->uFESpace()->map() );
2299  vector_Type uk (M_fluid->uFESpace()->map() + M_fluid->pFESpace()->map() );
2300  //vector_Type pk (M_fluid->pFESpace()->map() );
2301 
2302  vector_Type meshVelRep ( *meshVelocity, Repeated ) ;
2303 
2304  //When this class is used, the convective term is used implictly
2305  un.subset ( solution, 0 );
2306 
2307  uk.subset ( solution, 0 );
2308  //vector_Type veloFluidMesh ( M_uFESpace->map(), Repeated );
2309  //this->transferMeshMotionOnFluid ( meshVelRep, veloFluidMesh );
2310 
2311 
2312  // Simone check with Davide
2313  M_ale->updateShapeDerivatives ( alpha,
2314  density,
2315  viscosity,
2316  un,
2317  uk,
2318  // pk
2319  meshVelRep, // or veloFluidMesh
2320  *M_fluid->uFESpace(),
2321  *M_fluid->pFESpace(),
2322  true, //This flag tells the method to consider the velocity of the domain implicitly,
2323  true, //This flag tells the method to consider the convective term implicitly ,
2324  *M_fluidBC);
2325  }
2326 
2327  //------------------------------------------------------------//
2328  // Post-step tris: update the apply operator for the Jacobian //
2329  //------------------------------------------------------------//
2330 
2331  if ( !M_nonconforming )
2332  initializeApplyOperatorJacobian();
2333 }
2334 
2335 void
2336 FSIHandler::solveJac( vector_Type& increment, const vector_Type& residual, const Real /*linearRelTol*/ )
2337 {
2338  increment.zero();
2339 
2340  if ( M_nonconforming )
2341  {
2342  M_applyOperatorJacobianNonConforming->setComm ( M_comm );
2343  M_applyOperatorJacobianNonConforming->setTimeStep ( M_dt );
2344  M_applyOperatorJacobianNonConforming->setDatafile ( M_datafile );
2345  M_applyOperatorJacobianNonConforming->setMonolithicMap ( M_monolithicMap );
2346  M_applyOperatorJacobianNonConforming->setMaps ( M_fluid->uFESpace()->mapPtr(),
2347  M_fluid->pFESpace()->mapPtr(),
2348  M_displacementFESpace->mapPtr(),
2349  M_lagrangeMap,
2350  M_aleFESpace->mapPtr());
2351 
2352  M_applyOperatorJacobianNonConforming->setInterfaceMassMatrices ( M_interface_mass_fluid, M_interface_mass_structure );
2353 
2354  if ( M_fluid->useStabilization() )
2355  M_applyOperatorJacobianNonConforming->setFluidBlocks ( M_fluid->block00(), M_fluid->block01(), M_fluid->block10(), M_fluid->block11());
2356  else
2357  M_applyOperatorJacobianNonConforming->setFluidBlocks ( M_fluid->block00(), M_fluid->block01(), M_fluid->block10() );
2358 
2359  M_applyOperatorJacobianNonConforming->setStructureBlock ( M_matrixStructure );
2360 
2361  M_applyOperatorJacobianNonConforming->setALEBlock ( M_ale->matrix() );
2362 
2363  M_applyOperatorJacobianNonConforming->setUseShapeDerivatives ( M_useShapeDerivatives );
2364 
2365  M_applyOperatorJacobianNonConforming->setTimeStep(M_dt);
2366 
2367  M_applyOperatorJacobianNonConforming->setInterpolants ( M_FluidToStructureInterpolant, M_StructureToFluidInterpolant, M_useMasses );
2368 
2369  if ( M_useBDF )
2370  {
2371  M_applyOperatorJacobianNonConforming->setBDFcoeff ( M_structureTimeAdvanceBDF->coefficientFirstDerivative() );
2372  }
2373  else
2374  {
2375  M_applyOperatorJacobianNonConforming->setGamma ( M_structureTimeAdvance->get_gamma() );
2376 
2377  M_applyOperatorJacobianNonConforming->setBeta ( M_structureTimeAdvance->get_beta() );
2378  }
2379 
2380  if ( M_useShapeDerivatives )
2381  {
2382  M_applyOperatorJacobianNonConforming->setShapeDerivativesBlocks ( M_ale->shapeDerivativesVelocity(),
2383  M_ale->shapeDerivativesPressure() );
2384  }
2385 
2386  M_invOper->setOperator(M_applyOperatorJacobianNonConforming);
2387  }
2388  else
2389  {
2390  M_invOper->setOperator(M_applyOperatorJacobian);
2391  }
2392 
2393  //---------------------------------------------------//
2394  // First: set the fluid blocks in the preconditioner //
2395  //---------------------------------------------------//
2396 
2397  if ( !M_fluid->useStabilization() )
2398  M_prec->setFluidBlocks( M_fluid->block00(), M_fluid->block01(), M_fluid->block10() );
2399  else
2400  M_prec->setFluidBlocks( M_fluid->block00(), M_fluid->block01(), M_fluid->block10(), M_fluid->block11() );
2401 
2402  if (M_useShapeDerivatives)
2403  {
2404  M_prec->setShapeDerivativesBlocks(M_ale->shapeDerivativesVelocity(), M_ale->shapeDerivativesPressure());
2405  }
2406 
2407  if ( !M_linearElasticity )
2408  {
2409  LifeChrono smallThingsChrono;
2410  M_displayer.leaderPrint ( "\t Set and approximate structure block in the preconditioner.. " ) ;
2411  smallThingsChrono.start();
2412  M_prec->setStructureBlock ( M_matrixStructure );
2413  M_prec->updateApproximatedStructureMomentumOperator ( );
2414  smallThingsChrono.stop();
2415  M_displayer.leaderPrintMax ( "done in ", smallThingsChrono.diff() ) ;
2416  }
2417 
2418  if ( M_nonconforming)
2419  {
2420  if ( M_useBDF )
2421  {
2422  M_prec->setBDFcoeff ( M_structureTimeAdvanceBDF->coefficientFirstDerivative() );
2423  }
2424  else
2425  {
2426  M_prec->setGamma ( M_structureTimeAdvance->get_gamma() );
2427  M_prec->setBeta ( M_structureTimeAdvance->get_beta() );
2428  }
2429  M_prec->setVelocityFESpace ( M_fluid->uFESpace() );
2430  M_prec->setBC ( M_interfaceFluidBC );
2431  M_prec->setTimeStep ( M_dt );
2432  M_prec->setMonolithicMap ( M_monolithicMap );
2433  }
2434  else
2435  {
2436  M_prec->setVelocityFESpace ( M_fluid->uFESpace() );
2437  M_prec->setBC ( M_interfaceFluidBC );
2438  M_prec->setDomainMap(M_applyOperatorJacobian->OperatorDomainBlockMapPtr());
2439  M_prec->setRangeMap(M_applyOperatorJacobian->OperatorRangeBlockMapPtr());
2440  }
2441 
2442  //--------------------------------------------------------------------------------//
2443  // Second: update the operators associated to shur complements and fluid momentum //
2444  //--------------------------------------------------------------------------------//
2445 
2446  LifeChrono smallThingsChrono;
2447  M_displayer.leaderPrint ( "\n Set preconditioner for the fluid momentum and the shur complements\n" ) ;
2448  M_displayer.leaderPrint ( "\t Set and approximate fluid momentum in the preconditioner.. " ) ;
2449  smallThingsChrono.start();
2450 
2451  // To be changed
2452  M_prec->updateApproximatedFluidOperator();
2453  smallThingsChrono.stop();
2454  M_displayer.leaderPrintMax ( "done in ", smallThingsChrono.diff() ) ;
2455 
2456  if ( M_comm->MyPID()==0 )
2457  {
2458  M_outputPreconditionerComputation << " " << smallThingsChrono.diff();
2459  }
2460 
2461  //------------------------------------------------------//
2462  // Third: set the preconditioner of the jacobian system //
2463  //------------------------------------------------------//
2464 
2465  M_invOper->setPreconditioner(M_prec);
2466 
2467  //-------------------------//
2468  // Forth: solve the system //
2469  //-------------------------//
2470 
2471  M_invOper->ApplyInverse(residual.epetraVector() , increment.epetraVector());
2472 
2473  if ( M_comm->MyPID()==0 )
2474  {
2475  M_outputLinearIterations << " " << M_invOper->NumIter();
2476  M_outputTimeLinearSolver << " " << M_invOper->TimeSolver();
2477  }
2478 
2479  M_displayer.leaderPrint (" FSI- End of solve Jac ... ");
2480 
2481  if (M_printSteps)
2482  {
2483  // Defining vectors for the single components of the residual
2484  vectorPtr_Type s_fluid_vel ( new vector_Type (M_fluid->uFESpace()->map() ) );
2485  vectorPtr_Type s_fluid_press ( new vector_Type (M_fluid->pFESpace()->map() ) );
2486  vectorPtr_Type s_structure_displ ( new vector_Type (M_displacementFESpace->map() ) );
2487  vectorPtr_Type s_coupling ( new vector_Type (*M_lagrangeMap ) );
2488  vectorPtr_Type s_fluid_displ ( new vector_Type (M_aleFESpace->map() ) );
2489 
2490  // Getting each single contribution
2491  s_fluid_vel->subset(increment);
2492  s_fluid_press->subset(increment, M_fluid->uFESpace()->dof().numTotalDof() * 3);
2493  s_structure_displ->subset(increment, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() );
2494  s_coupling->subset(increment, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize() );
2495  s_fluid_displ->subset(increment, M_fluid->uFESpace()->map().mapSize() + M_fluid->pFESpace()->map().mapSize() + M_displacementFESpace->map().mapSize() + M_lagrangeMap->mapSize() );
2496 
2497  // Computing the norms
2498  Real norm_full_step = increment.normInf();
2499  Real norm_u_step = s_fluid_vel->normInf();
2500  Real norm_p_step = s_fluid_press->normInf();
2501  Real norm_ds_step = s_structure_displ->normInf();
2502  Real norm_lambda_step = s_coupling->normInf();
2503  Real norm_df_step = s_fluid_displ->normInf();
2504 
2505  // Writing the norms into a file
2506  if ( M_comm->MyPID()==0 && M_NewtonIter == 0)
2507  {
2508  M_outputSteps << "------------------------------------------------------------------------------------" << std::endl;
2509  M_outputSteps << "# time = " << M_time << std::endl;
2510  M_outputSteps << "iter ||s|| ||s_u|| ||s_p|| ||s_ds|| ||s_lambda|| ||s_df||" << std::endl;
2511  M_outputSteps << M_NewtonIter+1 << std::setw (15) << norm_full_step << std::setw (15) << norm_u_step << std::setw (15) << norm_p_step << std::setw (15) <<
2512  norm_ds_step << std::setw (15) << norm_lambda_step << std::setw (15) << norm_df_step << std::endl;
2513  }
2514  else if ( M_comm->MyPID()==0 && M_NewtonIter > 0 )
2515  {
2516  M_outputSteps << M_NewtonIter+1 << std::setw (15) << norm_full_step << std::setw (15) << norm_u_step << std::setw (15) << norm_p_step << std::setw (15) <<
2517  norm_ds_step << std::setw (15) << norm_lambda_step << std::setw (15) << norm_df_step << std::endl;
2518  }
2519  }
2520 
2521 }
2522 
2523 void
2524 FSIHandler::moveMesh ( const VectorEpetra& displacement )
2525 {
2526  M_displayer.leaderPrint (" FSI- Moving the mesh ... ");
2527  M_fluidLocalMesh->meshTransformer().moveMesh (displacement, M_aleFESpace->dof().numTotalDof() );
2528  M_displayer.leaderPrint ( "done\n" );
2529 }
2530 
2531 void
2532 FSIHandler::updateSystem ( )
2533 {
2534  M_rhs_velocity.reset ( new VectorEpetra ( M_fluid->uFESpace()->map ( ) ) );
2535  M_rhs_velocity->zero();
2536 
2537  // Compute rhs contribution due to the time derivative
2538  M_fluidTimeAdvance->rhsContribution (*M_rhs_velocity);
2539 
2540  // Get the vector needed for the coupling of the velocities
2541  get_structure_coupling_velocities ( );
2542 
2543  if ( M_nonconforming )
2544  updateRhsCouplingVelocities_nonconforming ( );
2545  else
2546  updateRhsCouplingVelocities ( );
2547 }
2548 
2549 void
2550 FSIHandler::initializeApplyOperatorJacobian ( )
2551 {
2552  Operators::FSIApplyOperator::operatorPtrContainer_Type operDataJacobian(5,5);
2553  operDataJacobian(0,0) = M_fluid->block00()->matrixPtr();
2554  operDataJacobian(0,1) = M_fluid->block01()->matrixPtr();
2555  operDataJacobian(0,3) = M_coupling->lambdaToFluidMomentum()->matrixPtr();
2556  operDataJacobian(1,0) = M_fluid->block10()->matrixPtr();
2557  if ( M_fluid->useStabilization() )
2558  operDataJacobian(1,1) = M_fluid->block11()->matrixPtr();
2559  operDataJacobian(2,2) = M_matrixStructure->matrixPtr();
2560  operDataJacobian(2,3) = M_coupling->lambdaToStructureMomentum()->matrixPtr();
2561  operDataJacobian(3,0) = M_coupling->fluidVelocityToLambda()->matrixPtr();
2562  operDataJacobian(3,2) = M_coupling->structureDisplacementToLambda()->matrixPtr();
2563  operDataJacobian(4,2) = M_coupling->structureDisplacementToFluidDisplacement()->matrixPtr();
2564  operDataJacobian(4,4) = M_ale->matrix()->matrixPtr();
2565 
2566  if (M_useShapeDerivatives)
2567  {
2568  operDataJacobian(0,4) = M_ale->shapeDerivativesVelocity()->matrixPtr(); // shape derivatives
2569  operDataJacobian(1,4) = M_ale->shapeDerivativesPressure()->matrixPtr(); // shape derivatives
2570  }
2571  M_applyOperatorJacobian->setMonolithicMap(M_monolithicMap);
2572  M_applyOperatorJacobian->setUp(operDataJacobian, M_comm);
2573 }
2574 
2575 }
void setupStructure()
Setup solid sub-problem.
Definition: FSIHandler.cpp:349
commPtr_Type M_comm
communicator
Definition: FSIHandler.hpp:395
bool M_prescribeInflowFlowrate
Definition: FSIHandler.hpp:575
std::shared_ptr< comm_Type > commPtr_Type
Definition: FSIHandler.hpp:136
bool M_extrapolateInitialGuess
Definition: FSIHandler.hpp:525
~FSIHandler()
Destructor.
Definition: FSIHandler.cpp:76
void setup()
Setup the solver.
Definition: FSIHandler.cpp:165
void setupExporters()
Setup the exporters of fluid and solid.
Definition: FSIHandler.cpp:290
void setDatafile(const GetPot &dataFile)
Set the datafile.
Definition: FSIHandler.cpp:89
void partitionMeshes()
Partitioning the fluid and solid meshes.
Definition: FSIHandler.cpp:135
void setParameterLists()
Set the parameter list of the problem.
Definition: FSIHandler.cpp:96
Displayer M_displayer
Displayer to print in parallel (only PID 0 will print)
Definition: FSIHandler.hpp:447
void readPartitionedMeshes()
Read fluid and solid meshes that have been already partitioned offline.
Definition: FSIHandler.cpp:147
void updateBoundaryConditions()
Update all the bc handlers.
Definition: FSIHandler.cpp:459
double Real
Generic real data.
Definition: LifeV.hpp:175
void readMeshes()
Read the fluid and solid meshes.
Definition: FSIHandler.cpp:114
void setSolversOptions(const Teuchos::ParameterList &solversOptions)
Set options linear solver.
Definition: FSIHandler.cpp:106
bool M_subiterateFluidDirichlet
Definition: FSIHandler.hpp:533
UInt M_orderExtrapolationInitialGuess
Definition: FSIHandler.hpp:526
std::shared_ptr< ExporterHDF5< mesh_Type > > M_importerStructure
Definition: FSIHandler.hpp:562
FSIHandler(const commPtr_Type &communicator)
Constructor.
Definition: FSIHandler.cpp:42
void createAleFESpace()
Create ALE FE spaces.
Definition: FSIHandler.cpp:391
void initializeTimeAdvance()
Update the time advancing schemes.
Definition: FSIHandler.cpp:468
Real M_dt
Variables for the time advancing.
Definition: FSIHandler.hpp:450
void setGravity(const Real &gravity, const Real &gravity_direction)
Set gravity, if considered.
Definition: FSIHandler.cpp:81