44 #include <lifev/core/LifeV.hpp> 45 #include <lifev/fsi/solver/FSIOperator.hpp> 53 FSIOperator::FSIOperator() :
77 M_fluidTimeAdvanceMethod ( ),
78 M_solidTimeAdvanceMethod ( ),
79 M_ALETimeAdvanceMethod ( ),
80 M_fluidTimeAdvance ( ),
81 M_fluidMassTimeAdvance ( ),
82 M_solidTimeAdvance ( ),
85 M_meshDataFluid (
new MeshData() ),
86 M_meshDataSolid (
new MeshData() ),
88 M_fluidInterfaceMap ( ),
89 M_solidInterfaceMap ( ),
90 M_fluidInterfaceMapOnZero ( ),
91 M_solidInterfaceMapOnZero ( ),
92 M_dofFluidToStructure ( ),
93 M_dofStructureToFluid ( ),
94 M_dofStructureToSolid ( ),
95 M_dofStructureToHarmonicExtension ( ),
96 M_dofHarmonicExtensionToFluid ( ),
101 M_bcvFluidInterfaceDisp ( ),
102 M_bcvFluidLoadToStructure ( ),
103 M_bcvSolidLoadToStructure ( ),
104 M_bcvStructureToFluid ( ),
105 M_bcvStructureDispToFluid ( ),
106 M_bcvStructureDispToSolid ( ),
107 M_bcvStructureDispToHarmonicExtension( ),
108 M_bcvHarmonicExtensionVelToFluid ( ),
109 M_bcvDerHarmonicExtensionVelToFluid ( ),
110 M_bcvDerFluidLoadToStructure ( ),
111 M_bcvDerFluidLoadToFluid ( ),
112 M_bcvDerStructureDispToSolid ( ),
113 M_bcfRobinOuterWall ( ),
115 M_lambdaFluidRepeated ( ),
123 M_epetraWorldComm ( ),
124 M_structureNonLinear (
false),
127 M_lambdaSolidRepeated ( ),
128 M_lambdaSolidOld ( ),
129 M_lambdaDotSolid ( ),
130 M_lambdaDotSolidRepeated ( ),
133 M_sigmaFluidRepeated ( ),
134 M_sigmaSolidRepeated ( ),
135 M_minusSigmaFluid ( ),
136 M_minusSigmaFluidRepeated ( ),
137 M_dispFluidMeshOld ( ),
139 M_derVeloFluidMesh ( ),
143 M_linearFluid (
false ),
144 M_linearSolid (
false ),
147 M_aleOrder ( std::string (
"P1") )
151 FSIOperator::~FSIOperator()
160 FSIOperator::setDataFile (
const GetPot& dataFile )
162 M_fluidMesh.reset (
new mesh_Type ( M_epetraComm ) );
163 M_meshDataFluid->setup (dataFile,
"fluid/space_discretization");
164 readMesh (*M_fluidMesh, *M_meshDataFluid);
166 M_solidMesh.reset (
new mesh_Type ( M_epetraComm ) );
167 M_meshDataSolid->setup (dataFile,
"solid/space_discretization");
168 readMesh (*M_solidMesh, *M_meshDataSolid);
170 M_dataFile = dataFile;
172 M_fluidTimeAdvanceMethod = dataFile (
"fluid/time_discretization/method",
"BDF");
173 M_aleOrder = dataFile (
"fluid/space_discretization/ale_order",
"P1");
174 M_solidTimeAdvanceMethod = dataFile (
"solid/time_discretization/method",
"BDF");
175 M_ALETimeAdvanceMethod = dataFile (
"mesh_motion/time_discretization/method",
"BDF");
176 M_structureNonLinear = M_data->dataSolid()->lawType().compare (
"linear");
177 this->setupTimeAdvance ( dataFile );
181 FSIOperator::setupFEspace()
183 Displayer disp (M_epetraComm);
184 disp.leaderPrint (
"FSI- Setting ReferenceFE and QuadratureRule ... \n");
186 std::string uOrder = M_data->dataFluid()->uOrder();
187 std::string pOrder = M_data->dataFluid()->pOrder();
188 std::string dOrder = M_data->dataSolid()->order();
190 ASSERT ( ! ( (!uOrder.compare (
"P2") && !dOrder.compare (
"P1") ) ),
"You are using P2 FE for the fluid velocity and P1 FE for the structure: when the coupling is enforced only in the P1 nodes, the energy is not conserved across the interface." );
191 ASSERT ( ! ( (!uOrder.compare (
"P1") && !dOrder.compare (
"P2") ) ),
"You are using P1 FE for the fluid velocity and P2 FE for the structure: when the coupling is enforced only in the P1 nodes, the energy is not conserved across the interface." );
192 ASSERT ( ! ( (!uOrder.compare (
"P1Bubble") && !dOrder.compare (
"P2") ) ),
"You are using P2 FE for the fluid velocity and P1 FE for the structure: when the coupling is enforced only in the P1 nodes, the energy is not conserved across the interface." );
194 if ( M_aleOrder.compare ( M_meshDataFluid->mOrder() ) )
196 disp.leaderPrint (
"FSI- WARNING! The mesh order is different\n");
197 disp.leaderPrint (
" => The nodes of the mesh will not entirely follow the computed displacement.\n");
216 if ( uOrder.compare (
"P2") == 0 )
218 refFE_vel = &feTetraP2;
222 else if ( uOrder.compare (
"P1") == 0 )
224 refFE_vel = &feTetraP1;
228 else if ( uOrder.compare (
"P1Bubble") == 0 )
230 refFE_vel = &feTetraP1bubble;
236 ERROR_MSG (uOrder +
" velocity FE not implemented yet.");
239 if ( pOrder.compare (
"P2") == 0 )
241 refFE_press = &feTetraP2;
245 else if ( pOrder.compare (
"P1") == 0 )
247 refFE_press = &feTetraP1;
253 ERROR_MSG (pOrder +
" pressure FE not implemented yet.");
256 if ( dOrder.compare (
"P2") == 0 )
258 refFE_struct = &feTetraP2;
262 else if ( dOrder.compare (
"P1") == 0 )
264 refFE_struct = &feTetraP1;
270 ERROR_MSG (dOrder +
" structure FE not implemented yet.");
273 if ( M_aleOrder.compare (
"P2") == 0 )
275 refFE_mesh = &feTetraP2;
279 else if ( M_aleOrder.compare (
"P1") == 0 )
281 refFE_mesh = &feTetraP1;
285 else if ( M_aleOrder.compare (
"P1Bubble") == 0 )
287 refFE_mesh = &feTetraP1bubble;
293 ERROR_MSG (M_aleOrder +
" mesh FE not implemented yet.");
296 disp.leaderPrint (
"done\n");
298 disp.leaderPrint (
"FSI- Building fluid FESpace ... \n");
299 if (
this->isFluid() )
302 M_mmFESpace.reset (
new FESpace<mesh_Type, MapEpetra> (M_fluidLocalMesh,
310 M_uFESpace.reset (
new FESpace<mesh_Type, MapEpetra> (M_fluidLocalMesh,
318 M_pFESpace.reset (
new FESpace<mesh_Type, MapEpetra> (M_fluidLocalMesh,
328 M_mmFESpace.reset (
new FESpace<mesh_Type, MapEpetra> (M_fluidMesh,
336 M_uFESpace.reset (
new FESpace<mesh_Type, MapEpetra> (M_fluidMesh,
344 M_pFESpace.reset (
new FESpace<mesh_Type, MapEpetra> (M_fluidMesh,
352 M_epetraWorldComm->Barrier();
354 disp.leaderPrint (
"FSI- Building solid FESpace ... \n");
355 if (
this->isSolid() )
357 M_dFESpace.reset (
new FESpace<mesh_Type, MapEpetra> ( M_solidLocalMesh,
365 M_dETFESpace.reset (
new ETFESpace<mesh_Type, MapEpetra, 3, 3> ( M_solidLocalMesh,
366 & (M_dFESpace->refFE() ),
367 & (M_dFESpace->fe().geoMap() ),
373 M_dFESpace.reset (
new FESpace<mesh_Type, MapEpetra> (M_solidMesh,
381 M_dETFESpace.reset (
new ETFESpace<mesh_Type, MapEpetra, 3, 3> (M_solidMesh,
382 & (M_dFESpace->refFE() ),
383 & (M_dFESpace->fe().geoMap() ),
387 M_epetraWorldComm->Barrier();
392 FSIOperator::partitionMeshes()
394 if (
this->isFluid() )
396 MeshPartitioner< mesh_Type > fluidPartitioner (M_fluidMesh, M_epetraComm);
397 M_fluidLocalMesh = fluidPartitioner.meshPartition();
399 if (
this->isSolid() )
401 MeshPartitioner< mesh_Type > solidPartitioner (M_solidMesh, M_epetraComm);
402 M_solidLocalMesh = solidPartitioner.meshPartition();
417 FSIOperator::setupDOF (
void )
419 Displayer disp (M_epetraWorldComm);
420 disp.leaderPrint (
"FSI: setting DOF ... " );
421 DOF uDof (*M_fluidMesh, M_uFESpace->refFE() );
422 DOF dDof (*M_solidMesh, M_dFESpace->refFE() );
424 M_dofFluidToStructure .reset (
new DOFInterface3Dto3D );
425 M_dofStructureToFluid .reset (
new DOFInterface3Dto3D );
426 M_dofStructureToSolid .reset (
new DOFInterface3Dto3D );
427 M_dofStructureToHarmonicExtension .reset (
new DOFInterface3Dto3D );
428 M_dofHarmonicExtensionToFluid .reset (
new DOFInterface3Dto3D );
429 M_dofFluid .reset (
new DOFInterface3Dto2D );
430 M_dofSolid .reset (
new DOFInterface3Dto2D );
431 M_dofFluidInv .reset (
new DOFInterface3Dto2D );
432 M_dofSolidInv .reset (
new DOFInterface3Dto2D );
433 M_bcvFluidInterfaceDisp .reset (
new BCVectorInterface );
434 M_bcvFluidLoadToStructure .reset (
new BCVectorInterface );
435 M_bcvSolidLoadToStructure .reset (
new BCVectorInterface );
436 M_bcvStructureToFluid .reset (
new BCVectorInterface );
437 M_bcvStructureDispToFluid .reset (
new BCVectorInterface );
438 M_bcvStructureDispToSolid .reset (
new BCVectorInterface );
439 M_bcvStructureDispToHarmonicExtension.reset (
new BCVectorInterface );
440 M_bcvHarmonicExtensionVelToFluid .reset (
new BCVectorInterface );
441 M_bcvDerHarmonicExtensionVelToFluid .reset (
new BCVectorInterface );
442 M_bcvDerFluidLoadToStructure .reset (
new BCVectorInterface );
443 M_bcvDerFluidLoadToFluid .reset (
new BCVectorInterface );
444 M_bcvDerStructureDispToSolid .reset (
new BCVectorInterface );
446 M_dofFluidToStructure->setup ( M_dFESpace->refFE(), M_dFESpace->dof(),
447 M_uFESpace->refFE(), uDof );
448 M_dofFluidToStructure->update ( *M_dFESpace->mesh(), M_data->structureInterfaceFlag(),
449 *M_fluidMesh, M_data->fluidInterfaceFlag(),
450 M_data->interfaceTolerance(),
451 M_data->structureInterfaceVertexFlag() );
454 M_dofStructureToHarmonicExtension->setup ( M_uFESpace->refFE(), M_uFESpace->dof(),
455 M_dFESpace->refFE(), dDof );
456 M_dofStructureToHarmonicExtension->update ( *M_uFESpace->mesh(), M_data->fluidInterfaceFlag(),
457 *M_solidMesh, M_data->structureInterfaceFlag(),
458 M_data->interfaceTolerance(),
459 M_data->fluidInterfaceVertexFlag() );
461 M_dofStructureToSolid->setup ( M_dFESpace->refFE(), M_dFESpace->dof(),
462 M_dFESpace->refFE(), M_dFESpace->dof() );
463 M_dofStructureToSolid->update ( *M_dFESpace->mesh(), M_data->structureInterfaceFlag(),
464 *M_dFESpace->mesh(), M_data->structureInterfaceFlag(),
465 M_data->interfaceTolerance(),
466 M_data->structureInterfaceVertexFlag() );
468 M_dofStructureToFluid->setup ( M_uFESpace->refFE(), M_uFESpace->dof(),
469 M_dFESpace->refFE(), dDof );
470 M_dofStructureToFluid->update ( *M_uFESpace->mesh(), M_data->fluidInterfaceFlag(),
471 *M_solidMesh, M_data->structureInterfaceFlag(),
472 M_data->interfaceTolerance(),
473 M_data->fluidInterfaceVertexFlag() );
475 M_dofHarmonicExtensionToFluid->setup ( M_uFESpace->refFE(), M_uFESpace->dof(),
476 M_uFESpace->refFE(), M_uFESpace->dof() );
477 M_dofHarmonicExtensionToFluid->update ( *M_uFESpace->mesh(), M_data->fluidInterfaceFlag(),
478 *M_uFESpace->mesh(), M_data->fluidInterfaceFlag(),
479 M_data->interfaceTolerance(),
480 M_data->fluidInterfaceVertexFlag() );
482 M_epetraWorldComm->Barrier();
483 disp.leaderPrint (
"done\n");
485 createInterfaceMaps ( M_dofStructureToHarmonicExtension->localDofMap() );
489 FSIOperator::setupFluidSolid (
void )
491 setupFluidSolid (imposedFluxes() );
495 FSIOperator::setupFluidSolid (
UInt const fluxes )
497 M_meshMotion.reset (
new meshMotion_Type ( *M_mmFESpace, M_epetraComm ) );
499 if (
this->isFluid() )
501 M_fluid.reset (
new fluid_Type ( M_data->dataFluid(), *M_uFESpace, *M_pFESpace, M_epetraComm, fluxes ) );
504 M_rhs.reset (
new vector_Type ( M_fluid->getMap() ) );
507 M_solid.reset (
new solid_Type( ) );
508 M_solid->setup ( M_data->dataSolid(), M_dFESpace, M_dETFESpace, M_epetraComm );
510 M_epetraWorldComm->Barrier();
516 FSIOperator::setupSystem (
void )
518 if (
this->isFluid() )
521 M_fluid->setUp ( M_dataFile );
522 M_meshMotion->setUp ( M_dataFile );
527 if (
this->isSolid() )
529 M_solid->setDataFromGetPot ( M_dataFile );
534 M_epetraWorldComm->Barrier();
538 FSIOperator::buildSystem()
540 if (
this->isFluid() )
542 M_fluid->buildSystem();
547 if (
this->isSolid() )
549 M_data->dataSolid()->showMe();
551 double xi = M_solidTimeAdvance->coefficientSecondDerivative ( 0 ) / ( M_data->dataSolid()->dataTime()->timeStep() * M_data->dataSolid()->dataTime()->timeStep() );
552 M_solid->buildSystem (xi);
553 M_solid->massMatrix()->globalAssemble();
559 FSIOperator::updateSystem()
561 if (
this->isFluid() )
563 M_ALETimeAdvance->updateRHSContribution (M_data->dataFluid()->dataTime()->timeStep() );
564 M_fluidTimeAdvance->updateRHSContribution (M_data->dataFluid()->dataTime()->timeStep() );
566 if (M_data->dataFluid()->conservativeFormulation() )
568 M_fluidMassTimeAdvance->updateRHSContribution (M_data->dataFluid()->dataTime()->timeStep() );
571 transferMeshMotionOnFluid (M_meshMotion->disp(), *
this->M_dispFluidMeshOld);
575 if (
this->isSolid() )
577 M_solid->updateSystem();
578 M_solidTimeAdvance->updateRHSContribution ( M_data->dataSolid()->dataTime()->timeStep() );
579 vector_Type rhsW (M_dFESpace->map(), Repeated);
580 rhsW = (*M_solid->massMatrix() * (M_solidTimeAdvance->rhsContributionSecondDerivative() ) * M_data->dataSolid()->dataTime()->timeStep() * M_data->dataSolid()->dataTime()->timeStep() / M_solidTimeAdvance->coefficientSecondDerivative ( 0 ) );
581 M_solid->setRightHandSide ( rhsW );
584 couplingVariableExtrap( );
590 void FSIOperator::couplingVariableExtrap( )
592 *M_lambda = lambdaSolid();
594 if (!M_lambdaDot.get() )
596 M_lambdaDot.reset (
new vector_Type (*M_fluidInterfaceMap, Unique) );
597 *M_lambda += M_data->dataFluid()->dataTime()->timeStep() * lambdaDotSolid();
601 if (
this->isSolid() )
603 vector_Type solidDisp (M_solid->displacement() );
604 vector_Type solidVel (M_solid->displacement() );
605 M_solidTimeAdvance->extrapolation (solidDisp);
606 M_solidTimeAdvance->extrapolationFirstDerivative (solidVel);
607 transferSolidOnInterface (solidDisp, *M_lambda);
608 transferSolidOnInterface (solidVel, *M_lambdaDot);
611 displayer().leaderPrint (
"FSI- norm( disp ) init = ", M_lambda->normInf(),
"\n" );
612 displayer().leaderPrint (
"FSI- norm( velo ) init = ", M_lambdaDot->normInf(),
"\n");
616 FSIOperator::updateSolution (
const vector_Type& )
618 if (
this->isFluid() )
620 M_ALETimeAdvance->shiftRight (
this->M_meshMotion->disp() );
621 M_fluidTimeAdvance->shiftRight ( *M_fluid->solution() );
622 if (M_data->dataFluid()->conservativeFormulation() )
624 M_fluidTimeAdvance->shiftRight ( M_fluid->matrixMass() * (*M_fluid->solution() ) );
627 if (
this->isSolid() )
629 M_solidTimeAdvance->shiftRight ( M_solid->displacement() );
634 FSIOperator::imposedFluxes (
void )
636 if (
this->isFluid() )
638 std::vector<bcName_Type> fluxVector = M_BCh_u->findAllBCWithType ( Flux );
639 UInt numLM =
static_cast<UInt> ( fluxVector.size() );
641 UInt offset = M_uFESpace->map().map (Unique)->NumGlobalElements()
642 + M_pFESpace->map().map (Unique)->NumGlobalElements();
644 for (
UInt i = 0; i < numLM; ++i )
646 M_BCh_u->setOffset ( fluxVector[i], offset + i );
770 ASSERT ( initialFluidVel.size() == M_fluidTimeAdvance->size(),
"The number of vectors for initializing the time scheme for the fluid velocity is not consistent with the discretization chosen" );
774 ASSERT ( initialFluidVel.size() == M_fluidMassTimeAdvance->size(),
"The number of vectors for initializing the time scheme for the fluid velocity is not consistent with the discretization chosen" );
777 ASSERT (initialFluidDisp.size() == M_ALETimeAdvance->size() ,
"The number of vectors for initializing the time discretization for the ALE map is not consistent with the discretization chosen");
790 ASSERT (initialSolidDisp.size() == M_solidTimeAdvance->size(),
"The number of vectors for initializing the time scheme for the structure displacement is not consistent with the discretization chosen" );
const QuadratureRule quadRuleTetra64pt(pt_tetra_64pt, 6, "Quadrature rule 64 points on a tetraedra", TETRA, 64, 7)
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
const QuadratureRule quadRuleTetra15pt(pt_tetra_15pt, 5, "Quadrature rule 15 points on a tetraedra", TETRA, 15, 5)
const QuadratureRule quadRuleTetra4pt(pt_tetra_4pt, 2, "Quadrature rule 4 points on a tetraedra", TETRA, 4, 2)
std::shared_ptr< std::vector< Int > > M_isOnProc
const QuadratureRule quadRuleTria3pt(pt_tria_3pt, 2, "Quadrature rule 3 points on a triangle", TRIANGLE, 3, 2)
The class for a reference Lagrangian finite element.
QuadratureRule - The basis class for storing and accessing quadrature rules.
uint32_type UInt
generic unsigned integer (used mainly for addressing)