27 #include <lifev/fsi/solver/FSIExactJacobian.hpp> 57 const vector_Type& _res,
58 const Real _linearRelTol)
60 if (
this->isFluid() &&
this->isLeader() )
64 if (
this->isSolid() &&
this->isLeader() )
69 this->displayer().leaderPrint (
"FSI --- solveJac: NormInf res " , _res.normInf(),
"\n" );
72 M_linearSolver.setTolerance ( _linearRelTol );
73 M_linearSolver.setMaxNumIterations ( 100 );
75 vector_Type res (_res);
77 M_linearSolver.setOperator (M_epetraOper);
79 this->displayer().leaderPrint (
"FSI --- Solving Jacobian FSI system... " );
82 M_linearSolver.solve (_muk, res);
84 this->displayer().leaderPrint (
"FSI --- Solving the Jacobian FSI system done.\n" );
88 const vector_Type& disp,
93 std::cout <<
"FSI --- Residual computation g(x_" << iter <<
" )\n";
96 setLambdaSolidOld (disp);
101 res =
this->lambdaSolid();
104 if (
this->isSolid() )
106 M_solid->updateJacobian (M_solid->displacement() );
109 this->displayer().leaderPrint (
"FSI --- NormInf res = " , res.normInf(),
"\n" );
110 if (
this->isSolid() )
112 this->displayer().leaderPrint (
"FSI --- NormInf res_d = " ,
this->solid().residual().normInf(),
"\n" );
121 vector_Type dispFluidDomain ( M_fluid->matrixNoBC().map(), Unique, Zero);
122 dispFluidDomain.setCombineMode (Zero);
123 vector_Type dispFluidMesh (
this->derVeloFluidMesh().map(), Repeated);
125 if (
false &&
this->M_data->dataFluid()->isSemiImplicit() ==
true)
137 this->transferSolidOnFluid (
this->M_solid->displacement(), dispFluidMesh);
141 this->transferMeshMotionOnFluid (M_meshMotion->disp(),
145 dispFluidDomain = dispFluidMesh;
148 this->derVeloFluidMesh() = dispFluidMesh;
149 this->derVeloFluidMesh() *= M_fluidTimeAdvance->coefficientFirstDerivative (0) / (M_data->dataFluid()->dataTime()->timeStep() );
150 this->displayer().leaderPrint (
" norm inf dw = " , derVeloFluidMesh().normInf(),
"\n" );
153 double alpha =
this->M_fluidTimeAdvance->coefficientFirstDerivative ( 0 ) / M_data->dataFluid()->dataTime()->timeStep();
155 if (!
this->M_fluid->stabilization() )
158 this->M_fluid->updateLinearSystem ( M_fluid->matrixNoBC(),
160 M_fluidTimeAdvance->singleElement (0),
161 *M_fluid->solution(),
172 M_matrShapeDer.reset (
new matrix_Type (M_fluid->matrixNoBC().map() ) );
173 this->M_fluid->updateShapeDerivatives (
176 M_fluidTimeAdvance->singleElement (0),
177 *M_fluid->solution(),
187 M_matrShapeDer->globalAssemble();
188 *M_matrShapeDer *= -1;
191 *M_rhsNew = (*M_matrShapeDer) * dispFluidDomain;
192 M_fluid->updateLinearRightHandSideNoBC (*M_rhsNew);
195 this->M_fluid->solveLinearSystem ( *
this->M_BCh_du );
201 M_solid->iterateLin ( M_BCh_dz );
207 setLinearFluid (
true);
208 setLinearSolid (
true);
210 super::setupFEspace();
216 super::setupFluidSolid();
218 M_epetraOper.setOperator (
this);
220 if (
this->isFluid() )
222 M_rhsNew.reset (
new vector_Type (
this->M_fluid->getMap() ) );
223 M_beta.reset (
new vector_Type (
this->M_fluid->getMap() ) );
231 super::setDataFile ( dataFile );
233 M_aitkFS.setDefaultOmega ( M_data->defaultOmega(), 0.001 );
234 M_aitkFS.setOmegaRange ( M_data->OmegaRange() );
236 M_linearSolver.setCommunicator ( M_epetraComm );
237 M_linearSolver.setDataFromGetPot (dataFile,
"jacobian");
244 FSIFactory_Type::instance().registerProduct (
"exactJacobian", &createEJ );
246 solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct (
"linearVenantKirchhoff", &super::createVenantKirchhoffLinear );
247 solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct (
"nonLinearVenantKirchhoff", &super::createVenantKirchhoffNonLinear );
258 if (
this->isFluid() )
260 UInt numLM = super::imposedFluxes();
262 std::vector<bcName_Type> fluxVector = M_BCh_du->findAllBCWithType ( Flux );
263 if ( numLM != (
static_cast<UInt> ( fluxVector.size() ) ) )
265 ERROR_MSG (
"Different number of fluxes imposed on Fluid and on LinearFluid");
268 UInt offset = M_uFESpace->map().map (Unique)->NumGlobalElements()
269 + M_pFESpace->map().map (Unique)->NumGlobalElements();
271 for (
UInt i = 0; i < numLM; ++i )
273 M_BCh_du->setOffset ( fluxVector[i], offset + i );
291 LifeChrono chronoFluid, chronoSolid, chronoInterface;
293 bool recomputeMatrices ( iter == 0 || ( !
this->M_data->dataFluid()->isSemiImplicit() &&
294 ( M_data->updateEvery() > 0 &&
295 (iter % M_data->updateEvery() == 0) ) ) );
301 this->M_fluid->resetPreconditioner();
307 this->setLambdaFluid (_disp);
310 vector_Type sigmaFluidUnique (
this->sigmaFluid(), Unique);
312 M_epetraWorldComm->Barrier();
317 M_meshMotion->iterate (*M_BCh_mesh);
325 if ( iter == 0 || !
this->M_data->dataFluid()->isSemiImplicit() )
331 M_ALETimeAdvance->updateRHSFirstDerivative (M_data->dataFluid()->dataTime()->timeStep() );
332 M_ALETimeAdvance->shiftRight (M_meshMotion->disp() );
333 M_ALETimeAdvance->extrapolation (M_meshMotion->disp() );
337 M_ALETimeAdvance->setSolution (M_meshMotion->disp() );
340 vector_Type meshDispRepeated ( M_meshMotion->disp(), Repeated );
341 this->moveMesh (meshDispRepeated);
342 vector_Type vel (
this->M_ALETimeAdvance->firstDerivative( ) );
343 transferMeshMotionOnFluid ( vel, veloFluidMesh() );
344 M_fluidTimeAdvance->extrapolation (*M_beta);
345 *M_beta -= veloFluidMesh();
349 if (M_data->dataFluid()->conservativeFormulation() )
352 *M_rhs = M_fluidMassTimeAdvance->rhsContributionFirstDerivative();
356 if (recomputeMatrices)
358 double alpha = M_fluidTimeAdvance->coefficientFirstDerivative (0) / M_data->dataFluid()->dataTime()->timeStep();
359 this->M_fluid->updateSystem ( alpha, *M_beta, *M_rhs );
363 this->M_fluid->updateRightHandSide ( *M_rhs );
365 if (!M_data->dataFluid()->conservativeFormulation() )
367 *M_rhs = M_fluid->matrixMass() * M_fluidTimeAdvance->rhsContributionFirstDerivative();
368 this->M_fluid->updateRightHandSide ( *M_rhs );
372 this->M_fluid->iterate ( *M_BCh_u );
374 this->transferFluidOnInterface (
this->M_fluid->residual(), sigmaFluidUnique);
377 M_epetraWorldComm->Barrier();
379 this->displayer().leaderPrintMax (
" Fluid solution total time: ", chronoFluid.diff() );
381 if (
false &&
this->isFluid() )
383 vector_Type vel (
this->fluid().velocityFESpace().map() );
384 vector_Type press (
this->fluid().pressureFESpace().map() );
386 vel.subset (*
this->M_fluid->solution() );
387 press.subset (*
this->M_fluid->solution(),
this->fluid().velocityFESpace().dim() *
this->fluid().pressureFESpace().fieldDim() );
389 std::cout <<
"norm_inf( vel ) " << vel.normInf() << std::endl;
390 std::cout <<
"norm_inf( press ) " << press.normInf() << std::endl;
395 chronoInterface.start();
397 this->setSigmaFluid ( sigmaFluidUnique );
398 this->setSigmaSolid ( sigmaFluidUnique );
402 vector_Type lambdaSolidUnique (
this->lambdaSolid(), Unique);
403 vector_Type lambdaDotSolidUnique (
this->lambdaDotSolid(), Unique);
404 vector_Type sigmaSolidUnique (
this->sigmaSolid(), Unique);
406 chronoInterface.stop();
407 M_epetraWorldComm->Barrier();
410 if (
this->isSolid() )
412 this->M_solid->iterate ( M_BCh_d );
415 M_epetraWorldComm->Barrier();
417 this->displayer().leaderPrintMax (
" Solid solution total time: ", chronoSolid.diff() );
419 chronoInterface.start();
421 if (
this->isSolid() )
423 this->transferSolidOnInterface (
this->M_solid->displacement(), lambdaSolidUnique);
424 this->transferSolidOnInterface (
this->M_solidTimeAdvance->firstDerivative (
this->M_solid->displacement() ), lambdaDotSolidUnique );
425 this->transferSolidOnInterface (
this->M_solid->residual(), sigmaSolidUnique);
428 this->setLambdaSolid ( lambdaSolidUnique);
429 this->setLambdaDotSolid ( lambdaDotSolidUnique);
430 this->setSigmaSolid ( sigmaSolidUnique);
432 chronoInterface.stop();
433 this->displayer().leaderPrintMax (
" Interface transfer total time: ", chronoInterface.diffCumul() );
438 this->displayer().leaderPrint (
" Norm(disp ) = ", _disp.normInf(),
"\n");
439 this->displayer().leaderPrint (
" Norm(dispNew ) = " ,
this->lambdaSolid().normInf(),
"\n" );
440 this->displayer().leaderPrint (
" Norm(velo ) = " ,
this->lambdaDotSolid().normInf(),
"\n" );
441 this->displayer().leaderPrint (
" Max Residual Fluid = " ,
this->sigmaFluid().normInf(),
"\n" );
442 this->displayer().leaderPrint (
" Max Residual Solid = " ,
this->sigmaSolid().normInf(),
"\n" );
444 if (
this->isFluid() )
446 this->displayer().leaderPrint (
" Max ResidualF = " , M_fluid->residual().normInf(),
"\n" );
448 if (
this->isSolid() )
450 this->displayer().leaderPrint (
" NL2 Diplacement S. = " , M_solid->displacement().norm2(),
"\n" );
451 this->displayer().leaderPrint (
" Max Residual Solid = " , M_solid->residual().normInf(),
"\n" );
482 ASSERT (ej != 0,
"passing NULL pointer to se operator");
484 M_operatorDomainMap = M_ej->solidInterfaceMap()->map (Repeated);
485 M_operatorRangeMap = M_ej->solidInterfaceMap()->map (Repeated);
486 M_comm = M_ej->worldComm();
492 LifeChrono chronoFluid, chronoSolid, chronoInterface;
499 Epetra_FEVector dz (Y.Map() );
501 if (M_ej->isSolid() )
503 std::cout <<
"\n ***** norm (z)= " << xnorm << std::endl << std::endl;
514 vector_Type
const z (X, M_ej->solidInterfaceMap(), Unique);
516 M_ej->displayer().leaderPrint (
"NormInf res " , z.normInf(),
"\n" );
526 M_ej->setLambdaFluid (z);
530 chronoInterface.start();
531 vector_Type sigmaFluidUnique (M_ej->sigmaFluid(), Unique);
532 chronoInterface.stop();
537 if (M_ej->isFluid() )
541 if (
true || ( !
this->M_ej->dataFluid()->isSemiImplicit() ) )
543 M_ej->meshMotion().iterate (*M_ej->BCh_harmonicExtension() );
547 M_ej->displayer().leaderPrint (
" norm inf dx = " , M_ej->meshMotion().disp().normInf(),
"\n" );
551 M_ej->transferFluidOnInterface (M_ej->fluid().residual(), sigmaFluidUnique);
558 M_ej->displayer().leaderPrintMax (
"Fluid linear solution: total time : ", chronoFluid.diff() );
561 chronoInterface.start();
563 M_ej->setSigmaSolid (sigmaFluidUnique);
566 vector_Type lambdaSolidUnique (M_ej->lambdaSolid(), Unique);
567 chronoInterface.stop();
572 if (M_ej->isSolid() )
575 M_ej->transferSolidOnInterface (M_ej->solid().displacement(), lambdaSolidUnique);
580 M_ej->displayer().leaderPrintMax (
"Solid linear solution: total time : " , chronoSolid.diff() );
582 chronoInterface.start();
583 M_ej->setLambdaSolid (lambdaSolidUnique);
585 chronoInterface.stop();
586 M_ej->displayer().leaderPrintMax (
"Interface linear transfer: total time : " , chronoInterface.diffCumul() );
588 dz = lambdaSolidUnique.epetraVector();
593 Y.Update (1., dz, -1.);
598 if (M_ej->isSolid() )
599 std::cout <<
"\n\n ***** norm (Jz)= " << ynorm
600 << std::endl << std::endl;
void setOperator(FSIExactJacobian *ej)
sets the exactJacobian pointer and some contents thereof
void solveLinearSolid()
Solves the linear structure problem.
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
void registerMyProducts()
register the product for the factory
void eval(const vector_Type &_res, UInt status)
void solveLinearFluid()
Solves the linear fluid problem.
FSIExactJacobian()
Empty Constructor.
void setDataFile(GetPot const &data)
initializes the GetPot data file
Epetra_ExactJacobian()
Empty Constructor.
matrixPtr_Type M_matrShapeDer
Epetra_ExactJacobian This class implements an Epetra_Operator to be passed to AztecOO.
double Real
Generic real data.
FSIModelExactJacobian - Implementation of an FSI (Operator) with Newton algorithm.
void setupFluidSolid()
setup of the fluid and solid solver classes
void setupFEspace()
sets the space discretization parameters
void evalResidual(vector_Type &_res, const vector_Type &_disp, const UInt _iter)
Evaluates the nonlinear residual of the FSI system.
int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
apply the jacobian to X and returns the result in Y
mapPtr_Type M_operatorRangeMap
~FSIExactJacobian()
Destructor.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
mapPtr_Type M_operatorDomainMap
void solveJac(vector_Type &_muk, const vector_Type &_res, const Real _linearRelTol)
solves the Jacobian system