36 #include <lifev/core/LifeV.hpp> 37 #include <lifev/fsi/solver/FSISolver.hpp> 39 #include <lifev/core/algorithm/NonLinearRichardson.hpp> 47 FSISolver::FSISolver() :
50 M_fluidInterfaceMap ( ),
51 M_solidInterfaceMap ( ),
53 M_epetraWorldComm ( ),
54 M_localComm (
new MPI_Comm ),
55 M_interComm (
new MPI_Comm )
58 debugStream ( 6220 ) <<
"FSISolver::FSISolver constructor starts\n";
68 FSISolver::setData (
const dataPtr_Type& data )
73 MPI_Comm_rank (MPI_COMM_WORLD, &rank);
74 MPI_Comm_size (MPI_COMM_WORLD, &numtasks);
82 if ( ( data->method().compare (
"monolithicGE") && data->method().compare (
"monolithicGI") ) )
84 MPI_Group originGroup, newGroup;
85 MPI_Comm_group (MPI_COMM_WORLD, &originGroup);
89 std::cout <<
"Serial Fluid/Structure computation" << std::endl;
93 fluidLeader = solidLeader;
95 M_epetraWorldComm.reset (
new Epetra_MpiComm (MPI_COMM_WORLD) );
96 M_epetraComm = M_epetraWorldComm;
100 std::vector<
int> members (numtasks);
103 fluidLeader = 1 - solidLeader;
105 if (rank == solidLeader)
107 members[0] = solidLeader;
109 MPI_Group_incl (originGroup, 1, &members[0], &newGroup);
114 for (Int ii = 0; ii <= numtasks; ++ii)
116 if ( ii < solidLeader)
120 else if ( ii > solidLeader)
122 members[ii - 1] = ii;
126 MPI_Group_incl (originGroup, numtasks - 1, &members[0], &newGroup);
130 MPI_Comm* localComm =
new MPI_Comm;
131 MPI_Comm_create (MPI_COMM_WORLD, newGroup, localComm);
132 M_localComm.reset (localComm);
134 M_epetraComm.reset (
new Epetra_MpiComm (*M_localComm.get() ) );
135 M_epetraWorldComm.reset (
new Epetra_MpiComm (MPI_COMM_WORLD) );
143 fluidLeader = solidLeader;
145 M_epetraWorldComm.reset (
new Epetra_MpiComm (MPI_COMM_WORLD) );
146 M_epetraComm = M_epetraWorldComm;
152 debugStream (6220) << M_epetraComm->MyPID()
153 <<
" ( " << rank <<
" ) " 154 <<
" out of " << M_epetraComm->NumProc()
155 <<
" ( " << numtasks <<
" ) " 156 <<
" is fluid." << std::endl;
160 debugStream (6220) << M_epetraComm->MyPID()
161 <<
" ( " << rank <<
" ) " 162 <<
" out of " << M_epetraComm->NumProc()
163 <<
" ( " << numtasks <<
" ) " 164 <<
" is solid." << std::endl;
168 M_epetraWorldComm->Barrier();
201 M_oper->setFluid ( fluid );
202 M_oper->setSolid ( solid );
204 M_oper->setFluidLeader ( fluidLeader );
205 M_oper->setSolidLeader ( solidLeader );
207 M_oper->setComm ( M_epetraComm, M_epetraWorldComm );
210 if (M_epetraWorldComm->MyPID() == 0)
212 M_out_iter.open (
"iter");
213 M_out_res .open (
"res");
216 M_epetraWorldComm->Barrier();
219 debugStream ( 6220 ) <<
"FSISolver constructor ends\n";
231 M_oper->setData ( data );
235 FSISolver::setup (
void )
237 M_oper->setupFluidSolid();
239 M_oper->setupSystem();
241 M_oper->buildSystem();
245 FSISolver::initialize (std::vector< vectorPtr_Type> u0, std::vector< vectorPtr_Type> ds0, std::vector< vectorPtr_Type> df0)
248 if (!u0.size() || !ds0.size() || !df0.size() )
250 if (
this->isFluid() )
252 for (i = 0; i < M_oper->fluidTimeAdvance()->size(); ++i)
254 vectorPtr_Type vec (
new vector_Type (M_oper->fluid().getMap() ) );
257 for (i = 0; i < M_oper->ALETimeAdvance()->size(); ++i)
259 vectorPtr_Type vec (
new vector_Type (M_oper->meshMotion().getMap() ) );
263 if (
this->isSolid() )
265 for (i = 0; i < M_oper->solidTimeAdvance()->size(); ++i)
267 vectorPtr_Type vec (
new vector_Type (M_oper->solid().map() ) );
271 M_oper->initializeTimeAdvance (u0, ds0, df0);
276 M_oper->initializeTimeAdvance (u0, ds0, df0);
282 FSISolver::initializeMonolithicOperator (std::vector< vectorPtr_Type> u0, std::vector< vectorPtr_Type> ds0, std::vector< vectorPtr_Type> df0)
284 M_oper->initializeMonolithicOperator ( u0, ds0, df0);
291 debugStream ( 6220 ) <<
"============================================================\n";
292 debugStream ( 6220 ) <<
"Solving FSI at time " << M_data->dataFluid()->dataTime()->time() <<
" with FSI: " << M_data->method() <<
"\n";
293 debugStream ( 6220 ) <<
"============================================================\n";
295 if (M_epetraWorldComm->MyPID() == 0)
297 std::cerr << std::endl <<
"Warning: FSISolver::iterate() is deprecated!" << std::endl
298 <<
" You should use FSISolver::iterate( solution ) instead!" << std::endl;
302 M_oper->updateSystem( );
305 vector_Type lambda = M_oper->solution();
308 UInt maxiter = M_data->maxSubIterationNumber();
309 UInt status = NonLinearRichardson ( lambda,
311 M_data->absoluteTolerance(),
312 M_data->relativeTolerance(),
314 M_data->errorTolerance(),
315 M_data->NonLinearLineSearch(),
319 M_data->dataFluid()->dataTime()->time()
323 M_oper->updateSolution ( lambda );
326 M_oper->updateSystem( );
328 if (status == EXIT_FAILURE)
330 std::ostringstream __ex;
331 __ex <<
"FSISolver::iterate ( " << M_data->dataFluid()->dataTime()->time() <<
" ) Inners iterations failed to converge\n";
332 throw std::logic_error ( __ex.str() );
337 if (M_epetraWorldComm->MyPID() == 0)
339 M_out_iter << M_data->dataFluid()->dataTime()->time() <<
" " << maxiter;
343 debugStream ( 6220 ) <<
"FSISolver iteration at time " << M_data->dataFluid()->dataTime()->time() <<
" done\n";
344 debugStream ( 6220 ) <<
"============================================================\n";
345 std::cout << std::flush;
350 FSISolver::iterate ( vectorPtr_Type& solution )
352 debugStream ( 6220 ) <<
"============================================================\n";
353 debugStream ( 6220 ) <<
"Solving FSI at time " << M_data->dataFluid()->dataTime()->time() <<
" with FSI: " << M_data->method() <<
"\n";
354 debugStream ( 6220 ) <<
"============================================================\n";
357 M_oper->updateSystem( );
361 vector_Type lambda ( *solution );
365 UInt maxiter = M_data->maxSubIterationNumber();
366 UInt status = NonLinearRichardson ( lambda,
368 M_data->absoluteTolerance(),
369 M_data->relativeTolerance(),
371 M_data->errorTolerance(),
372 M_data->NonLinearLineSearch(),
376 M_data->dataFluid()->dataTime()->time()
383 if (status == EXIT_FAILURE)
385 std::ostringstream __ex;
386 __ex <<
"FSISolver::iterate ( " << M_data->dataFluid()->dataTime()->time() <<
" ) Inners iterations failed to converge\n";
387 throw std::logic_error ( __ex.str() );
392 if (M_epetraWorldComm->MyPID() == 0)
394 M_out_iter << M_data->dataFluid()->dataTime()->time() <<
" " << maxiter;
398 debugStream ( 6220 ) <<
"FSISolver iteration at time " << M_data->dataFluid()->dataTime()->time() <<
" done\n";
399 debugStream ( 6220 ) <<
"============================================================\n";
400 std::cout << std::flush;
407 FSISolver::setSourceTerms (
const fluidSource_Type& fluidSource,
408 const solidSource_Type& solidSource )
410 M_oper->fluid().setSourceTerm ( fluidSource );
411 M_oper->solid().setSourceTerm ( solidSource );
417 debugStream ( 6220 ) <<
"FSISolver::setFSI with operator " << M_data->method() <<
"\n";
418 M_oper = FSIOperPtr_Type ( FSIOperator::FSIFactory_Type::instance().createObject ( M_data->method() ) );
422 FSISolver::setFluidBC (
const fluidBchandlerPtr_Type& bc_fluid )
424 if (
this->isFluid() )
426 M_oper->setFluidBC ( bc_fluid );
431 FSISolver::setLinFluidBC (
const fluidBchandlerPtr_Type& bc_dfluid )
433 if (
this->isFluid() )
435 M_oper->setLinFluidBC ( bc_dfluid );
440 FSISolver::setInvLinFluidBC (
const fluidBchandlerPtr_Type& bc_dfluid_inv )
442 if (
this->isFluid() )
444 M_oper->setInvLinFluidBC ( bc_dfluid_inv );
449 FSISolver::setHarmonicExtensionBC (
const fluidBchandlerPtr_Type& bc_he )
451 if (
this->isFluid() )
453 M_oper->setHarmonicExtensionBC ( bc_he );
458 FSISolver::setSolidBC (
const solidBchandlerPtr_Type& bc_solid )
460 if (
this->isSolid() )
462 M_oper->setSolidBC ( bc_solid );
467 FSISolver::setLinSolidBC (
const solidBchandlerPtr_Type& bc_dsolid )
469 if (
this->isSolid() )
471 M_oper->setLinSolidBC ( bc_dsolid );
476 FSISolver::setInvLinSolidBC (
const solidBchandlerPtr_Type& bc_dsolid_inv )
478 if (
this->isSolid() )
480 M_oper->setInvLinSolidBC ( bc_dsolid_inv );