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
int COM::parallelProgram ( int  argc,
char *  argv[] 
)

Definition at line 400 of file SolverModuleDriverParallel.C.

References SolverModuleDriver::Disp, SolverModuleDriver::finalize(), SolverModuleDriver::init(), SolverModuleDriver::isChangeLoad(), SolverModuleDriver::isFSISim(), SolverModuleDriver::isStreamer(), SolverModuleDriver::Loads, SolverModuleDriver::myPaneId, SolverModuleDriver::nDisp, SolverModuleDriver::nLoads, SolverModuleDriver::nNodes, SolverModuleDriver::outfile, SolverModuleDriver::run(), SolverModuleDriver::setColor(), SolverModuleDriver::setComm(), SolverModuleDriver::setRank(), and SolverModuleDriver::updateSolution().

Referenced by main().

400  {
401  int parErr;
402  // instantiating IRAD's communicatorObject
403  // this constructor calls MPI_init internally and
404  // sets up everthing with MPI
405  std::cout <<"ElmerModuleDriver:Main: Setting up parallel communicator..." << std::endl;
406  CommType communicator(&argc,&argv);
407  MPI_Comm masterComm = communicator.GetCommunicator();
408  int rank = communicator.Rank();
409  int nproc = communicator.Size();
410  int color = 0;
411  std::cout << "ElmerModuleDriver:Main:Rank #"
412  << rank
413  << ", I see "
414  << nproc
415  << " proccesses."
416  << std::endl;
417  // initializing COM
418  COM_init( &argc, &argv);
419 
420  // instantiating solver driver object
421  SolverModuleDriver driverObject;
422  driverObject.setRank(rank);
423  driverObject.myPaneId=100+rank;
424 
425  // checking streamer process
426  if (driverObject.isStreamer())
427  std::cout << "Hi, I am a streamer ..." << std::endl;
428 
429  // setting up output files for parallel debugging
430  std::string outfile_name;
431  std::stringstream ss;
432  std::string str_rank;
433  ss << rank;
434  ss >> str_rank;
435  outfile_name = "out" + str_rank + ".dat";
436  driverObject.outfile.open(outfile_name.c_str());
437 
438  // setting color for the driver object
439  driverObject.setColor(color);
440  driverObject.outfile << "color = " << color << std::endl;
441  driverObject.outfile << "rank = " << rank << std::endl;
442  CommType newCommunicator;
443  communicator.Split(color, rank, newCommunicator);
444  driverObject.outfile << "communicator.Size() = " << communicator.Size() << std::endl;
445  driverObject.outfile << "newCommunicator.Size() = " << newCommunicator.Size() << std::endl;
446  driverObject.setComm(newCommunicator.GetCommunicator());
447  MPI_Comm newComm;
448  newComm = newCommunicator.GetCommunicator();
449  COM_set_default_communicator(newComm);
450 
451  // calling initializer, for FSI problems mesh and solution
452  // related datastructures will be automatically registered
453  driverObject.init(argc, argv);
454 
455  // get information about what was registered in this window
456  int numDataItems=0;
457  std::string output;
458  COM_get_dataitems("ELMModule", &numDataItems, output);
459  std::istringstream Istr(output);
460  std::vector<std::string> dataItemNames;
461  for (int i=0; i<numDataItems; ++i) {
462  std::string name;
463  Istr >> name;
464  dataItemNames.push_back(name);
465  std::cout << "Rank #" << rank
466  << ", ElmerModuleDriver:main: DataItem # " << i << ": " << name << std::endl;
467  }
468  // list of panes for this process: each process creates a single pane
469  // with paneId = 100 + rank
470  int numPanes;
471  int* paneList;
472  COM_get_panes("ELMModule", &numPanes, &paneList);
473  std::cout << "Rank #" << rank
474  << ", ELMModuleDriver:main: Number of Panes " << numPanes << std::endl;
475  for (int i=0; i<numPanes; ++i)
476  std::cout << "Rank #" << rank
477  << ", ELMModuleDriver:main: Pane ID # " << i+1 << "=" << paneList[i] << std::endl;
478 
479  // updating solution
480  driverObject.updateSolution();
481 
482  // dumping intial conditions to vtk
483  //if (driverObject.isFSISim())
484  // driverObject.vtkDump(0);
485 
486  // scattering FSI loads to the structures solver processes
487  // only for FSI problesm
488  if(driverObject.isFSISim() && driverObject.isChangeLoad()){
489  std::vector<int> nLoadsVec;
490  std::vector<int> nLoadsTotVec;
491  std::vector<int> nRecvAllVec;
492  nLoadsVec.push_back(driverObject.nNodes*driverObject.nLoads);
493  std::cout << "Rank #"<<rank
494  <<", nLoadsVec["<<rank<<"] = "<<nLoadsVec[rank]<<std::endl;
495  parErr = newCommunicator.Gatherv(nLoadsVec, nLoadsTotVec, nRecvAllVec);
496  if (parErr)
497  std::cout << "Error in gathering information from processes." << std::endl;
498  if (rank == 0){
499  for (int iProc=0; iProc<nLoadsTotVec.size(); iProc++)
500  std::cout << "Rank #"<<rank
501  <<", nLoadsTotVec["<<iProc<<"] = "<<nLoadsTotVec[iProc]<<std::endl;
502  }
503  // defining new loads
504  std::vector<double> loadsVec;
505  std::vector<double> loadsTotVec;
506  int nLoadsTot = 0;
507  if (rank == 0){
508  for (int iProc=0; iProc < nLoadsTotVec.size(); iProc++){
509  nLoadsTot += nLoadsTotVec[iProc];
510  }
511  loadsTotVec.resize(nLoadsTot,0.0);
512  for (int iLoad=1; iLoad < nLoadsTot; iLoad+=3)
513  loadsTotVec[iLoad] = 1.0;
514  std::cout << "Size of loadsTotVec = " << loadsTotVec.size() << std::endl;
515  }
516  // parallel scattering
517  parErr = newCommunicator.Scatterv(loadsTotVec, nLoadsTotVec, loadsVec);
518  if (parErr)
519  std::cout << "Error in scattering information to processes." << std::endl;
520  std::cout << "Rank #" << rank
521  << ", number of load components I received = " << loadsVec.size()
522  << std::endl;
523  // applying loads for each process
524  for (int iLoad=0; iLoad<(driverObject.nLoads*driverObject.nNodes); ++iLoad){
525  driverObject.Loads[iLoad] = loadsVec[iLoad];
526  std::cout << "Rank #" << rank
527  << ", driverObject.Loads ["<<iLoad<<"] = "
528  << driverObject.Loads[iLoad] << std::endl;
529  }
530  // setting a barrier here
531  std::cout << "Rank #"<<rank<<"...Reaching to barrier"<<std::endl;
532  newCommunicator.Barrier();
533  }
534 
535  // calling run step
536  driverObject.run();
537  newCommunicator.Barrier();
538 
539  // gathering all displacements in root
540  // only for FSI problesm
541  if(driverObject.isFSISim() && driverObject.isChangeLoad()){
542  std::vector<double> dispVec;
543  std::vector<double> dispTotVec;
544  std::vector<int> nSendAllVec;
545  for (int iDisp=0; iDisp<(driverObject.nDisp*driverObject.nNodes); ++iDisp){
546  dispVec.push_back(driverObject.Disp[iDisp]);
547  std::cout << "Rank #" << rank
548  << ", dispVec ["<<iDisp<<"] = " << dispVec[iDisp] << std::endl;
549  }
550  std::cout << "Rank #" << rank
551  << ", dispVec size = " << dispVec.size() << std::endl;
552  // parallel gathering
553  parErr = newCommunicator.Gatherv(dispVec, dispTotVec, nSendAllVec);
554  if (parErr)
555  std::cout << "Error in gathering information from processes." << std::endl;
556  std::cout << "Rank #" << rank
557  << ", size of dispTotVec = " << dispTotVec.size()
558  << std::endl;
559  // setting a barrier here
560  std::cout << "Rank #"<<rank<<"...Reaching to barrier"<<std::endl;
561  newCommunicator.Barrier();
562  // checking gather data vector
563  if (rank == 0){
564  double maxDisp = 0.0;
565  double minDisp = 0.0;
566  for (int iDisp=0; iDisp<dispTotVec.size(); iDisp++){
567  maxDisp = std::max(dispTotVec[iDisp], maxDisp);
568  minDisp = std::min(dispTotVec[iDisp], minDisp);
569  std::cout << "Rank #0, dispTotVec [" << iDisp << "] = "
570  << dispTotVec[iDisp] << std::endl;
571  }
572  outfile_name = "maxMinDisp.dat";
573  std::ofstream testFile;
574  testFile.open(outfile_name.c_str());
575  testFile << maxDisp << std::endl << minDisp << std::endl;
576  testFile.close();
577  }
578  // writing window to HDF
579  int OUT_set = COM_get_function_handle( "OUT.set_option");
580  int OUT_write = COM_get_function_handle( "OUT.write_dataitem");
581  const char *win_out= "ELMModule";
582  std::string win_out_pre(win_out);
583  win_out_pre.append(".");
584  int OUT_all = COM_get_dataitem_handle((win_out_pre+"all").c_str());
585  ss.clear();
586  ss.str("");
587  ss << "_proc_"
588  << rank;
589  std::string fileOut;
590  fileOut = "ELMModule_window" + ss.str();
591  COM_call_function( OUT_set, "format", "HDF4");
592  COM_call_function( OUT_write, (fileOut + ".hdf").c_str(), &OUT_all, win_out,
593  "0000");
594  }
595 
596  // calling finalize
597  driverObject.finalize();
598 
599  // closing log file for the driver object
600  driverObject.outfile.close();
601 
602  // finalize comm
603  COM_finalize();
604 
605  // finalizing communicator
606  communicator.Finalize();
607  return 0;
608  }
int init(int argc, char *argv[])
IRAD::Comm::CommunicatorObject CommType
Convenience typedef for CommunicatorObject.

Here is the call graph for this function:

Here is the caller graph for this function: