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
ElmerFSI/trunk/src/SolverModuleDriver.C
Go to the documentation of this file.
1 #include "com.h"
10 #include "com_devel.hpp"
11 #include <iostream>
12 #include <cstring>
13 #include <cstdlib>
14 #include <stdlib.h>
15 #include <sstream>
16 #include "primitive_utilities.H"
17 #include "SolverModuleDriver.H"
18 
19 COM_EXTERN_MODULE( ElmerCSC);
20 
21 void SolverModuleDriver::usage(char *exec){
22  std::cout << "SolverModuleDriver:usage: Usage: " << std::endl
23  << exec << " -com-mpi timeNext timeNext ... timeFinal" << std::endl
24  << "where at least -com-mpi and timeFinal is required." << std::endl
25  << "NOTES:" << std::endl
26  << "*currently it is required to use the -com-mpi flag" << std::endl
27  << "*steady state problems will always use a timestep" << std::endl
28  << " of 1.0, and should only have a timeFinal" << std::endl
29  << "*each time must be greater than the previous time" << std::endl
30  << " because the simulation begins at the previous time and runs" << std::endl
31  << " to the current time" << std::endl;
32  std::exit(1);
33 }
34 
35 int SolverModuleDriver::init(int argc, char *argv[]){
36 
37  COM_init( &argc, &argv);
38 
39  std::cout << "SoverModuleDriver:init: After COM_init" << std::endl;
40 
41  isNum = isFSI = changeLoads = false;
42  Disp = NULL;
43  DispSize = 0;
44  Coord = NULL;
45  Conn = NULL;
46  coord_handle = -1;
47  CoordSize=0;
48  coordData = false;
49  connCorrect = true;
50  ConnSize = 0;
51  Loads = NULL;
52  LoadsSize = 0;
53 
54  std::string arg;
55 
56  if(argc > 1){
57  for(int i=1; i < argc; i++){
58  ss.clear();
59  ss.str("");
60  ss << argv[i];
61  if(ss.str() == "-com-mpi")
62  continue;
63  if(ss.str() == "-fsi"){
64  isFSI = true;
65  continue;
66  }
67  if(ss.str() == "-loads"){
68  changeLoads = true;
69  continue;
70  }
71  for(int j=0; j < ss.str().size(); j++){
72  if(!isdigit(ss.str()[j]) && ss.str()[j] != 'e'
73  && ss.str()[j] != 'E' && ss.str()[j] != '-'
74  && ss.str()[j] != '.')
75  usage(argv[0]);
76  }
77  ss >> var;
78  tNext.push_back(var);
79  }
80  }
81  else
82  usage(argv[0]);
83 
84  for(int i=1; i < tNext.size(); i++){
85  if(tNext[i] <= tNext[i-1])
86  usage(argv[0]);
87  }
88 
89  COM_LOAD_MODULE_STATIC_DYNAMIC( ElmerCSC, "Window1");
90 
92  int init_handle = COM_get_function_handle("Window1.Initialize");
93  bool init_func = (init_handle > 0);
94  int verb=3;
95  runs = 0;
96  if(init_func){
97  COM_call_function(init_handle, &runs, &verb);
98  }
99 
100  return 0;
101 }
102 
104  if(isFSI){
106  // Check coordinate values
108  coord_handle = COM_get_dataitem_handle("Window1.nc");
109  CoordSize=0;
110  coordData = (coord_handle > 0);
111  std::cout << "SoverModuleDriver:run: coord_handle = " << coord_handle << std::endl;
112  if(coordData){
113  COM_get_size("Window1.nc",11,&CoordSize);
114  // Get the FSI mesh from the structures solver and print
115  // it out to check
116  COM_get_array("Window1.nc",11,&Coord);
117  std::cout << "SoverModuleDriver:run: Coord: " << std::endl;
118  for(int i=0; i < CoordSize; i++){
119  for(int j=0; j < 3; j++){
120  std::cout << Coord[i*3+j] << " ";
121  }
122  std::cout << std::endl;
123  }
124  Mesh().nc.init(CoordSize, Coord);
125  }
126 
128  // Check connectivity values
130  connCorrect = true;
131  ConnSize = 0;
132 
133  // Get the FSI mesh from the structures solver
134  COM_get_array("Window1.:b2:",11,&Conn);
135  if(Conn){
136  // Get the FSI mesh size from the structures solver
137  COM_get_size("Window1.:b2:",11,&ConnSize);
138  // check the values
139  std::cout << "SoverModuleDriver:run: Conn: " << std::endl;
140  for(int i=0; i < ConnSize; i++){
141  for(int j=0; j < 2; j++){
142  std::cout << Conn[i*2+j] << " ";
143  elems.push_back(Conn[i*2+j]);
144  }
145  std::cout << std::endl;
146  }
147  Mesh().con.AddElements(ConnSize,2,elems);
148  }
149 
150  if(Conn && coordData){
151  std::cout << "SoverModuleDriver:run: WriteMeshToStream: " << std::endl;
152  WriteMeshToStream(std::cout);
153  std::cout << std::endl;
154  }
155  // Check displacement data
156  COM_get_array("Window1.Displacements",11,&Disp);
157  if (Disp){
158  // Get the FSI displacement size from the structures solver
159  COM_get_size("Window1.Displacements",11,&DispSize);
160 
161  std::cout << "SoverModuleDriver:run: Checking displacements" << std::endl;
162  for(int i=0; i < DispSize; i++){
163  for(int j=0; j < 3; j++){
164  std::cout << Disp[i*3+j] << " ";
165  DispPass.push_back(Disp[i*3+j]);
166  }
167  std::cout << std::endl;
168  }
169  }
170  }
171 
172  std::cout << "Line = " << __LINE__ << std::endl;
173 
174  //If we want to prescribe loads here's where we do it
175  Loads = NULL;
176  LoadsSize = 0;
177 
178  // Get the FSI loads from the structures solver
179  if(isFSI && changeLoads){
180  COM_get_array("Window1.Loads",11,&Loads);
181  if(Loads){
182  std::cout << "SoverModuleDriver:run: Loads not NULL" << std::endl;
183  // Get the FSI load size from the structures solver
184  COM_get_size("Window1.Loads",11,&LoadsSize);
185  // Check load data
186 
187  std::cout << "SoverModuleDriver:run: Checking loads" << std::endl;
188  for(int i=0; i < LoadsSize; i++){
189  for(int j=0; j < 3; j++){
190  Loads[i*3 + j] = double(i*3 + j);
191  std::cout << Loads[i*3+j] << " ";
192  LoadsPass.push_back(Loads[i*3+j]);
193  }
194  std::cout << std::endl;
195  }
196  }
197  }
198  std::cout << "SoverModuleDriver:run: Line = " << __LINE__ << std::endl;
199 
200  //Put the displacements and loads in the Solution object
201  //so we can use its utilities and write a vtk file
202  if(Disp && isFSI){
203  Solution().Meta().AddField("displacement",'n',3,8,"m");
204  std::cout << "SoverModuleDriver:run: WriteSolnMetaToStream:" << std::endl;
205  WriteSolnMetaToStream(std::cout);
206  std::cout << std::endl;
207  }
208  if(Loads && isFSI){
209  Solution().Meta().AddField("loads",'n',3,8,"");
210  std::cout << "SoverModuleDriver:run: WriteSolnMetaToStream:" << std::endl;
211  WriteSolnMetaToStream(std::cout);
212  std::cout << std::endl;
213  }
214  std::cout << "SoverModuleDriver:run: Line = " << __LINE__ << std::endl;
215  if((Disp && isFSI) || Loads){
216  CreateSoln();
217  }
218  std::cout << "SoverModuleDriver:run: Line = " << __LINE__ << std::endl;
219  if(Disp && isFSI)
220  Solution().SetFieldBuffer("displacement",DispPass);
221  if(Loads && isFSI)
222  Solution().SetFieldBuffer("loads",LoadsPass);
223 
224  std::cout << "SoverModuleDriver:run: Line = " << __LINE__ << std::endl;
225 
226  //Write vtk file for timestep 0
227  if(isFSI && Conn && Coord){
228  std::ofstream Ouf;
229  std::string filename;
230  filename = "fsi0.vtk";
231  Ouf.open(filename.c_str());
232  if(!Ouf){
233  std::cerr << "SoverModuleDriver:run: SolverModuleDriver::DumpSolution:Error: Could not open output file, "
234  << filename << "." << std::endl;
235  return -1;
236  }
237  std::cout << "SoverModuleDriver:run: WriteVTKToStream time 0" << std::endl;
238  SolverUtils::WriteVTKToStream("Window1",*this,Ouf);
239  Ouf.close();
240  }
241 
242 
244  int run_handle = COM_get_function_handle("Window1.Run");
245  bool run_func = (run_handle > 0);
246  runs = 0;
247  if(run_func){
248  int timestep = 0;
249  for(int i=0; i < tNext.size(); i++){
250  //Change the load values as a test
251  if(Loads && isFSI){
252  std::cout << "SoverModuleDriver:run: Changing load values" << std::endl;
253  for(int k=0; k < LoadsSize; k++){
254  for(int j=0; j < 3; j++){
255  Loads[k*3 + j] = double(k*3 + j) + tNext[i];
256  std::cout << Loads[k*3 + j] << " ";
257  LoadsPass[k*3 + j] = Loads[k*3 + j];
258  }
259  std::cout << std::endl;
260  }
261  }
262 
263  std::cout << "SoverModuleDriver:run: Calling run function from driver" << std::endl;
264  COM_call_function(run_handle,&runs,&tNext[i]);
265 
266  //Update Solution's displacments for writing vtk file
267  if(isFSI && Disp){
268  std::cout << "SoverModuleDriver:run: Checking displacements" << std::endl;
269  for(int k=0; k < DispSize; k++){
270  for(int j=0; j < 3; j++){
271  std::cout << Disp[k*3+j] << " ";
272  DispPass[k*3+j] = Disp[k*3+j];
273  }
274  std::cout << std::endl;
275  }
276  }
277  timestep++;
278  //Write vtk file for timestep
279  if(isFSI && Conn && Coord){
280  std::ofstream Ouf;
281  ss.clear();
282  ss.str("");
283  ss << timestep;
284  std::string filename;
285  filename = "fsi" + ss.str() + ".vtk";
286  Ouf.open(filename.c_str());
287  if(!Ouf){
288  std::cerr << "SolverModuleDriver::DumpSolution:Error: Could not open output file, "
289  << filename << "." << std::endl;
290  return -1;
291  }
292  SolverUtils::WriteVTKToStream("Window1",*this,Ouf);
293  Ouf.close();
294  }
295  }
296  }
297  return 0;
298 }
299 
301 
303  int final_handle = COM_get_function_handle("Window1.Finalize");
304  bool final_func = (final_handle > 0);
305  runs = 0;
306  if(final_func){
307  COM_call_function(final_handle,&runs);
308  }
309 
310  COM_UNLOAD_MODULE_STATIC_DYNAMIC( ElmerCSC, "Window1");
311 
312  COM_finalize();
313  std::cout << "SolverModuleDriver:finalize: After COM_finalize" << std::endl;
314 
315  return 0;
316 
317 }
318 
319 int main(int argc, char *argv[]){
320 
321  SolverModuleDriver driverObject;
322 
323  driverObject.init(argc, argv);
324  driverObject.run();
325  driverObject.finalize();
326 
327  std::ofstream Outfile;
328 
329  Outfile.open("out.dat");
330 
331  Outfile << "howdy!" << std::endl;
332  Outfile << "1.2 4.2 5.6 7.8" << std::endl;
333  Outfile << " blargity blarg blarg" << std::endl;
334 
335  return 0;
336 }
337 
std::vector< double > DispPass
std::stringstream ss
std::vector< unsigned int > elems
int init(int argc, char *argv[])
COM_EXTERN_MODULE(OpenFoamFSI)
#define main
Definition: icoFoamModule.C:2
std::vector< double > tNext
std::vector< double > LoadsPass