28 #include <lifev/core/LifeV.hpp> 30 #include <lifev/fsi/solver/FSIMonolithicGI.hpp> 31 #include <lifev/fsi/solver/MonolithicBlockComposedDN.hpp> 32 #include <lifev/fsi/solver/MonolithicBlockComposedDND.hpp> 33 #include <lifev/fsi/solver/MonolithicBlockMatrixRN.hpp> 41 FSIMonolithicGI::FSIMonolithicGI() :
47 M_shapeDerivativesBlock (),
55 void FSIMonolithicGI::setup (
const GetPot& dataFile )
57 super_Type::setup ( dataFile );
60 void FSIMonolithicGI::setupFluidSolid ( UInt
const fluxes )
62 super_Type::setupFluidSolid ( fluxes );
63 UInt offset = M_monolithicMap->map ( Unique )->NumGlobalElements();
64 M_mapWithoutMesh.reset (
new MapEpetra ( *M_monolithicMap ) );
66 *M_monolithicMap += M_mmFESpace->map();
68 M_interface = M_monolithicMatrix->interface();
70 M_beta.reset (
new vector_Type (M_uFESpace->map() ) );
71 M_rhs.reset (
new vector_Type (*M_monolithicMap) );
72 M_rhsFull.reset (
new vector_Type (*M_monolithicMap) );
73 if (M_data->dataFluid()->useShapeDerivatives() )
75 M_shapeDerivativesBlock.reset (
new matrix_Type (*M_monolithicMap) );
77 M_uk.reset (
new vector_Type (*M_monolithicMap) );
79 M_meshMotion.reset (
new meshMotion_Type (*M_mmFESpace,
84 M_fluid.reset (
new fluid_Type (M_data->dataFluid(),
91 M_solid.reset (
new solid_Type() );
93 M_solid->setup (M_data->dataSolid(),
103 FSIMonolithicGI::buildSystem()
105 super_Type::buildSystem();
106 M_meshMotion->computeMatrix();
110 FSIMonolithicGI::evalResidual ( vector_Type& res,
111 const vector_Type& disp,
118 M_uk.reset (
new vector_Type ( disp ) );
120 UInt offset ( M_solidAndFluidDim + nDimensions * M_interface );
122 vectorPtr_Type meshDisp (
new vector_Type (M_mmFESpace->map() ) );
124 meshDisp->subset (disp, offset);
126 vectorPtr_Type mmRep (
new vector_Type (*meshDisp, Repeated ) );
133 M_ALETimeAdvance->updateRHSFirstDerivative (M_data->dataFluid()->dataTime()->timeStep() );
135 vector_Type meshVelocityRepeated (
this->M_ALETimeAdvance->firstDerivative ( *meshDisp ), Repeated );
136 vector_Type interpolatedMeshVelocity (
this->M_uFESpace->map() );
138 interpolateVelocity ( meshVelocityRepeated, interpolatedMeshVelocity );
139 vectorPtr_Type fluid (
new vector_Type ( M_uFESpace->map() ) );
140 M_beta->subset ( disp, 0 );
142 *M_beta -= interpolatedMeshVelocity;
144 assembleSolidBlock ( iter, disp );
145 assembleFluidBlock ( iter, disp );
146 assembleMeshBlock ( iter );
150 M_monolithicMatrix->setRobin ( M_robinCoupling, M_rhsFull );
151 M_precPtr->setRobin (M_robinCoupling, M_rhsFull);
153 if (!M_monolithicMatrix->set() )
155 M_BChs.push_back (M_BCh_d);
156 M_BChs.push_back (M_BCh_u);
158 M_FESpaces.push_back (M_dFESpace);
159 M_FESpaces.push_back (M_uFESpace);
161 M_BChs.push_back (M_BCh_mesh);
162 M_FESpaces.push_back (M_mmFESpace);
164 M_monolithicMatrix->push_back_matrix (M_solidBlockPrec,
false);
165 M_monolithicMatrix->push_back_matrix (M_fluidBlock,
true);
166 M_monolithicMatrix->push_back_matrix (M_meshBlock,
false);
167 M_monolithicMatrix->setConditions (M_BChs);
168 M_monolithicMatrix->setSpaces (M_FESpaces);
169 M_monolithicMatrix->setOffsets (3, M_offset, 0, M_solidAndFluidDim + nDimensions * M_interface);
170 M_monolithicMatrix->coupler (M_monolithicMap, M_dofStructureToFluid->localDofMap(), M_numerationInterface, M_data->dataFluid()->dataTime()->timeStep(), M_solidTimeAdvance->coefficientFirstDerivative ( 0 ), M_solid->rescaleFactor() );
171 M_monolithicMatrix->coupler ( M_monolithicMap, M_dofStructureToFluid->localDofMap(), M_numerationInterface, M_data->dataFluid()->dataTime()->timeStep(), M_solidTimeAdvance->coefficientFirstDerivative ( 0 ), M_solid->rescaleFactor(), 2);
175 M_monolithicMatrix->replace_matrix (M_solidBlockPrec, 0);
176 M_monolithicMatrix->replace_matrix (M_fluidBlock, 1);
177 M_monolithicMatrix->replace_matrix (M_meshBlock, 2);
180 M_monolithicMatrix->blockAssembling();
181 super_Type::checkIfChangedFluxBC ( M_monolithicMatrix );
185 if ( ! (M_data->dataSolid()->lawType().compare (
"linear") ) )
187 applyBoundaryConditions();
190 M_monolithicMatrix->GlobalAssemble();
192 super_Type::evalResidual ( disp, M_rhsFull, res,
false );
195 if ( ! ( M_data->dataSolid()->lawType().compare (
"nonlinear" ) ) )
197 res += *M_meshBlock * disp;
199 if ( !M_BCh_u->bcUpdateDone() )
201 M_BCh_u->bcUpdate ( *M_uFESpace->mesh(), M_uFESpace->feBd(), M_uFESpace->dof() );
203 M_BCh_d->setOffset ( M_offset );
204 if ( !M_BCh_d->bcUpdateDone() )
206 M_BCh_d->bcUpdate ( *M_dFESpace->mesh(), M_dFESpace->feBd(), M_dFESpace->dof() );
208 M_BCh_mesh->setOffset ( M_solidAndFluidDim + nDimensions * M_interface );
209 if ( !M_BCh_mesh->bcUpdateDone() )
211 M_BCh_mesh->bcUpdate ( *M_mmFESpace->mesh(), M_mmFESpace->feBd(), M_mmFESpace->dof() );
214 M_monolithicMatrix->applyBoundaryConditions ( dataFluid()->dataTime()->time() );
215 M_monolithicMatrix->GlobalAssemble();
217 bcManageResidual ( res, *M_rhsFull, disp, *M_uFESpace->mesh(), M_uFESpace->dof(), *M_BCh_u,
218 M_uFESpace->feBd(), M_data->dataFluid()->dataTime()->time(), 1. );
221 bcManageResidual ( res, *M_rhsFull, disp, *M_dFESpace->mesh(), M_dFESpace->dof(), *M_BCh_d,
222 M_dFESpace->feBd(), M_data->dataSolid()->dataTime()->time(), 1. );
223 bcManageResidual ( res, *M_rhsFull, disp, *M_mmFESpace->mesh(), M_mmFESpace->dof(), *M_BCh_mesh,
224 M_mmFESpace->feBd(), M_data->dataFluid()->dataTime()->time(), 1. );
229 void FSIMonolithicGI::applyBoundaryConditions()
231 if ( !M_BCh_u->bcUpdateDone() )
232 M_BCh_u->bcUpdate ( *M_uFESpace->mesh(),
235 M_BCh_d->setOffset ( M_offset );
236 if ( !M_BCh_d->bcUpdateDone() )
237 M_BCh_d->bcUpdate ( *M_dFESpace->mesh(),
240 M_BCh_mesh->setOffset ( M_solidAndFluidDim + nDimensions * M_interface );
241 if ( !M_BCh_mesh->bcUpdateDone() )
242 M_BCh_mesh->bcUpdate ( *M_mmFESpace->mesh(),
244 M_mmFESpace->dof() );
246 M_monolithicMatrix->applyBoundaryConditions (dataFluid()->dataTime()->time(), M_rhsFull);
249 void FSIMonolithicGI::setALEVectorInStencil (
const vectorPtr_Type& fluidDisp,
251 const bool lastVector)
257 if ( ( iter < M_fluidTimeAdvance->size() - 1 ) && !lastVector )
259 vectorPtr_Type harmonicSolutionRestartTime (
new vector_Type ( *M_monolithicMap, Unique, Zero ) );
261 *harmonicSolutionRestartTime *= 0.0;
263 UInt givenOffset ( M_solidAndFluidDim + nDimensions * M_interface );
264 harmonicSolutionRestartTime->subset (*fluidDisp, fluidDisp->map(), (UInt) 0, givenOffset );
267 * ( M_fluidTimeAdvance->stencil() [ iter + 1 ] ) += *harmonicSolutionRestartTime;
274 vector_Type* normalPointerToALEVector (
new vector_Type (*fluidDisp) );
275 (M_ALETimeAdvance->stencil() ).push_back ( normalPointerToALEVector );
279 vectorPtr_Type harmonicSolutionRestartTime (
new vector_Type ( *M_monolithicMap, Unique, Zero ) );
281 *harmonicSolutionRestartTime *= 0.0;
283 UInt givenOffset ( M_solidAndFluidDim + nDimensions * M_interface );
284 harmonicSolutionRestartTime->subset (*fluidDisp, fluidDisp->map(), (UInt) 0, givenOffset );
287 * ( M_fluidTimeAdvance->stencil() [ 0 ] ) += *harmonicSolutionRestartTime;
296 void FSIMonolithicGI::setupBlockPrec()
322 M_monolithicMatrix->blockAssembling();
324 if ( M_data->dataFluid()->useShapeDerivatives() )
326 *M_shapeDerivativesBlock *= 0.;
327 M_shapeDerivativesBlock->openCrsMatrix();
328 shapeDerivatives ( M_shapeDerivativesBlock );
329 M_shapeDerivativesBlock->globalAssemble();
330 M_monolithicMatrix->addToGlobalMatrix ( M_shapeDerivativesBlock );
333 if ( M_data->dataFluid()->useShapeDerivatives() || M_data->dataSolid()->getUseExactJacobian() )
335 if ( !M_BCh_u->bcUpdateDone() )
336 M_BCh_u->bcUpdate ( *M_uFESpace->mesh(),
339 M_BCh_d->setOffset ( M_offset );
340 if ( !M_BCh_d->bcUpdateDone() )
341 M_BCh_d->bcUpdate ( *M_dFESpace->mesh(),
344 M_BCh_mesh->setOffset ( M_solidAndFluidDim + nDimensions * M_interface );
345 if ( !M_BCh_mesh->bcUpdateDone() )
346 M_BCh_mesh->bcUpdate ( *M_mmFESpace->mesh(),
348 M_mmFESpace->dof() );
350 M_monolithicMatrix->applyBoundaryConditions ( dataFluid()->dataTime()->time() );
351 M_monolithicMatrix->GlobalAssemble();
354 super_Type::setupBlockPrec();
356 if ( M_precPtr->blockVector().size() < 3 )
358 M_precPtr->push_back_matrix ( M_meshBlock,
360 M_precPtr->setConditions ( M_BChs );
361 M_precPtr->setSpaces ( M_FESpaces );
362 M_precPtr->setOffsets ( 3, M_offset, 0, M_solidAndFluidDim + nDimensions * M_interface );
363 M_precPtr->coupler ( M_monolithicMap, M_dofStructureToFluid->localDofMap(), M_numerationInterface, M_data->dataFluid()->dataTime()->timeStep() , M_solidTimeAdvance->coefficientFirstDerivative ( 0 ), M_solid->rescaleFactor(), 2);
365 if (M_data->dataFluid()->useShapeDerivatives() )
367 std::shared_ptr<MatrixEpetra<Real> > staticCast = std::static_pointer_cast<MatrixEpetra<Real> > (M_shapeDerivativesBlock);
368 M_precPtr->push_back_coupling ( staticCast );
375 M_precPtr->replace_matrix ( M_meshBlock, 2 );
377 if ( M_data->dataFluid()->useShapeDerivatives() )
379 M_precPtr->replace_coupling ( M_shapeDerivativesBlock, 2 );
384 void FSIMonolithicGI::shapeDerivatives ( FSIOperator::fluid_Type::matrixPtr_Type sdMatrix )
386 Real alpha = M_fluidTimeAdvance->coefficientFirstDerivative ( 0 ) / M_data->dataFluid()->dataTime()->timeStep();
387 vectorPtr_Type rhsNew (
new vector_Type (*M_monolithicMap) );
388 vector_Type un (M_uFESpace->map() );
389 vector_Type uk (M_uFESpace->map() + M_pFESpace->map() );
391 vectorPtr_Type meshVelRep (
new vector_Type ( M_mmFESpace->map(), Repeated ) );
393 *meshVelRep = M_ALETimeAdvance->firstDerivative();
396 un.subset ( *M_uk, 0 );
398 uk.subset ( *M_uk, 0 );
399 vector_Type veloFluidMesh ( M_uFESpace->map(), Repeated );
400 this->transferMeshMotionOnFluid ( *meshVelRep, veloFluidMesh );
404 M_fluid->updateShapeDerivatives ( *sdMatrix, alpha,
408 M_solidAndFluidDim + M_interface * nDimensions,
414 void FSIMonolithicGI::assembleMeshBlock ( UInt )
417 M_meshBlock.reset (
new matrix_Type ( *M_monolithicMap ) );
418 M_meshMotion->addSystemMatrixTo ( M_meshBlock );
419 M_meshBlock->globalAssemble();
420 UInt offset ( M_solidAndFluidDim + nDimensions * M_interface );
421 std::map< ID, ID >::const_iterator ITrow;
422 std::map< ID, ID > locdofmap ( M_dofStructureToFluid->localDofMap() );
438 matrixPtr_Type diagFilter (
new matrix_Type (*M_monolithicMap) );
439 diagFilter->insertZeroDiagonal ();
440 for ( ID dim = 0; dim < nDimensions; ++dim )
442 for ( ITrow = locdofmap.begin(); ITrow != locdofmap.end(); ++ITrow )
444 int i = ITrow->first;
445 int iRow = i + offset + dim * M_mmFESpace->dof().numTotalDof();
446 if ( M_meshBlock->mapPtr()->map (Unique)->MyGID (iRow) )
448 M_meshBlock->diagonalize ( iRow, 1. );
456 diagFilter->matrixPtr()->SumIntoGlobalValues ( iRow, 1, myValues, myIndices );
461 diagFilter->globalAssemble();
463 Int numLocalEntries = diagFilter->matrixPtr()->RowMap().NumMyElements();
464 Int* globalEntries = diagFilter->matrixPtr()->RowMap().MyGlobalElements();
465 UInt globalRowIndex (0);
471 Int controlValue (0);
473 for (Int i (0); i < numLocalEntries; ++i)
476 globalRowIndex = globalEntries[i];
479 srcRow = diagFilter->matrixPtr()->LRID (
static_cast<EpetraInt_Type> (globalRowIndex) );
480 diagFilter->matrixPtr()->ExtractMyRowView (srcRow, controlValue, diagValue, indices);
482 ASSERT ( controlValue == 1,
"Error: The matrix should be diagonal.");
483 if (diagValue[0] < 0.0)
485 M_meshBlock->diagonalize ( globalRowIndex, 1. );
493 bool FSIMonolithicGI::S_register = BlockPrecFactory::instance().registerProduct (
"AdditiveSchwarzGI",
494 &MonolithicBlockMatrix::createAdditiveSchwarz )
495 && BlockPrecFactory::instance().registerProduct (
"ComposedDNGI",
496 &MonolithicBlockComposedDN::createComposedDNGI )
497 && MonolithicBlockMatrix::Factory_Type::instance().registerProduct (
"AdditiveSchwarzGI",
498 &MonolithicBlockMatrix::createAdditiveSchwarz )
499 && MonolithicBlockMatrix::Factory_Type::instance().registerProduct (
"AdditiveSchwarzRNGI",
500 &MonolithicBlockMatrixRN::createAdditiveSchwarzRN )
501 && FSIOperator::FSIFactory_Type::instance().registerProduct (
"monolithicGI",
502 &FSIMonolithicGI::instantiate )
503 && BlockPrecFactory::instance().registerProduct (
"ComposedDNDGI",
504 &MonolithicBlockComposedDND::createComposedDNDGI )
505 && BlockPrecFactory::instance().registerProduct (
"ComposedDND2GI",
506 &MonolithicBlockComposedDND::createComposedDND2GI )
507 && BlockPrecFactory::instance().registerProduct (
"ComposedDN2GI",
508 &MonolithicBlockComposedDN::createComposedDN2GI );