28 #include <EpetraExt_Reindex_MultiVector.h> 31 #include <lifev/core/LifeV.hpp> 32 #include <lifev/fsi/solver/FSIMonolithic.hpp> 40 FSIMonolithic::FSIMonolithic() :
51 M_solidAndFluidDim (0),
55 M_numerationInterface(),
58 M_diagonalScale (
false),
64 M_preconditionedSymmetrizedMatrix(),
69 FSIMonolithic::~FSIMonolithic()
77 FSIMonolithic::setupFEspace()
79 super_Type::setupFEspace();
82 M_dFESpace.reset (
new FESpace<mesh_Type, MapEpetra> ( M_solidMesh,
83 M_data->dataSolid()->order(),
90 FSIMonolithic::setupDOF (
void )
92 M_dofStructureToHarmonicExtension .reset (
new DOFInterface3Dto3D );
93 M_dofStructureToFluid .reset (
new DOFInterface3Dto3D );
95 M_dofStructureToHarmonicExtension->setup ( M_mmFESpace->refFE(), M_mmFESpace->dof(),
96 M_dFESpace->refFE(), M_dFESpace->dof() );
97 M_dofStructureToHarmonicExtension->update ( *M_mmFESpace->mesh(), M_data->fluidInterfaceFlag(),
98 *M_dFESpace->mesh(), M_data->structureInterfaceFlag(),
99 M_data->interfaceTolerance(),
100 M_data->fluidInterfaceVertexFlag() );
102 M_dofStructureToFluid->setup ( M_uFESpace->refFE(), M_uFESpace->dof(),
103 M_dFESpace->refFE(), M_dFESpace->dof() );
104 M_dofStructureToFluid->update ( *M_uFESpace->mesh(), M_data->fluidInterfaceFlag(),
105 *M_dFESpace->mesh(), M_data->structureInterfaceFlag(),
106 M_data->interfaceTolerance(),
107 M_data->fluidInterfaceVertexFlag() );
109 createInterfaceMaps (M_dofStructureToFluid->localDofMap() );
117 FSIMonolithic::setupDOF ( meshFilter_Type& filterMesh )
119 createInterfaceMaps (*filterMesh.getStoredInterface (0) );
124 FSIMonolithic::setupSystem( )
126 M_fluid->setUp ( M_dataFile );
127 setup ( M_dataFile );
131 FSIMonolithic::setup (
const GetPot& dataFile )
134 M_linearSolver.reset (
new solver_Type (M_epetraComm) );
136 M_linearSolver->setDataFromGetPot ( dataFile,
"linear_system/solver" );
137 std::string prectype = dataFile (
"problem/DDBlockPrec",
"PRECTYPE_UNDEFINED");
138 std::string opertype = dataFile (
"problem/blockOper",
"PRECTYPE_UNDEFINED");
140 M_precPtr.reset (BlockPrecFactory::instance().createObject ( prectype ) );
142 M_precPtr->setupSolver (*M_linearSolver, dataFile);
143 std::string section (
"linear_system/prec");
144 M_precPtr->setComm (M_epetraComm);
145 M_precPtr->setDataFromGetPot (dataFile, section);
146 M_monolithicMatrix->setComm (M_epetraComm);
147 M_monolithicMatrix->setDataFromGetPot (dataFile, section);
148 M_reusePrec = dataFile (
"linear_system/prec/reuse",
true);
149 M_maxIterSolver = dataFile (
"linear_system/solver/max_iter", -1);
150 M_diagonalScale = dataFile (
"linear_system/prec/diagonalScaling",
false );
151 M_restarts = dataFile (
"exporter/start" , 0 );
155 FSIMonolithic::setupFluidSolid( )
157 M_BCh_flux = M_BCh_u;
158 M_fluxes = M_BCh_u->size( );
160 setupFluidSolid ( M_fluxes );
162 M_BCh_flux->setOffset (M_offset - M_fluxes);
163 std::vector<BCBase>::iterator fluxIt = M_BCh_flux->begin( );
164 for ( UInt i = 0; i < M_fluxes; ++i, ++fluxIt )
166 fluxIt->setOffset ( i );
172 FSIMonolithic::setupFluidSolid ( UInt
const fluxes )
176 assert (M_fluidInterfaceMap->map (Unique)->NumGlobalElements() == M_solidInterfaceMap->map (Unique)->NumGlobalElements() );
178 M_interfaceMap = M_solidInterfaceMap;
181 std::map<ID, ID>::const_iterator ITrow;
183 M_monolithicMap.reset (
new MapEpetra (M_uFESpace->map() ) );
185 std::string opertype = M_dataFile (
"problem/blockOper",
"AdditiveSchwarz");
187 createOperator ( opertype );
189 *M_monolithicMap += M_pFESpace->map();
190 *M_monolithicMap += fluxes;
191 *M_monolithicMap += M_dFESpace->map();
193 M_monolithicMatrix->createInterfaceMap ( *M_interfaceMap, M_dofStructureToFluid->localDofMap(), M_dFESpace->map().map (Unique)->NumGlobalElements() / nDimensions, M_epetraWorldComm );
194 *M_monolithicMap += *M_monolithicMatrix->interfaceMap();
197 M_monolithicMatrix->numerationInterface (M_numerationInterface);
198 M_beta.reset (
new vector_Type (M_uFESpace->map() ) );
200 M_offset = M_uFESpace->dof().numTotalDof() * nDimensions + fluxes + M_pFESpace->dof().numTotalDof();
201 M_solidAndFluidDim = M_offset + M_dFESpace->dof().numTotalDof() * nDimensions;
202 M_BCh_d->setOffset (M_offset);
211 FSIMonolithic::monolithicToInterface (vector_Type& lambdaSolid,
const vector_Type& disp)
213 if (disp.mapType() == Repeated)
215 vector_Type
const dispUnique (disp, Unique);
216 monolithicToInterface (lambdaSolid, dispUnique);
219 if (lambdaSolid.mapType() == Repeated)
221 vector_Type lambdaSolidUn (lambdaSolid.map(), Unique);
222 monolithicToInterface ( lambdaSolidUn, disp);
223 lambdaSolid = lambdaSolidUn;
227 MapEpetra subMap (*disp.map().map (Unique), M_offset, disp.map().map (Unique)->NumGlobalElements() );
228 vector_Type subDisp (subMap, Unique);
229 subDisp.subset (disp, M_offset);
230 lambdaSolid = subDisp;
234 FSIMonolithic::monolithicToX (
const vector_Type& disp, vector_Type& dispFluid, MapEpetra& map, UInt offset)
236 if (disp.mapType() == Repeated)
238 vector_Type dispUnique (disp, Unique);
239 monolithicToX (dispUnique, dispFluid, map, offset);
240 dispFluid = dispUnique;
243 dispFluid.subset (disp, map, offset, offset);
248 FSIMonolithic::buildSystem()
250 M_solid->buildSystem ( M_solidTimeAdvance->coefficientSecondDerivative ( 0 ) / (M_data->dataSolid()->dataTime()->timeStep() *M_data->dataSolid()->dataTime()->timeStep() ) );
253 #ifdef HAVE_TRILINOS_ANASAZI 255 FSIMonolithic::computeMaxSingularValue( )
257 typedef Epetra_Operator operatorPtr_Type;
259 M_preconditionedSymmetrizedMatrix.reset (
new ComposedOperator<Epetra_Operator> (M_epetraComm) );
261 std::shared_ptr<operatorPtr_Type> ComposedPrecPtr (M_linearSolver->preconditioner()->preconditioner() );
264 std::shared_ptr<Epetra_FECrsMatrix> matrCrsPtr (
new Epetra_FECrsMatrix (*M_monolithicMatrix->matrix()->matrixPtr() ) );
265 M_preconditionedSymmetrizedMatrix->push_back (std::static_pointer_cast<operatorPtr_Type> (matrCrsPtr) );
266 M_preconditionedSymmetrizedMatrix->push_back ( (ComposedPrecPtr),
true);
267 M_preconditionedSymmetrizedMatrix->push_back ( (ComposedPrecPtr),
true,
true);
268 M_preconditionedSymmetrizedMatrix->push_back (std::static_pointer_cast<operatorPtr_Type> (matrCrsPtr),
false,
true);
270 std::vector<LifeV::Real> real;
271 std::vector<LifeV::Real> imaginary;
273 std::shared_ptr<EigenSolver> eig;
275 UInt nev = M_dataFile (
"eigensolver/nevec", 10);
278 eig.reset (
new EigenSolver (M_preconditionedSymmetrizedMatrix, M_preconditionedSymmetrizedMatrix->OperatorDomainMap(), nev) );
279 eig->setDataFromGetPot (M_dataFile,
"eigensolver/");
281 eig->eigenvalues (real, imaginary);
285 throw UNDEF_EIGENSOLVER_EXCEPTION();
287 for (UInt i = 0; i < real.size(); ++i)
289 displayer().leaderPrint (
"\n real part ", real[i]);
290 displayer().leaderPrint (
"\n imaginary part ", imaginary[i]);
297 FSIMonolithic::computeFluidNormals ( vector_Type& normals)
299 BCManageNormal<matrix_Type> normalManager;
300 if ( !M_BChWS->bcUpdateDone() )
302 M_BChWS->bcUpdate (*M_uFESpace->mesh(), M_uFESpace->feBd(), M_uFESpace->dof() );
304 normalManager.init ( (*M_BChWS) [0], 0.);
305 normalManager.computeIntegratedNormals (M_uFESpace->dof(), M_uFESpace->feBd(), normals, *M_uFESpace->mesh() );
309 FSIMonolithic::solveJac ( vector_Type& step,
const vector_Type& res,
const Real )
313 checkIfChangedFluxBC ( M_precPtr );
315 M_precPtr->blockAssembling();
316 M_precPtr->applyBoundaryConditions ( dataFluid()->dataTime()->time() );
317 M_precPtr->GlobalAssemble();
319 #ifdef HAVE_LIFEV_DEBUG 320 M_solid->displayer().leaderPrint (
" M- Residual NormInf: ", res.normInf(),
"\n");
322 iterateMonolithic (res, step);
323 #ifdef HAVE_LIFEV_DEBUG 324 M_solid->displayer().leaderPrint (
" M- Solution NormInf: ", step.normInf(),
"\n");
329 FSIMonolithic::updateSystem()
333 this->M_fluid->resetStabilization();
341 FSIMonolithic::iterateMonolithic (
const vector_Type& rhs, vector_Type& step)
345 displayer().leaderPrint (
" M- Solving the system ... \n" );
350 M_linearSolver->setOperator (*M_monolithicMatrix->matrix()->matrixPtr() );
352 M_linearSolver->setReusePreconditioner ( (M_reusePrec) && (!M_resetPrec) );
354 int numIter = M_precPtr->solveSystem ( rhs, step, M_linearSolver );
360 M_solid->displayer().leaderPrint (
" Iterative solver failed, numiter = ", -numIter );
362 if (numIter <= -M_maxIterSolver)
364 M_solid->displayer().leaderPrint (
" ERROR: Iterative solver failed.\n");
372 FSIMonolithic::couplingRhs (vectorPtr_Type rhs)
374 std::map<ID, ID>
const& localDofMap = M_dofStructureToFluid->localDofMap();
375 std::map<ID, ID>::const_iterator ITrow;
377 vector_Type rhsStructureVelocity (M_solidTimeAdvance->rhsContributionFirstDerivative() *M_solid->rescaleFactor(), Unique, Add);
378 vector_Type lambda (*M_interfaceMap, Unique);
380 this->monolithicToInterface (lambda, rhsStructureVelocity);
382 UInt interface (M_monolithicMatrix->interface() );
383 UInt totalDofs (M_dFESpace->dof().numTotalDof() );
386 for (UInt dim = 0; dim < nDimensions; ++dim)
388 for ( ITrow = localDofMap.begin(); ITrow != localDofMap.end() ; ++ITrow)
390 if (M_interfaceMap->map (Unique)->LID (
static_cast<EpetraInt_Type> (ITrow->second ) ) >= 0 )
394 (*rhs) [ (
int) (*M_numerationInterface) [ITrow->second ] + dim * interface + M_solidAndFluidDim ] = -lambda ( ITrow->second + dim * totalDofs );
403 evalResidual (
const vector_Type& sol,
const vectorPtr_Type& rhs, vector_Type& res,
bool diagonalScaling)
405 if ( diagonalScaling )
407 diagonalScale (*rhs, M_monolithicMatrix->matrix() );
411 if ( ! ( M_data->dataSolid()->lawType().compare (
"nonlinear") ) )
415 vectorPtr_Type solidPart (
new vector_Type ( M_dFESpace->map() ) );
416 solidPart->subset (sol, M_offset );
418 vectorPtr_Type resSolidPart (
new vector_Type ( M_dFESpace->map() ) );
419 resSolidPart->subset (res, M_offset );
422 *solidPart *= M_solid->rescaleFactor();
425 M_solid->apply (*solidPart, *resSolidPart);
427 resSolidPart->globalAssemble();
432 res.subset ( *resSolidPart, resSolidPart->map(), UInt (0), M_offset);
434 res.globalAssemble();
436 M_fluidBlock->globalAssemble();
438 res += ( (*M_fluidBlock) * sol);
440 M_monolithicMatrix->coupling()->globalAssemble();
442 res += *M_monolithicMatrix->coupling() * sol;
447 res = * (M_monolithicMatrix->matrix() ) * sol;
455 updateSolidSystem ( vectorPtr_Type& rhsFluidCoupling )
457 Real coefficient ( M_data->dataSolid()->dataTime()->timeStep() * M_data->dataSolid()->dataTime()->timeStep() * M_solid->rescaleFactor() / M_solidTimeAdvance->coefficientSecondDerivative ( 0 ) );
459 M_solidTimeAdvance->updateRHSContribution ( M_data->dataSolid()->dataTime()->timeStep() );
462 vectorPtr_Type solidPortionRHSSecondDerivative (
new vector_Type ( M_dFESpace->map() ) );
463 solidPortionRHSSecondDerivative->subset (M_solidTimeAdvance->rhsContributionSecondDerivative(), M_offset );
466 std::shared_ptr<MatrixEpetra<Real> > solidMassMatrix (
new MatrixEpetra<Real> ( M_solid->map(), 1 ) );
467 *solidMassMatrix *= 0.0;
468 *solidMassMatrix += *M_solid->massMatrix();
469 solidMassMatrix->globalAssemble();
471 vectorPtr_Type solidPortionRHSFluidCoupling (
new vector_Type ( M_dFESpace->map() ) );
472 *solidPortionRHSFluidCoupling *= 0.0;
475 *solidPortionRHSFluidCoupling = *solidMassMatrix * ( *solidPortionRHSSecondDerivative * coefficient );
478 rhsFluidCoupling->subset ( *solidPortionRHSFluidCoupling, solidPortionRHSFluidCoupling->map(), UInt (0), M_offset);
482 void FSIMonolithic::setVectorInStencils (
const vectorPtr_Type& vel,
483 const vectorPtr_Type& pressure,
484 const vectorPtr_Type& solidDisp,
488 setFluidVectorInStencil (vel, pressure, iter);
489 setSolidVectorInStencil (solidDisp, iter);
494 void FSIMonolithic::setFluidVectorInStencil (
const vectorPtr_Type& vel,
495 const vectorPtr_Type& pressure,
503 vectorPtr_Type vectorMonolithicFluidVelocity (
new vector_Type (*M_monolithicMap, Unique, Zero) );
504 vectorPtr_Type vectorMonolithicFluidPressure (
new vector_Type (*M_monolithicMap, Unique, Zero) );
506 *vectorMonolithicFluidVelocity *= 0.0;
507 *vectorMonolithicFluidPressure *= 0.0;
509 vectorMonolithicFluidVelocity->subset (*vel, vel->map(), UInt (0), UInt (0) ) ;
510 vectorMonolithicFluidPressure->subset ( *pressure, pressure->map(), UInt (0), (UInt) 3 * M_uFESpace->dof().numTotalDof() );
512 *vectorMonolithicFluidVelocity += *vectorMonolithicFluidPressure;
514 vector_Type* normalPointerToFluidVector (
new vector_Type (*vectorMonolithicFluidVelocity) );
515 (M_fluidTimeAdvance->stencil() ).push_back ( normalPointerToFluidVector );
519 void FSIMonolithic::setSolidVectorInStencil (
const vectorPtr_Type& solidDisp,
523 vectorPtr_Type vectorMonolithicSolidDisplacement (
new vector_Type (*M_monolithicMap, Unique, Zero) );
524 *vectorMonolithicSolidDisplacement *= 0.0;
525 vectorMonolithicSolidDisplacement->subset ( *solidDisp, solidDisp->map(), (UInt) 0, M_offset);
526 *vectorMonolithicSolidDisplacement *= 1.0 / M_solid->rescaleFactor();
531 if ( iter <= M_fluidTimeAdvance->size() - 1 )
533 * ( M_fluidTimeAdvance->stencil() [ iter ] ) += *vectorMonolithicSolidDisplacement;
536 vector_Type* normalPointerToSolidVector (
new vector_Type (*vectorMonolithicSolidDisplacement) );
537 (M_solidTimeAdvance->stencil() ).push_back ( normalPointerToSolidVector );
541 void FSIMonolithic::finalizeRestart( )
544 vector_Type zeroFluidSolid (*M_monolithicMap, Unique, Zero);
545 vector_Type zeroALE (M_mmFESpace->map(), Unique, Zero);
547 zeroFluidSolid *= 0.0;
550 M_fluidTimeAdvance->setInitialRHS (zeroFluidSolid);
551 M_solidTimeAdvance->setInitialRHS (zeroFluidSolid);
552 M_ALETimeAdvance->setInitialRHS (zeroALE);
558 M_ALETimeAdvance->updateRHSFirstDerivative ( M_data->dataFluid()->dataTime()->timeStep() );
561 void FSIMonolithic::initializeMonolithicOperator ( std::vector< vectorPtr_Type> u0,
562 std::vector< vectorPtr_Type> ds0,
563 std::vector< vectorPtr_Type> df0)
566 if (!u0.size() || !ds0.size() || !df0.size() )
568 if (
this->isFluid() )
570 for (i = 0; i < M_fluidTimeAdvance->size(); ++i)
572 vectorPtr_Type vec (
new vector_Type ( *M_monolithicMap ) );
575 for (i = 0; i < M_ALETimeAdvance->size(); ++i)
577 vectorPtr_Type vec (
new vector_Type ( M_mmFESpace->map() ) );
581 if (
this->isSolid() )
583 for (i = 0; i < M_solidTimeAdvance->size(); ++i)
585 vectorPtr_Type vec (
new vector_Type ( *M_monolithicMap ) );
589 initializeTimeAdvance (u0, ds0, df0);
594 initializeTimeAdvance (u0, ds0, df0);
601 diagonalScale (vector_Type& rhs, matrixPtr_Type matrFull)
603 Epetra_Vector diagonal (*rhs.map().map (Unique) );
607 matrFull->matrixPtr()->InvColMaxs (diagonal);
608 matrFull->matrixPtr()->LeftScale (diagonal);
609 rhs.epetraVector().Multiply (1, rhs.epetraVector(), diagonal, 0);
613 FSIMonolithic::variablesInit (
const std::string& dOrder)
615 M_dFESpace.reset (
new FESpace<mesh_Type, MapEpetra> (M_solidLocalMesh,
620 M_dETFESpace.reset (
new ETFESpace<mesh_Type, MapEpetra, 3, 3> (M_solidLocalMesh,
621 & (M_dFESpace->refFE() ),
622 & (M_dFESpace->fe().geoMap() ),
627 M_lambdaFluid.reset (
new vector_Type (*M_fluidInterfaceMap, Unique) );
628 M_lambdaFluidRepeated.reset (
new vector_Type (*M_fluidInterfaceMap, Repeated) );
631 void FSIMonolithic::setupBlockPrec( )
633 if (! (M_precPtr->set() ) )
635 M_precPtr->push_back_matrix (M_solidBlockPrec, M_structureNonLinear);
636 M_precPtr->push_back_matrix (M_fluidBlock,
true);
637 M_precPtr->setConditions (M_BChs);
638 M_precPtr->setSpaces (M_FESpaces);
639 M_precPtr->setOffsets (2, M_offset, 0);
640 M_precPtr->coupler (M_monolithicMap, M_dofStructureToFluid->localDofMap(), M_numerationInterface, M_data->dataFluid()->dataTime()->timeStep(), M_solidTimeAdvance->coefficientFirstDerivative ( 0 ), M_solid->rescaleFactor() );
644 M_precPtr->replace_matrix (M_fluidBlock, 1);
645 M_precPtr->replace_matrix (M_solidBlockPrec, 0);
650 std::shared_ptr<MonolithicBlockComposed> blockPrecPointer ( std::dynamic_pointer_cast<MonolithicBlockComposed> M_precPtr);
652 if (blockPrecPointer.get() != 0)
654 UInt fluidPosition = blockPrecPointer->whereIsBlock (MonolithicBlockComposed::fluid);
655 ASSERT (blockPrecPointer->blockPrecs().size() < fluidPosition,
"The preconditioner corresponding to the fluid block is probably not PCD. Check in the data file");
656 std::shared_ptr<PreconditionerPCD> prec_PCD ( std::dynamic_pointer_cast<PreconditionerPCD> blockPrecPointer->blockPrecs() [fluidPosition] );
659 if (prec_PCD.get() != 0)
661 prec_PCD->setFESpace (M_uFESpace, M_pFESpace);
662 prec_PCD->setBCHandler (M_BCh_u);
663 prec_PCD->setTimestep (M_data->dataFluid()->dataTime()->timeStep() );
664 prec_PCD->setViscosity (M_data->dataFluid()->viscosity() );
665 prec_PCD->setDensity (M_data->dataFluid()->density() );
666 prec_PCD->setCouplingMatrixView (M_precPtr->couplingVector() [MonolithicBlockComposed::fluid]);
667 prec_PCD->setMapStructure (&M_dFESpace->map() );
668 prec_PCD->updateBeta (M_fluidTimeAdvance->singleElement (0) );
675 FSIMonolithic::assembleSolidBlock ( UInt iter,
const vector_Type& solution )
679 updateSolidSystem (
this->M_rhs);
683 M_solidBlockPrec.reset (
new matrix_Type (*M_monolithicMap, 1) );
684 *M_solidBlockPrec *= 0.0;
689 vectorPtr_Type solidPortion (
new vector_Type ( M_dFESpace->map() ) );
690 solidPortion->subset (solution, M_offset );
693 *solidPortion *= M_solid->rescaleFactor();
698 MapEpetra mapEpetraFluxes ( M_fluxes, M_epetraComm );
703 matrixBlockPtr_Type globalMatrixWithOnlyStructure;
706 if ( !M_data->method().compare (
"monolithicGI") )
708 globalMatrixWithOnlyStructure.reset (
new matrixBlock_Type ( M_uFESpace->map() | M_pFESpace->map() | mapEpetraFluxes | M_dFESpace->map()
709 | * (M_monolithicMatrix->interfaceMap() ) | M_mmFESpace->map() ) );
714 globalMatrixWithOnlyStructure.reset (
new matrixBlock_Type ( M_uFESpace->map() | M_pFESpace->map() | mapEpetraFluxes | M_dFESpace->map()
715 | * (M_monolithicMatrix->interfaceMap() ) ) );
719 M_solid->material()->updateJacobianMatrix ( *solidPortion, dataSolid(), M_solid->mapMarkersVolumes(), M_solid->mapMarkersIndexes(), M_solid->displayerPtr() );
722 std::shared_ptr<MatrixEpetra<Real> > solidMatrix (
new MatrixEpetra<Real> ( M_solid->map(), 1 ) );
725 *solidMatrix += *M_solid->massMatrix();
726 *solidMatrix += * (M_solid->material()->jacobian() );
728 solidMatrix->globalAssemble();
730 MatrixEpetra<Real>* rawPointerToMatrix =
new MatrixEpetra<Real> ( *solidMatrix );
732 matrixBlockView_Type structurePart (* (globalMatrixWithOnlyStructure->block (3, 3) ) );
734 structurePart.setup (UInt (0), UInt (0), UInt (3 * M_dFESpace->dof().numTotalDof() ), UInt (3 * M_dFESpace->dof().numTotalDof() ), rawPointerToMatrix);
736 using namespace MatrixEpetraStructuredUtility;
739 copyBlock ( structurePart, * (globalMatrixWithOnlyStructure->block (3, 3) ) );
741 globalMatrixWithOnlyStructure->globalAssemble();
744 *M_solidBlockPrec += *globalMatrixWithOnlyStructure;
746 M_solidBlockPrec->globalAssemble();
748 *M_solidBlockPrec *= M_solid->rescaleFactor();
750 delete rawPointerToMatrix;
754 FSIMonolithic::assembleFluidBlock (UInt iter,
const vector_Type& solution)
756 M_fluidBlock.reset (
new FSIOperator::fluid_Type::matrix_Type (*M_monolithicMap) );
758 Real alpha = M_fluidTimeAdvance->coefficientFirstDerivative ( 0 ) / M_data->dataFluid()->dataTime()->timeStep();
761 M_fluid->updateSystem (alpha, *
this->M_beta, *
this->M_rhs, M_fluidBlock, solution );
771 M_fluidTimeAdvance->updateRHSContribution ( M_data->dataFluid()->dataTime()->timeStep() );
772 if (!M_data->dataFluid()->conservativeFormulation() )
774 *M_rhs += M_fluid->matrixMass() * (M_fluidTimeAdvance->rhsContributionFirstDerivative() );
778 *M_rhs += (M_fluidMassTimeAdvance->rhsContributionFirstDerivative() );
784 if (M_data->dataFluid()->conservativeFormulation() )
786 M_fluid->updateSystem (alpha, *
this->M_beta, *
this->M_rhs, M_fluidBlock, solution );
788 this->M_fluid->updateStabilization (*M_fluidBlock);
791 void FSIMonolithic::updateRHS()
794 M_fluidTimeAdvance->updateRHSContribution ( M_data->dataFluid()->dataTime()->timeStep() );
795 *M_rhs += M_fluid->matrixMass() * (M_fluidTimeAdvance->rhsContributionFirstDerivative() );
799 updateSolidSystem (M_rhs);
807 static Real fZero (
const Real& ,
const Real& ,
const Real& ,
const Real& ,
const ID& )
811 static Real fOne (
const Real& ,
const Real& ,
const Real& ,
const Real& ,
const ID& )
817 void FSIMonolithic::enableStressComputation (UInt flag)
819 M_BChWS.reset (
new solidBchandler_Type() );
820 BCFunctionBase bcfZero (fZero);
821 BCFunctionBase bcfOne (fOne);
822 M_bcfWs.setFunctions_Robin (bcfOne, bcfOne);
824 M_BChWS->addBC (
"WS", (UInt) flag, Robin, Full, M_bcfWs, 3);
827 FSIMonolithic::vectorPtr_Type FSIMonolithic::computeStress()
829 vector_Type lambda (M_monolithicMatrix->interfaceMap() );
830 lambda.subset (M_fluidTimeAdvance->singleElement (0), M_solidAndFluidDim);
832 M_boundaryMass.reset (
new matrix_Type (*M_interfaceMap) );
833 if ( !M_BChWS->bcUpdateDone() )
835 M_BChWS->bcUpdate (*M_dFESpace->mesh(), M_dFESpace->feBd(), M_dFESpace->dof() );
837 bcManageMatrix (*M_boundaryMass, *M_dFESpace->mesh(), M_dFESpace->dof(), *M_BChWS, M_dFESpace->feBd(), 1., dataSolid()->dataTime()->time() );
838 M_boundaryMass->globalAssemble();
840 solver_Type solverMass (M_epetraComm);
841 solverMass.setDataFromGetPot ( M_dataFile,
"solid/solver" );
842 solverMass.setupPreconditioner (M_dataFile,
"solid/prec");
844 std::shared_ptr<PreconditionerIfpack> P (
new PreconditionerIfpack() );
846 vectorPtr_Type sol (
new vector_Type (M_monolithicMatrix->interfaceMap() ) );
847 solverMass.setMatrix (*M_boundaryMass);
848 solverMass.setReusePreconditioner (
false);
849 solverMass.solveSystem ( lambda, *sol, M_boundaryMass);
851 EpetraExt::MultiVector_Reindex reindexMV (*M_interfaceMap->map (Unique) );
852 std::shared_ptr<MapEpetra> newMap (
new MapEpetra ( *M_interfaceMap ) );
853 M_stress.reset (
new vector_Type (reindexMV (lambda.epetraVector() ), newMap, Unique) );
858 FSIMonolithic::checkIfChangedFluxBC ( precPtr_Type oper )
860 UInt nfluxes (M_BChs[1]->numberOfBCWithType (Flux) );
861 if (M_fluxes != nfluxes)
863 for (UInt i = 0; i < M_fluxes; ++i)
865 const BCBase* bc (M_BChs[1]->findBCWithName (M_BCFluxNames[i]) );
866 if (bc->type() != Flux)
868 oper->addToCoupling (1., M_fluxOffset[i], M_fluxOffset[i], 1 );