ElmerFoamFSI  2.0
ElmerFoamFSI is fluid-solid interaction simulation application built up from OpenFOAM CFD and Elmer CSM coupled through the IMPACT multiphysics software integration infrastructure.
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Macros Groups Pages
FsiCoupling.H
Go to the documentation of this file.
1 
9 #ifndef __FSI_COUPLING_H__
10 #define __FSI_COUPLING_H__
11 
12 //#include "Parameters.H"
13 #include "InterfaceLayer.H"
14 #include "Orchestrator.H"
15 #include "OpenFoamAgent.H"
16 #include "ElmerAgent.H"
17 #include "Global.H"
18 
19 typedef SolverUtils::TransferObject transferagent;
22 typedef IRAD::Profiler::ProfilerObj ProfilerType;
23 typedef std::string StackType;
24 typedef IRAD::Global::GlobalObj<StackType,int,ProfilerType> GlobalType;
25 
27 {
28 protected:
32 
33  std::string fluidsInterfaceName;
35  std::string transferInterfaceName;
36  std::string surfUtilInterfaceName;
37  std::string simpalInterfaceName;
38 
42 
43  int runMode;
44  bool writeHDF;
45  bool writeVTK;
46  int verblevel;
47 
48 public:
49  fsicoupling() : GlobalType("fsicoupling"), fluidsAgent(NULL), structuresAgent(NULL), transferAgent(NULL),
50  runMode(0), writeHDF(true), writeVTK(true) {};
51  fsicoupling(GlobalType &globin) : GlobalType(globin), fluidsAgent(NULL), structuresAgent(NULL), transferAgent(NULL),
52  runMode(0), writeHDF(true), writeVTK(true) {
53  SetName("fsicoupling");
54  };
55  // JK: Making stuff for verblevel in fsicoupling functions
56  void SetVerbLevel(int verb){ verblevel = verb;};
57  int VerbLevel() const { return verblevel;};
58  // JK: End verblevel
59  int TransferDisplacementsToFluid(solidagent *solidAgent,fluidagent *fluidAgent)
60  {
61  std::stringstream outString;
62  // Masoud: Checking quality of coordinate transfer
63  std::vector<double> crdVecSolid1(solidAgent->Coordinates());
64  std::vector<double> crdVecFluid1(fluidAgent->Coordinates());
65  if ( verblevel >= 3 ) {
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;
71  //StdOut(outString.str(),0, true);
72  std::cout << outString.str() << std::endl;
73  outString.clear();
74  outString.str("");
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;
80  //StdOut(outString.str(),0,true);
81  std::cout << outString.str() << std::endl;
82  outString.clear();
83  outString.str("");
84  }
85  // Masoud: End
86 
87  // Masoud: Checking quality of displacement transfer
88  double *fluidDisp1 = NULL;
89  double *fluidDisp2 = NULL;
90  double *solidDisp1 = NULL;
91  double *solidDisp2 = NULL;
92  std::string fluidsCoordinateName(fluidsInterfaceName+".solidDisplacement");
93  std::string solidsCoordinateName(structuresInterfaceName+".Displacements");
94  COM_get_array(fluidsCoordinateName.c_str(),fluidsAgent->PaneID(),&fluidDisp1);
95  COM_get_array(solidsCoordinateName.c_str(),structuresAgent->PaneID(),&solidDisp1);
96  int numberFluidNodes = fluidsAgent->Coordinates().size()/3;
97  int numberSolidNodes = structuresAgent->Coordinates().size()/3;
98  if (verblevel >= 3){
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;
104  //StdOut(outString.str(),0,true);
105  std::cout << outString.str() << std::endl;
106  outString.clear();
107  outString.str("");
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;
114  //StdOut(outString.str(),0,true);
115  std::cout << outString.str() << std::endl;
116  outString.clear();
117  outString.str("");
118  }
119 
120  transferAgent->Interpolate("Displacements","solidDisplacement");
121  //transferAgent->Interpolate("solidDisplacement","Displacements");
122 
123  if (verblevel >= 3){
124  COM_get_array(fluidsCoordinateName.c_str(),fluidsAgent->PaneID(),&fluidDisp2);
125  COM_get_array(solidsCoordinateName.c_str(),structuresAgent->PaneID(),&solidDisp2);
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;
132  //StdOut(outString.str(),0,true);
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;
140  outString.clear();
141  outString.str("");
142 
143  // Masoud: Cheking if displacements are updated properly
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)
148  {
149  // adding some value to it
150  outString << crdVecFluid2[i] - crdVecFluid1[i] << " "
151  << crdVecFluid2[i+1] - crdVecFluid1[i+1]<< " "
152  << crdVecFluid2[i+2] - crdVecFluid1[i+2]<< std::endl;
153  }
154  //StdOut(outString.str(),0,true);
155  std::cout << outString.str() << std::endl;
156  outString.clear();
157  outString.str("");
158  outString << "Solid Coodinate Updates : " << std::endl;
159  for (int i = 0; i < crdVecSolid2.size(); i = i + 3)
160  {
161  outString << crdVecSolid2[i] - crdVecSolid1[i] << " "
162  << crdVecSolid2[i+1] - crdVecSolid1[i+1]<< " "
163  << crdVecSolid2[i+2] - crdVecSolid1[i+2]<< std::endl;
164  }
165  //StdOut(outString.str(),0,true);
166  std::cout << outString.str() << std::endl;
167  outString.clear();
168  outString.str("");
169  }
170  // Masoud: End
171 
172  return(0);
173  };
174 
175 
176  int TransferLoadsToStructures(fluidagent *fluidAgent,solidagent *solidAgent)
177  {
178  std::stringstream outString;
179  int stride = 0;
180  int cap = 0;
181  double *tractions = NULL;
182  COM_get_array((fluidsInterfaceName+".traction").c_str(),101,&tractions,&stride,&cap);
183  int isize = cap*stride;
184  outString << "Transfering loads to the structures solver." << std::endl;
185  StdOut(outString.str(),2,true);
186  outString.clear();
187  outString.str("");
188 
189  if (verblevel >= 3){
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);
196  outString.clear();
197  outString.str("");
198  }
199 
200  transferAgent->Transfer("traction","Loads",true);
201 
202  //Get loads array from solid solver to check
203  if (verblevel >= 3){
204  int solidLoadStride = 0, solidLoadCap = 0;
205  double *solidLoads = NULL;
206  COM_get_array((structuresInterfaceName+".Loads").c_str(),11,&solidLoads,
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);
213  outString.clear();
214  outString.str("");
215  }
216  }
217  return(0);
218  };
219 
220 
222  {
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;
227 
228  //Get pressure array from fluid solver
229  COM_get_array((fluidsInterfaceName+".pressure").c_str(),101,&pressures,&stride,&cap);
230  int isize = cap*stride;
231  //Add atmospheric pressure
232  for(int i = 0;i < isize;i++){
233  std::cout << "Pressure(" << i << ") = " << pressures[i] << std::endl;
234  }
235  //Transfer the pressures from the fluid to the solid
236  transferAgent->Transfer("pressure","Pressures",true);
237  transferAgent->Transfer("pressure","NodePressures",true);
238 
240  //Get handles for dataitems needed
241  int solidFaceLoadsHandle = COM_get_dataitem_handle(structuresInterfaceName+".FaceLoads");
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);
246  outString.clear();
247  outString.str("");
248  return(1);
249  }
250  int solidPressuresHandle = COM_get_dataitem_handle(structuresInterfaceName+".Pressures");
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);
255  outString.clear();
256  outString.str("");
257  return(1);
258  }
259 
260  //Account for atmospheric pressure when transferring to Elmer (we aren't doing this)
261  //Get pressure array from solid solver
262  COM_get_array((structuresInterfaceName+".Pressures").c_str(),11,&solidPressures,
263  &solidStride,&solidCap);
264  int solidIsize = solidCap*solidStride;
265  //Add atmospheric pressure (we aren't doing this - should we?)
266  for(int i = 0;i < solidIsize;i++){
267  //solidPressures[i] += 101325.0;
268  //solidPressures[i] = 1.0;
269  outString << std::setprecision(15) << "solidPressure(" << i << ") = " << solidPressures[i] << std::endl;
270  }
271  StdOut(outString.str(),3,true);
272  outString.clear();
273  outString.str("");
274 
275  //Get handles for functions needed
276  std::string funcName;
277  funcName = surfUtilInterfaceName + ".compute_element_normals";
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);
283  outString.clear();
284  outString.str("");
285  return(1);
286  }
287  funcName = simpalInterfaceName + ".mul";
288  int mulHandle = COM_get_function_handle(funcName.c_str());
289  if(mulHandle < 0){
290  outString << "Error: (TransferPressuresToStructures)" << std::endl
291  << " No handle for simpal multiply function " << std::endl;
292  StdOut(outString.str(),0,true);
293  outString.clear();
294  outString.str("");
295  return(1);
296  }
297  funcName = simpalInterfaceName + ".neg";
298  int negHandle = COM_get_function_handle(funcName.c_str());
299  if(negHandle < 0){
300  outString << "Error: (TransferPressuresToStructures)" << std::endl
301  << " No handle for simpal negate function " << std::endl;
302  StdOut(outString.str(),0,true);
303  outString.clear();
304  outString.str("");
305  return(1);
306  }
307 
308  //Execute the appropriate function calls
309  //I'm gonna try not normalizing them!!
310  int normalize=1;
311  //Call function to get face normals, store them in solidFaceLoads, do not
312  //normalize them
313  COM_call_function(faceNormalsHandle, &solidFaceLoadsHandle, &normalize);
314  //Call function to get face normals, store them in solidFaceLoads, do not
315  //normalize them
316  COM_call_function(mulHandle, &solidFaceLoadsHandle, &solidPressuresHandle,
317  &solidFaceLoadsHandle);
318  COM_call_function(negHandle, &solidFaceLoadsHandle, &solidFaceLoadsHandle);
320 
322  transferagent *structuresTransferAgent = new transferagent("structuresTransferAgent");
323 
324  // Initialize the transfer module's common refinement
325  structuresTransferAgent->Overlay(structuresInterfaceName,structuresInterfaceName);
326 
327  // Call the transfer now
328  structuresTransferAgent->Transfer("FaceLoads","Loads");
329 
330  //Get loads array from solid solver to check
331  COM_get_array((structuresInterfaceName+".Loads").c_str(),11,&solidLoads,
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;
336  }
337 
338  //Print out the face normals from the fluid solver as a check
339  int fluidFaceNormalsHandle = COM_get_dataitem_handle(fluidsInterfaceName+".normals");
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);
344  outString.clear();
345  outString.str("");
346  return(1);
347  }
348  normalize=0;
349  COM_call_function(faceNormalsHandle, &fluidFaceNormalsHandle, &normalize);
350  double *fluidFaceNormals = NULL;
351  COM_get_array((fluidsInterfaceName+".normals").c_str(),101,&fluidFaceNormals,&stride,&cap);
352  isize = stride*cap;
353 
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];
361  }
362  outString << std::endl;
363  }
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);
369  outString.clear();
370  outString.str("");
371 
372  return(0);
373  };
374 
375 
376  void SetRunMode(const std::string &inMode)
377  {
378  std::stringstream outString;
379  if(inMode == "Fluid" ||
380  inMode == "fluid"){
381  runMode = 1;
382  } else if(inMode == "Structure" ||
383  inMode == "structure" ||
384  inMode == "Solid" ||
385  inMode == "solid"){
386  runMode = 2;
387  } else {
388  runMode = 0;
389  }
390  };
391 
392  void WriteVTK(bool toggle) { writeVTK = toggle;};
393 
394  void WriteHDF(bool toggle) { writeHDF = toggle;};
395 
397  {
398  std::stringstream outString;
399  double *fluidCoordinates = NULL;
400  double *solidCoordinates = NULL;
401  std::string fluidsCoordinateName(fluidsInterfaceName+".nc");
402  std::string solidsCoordinateName(structuresInterfaceName+".nc");
403  COM_get_array(fluidsCoordinateName.c_str(),fluidsAgent->PaneID(),&fluidCoordinates);
404  COM_get_array(solidsCoordinateName.c_str(),structuresAgent->PaneID(),&solidCoordinates);
405  int numberFluidNodes = fluidsAgent->Coordinates().size()/3;
406  int numberSolidNodes = structuresAgent->Coordinates().size()/3;
407  if(!fluidCoordinates || !solidCoordinates){
408  outString << "FSICoupling::TestTransfer:Error: Failed to get coordinate arrays. Exiting."
409  << std::endl;
410  StdOut(outString.str(),0,true);
411  outString.clear();
412  outString.str("");
413  exit(1);
414  }
415  double tolerance = 1e-12;
416  double maxdiff = 0;
417  const std::vector<double> &fluidCoordArray(fluidsAgent->Coordinates());
418  const std::vector<double> &structCoordArray(structuresAgent->Coordinates());
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;
423  }
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;
427  }
428  StdOut(outString.str(),3,true);
429  outString.clear();
430  outString.str("");
431  transferAgent->Interpolate("coords","coords"); // transfer from structures to fluids the node coordinates
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]
444  << ")" << std::endl;
445  }
446  }
447  outString << "FSICoupling::TestTransfer: Maximum transferred (s->f) coordinate difference: " << maxdiff << std::endl;
448  StdOut(outString.str(),3,true);
449  outString.clear();
450  outString.str("");
451  };
452 
453  int WriteAgentToVTK(const std::string &nameRoot,SolverUtils::FEM::SolverAgent &solverAgent)
454  {
455  std::stringstream outString;
456  std::ofstream outStream;
457  std::ostringstream timeString;
458  timeString << simulationTime;
459  std::string fileName(nameRoot+"_"+timeString.str()+".vtk");
460  outStream.open(fileName.c_str());
461  if(!outStream){
462  outString << "FSICoupling::DumpSolution:Error: Could not open output file, "
463  << fileName << "." << std::endl;
464  StdOut(outString.str(),0,true);
465  outString.clear();
466  outString.str("");
467  return(1);
468  }
469  SolverUtils::WriteVTKToStream(nameRoot, solverAgent, outStream);
470  outStream.close();
471  };
472 
473  virtual int DumpSolution()
474  {
475  std::stringstream outString;
476  outString << "FSICoupling: Dumping solutions." << std::endl;
477  StdOut(outString.str(),2,true);
478  outString.clear();
479  outString.str("");
480  if(runMode < 2){
481  if(writeHDF)
482  SolverUtils::WriteWindow(fluidsInterfaceName,simulationTime);
483  if(false)
484  WriteAgentToVTK("fluid",*fluidsAgent);
485  }
486  if(!(runMode == 1)){
487  if(writeHDF)
488  SolverUtils::WriteWindow(structuresInterfaceName,simulationTime);
489  if(false)
490  WriteAgentToVTK("structure",*structuresAgent);
491  }
492  outString << "FSICoupling: Done with solution dump." << std::endl;
493  StdOut(outString.str(),2,true);
494  outString.clear();
495  outString.str("");
496  return(0);
497  }
498  virtual int Initialize(std::vector<std::string> &componentInterfaceNames,
499  double finalTime, double timeStep){
500 
501  FunctionEntry("Initialize");
502  std::stringstream outString;
503  //Masoud
504  outString << "Final Time = " << finalTime << std::endl;
505  outString << "Time Step = " << timeStep << std::endl;
506  //Masoud: End
507  StdOut(outString.str(),0,true);
508  outString.clear();
509  outString.str("");
510 
511  if(componentInterfaceNames.size() < 2)
512  return(1);
513 
514  fluidsInterfaceName = componentInterfaceNames[0];
515  structuresInterfaceName = componentInterfaceNames[1];
516  transferInterfaceName = componentInterfaceNames[2];
517  surfUtilInterfaceName = componentInterfaceNames[3];
518  simpalInterfaceName = componentInterfaceNames[4];
519 
520  fluidsAgent = new fluidagent;
523 
524  // Initialize the fluids module
525  if(runMode != 2)
527 
528  // Initialize the structures module
529  if(runMode != 1)
531 
532  // Initialize the transfer module's common refinement
533  if(runMode == 0) {
535  // TestTransfer();
536  }
537  // exit(1);
538 
539 
540  componentAgents.resize(2);
543 
544  simulationTime = 0; // ? (restart)
545  simulationFinalTime = finalTime;
546  simulationTimeStep = timeStep;
547 
548  //DumpSolution();
549 
550  FunctionExit("Initialize");
551  return(0);
552 
553  };
554 
555 
556  virtual int Run(){
557  FunctionEntry("Run");
558  // Enter timestepping
559  int innerCount = 0;
560  int maxSubSteps = 1000;
561  int dumpinterval = 1;
562  int systemStep = 0;
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;
570  outString << " Simulation final time = " << simulationFinalTime << std::endl;
571  outString << " Simulation time step = " << simulationTimeStep << std::endl;
572  outString << std::endl;
573  StdOut(outString.str(),0,true);
574  outString.clear();
575  outString.str("");
577 
578  // if(!(time%screenInterval) && (innerCount == 0)){
579  // Write some stuff to screen
580  outString << "ElmerFoamDriver:Run: System timestep " << ++systemStep
581  << " @ Time = " << simulationTime << std::endl;
582  StdOut(outString.str(),1,true);
583  outString.clear();
584  outString.str("");
585 
586  // }
587 
588  if(!runMode){
589  // Transfer displacements @ Tn to fluids
590  outString << "ElmerFoamDriver:Run: Transferring displacements from structures to fluids @ time("
591  << simulationTime << ")" << std::endl;
592  StdOut(outString.str(),1,true);
593  outString.clear();
594  outString.str("");
596  }
597  if(runMode < 2){
599  // Step fluids to get loads @ T(n+1)
600  outString << "ElmerFoamDriver:Run: Stepping fluids to time("
601  << simulationTime+simulationTimeStep << ")" << std::endl;
602  StdOut(outString.str(),1,true);
603  outString.clear();
604  outString.str("");
606  }
607 
608  if(!runMode){
609  // Transfer loads @ T(n+1) to structures
610  //std::cout << "FSICoupling: Transferring loads from fluids to structures @ time("
611  // << simulationTime+simulationTimeStep << ")" << std::endl;
613  // Transfer pressures @ T(n+1) to structures
614  //std::cout << "FSICoupling: Transferring pressures from fluids to structures @ time("
615  // << simulationTime+simulationTimeStep << ")" << std::endl;
616  //TransferPressuresToStructures(fluidsAgent,structuresAgent);
617  //std::cout << "FSICoupling: Transferring pressures from fluids to structures with "
618  // << "TransferLoad function" << std::endl;
619  //int err = transferAgent->TransferLoad("pressure","Loads",true);
620  //if(err == -1){
621  // std::cout << "FSICoupling: Error: Unable to transfer pressures from fluids agent"
622  // << "to loads at structures agent." << std::endl;
623  // exit(1);
624  //}
625  }
626  if(!(runMode==1)){
628  // Step structures to get displacements @ T(n+1)
629  /* WK
630  outString << "ElmerFoamDriver:Run: Stepping structures to time("
631  << simulationTime+simulationTimeStep << ")" << std::endl; */
632  outString << "ElmerFoamDriver:Run: Stepping structures to time("
633  << simulationTime+simulationTimeStep << ")" << std::endl;
634  StdOut(outString.str(),1,true);
635  outString.clear();
636  outString.str("");
638  }
639 
640  // Finalize timestep and advance time T(n) --> T(n+1)
641  bool converged = true;
642  if(converged){
644  outString << "ElmerFoamDriver:Run: Converged at time("
645  << simulationTime << ")" << std::endl;
646  outString << "ElmerFoamDriver:Run: Converged at time("
647  << simulationTime << ")" << std::endl;
648  StdOut(outString.str(),1,true);
649  outString.clear();
650  outString.str("");
651  if(runMode < 2)
653  if(!(runMode == 1))
655  innerCount = 0;
656  } else {
657  innerCount++;
658  if(innerCount > maxSubSteps){
659  outString << "ElmerFoamDriver:Run: Failed to converge after "
660  << maxSubSteps << ", giving up." << std::endl;
661  StdOut(outString.str(),0,true);
662  outString.clear();
663  outString.str("");
664  return(1);
665  }
666  }
667 
668  StdOut(outString.str(),0,true);
669  outString.clear();
670  outString.str("");
671 
672  if(!(systemStep%dumpinterval)){
673  //DumpSolution();
674  }
675 
676  }
677  FunctionExit("Run");
678  return(0);
679  };
680  virtual int Finalize(){
681  // Finalize the fluids module
682  if(runMode < 2)
684  // Finalize the structures module
685  if(!(runMode == 1))
687  // Anything I need to do to finalize myself
688  return(0);
689  }
690 
691 
692  //WK NS
694  std::vector<std::string> getVariable(){
695  std::vector<std::string> varVector;
696  varVector.push_back(this->fluidsInterfaceName);
697  varVector.push_back(this->structuresInterfaceName);
698  varVector.push_back(this->transferInterfaceName);
699  varVector.push_back(this->surfUtilInterfaceName);
700  varVector.push_back(this->simpalInterfaceName);
701  return varVector;
702  }
703 
704  double getSimulationTime() {return this->simulationTime;}
706  int getRunMode() {return this->runMode;}
707 
710 
711  std::string getFluidIntName() {return this->fluidsInterfaceName;}
712  std::string getSolidIntName() {return this->structuresInterfaceName;}
713 
714  //WK NS
715 };
716 
717 #endif
void TestTransfer()
Definition: FsiCoupling.H:396
fluidagent * fluidsAgent
Definition: FsiCoupling.H:29
std::string getSolidIntName()
Definition: FsiCoupling.H:712
SolverUtils::TransferObject transferagent
Definition: FsiCoupling.H:19
void WriteHDF(bool toggle)
Definition: FsiCoupling.H:394
fsicoupling(GlobalType &globin)
Definition: FsiCoupling.H:51
solidagent * getStructureAgent()
Definition: FsiCoupling.H:709
bool writeVTK
Definition: FsiCoupling.H:45
double getSimulationTime()
Definition: FsiCoupling.H:704
virtual int Run(double endTime)
Definition: OpenFoamAgent.H:65
int TransferDisplacementsToFluid(solidagent *solidAgent, fluidagent *fluidAgent)
Definition: FsiCoupling.H:59
virtual int FinalizeTimeStep(double time)
Definition: Orchestrator.H:25
solidagent * structuresAgent
Definition: FsiCoupling.H:30
std::vector< impact::orchestrator::agentbase * > componentAgents
Definition: Orchestrator.H:44
transferagent * transferAgent
Definition: FsiCoupling.H:31
std::string simpalInterfaceName
Definition: FsiCoupling.H:37
int WriteAgentToVTK(const std::string &nameRoot, SolverUtils::FEM::SolverAgent &solverAgent)
Definition: FsiCoupling.H:453
virtual int Initialize(const std::string &interfaceName, int verblevel=1)
Definition: ElmerAgent.H:10
IRAD::Global::GlobalObj< StackType, int, ProfilerType > GlobalType
Definition: FsiCoupling.H:24
std::string StackType
Convenience type definition for program stack.
Definition: Driver.H:46
std::string transferInterfaceName
Definition: FsiCoupling.H:35
double simulationTimeStep
Definition: FsiCoupling.H:41
void SetRunMode(const std::string &inMode)
Definition: FsiCoupling.H:376
virtual int DumpSolution()
Definition: FsiCoupling.H:473
virtual int Run()
Definition: FsiCoupling.H:556
virtual int Finalize()
Definition: ElmerAgent.H:81
fluidagent * getFluidAgent()
Definition: FsiCoupling.H:708
virtual int InitializeTimeStep(double time)
Definition: Orchestrator.H:24
std::vector< std::string > getVariable()
Helper function that allows access to protected data members.
Definition: FsiCoupling.H:694
bool writeHDF
Definition: FsiCoupling.H:44
std::string structuresInterfaceName
Definition: FsiCoupling.H:34
int PaneID()
Definition: ElmerAgent.H:80
std::string surfUtilInterfaceName
Definition: FsiCoupling.H:36
const std::vector< double > & Coordinates() const
Definition: ElmerAgent.H:79
int VerbLevel() const
Definition: FsiCoupling.H:57
IRAD::Profiler::ProfilerObj ProfilerType
Encapsulate example program-specific code constructs.
Definition: Driver.H:42
std::string fluidsInterfaceName
Definition: FsiCoupling.H:33
openfoamagent fluidagent
Definition: FsiCoupling.H:20
int TransferLoadsToStructures(fluidagent *fluidAgent, solidagent *solidAgent)
Definition: FsiCoupling.H:176
virtual int Run(double time)
Definition: ElmerAgent.H:71
double simulationTime
Definition: FsiCoupling.H:39
const std::vector< double > & Coordinates() const
Definition: OpenFoamAgent.H:63
void SetVerbLevel(int verb)
Definition: FsiCoupling.H:56
int TransferPressuresToStructures(fluidagent *fluidAgent, solidagent *solidAgent)
Definition: FsiCoupling.H:221
void WriteVTK(bool toggle)
Definition: FsiCoupling.H:392
int getRunMode()
Definition: FsiCoupling.H:706
double getSimulationFinalTime()
Definition: FsiCoupling.H:705
double simulationFinalTime
Definition: FsiCoupling.H:40
elmeragent solidagent
Definition: FsiCoupling.H:21
std::string getFluidIntName()
Definition: FsiCoupling.H:711
virtual int Initialize(std::vector< std::string > &componentInterfaceNames, double finalTime, double timeStep)
Definition: FsiCoupling.H:498
virtual int Initialize(const std::string interfaceName, int verblevel=1)
Definition: OpenFoamAgent.H:9
virtual int Finalize()
Definition: FsiCoupling.H:680