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
FsiCouplingPar.H
Go to the documentation of this file.
1 
9 #ifndef __FSI_COUPLING_PAR_H__
10 #define __FSI_COUPLING_PAR_H__
11 
12 //#include "Parameters.H"
13 #include "InterfaceLayer.H"
14 #include "Orchestrator.H"
15 #include "OpenFoamParAgent.H"
16 #include "ElmerParAgent.H"
17 #include "Global.H"
18 #include <ctime>
19 #include <unistd.h>
20 
21 typedef SolverUtils::TransferObjectPar transferagentpar;
24 typedef IRAD::Profiler::ProfilerObj ProfilerType;
25 typedef std::string StackType;
26 typedef IRAD::Comm::CommunicatorObject CommTypeIrad;
27 typedef IRAD::Global::ParallelGlobalObj<CommTypeIrad,StackType,int,ProfilerType> PGlobalType;
28 
30 {
31 protected:
35 
36  std::string fluidsInterfaceName;
38  std::string transferInterfaceName;
39  std::string surfUtilInterfaceName;
40  std::string simpalInterfaceName;
41  std::string simoutInterfaceName;
42  std::string siminInterfaceName;
43 
44  std::string fluidsWinFnameHDF;
45  std::string structuresWinFnameHDF;
46 
50 
51  int runMode;
52  bool writeHDF;
53  bool writeVTK;
54  int verblevel;
55 
56  // probe variables
57  int setsProb;
59  int probNdeId;
60  std::string probSolverName;
61 
62 public:
63  fsicouplingpar() : PGlobalType("fsicoupling"), fluidsAgent(NULL), structuresAgent(NULL), transferAgent(NULL),
64  runMode(0), writeHDF(true), writeVTK(true), setsProb(0) {};
66  runMode(0), writeHDF(true), writeVTK(true), setsProb(0) {
67  SetName("fsicouplingpar");
68  };
69  // verbosity
70  void SetVerbLevel(int verb){ verblevel = verb;};
71  int VerbLevel() const { return verblevel;};
72 
73  // probe
74  void SetProbe(int inProbProcId, int inProbNdeId, std::string inProbSlvName) {
75  if (inProbProcId!=-1) {
76  setsProb = 1;
77  probProcId = inProbProcId;
78  probNdeId = inProbNdeId;
79  probSolverName = inProbSlvName;
80  }
81  }
82 
83  // solution transfer
85  {
86  transferAgent->Interpolate("Displacements","solidDisplacement");
87  //transferAgent->Interpolate("solidDisplacement","Displacements");
88 
89  return(0);
90  };
91 
92 
94  {
95 
96  transferAgent->Transfer("traction","Loads",true);
97 
98  return(0);
99  };
100 
102  {
103  std::stringstream outString;
104  double *fluidCoordinates = NULL;
105  double *solidCoordinates = NULL;
106  std::string fluidsCoordinateName(fluidsInterfaceName+".nc");
107  std::string solidsCoordinateName(structuresInterfaceName+".nc");
108  COM_get_array(fluidsCoordinateName.c_str(),fluidsAgent->PaneID(),&fluidCoordinates);
109  COM_get_array(solidsCoordinateName.c_str(),structuresAgent->PaneID(),&solidCoordinates);
110  int numberFluidNodes = fluidsAgent->Coordinates().size()/3;
111  int numberSolidNodes = structuresAgent->Coordinates().size()/3;
112  if(!fluidCoordinates || !solidCoordinates){
113  outString << "FSICoupling::TestTransfer:Error: Failed to get coordinate arrays. Exiting."
114  << std::endl;
115  StdOut(outString.str(),0,true);
116  outString.clear();
117  outString.str("");
118  exit(1);
119  }
120  double tolerance = 1e-12;
121  double maxdiff = 0;
122  const std::vector<double> &fluidCoordArray(fluidsAgent->Coordinates());
123  const std::vector<double> &structCoordArray(structuresAgent->Coordinates());
124  outString << "BEFORE TRANSFER: " << std::endl;
125  for(int i = 0; i < numberFluidNodes;i++){
126  outString << "F(" << fluidCoordArray[i*3] << "," << fluidCoordArray[i*3+1] << ","
127  << fluidCoordArray[i*3+2] << ")" << std::endl;
128  }
129  for(int i = 0; i < numberSolidNodes;i++){
130  outString << "S(" << structCoordArray[i*3] << "," << structCoordArray[i*3+1] << ","
131  << structCoordArray[i*3+2] << ")" << std::endl;
132  }
133  StdOut(outString.str(),3,true);
134  outString.clear();
135  outString.str("");
136  transferAgent->Interpolate("coords","coords"); // transfer from structures to fluids the node coordinates
137  //transferAgent->Transfer("coords","coords"); // transfer from structures to fluids the node coordinates
138  outString << "FLUIDS AFTER TRANSFER: " << std::endl;
139  for(int i = 0; i < numberFluidNodes;i++){
140  double diff1 = std::abs(fluidCoordinates[i*3] - fluidCoordArray[i*3]);
141  double diff2 = std::abs(fluidCoordinates[i*3+1] - fluidCoordArray[i*3+1]);
142  double diff3 = std::abs(fluidCoordinates[i*3+2] - fluidCoordArray[i*3+2]);
143  double diff = std::sqrt(diff1*diff1 + diff2*diff2 + diff3*diff3);
144  if(diff > maxdiff) maxdiff = diff;
145  if(diff > tolerance){
146  outString << "FSICoupling::TestTransfer: Coordinate transfer tolerance exceeded for node " << i+1
147  << " (" << diff << ")" << std::endl
148  << "(" << fluidCoordinates[i*3] << "," << fluidCoordinates[i*3+1] << "," << fluidCoordinates[i*3+2]
149  << ") : (" << fluidCoordArray[i*3] << "," << fluidCoordArray[i*3+1] << "," << fluidCoordArray[i*3+2]
150  << ")" << std::endl;
151  }
152  }
153  outString << "FSICoupling::TestTransfer: Maximum transferred (s->f) coordinate difference: " << maxdiff << std::endl;
154  StdOut(outString.str(),3,true);
155  outString.clear();
156  outString.str("");
157  };
158  // operation mode
159  void SetRunMode(const std::string &inMode)
160  {
161  std::stringstream outString;
162  if(inMode == "Fluid" ||
163  inMode == "fluid"){
164  runMode = 1;
165  } else if(inMode == "Structure" ||
166  inMode == "structure" ||
167  inMode == "Solid" ||
168  inMode == "solid"){
169  runMode = 2;
170  } else {
171  runMode = 0;
172  }
173  };
174 
175  void WriteVTK(bool toggle) { writeVTK = toggle;};
176 
177  void WriteHDF(bool toggle) { writeHDF = toggle;};
178 
179 
180  int WriteAgentToVTK(const std::string &nameRoot,SolverUtils::FEM::SolverAgent &solverAgent)
181  {
182  std::stringstream outString;
183  std::ofstream outStream;
184  std::ostringstream timeString;
185  timeString << simulationTime;
186  std::string fileName(nameRoot+"_"+timeString.str()+".vtk");
187  outStream.open(fileName.c_str());
188  if(!outStream){
189  outString << "FSICoupling::DumpSolution:Error: Could not open output file, "
190  << fileName << "." << std::endl;
191  StdOut(outString.str(),0,true);
192  outString.clear();
193  outString.str("");
194  return(1);
195  }
196  SolverUtils::WriteVTKToStream(nameRoot, solverAgent, outStream);
197  outStream.close();
198  };
199 
200  virtual int DumpSolution()
201  {
202  std::stringstream outString;
203  outString << "FSICoupling: Dumping solutions." << std::endl;
204  StdOut(outString.str(),2,true);
205  outString.clear();
206  outString.str("");
207  if(runMode < 2){
208  if(writeHDF)
209  SolverUtils::WriteWindow(fluidsInterfaceName,simulationTime);
210  if(false)
211  WriteAgentToVTK("fluid",*fluidsAgent);
212  }
213  if(!(runMode == 1)){
214  if(writeHDF)
215  SolverUtils::WriteWindow(structuresInterfaceName,simulationTime);
216  if(false)
217  WriteAgentToVTK("structure",*structuresAgent);
218  }
219  outString << "FSICoupling: Done with solution dump." << std::endl;
220  StdOut(outString.str(),2,true);
221  outString.clear();
222  outString.str("");
223  return(0);
224  }
225 
226  void virtual writeWin(const char* winName, std::string timeMark, std::string& wFnameHdf)
227  {
228  int OUT_set = COM_get_function_handle( (simoutInterfaceName + ".set_option").c_str());
229  int OUT_write = COM_get_function_handle( (simoutInterfaceName + ".write_dataitem").c_str());
230  int OUT_write_ctrl = COM_get_function_handle( (simoutInterfaceName + ".write_rocin_control_file").c_str());
231 
232  std::string win_out_pre( winName);
233  win_out_pre.append(".");
234  int OUT_all = COM_get_dataitem_handle((win_out_pre+"all").c_str());
235 
236 
237  std::stringstream ss;
238  ss.clear();
239  ss.str("");
240  ss << "_proc_"
241  << Rank();
242 
243  std::string hdf_fname, ctrl_fname;
244  hdf_fname = (std::string)winName +"_window" + ss.str();
245  ctrl_fname = (std::string)winName + "_time_" + timeMark +".txt";
246 
247  COM_call_function( OUT_set, "format", "HDF4");
248  COM_call_function( OUT_write, (hdf_fname + ".hdf").c_str(), &OUT_all, winName, "0000");
249  COM_call_function( OUT_write_ctrl, winName, hdf_fname.c_str(), ctrl_fname.c_str());
250 
251  wFnameHdf = (std::string)winName +"_window_proc_*.hdf";
252  }
253 
254  virtual int Initialize(std::vector<std::string> &componentInterfaceNames,
255  double finalTime, double timeStep){
256 
257  FunctionEntry("Initialize");
258  std::stringstream outString;
259  outString << "Final Time = " << finalTime << std::endl;
260  outString << "Time Step = " << timeStep << std::endl;
261  StdOut(outString.str(),0,true);
262  outString.clear();
263  outString.str("");
264 
265  if(componentInterfaceNames.size() < 2)
266  return(1);
267 
268  fluidsInterfaceName = componentInterfaceNames[0];
269  structuresInterfaceName = componentInterfaceNames[1];
270  transferInterfaceName = componentInterfaceNames[2];
271  surfUtilInterfaceName = componentInterfaceNames[3];
272  simpalInterfaceName = componentInterfaceNames[4];
273  simoutInterfaceName = componentInterfaceNames[5];
274 
277  transferAgent = new transferagentpar(transferInterfaceName, (this->Communicator()).GetCommunicator(),
278  verblevel);
279 
280  // Initialize the fluids module and writing the window
281  if(runMode != 2)
283  Communicator().Barrier();
284  writeWin((const char *)fluidsInterfaceName.c_str(), "0", fluidsWinFnameHDF);
285  Communicator().Barrier();
286 
287 
288  // Initialize the structures module and writing the window
289  if(runMode != 1)
291  writeWin((const char *)structuresInterfaceName.c_str(), "0", structuresWinFnameHDF);
292  Communicator().Barrier();
293 
294  // accessing a dataitem for fast debugging
295  /*
296  double* Disps;
297  int stride, cap;
298  COM_get_array((structuresInterfaceName+".Displacements").c_str(), structuresAgent->PaneID(),
299  &Disps, &stride, &cap);
300  for (int i=0; i<stride*cap; i++)
301  std::cout << "Rank " << Rank()
302  << "Item = " << Disps[i]
303  << std::endl;
304  */
305 
306  // Initialize the transfer module's common refinement
307  if(runMode == 0) {
310  //TestTransfer();
311  }
312 
313  // setting up probe for the solver
314  // only implementd for fluids solver
315  COM_set_array((fluidsInterfaceName+".setsProb").c_str(),0,&setsProb);
316  if(setsProb){
317  std::string newDataItemName(probSolverName+".probProcId");
318  COM_set_array(newDataItemName.c_str(),0,&probProcId);
319  newDataItemName = probSolverName+".probNdeId";
320  COM_set_array(newDataItemName.c_str(),0,&probNdeId);
321  }
322 
323  componentAgents.resize(2);
326 
327  simulationTime = 0; // ? (restart)
328  simulationFinalTime = finalTime;
329  simulationTimeStep = timeStep;
330 
331  //DumpSolution();
332 
333 
334  FunctionExit("Initialize");
335  return(0);
336 
337  };
338 
339 
340  virtual int Run(){
341  FunctionEntry("Run");
342  // Enter timestepping
343  int innerCount = 0;
344  int maxSubSteps = 1000;
345  int dumpinterval = 1;
346  int systemStep = 0;
347 
348  // gathering some information for user
349  time_t nowStart = time(0);
350  char* dtChar = ctime(&nowStart);
351  char* hostName;
352  gethostname(hostName, 150);
353 
354  std::stringstream outString;
355  outString << std::endl << std::endl
356  << "************************************************* " << std::endl;
357  outString << "* Starting Stepping in Time * " << std::endl;
358  outString << "************************************************* " << std::endl;
359  outString << "* Starting Simulation at " << dtChar;
360  outString << "* Summary of the simulation: " << std::endl;
361  outString << "* " << std::endl;
362  outString << "* Simulation Type = ElmerFoamFSIPar " << std::endl;
363  outString << "* Simulation start time = " << simulationTime << std::endl;
364  outString << "* Simulation final time = " << simulationFinalTime << std::endl;
365  outString << "* Simulation time step = " << simulationTimeStep << std::endl;
366  outString << "* Number of time steps = " << int(simulationFinalTime/simulationTimeStep) << std::endl;
367  outString << "* " <<std::endl;
368  outString << "* Hostname = " << hostName << std::endl;
369  outString << "* Number of processors = " << NProc() << std::endl;
370  outString << "************************************************* " << std::endl;
371  outString << std::endl;
372  StdOut(outString.str(),0,true);
373  outString.clear();
374  outString.str("");
376 
377  // Write some stuff to screen
378  outString << "System timestep " << ++systemStep
379  << " @ Time = " << simulationTime << std::endl;
380  StdOut(outString.str(),1,true);
381  outString.clear();
382  outString.str("");
383 
384 
385  if(!runMode){
386  // Transfer displacements @ Tn to fluids
387  outString << "Transferring displacements from structures to fluids @ time("
388  << simulationTime << ")" << std::endl;
389  StdOut(outString.str(),1,true);
390  outString.clear();
391  outString.str("");
393  }
394 
395  if(runMode < 2){
397  // Step fluids to get loads @ T(n+1)
398  outString << "Stepping fluids to time("
399  << simulationTime+simulationTimeStep << ")" << std::endl;
400  StdOut(outString.str(),1,true);
401  outString.clear();
402  outString.str("");
404  }
405 
406  if(!runMode){
407  outString << "Transferring loads from fluids to structures @ time("
408  << simulationTime << ")" << std::endl;
409  StdOut(outString.str(),1,true);
410  // Transfer loads @ T(n+1) to structures
411  //std::cout << "FSICoupling: Transferring loads from fluids to structures @ time("
412  // << simulationTime+simulationTimeStep << ")" << std::endl;
414  }
415 
416  if(!(runMode==1)){
418  // Step structures to get displacements @ T(n+1)
419  outString << "Stepping structures to time("
420  << simulationTime+simulationTimeStep << ")" << std::endl;
421  StdOut(outString.str(),1,true);
422  outString.clear();
423  outString.str("");
425  }
426 
427  // Finalize timestep and advance time T(n) --> T(n+1)
428  bool converged = true;
429  if(converged){
431  outString << "Converged at time("
432  << simulationTime << ")" << std::endl;
433  StdOut(outString.str(),1,true);
434  outString.clear();
435  outString.str("");
436  if(runMode < 2)
438  if(!(runMode == 1))
440  innerCount = 0;
441  } else {
442  innerCount++;
443  if(innerCount > maxSubSteps){
444  outString << "Failed to converge after "
445  << maxSubSteps << ", giving up." << std::endl;
446  StdOut(outString.str(),0,true);
447  outString.clear();
448  outString.str("");
449  return(1);
450  }
451  }
452 
453  StdOut(outString.str(),0,true);
454  outString.clear();
455  outString.str("");
456 
457  if(!(systemStep%dumpinterval)){
458  //DumpSolution();
459  }
460 
461  }
462  Communicator().Barrier();
463 
464  // gathering some information for user
465  time_t nowEnd = time(0);
466  dtChar = ctime(&nowEnd);
467  outString << std::endl << std::endl
468  << "************************************************* " << std::endl;
469  outString << "* Finishing Stepping in Time * " << std::endl;
470  outString << "************************************************* " << std::endl;
471  outString << "* Ending simulation at " << dtChar;
472  outString << "* Total simulation time (s) = " << nowEnd - nowStart << std::endl;
473  outString << "* Summary of the simulation: " << std::endl;
474  outString << "* " << std::endl;
475  outString << "* Simulation Type = ElmerFoamFSIPar " << std::endl;
476  outString << "* Simulation final time = " << simulationFinalTime << std::endl;
477  outString << "* Simulation time step = " << simulationTimeStep << std::endl;
478  outString << "* Number of time steps = " << int(simulationFinalTime/simulationTimeStep) << std::endl;
479  outString << "* " <<std::endl;
480  outString << "* Hostname = " << hostName << std::endl;
481  outString << "* Number of processors = " << NProc() << std::endl;
482  outString << "************************************************* " << std::endl;
483  outString << std::endl;
484  StdOut(outString.str(),0,true);
485 
486  FunctionExit("Run");
487 
488  return(0);
489  };
490 
491  virtual int Finalize(){
492  // Finalize the fluids module
493  if(runMode < 2)
495  // Finalize the structures module
496  if(!(runMode == 1))
498  // Anything I need to do to finalize myself
499  return(0);
500  }
501 
502 
504  std::vector<std::string> getVariable(){
505  std::vector<std::string> varVector;
506  varVector.push_back(this->fluidsInterfaceName);
507  varVector.push_back(this->structuresInterfaceName);
508  varVector.push_back(this->transferInterfaceName);
509  varVector.push_back(this->surfUtilInterfaceName);
510  varVector.push_back(this->simpalInterfaceName);
511  varVector.push_back(this->simoutInterfaceName);
512  return varVector;
513  }
514 
515  double getSimulationTime() {return this->simulationTime;}
516  double getSimulationTimeStep() {return this->simulationTimeStep;}
518  int getRunMode() {return this->runMode;}
519 
522 
523  std::string getFluidIntName() {return this->fluidsInterfaceName;}
524  std::string getSolidIntName() {return this->structuresInterfaceName;}
525 
526 };
527 
528 #endif
std::string fluidsWinFnameHDF
const std::vector< double > & Coordinates() const
Definition: ElmerParAgent.H:87
std::string getFluidIntName()
void WriteHDF(bool toggle)
transferagentpar * transferAgent
double simulationTimeStep
virtual int Finalize()
solidagentpar * structuresAgent
fluidagentpar * getFluidAgent()
std::string fluidsInterfaceName
virtual int Initialize(const std::string interfaceName, int verblevel=1)
int VerbLevel() const
std::string siminInterfaceName
int TransferDisplacementsToFluid(solidagentpar *solidAgent, fluidagentpar *fluidAgent)
virtual int Initialize(const std::string &interfaceName, int verblevel=1)
Definition: ElmerParAgent.H:10
std::string structuresInterfaceName
double getSimulationTimeStep()
SolverUtils::TransferObjectPar transferagentpar
virtual int FinalizeTimeStep(double time)
Definition: Orchestrator.H:25
std::vector< impact::orchestrator::agentbase * > componentAgents
Definition: Orchestrator.H:44
fsicouplingpar(PGlobalType &globin)
virtual void writeWin(const char *winName, std::string timeMark, std::string &wFnameHdf)
double getSimulationFinalTime()
virtual int Run()
std::vector< std::string > getVariable()
Helper functions for accessing protected data members.
int TransferLoadsToStructures(fluidagentpar *fluidAgent, solidagentpar *solidAgent)
std::string transferInterfaceName
std::string StackType
Convenience type definition for program stack.
Definition: Driver.H:46
openfoamagentpar fluidagentpar
int WriteAgentToVTK(const std::string &nameRoot, SolverUtils::FEM::SolverAgent &solverAgent)
double simulationTime
void SetVerbLevel(int verb)
double getSimulationTime()
elmeragentpar solidagentpar
virtual int Initialize(std::vector< std::string > &componentInterfaceNames, double finalTime, double timeStep)
virtual int Run(double endTime)
virtual int DumpSolution()
virtual int InitializeTimeStep(double time)
Definition: Orchestrator.H:24
std::string simpalInterfaceName
virtual int Run(double time)
Definition: ElmerParAgent.H:79
void SetProbe(int inProbProcId, int inProbNdeId, std::string inProbSlvName)
void SetRunMode(const std::string &inMode)
virtual int Finalize()
Definition: ElmerParAgent.H:89
IRAD::Profiler::ProfilerObj ProfilerType
Encapsulate example program-specific code constructs.
Definition: Driver.H:42
const std::vector< double > & Coordinates() const
void WriteVTK(bool toggle)
fluidagentpar * fluidsAgent
std::string probSolverName
IRAD::Global::ParallelGlobalObj< CommTypeIrad, StackType, int, ProfilerType > PGlobalType
std::string getSolidIntName()
solidagentpar * getStructureAgent()
std::string simoutInterfaceName
std::string surfUtilInterfaceName
double simulationFinalTime
IRAD::Comm::CommunicatorObject CommTypeIrad
std::string structuresWinFnameHDF