9 #ifndef __FSI_COUPLING_H__
10 #define __FSI_COUPLING_H__
13 #include "InterfaceLayer.H"
24 typedef IRAD::Global::GlobalObj<StackType,int,ProfilerType>
GlobalType;
53 SetName(
"fsicoupling");
61 std::stringstream outString;
63 std::vector<double> crdVecSolid1(solidAgent->
Coordinates());
64 std::vector<double> crdVecFluid1(fluidAgent->
Coordinates());
66 outString <<
"Solid Coodinates are : " << std::endl;
67 for (
int i = 0; i < crdVecSolid1.size()/3; i++)
68 outString << crdVecSolid1[i*3] <<
" "
69 << crdVecSolid1[i*3+1] <<
" "
70 << crdVecSolid1[i*3+2] << std::endl;
72 std::cout << outString.str() << std::endl;
75 outString <<
" Fluid Coodinates are : " << std::endl;
76 for (
int i = 0; i < crdVecFluid1.size()/3; i++)
77 outString << crdVecFluid1[i*3] <<
" "
78 << crdVecFluid1[i*3+1] <<
" "
79 << crdVecFluid1[i*3+2] << std::endl;
81 std::cout << outString.str() << std::endl;
88 double *fluidDisp1 = NULL;
89 double *fluidDisp2 = NULL;
90 double *solidDisp1 = NULL;
91 double *solidDisp2 = NULL;
99 outString <<
"Fluid displacements before transfer: " << std::endl;
100 for (
int i = 0; i < numberFluidNodes; i++)
101 outString << fluidDisp1[i*3] <<
" "
102 << fluidDisp1[i*3+1] <<
" "
103 << fluidDisp1[i*3+2] << std::endl;
105 std::cout << outString.str() << std::endl;
108 outString <<
" Solid displacements before transfer " << std::endl;
109 outString <<
"Number of nodes: " << numberSolidNodes << std::endl;
110 for (
int i = 0; i < numberSolidNodes; i++)
111 outString << solidDisp1[i*3] <<
" "
112 << solidDisp1[i*3+1] <<
" "
113 << solidDisp1[i*3+2] << std::endl;
115 std::cout << outString.str() << std::endl;
120 transferAgent->Interpolate(
"Displacements",
"solidDisplacement");
126 outString <<
"Number of fluid nodes: " << numberFluidNodes <<std::endl;
127 outString <<
"Fluid displacements after transfer : " << std::endl;
128 for (
int i = 0; i < numberFluidNodes; i++)
129 outString << fluidDisp2[i*3] <<
" "
130 << fluidDisp2[i*3+1] <<
" "
131 << fluidDisp2[i*3+2] << std::endl;
133 outString <<
"Number of solid nodes: " << numberFluidNodes <<std::endl;
134 outString <<
"solid displacements after transfer : " << std::endl;
135 for (
int i = 0; i < numberSolidNodes; i++)
136 outString << solidDisp2[i*3] <<
" "
137 << solidDisp2[i*3+1] <<
" "
138 << solidDisp2[i*3+2] << std::endl;
139 std::cout << outString.str() << std::endl;
144 std::vector<double> crdVecSolid2(solidAgent->
Coordinates());
145 std::vector<double> crdVecFluid2(fluidAgent->
Coordinates());
146 outString <<
"Fluid Coodinate Updates : " << std::endl;
147 for (
int i = 0; i < crdVecFluid2.size(); i = i + 3)
150 outString << crdVecFluid2[i] - crdVecFluid1[i] <<
" "
151 << crdVecFluid2[i+1] - crdVecFluid1[i+1]<<
" "
152 << crdVecFluid2[i+2] - crdVecFluid1[i+2]<< std::endl;
155 std::cout << outString.str() << std::endl;
158 outString <<
"Solid Coodinate Updates : " << std::endl;
159 for (
int i = 0; i < crdVecSolid2.size(); i = i + 3)
161 outString << crdVecSolid2[i] - crdVecSolid1[i] <<
" "
162 << crdVecSolid2[i+1] - crdVecSolid1[i+1]<<
" "
163 << crdVecSolid2[i+2] - crdVecSolid1[i+2]<< std::endl;
166 std::cout << outString.str() << std::endl;
178 std::stringstream outString;
181 double *tractions = NULL;
183 int isize = cap*stride;
184 outString <<
"Transfering loads to the structures solver." << std::endl;
185 StdOut(outString.str(),2,
true);
190 outString <<
"Tractions (driver): " << std::endl;
191 for(
int i = 0;i < isize/3;i++)
192 outString << tractions[3*i + 0] <<
" "
193 << tractions[3*i + 1] <<
" "
194 << tractions[3*i + 2] << std::endl;
195 StdOut(outString.str(),3,
true);
204 int solidLoadStride = 0, solidLoadCap = 0;
205 double *solidLoads = NULL;
207 &solidLoadStride,&solidLoadCap);
208 int solidLoadsize = solidLoadCap*solidLoadStride;
209 outString <<
"Loads transfered to the solid : " << std::endl;
210 for(
int i = 0;i < solidLoadsize;i++){
211 outString << std::setprecision(15) <<
"solidLoads(" << i <<
") = " << solidLoads[i] << std::endl;
212 StdOut(outString.str(),3,
true);
223 std::stringstream outString;
224 int stride = 0, solidStride = 0, solidLoadStride = 0;
225 int cap = 0, solidCap = 0, solidLoadCap = 0;
226 double *pressures = NULL, *solidPressures = NULL, *solidLoads = NULL;
230 int isize = cap*stride;
232 for(
int i = 0;i < isize;i++){
233 std::cout <<
"Pressure(" << i <<
") = " << pressures[i] << std::endl;
242 if(solidFaceLoadsHandle < 0){
243 outString <<
"Error: (TransferPressuresToStructures)" << std::endl
244 <<
" No handle for FaceLoads with structure solver" << std::endl;
245 StdOut(outString.str(),0,
true);
251 if(solidPressuresHandle < 0){
252 outString <<
"Error: (TransferPressuresToStructures)" << std::endl
253 <<
" No handle for Pressures with structure solver" << std::endl;
254 StdOut(outString.str(),0,
true);
263 &solidStride,&solidCap);
264 int solidIsize = solidCap*solidStride;
266 for(
int i = 0;i < solidIsize;i++){
269 outString << std::setprecision(15) <<
"solidPressure(" << i <<
") = " << solidPressures[i] << std::endl;
271 StdOut(outString.str(),3,
true);
276 std::string funcName;
278 int faceNormalsHandle = COM_get_function_handle(funcName.c_str());
279 if(faceNormalsHandle < 0){
280 outString <<
"Error: (TransferPressuresToStructures)" << std::endl
281 <<
" No handle for compute_element_normals function " << std::endl;
282 StdOut(outString.str(),0,
true);
288 int mulHandle = COM_get_function_handle(funcName.c_str());
290 outString <<
"Error: (TransferPressuresToStructures)" << std::endl
291 <<
" No handle for simpal multiply function " << std::endl;
292 StdOut(outString.str(),0,
true);
298 int negHandle = COM_get_function_handle(funcName.c_str());
300 outString <<
"Error: (TransferPressuresToStructures)" << std::endl
301 <<
" No handle for simpal negate function " << std::endl;
302 StdOut(outString.str(),0,
true);
313 COM_call_function(faceNormalsHandle, &solidFaceLoadsHandle, &normalize);
316 COM_call_function(mulHandle, &solidFaceLoadsHandle, &solidPressuresHandle,
317 &solidFaceLoadsHandle);
318 COM_call_function(negHandle, &solidFaceLoadsHandle, &solidFaceLoadsHandle);
328 structuresTransferAgent->Transfer(
"FaceLoads",
"Loads");
332 &solidLoadStride,&solidLoadCap);
333 int solidLoadsize = solidLoadCap*solidLoadStride;
334 for(
int i = 0;i < solidLoadsize;i++){
335 std::cout << std::setprecision(15) <<
"solidLoads(" << i <<
") = " << solidLoads[i] << std::endl;
340 if(fluidFaceNormalsHandle < 0){
341 outString <<
"Error: (TransferPressuresToStructures)" << std::endl
342 <<
" No handle for FaceNormals with fluids solver" << std::endl;
343 StdOut(outString.str(),0,
true);
349 COM_call_function(faceNormalsHandle, &fluidFaceNormalsHandle, &normalize);
350 double *fluidFaceNormals = NULL;
351 COM_get_array((
fluidsInterfaceName+
".normals").c_str(),101,&fluidFaceNormals,&stride,&cap);
354 outString <<
"stride = " << stride << std::endl;
355 std::vector<double> sums (stride, 0.0);
356 outString <<
"Driver: fluid face normals:" << std::endl;
357 for(
int i=0; i < cap; i++){
358 for(
int j=0; j < stride; j++){
359 outString << fluidFaceNormals[stride*i + j] <<
" ";
360 sums[j] += fluidFaceNormals[stride*i + j];
362 outString << std::endl;
364 outString <<
"sums: ";
365 for(
int i=0; i < sums.size(); i++)
366 outString << sums[i] <<
" ";
367 outString << std::endl;
368 StdOut(outString.str(),3,
true);
378 std::stringstream outString;
379 if(inMode ==
"Fluid" ||
382 }
else if(inMode ==
"Structure" ||
383 inMode ==
"structure" ||
398 std::stringstream outString;
399 double *fluidCoordinates = NULL;
400 double *solidCoordinates = NULL;
403 COM_get_array(fluidsCoordinateName.c_str(),
fluidsAgent->
PaneID(),&fluidCoordinates);
407 if(!fluidCoordinates || !solidCoordinates){
408 outString <<
"FSICoupling::TestTransfer:Error: Failed to get coordinate arrays. Exiting."
410 StdOut(outString.str(),0,
true);
415 double tolerance = 1e-12;
419 outString <<
"BEFORE TRANSFER: " << std::endl;
420 for(
int i = 0; i < numberFluidNodes;i++){
421 outString <<
"F(" << fluidCoordArray[i*3] <<
"," << fluidCoordArray[i*3+1] <<
","
422 << fluidCoordArray[i*3+2] <<
")" << std::endl;
424 for(
int i = 0; i < numberSolidNodes;i++){
425 outString <<
"S(" << structCoordArray[i*3] <<
"," << structCoordArray[i*3+1] <<
","
426 << structCoordArray[i*3+2] <<
")" << std::endl;
428 StdOut(outString.str(),3,
true);
432 outString <<
"FLUIDS AFTER TRANSFER: " << std::endl;
433 for(
int i = 0; i < numberFluidNodes;i++){
434 double diff1 = std::abs(fluidCoordinates[i*3] - fluidCoordArray[i*3]);
435 double diff2 = std::abs(fluidCoordinates[i*3+1] - fluidCoordArray[i*3+1]);
436 double diff3 = std::abs(fluidCoordinates[i*3+2] - fluidCoordArray[i*3+2]);
437 double diff = std::sqrt(diff1*diff1 + diff2*diff2 + diff3*diff3);
438 if(diff > maxdiff) maxdiff = diff;
439 if(diff > tolerance){
440 outString <<
"FSICoupling::TestTransfer: Coordinate transfer tolerance exceeded for node " << i+1
441 <<
" (" << diff <<
")" << std::endl
442 <<
"(" << fluidCoordinates[i*3] <<
"," << fluidCoordinates[i*3+1] <<
"," << fluidCoordinates[i*3+2]
443 <<
") : (" << fluidCoordArray[i*3] <<
"," << fluidCoordArray[i*3+1] <<
"," << fluidCoordArray[i*3+2]
447 outString <<
"FSICoupling::TestTransfer: Maximum transferred (s->f) coordinate difference: " << maxdiff << std::endl;
448 StdOut(outString.str(),3,
true);
453 int WriteAgentToVTK(
const std::string &nameRoot,SolverUtils::FEM::SolverAgent &solverAgent)
455 std::stringstream outString;
457 std::ostringstream timeString;
459 std::string fileName(nameRoot+
"_"+timeString.str()+
".vtk");
460 outStream.open(fileName.c_str());
462 outString <<
"FSICoupling::DumpSolution:Error: Could not open output file, "
463 << fileName <<
"." << std::endl;
464 StdOut(outString.str(),0,
true);
469 SolverUtils::WriteVTKToStream(nameRoot, solverAgent, outStream);
475 std::stringstream outString;
476 outString <<
"FSICoupling: Dumping solutions." << std::endl;
477 StdOut(outString.str(),2,
true);
492 outString <<
"FSICoupling: Done with solution dump." << std::endl;
493 StdOut(outString.str(),2,
true);
498 virtual int Initialize(std::vector<std::string> &componentInterfaceNames,
499 double finalTime,
double timeStep){
501 FunctionEntry(
"Initialize");
502 std::stringstream outString;
504 outString <<
"Final Time = " << finalTime << std::endl;
505 outString <<
"Time Step = " << timeStep << std::endl;
507 StdOut(outString.str(),0,
true);
511 if(componentInterfaceNames.size() < 2)
550 FunctionExit(
"Initialize");
557 FunctionEntry(
"Run");
560 int maxSubSteps = 1000;
561 int dumpinterval = 1;
563 std::stringstream outString;
564 outString << std::endl << std::endl
565 <<
"***************************************** " << std::endl;
566 outString <<
" Starting Stepping in Time " << std::endl;
567 outString <<
"***************************************** " << std::endl << std::endl;
568 outString <<
"ElmerFoamDriver:Run: Summary of the simulation " << std::endl;
569 outString <<
" Simulation Type = ElmerFoamFSI" << std::endl;
572 outString << std::endl;
573 StdOut(outString.str(),0,
true);
580 outString <<
"ElmerFoamDriver:Run: System timestep " << ++systemStep
582 StdOut(outString.str(),1,
true);
590 outString <<
"ElmerFoamDriver:Run: Transferring displacements from structures to fluids @ time("
592 StdOut(outString.str(),1,
true);
600 outString <<
"ElmerFoamDriver:Run: Stepping fluids to time("
602 StdOut(outString.str(),1,
true);
632 outString <<
"ElmerFoamDriver:Run: Stepping structures to time("
634 StdOut(outString.str(),1,
true);
641 bool converged =
true;
644 outString <<
"ElmerFoamDriver:Run: Converged at time("
646 outString <<
"ElmerFoamDriver:Run: Converged at time("
648 StdOut(outString.str(),1,
true);
658 if(innerCount > maxSubSteps){
659 outString <<
"ElmerFoamDriver:Run: Failed to converge after "
660 << maxSubSteps <<
", giving up." << std::endl;
661 StdOut(outString.str(),0,
true);
668 StdOut(outString.str(),0,
true);
672 if(!(systemStep%dumpinterval)){
695 std::vector<std::string> varVector;
std::string getSolidIntName()
SolverUtils::TransferObject transferagent
void WriteHDF(bool toggle)
fsicoupling(GlobalType &globin)
solidagent * getStructureAgent()
double getSimulationTime()
virtual int Run(double endTime)
int TransferDisplacementsToFluid(solidagent *solidAgent, fluidagent *fluidAgent)
virtual int FinalizeTimeStep(double time)
solidagent * structuresAgent
std::vector< impact::orchestrator::agentbase * > componentAgents
transferagent * transferAgent
std::string simpalInterfaceName
int WriteAgentToVTK(const std::string &nameRoot, SolverUtils::FEM::SolverAgent &solverAgent)
virtual int Initialize(const std::string &interfaceName, int verblevel=1)
IRAD::Global::GlobalObj< StackType, int, ProfilerType > GlobalType
std::string StackType
Convenience type definition for program stack.
std::string transferInterfaceName
double simulationTimeStep
void SetRunMode(const std::string &inMode)
virtual int DumpSolution()
fluidagent * getFluidAgent()
virtual int InitializeTimeStep(double time)
std::vector< std::string > getVariable()
Helper function that allows access to protected data members.
std::string structuresInterfaceName
std::string surfUtilInterfaceName
const std::vector< double > & Coordinates() const
IRAD::Profiler::ProfilerObj ProfilerType
Encapsulate example program-specific code constructs.
std::string fluidsInterfaceName
int TransferLoadsToStructures(fluidagent *fluidAgent, solidagent *solidAgent)
virtual int Run(double time)
const std::vector< double > & Coordinates() const
void SetVerbLevel(int verb)
int TransferPressuresToStructures(fluidagent *fluidAgent, solidagent *solidAgent)
void WriteVTK(bool toggle)
double getSimulationFinalTime()
double simulationFinalTime
std::string getFluidIntName()
virtual int Initialize(std::vector< std::string > &componentInterfaceNames, double finalTime, double timeStep)
virtual int Initialize(const std::string interfaceName, int verblevel=1)