vtf-logo

fsi/sfc-amroc/ThinPlate/src/ShellManagerSpecific.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00004 // 
00005 //                           Fehmi Cirak, Ralf Deiterding
00006 //                        California Institute of Technology
00007 //                           (C) 2004 All Rights Reserved
00008 //
00009 // <LicenseText>
00010 //
00011 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00012 //
00013 #ifndef SHELLMANAGERSPECIFIC_H
00014 #define SHELLMANAGERSPECIFIC_H
00015 #include <vector>
00016 #include <fstream>
00017 #include <string>
00018 #include <limits>
00019 
00020 #include "mpi.h"
00021 #include "elc/LagrangianComm.h"
00022 
00023 #include "shells/driverCC/ShellManagerBasic.h"
00024 #include "shells/parallel/ShellManagerParallel.h"
00025 #include "shells/utilities/BasicSensor.h"
00026 #include "shells/utilities/MakeUniqueName.h"
00027 #include "shells/utilities/PropertiesParser.h"
00028 #include "shells/driverCC/SVertexFunctors.h"
00029 #include "shells/driverCC/PrescribeVarFunctor.h"
00030 
00031 
00032 typedef shells::ShellManagerParallel<shells::ShellManagerBasic>  SMPF; 
00033 
00034 
00035 class ShellManagerSpecific : public SMPF {  
00036 private:
00037     typedef utilities::BasicSensor<shells::SVertexDisplacement> BasicSensorSp;
00038     
00039 public:
00040     ShellManagerSpecific(const std::string& controlFileName, MPI_Comm solidComm,
00041                          int numFluidNodes, int firstFluidNode) : 
00042         SMPF(controlFileName, solidComm), _subIterations(1) {
00043         
00044 #ifdef DEBUG_PRINT
00045         int myRank;
00046         std::ostringstream obuf;
00047         MPI_Comm_rank(solidComm, &myRank);
00048         obuf << "S" << myRank << ".log" << static_cast<char>(0);
00049         oflog.open(obuf.str().c_str());     
00050         _olog = new std::ostream(oflog.rdbuf());
00051 #endif
00052         
00053         computeMassPrepareAdvance();
00054         
00055 #ifdef DEBUG_PRINT_ELC
00056         (*_olog << "*** LagrangianComm: " << numFluidNodes << "  " << firstFluidNode ).flush();
00057 #endif  
00058         // instantiate an elc object for data exchange
00059         _elcLag = new elc::LagrangianComm<DIM, double>(MPI_COMM_WORLD, solidComm, numFluidNodes,
00060                                                        firstFluidNode, elc::GlobalIdentifiers);
00061 #ifdef DEBUG_PRINT_ELC
00062         (*_olog << " created.\n").flush();
00063 #endif  
00064 
00065         // read _subIterations from input file
00066         utilities::PropertiesParser *prop = new utilities::PropertiesParser;
00067         prop->registerPropertiesVar("SubIterations", _subIterations);
00068         std::ifstream inputFile("./shellInput.dat");
00069         if (!inputFile.is_open()) assert(false);
00070         prop->readValues(inputFile);    
00071         delete prop;
00072         inputFile.close();
00073         
00074 #ifdef DEBUG_PRINT
00075         (*_olog << "*** ShellManagerSpecific created.\n").flush();
00076 #endif
00077 
00078         if (_subIterations<=0) 
00079             _subIterations=1;
00080     }
00081 
00082 
00083     ~ShellManagerSpecific() {
00084 //      if (_sensor!=NULL) delete _sensor;
00085         if (_elcLag!=NULL) delete _elcLag;
00086         if (_olog!=NULL) delete _olog;
00087         if (_gnuplotFile!=NULL) {
00088             _gnuplotFile->close();
00089             delete _gnuplotFile;
00090         }
00091     }
00092 
00093    
00094     void sendBoundaryReceivePressure() {
00095         double *elCoordinates = NULL;
00096         double *elVelocities = NULL;
00097         int *elGlobalNodeIDs = NULL;
00098         int elNumNodes;
00099         int *elConnectivity = NULL;
00100         int elNumElements;
00101         
00102         SMPF::decode(&elCoordinates, &elVelocities, &elGlobalNodeIDs,
00103                      &elNumNodes, &elConnectivity, &elNumElements);
00104         
00105         // allocate space for pressure and initialize
00106         _elPressures.resize(elNumElements);       
00107         std::fill(_elPressures.begin(), _elPressures.end(), 0.0);
00108         
00109 #ifdef DEBUG_PRINT_ELC
00110         ( *_olog << "*** ShellManagerSpecific::sendBoundaryReceivePressure" ).flush();
00111 #endif
00112         
00113         _elcLag->sendMesh(elNumNodes, reinterpret_cast<void*>(elGlobalNodeIDs), 
00114                           reinterpret_cast<void*>(elCoordinates), 
00115                           reinterpret_cast<void*>(elVelocities), 
00116                           elNumElements, reinterpret_cast<void*>(elConnectivity));
00117         _elcLag->waitForMesh();
00118         _elcLag->receivePressure(elNumElements, reinterpret_cast<void*>(&(_elPressures[0])));
00119         _elcLag->waitForPressure();
00120 
00121         // Necessary if solid domain larger than fluid domain
00122         for (unsigned int n=0; n<_elPressures.size(); n++) {
00123             if (_elPressures[n] == std::numeric_limits<double>::max()) {
00124                 _elPressures[n] = 0.0;
00125             }
00126         }
00127 
00128         encodePressure(&(_elPressures[0]), _elPressures.size(), element);
00129         
00130 #ifdef DEBUG_PRINT_ELC
00131         ( *_olog << " done.\n" ).flush();
00132 #endif
00133     }
00134 
00135 
00136     virtual void advanceSp(double& t, double& dt){
00137         dt /= _subIterations;
00138         setTimeStep(dt);
00139 
00140 #ifdef DEBUG_PRINT
00141         (*_olog << "*** advancing in time.\n").flush();
00142 #endif
00143         
00144         predictAndEnforceBC();
00145         sendBoundaryReceivePressure();
00146         internalExternalForces();       
00147         correct();      
00148         incrementCurrentTimeAndStep();
00149 
00150         for (int n=1; n<_subIterations; n++) {      
00151             predictAndEnforceBC();       
00152             internalExternalForces();   
00153             correct();  
00154             incrementCurrentTimeAndStep();
00155         }
00156 
00157         dt = stableTimeStep()*_subIterations;
00158         t = getCurrentTime();
00159         
00160         // print sensors
00161         std::for_each(_sensors.begin(), _sensors.end(), 
00162                       std::bind2nd(std::mem_fun(&BasicSensorSp::printData), t));
00163     }
00164     
00165     
00166     void addSensors(double xyz[3]) {
00167         // open a file and instantiate a sensor
00168         const int myRank = communicatorRank();
00169         std::string nameGnuplot = utilities::makeUniqueName(_sensors.size(), myRank, "./dispSensor-", "dat");
00170         std::ofstream *gnuplotFile = new std::ofstream(nameGnuplot.c_str(), std::ofstream::app);
00171         BasicSensorSp *s = new BasicSensorSp(*gnuplotFile, ShellManagerBasic::mShell(), xyz);   
00172         _sensors.push_back(s);
00173     }
00174 
00175          
00176     void initialize(double& t, double& dt){
00177         sendBoundaryReceivePressure();
00178         dt = stableTimeStep()*_subIterations;
00179         t = getCurrentTime();
00180         
00181         // add sensors
00182         double first[3] = {0.5, 0.5, 0.};
00183         addSensors(first);
00184     }
00185 
00186  
00187     void output() {
00188         printDataParallel(true);
00189 
00190 #ifdef DEBUG_PRINT
00191         ( *_olog << " Printing interface mesh and pressure.\n" ).flush();
00192         printIFaceMeshPressureParallel();
00193 #endif
00194     }
00195 
00196 
00197     int nSteps() {
00198         return getCurrentStepNum()/_subIterations;
00199     }
00200 
00201 
00202     void checkpointing() {
00203         checkPointingParallel();
00204     }
00205 
00206     void restartSp(double& t, double& dt) {
00207         restartParallel();
00208         t = getCurrentTime();
00209         dt = stableTimeStep()*_subIterations;
00210         
00211         sendBoundaryReceivePressure();
00212         return;
00213     }
00214 
00215     
00216 // copy and assignment constructors - not implemented
00217 private:
00218     ShellManagerSpecific(const ShellManagerSpecific &);
00219     const ShellManagerSpecific & operator=(const ShellManagerSpecific &);   
00220     
00221 private:
00222     elc::LagrangianComm<DIM, double>     *_elcLag;
00223 
00224     std::ostream                         *_olog;
00225     std::ofstream                         oflog; 
00226 
00227     std::ofstream                        *_gnuplotFile;
00228         
00229     std::vector<double>                  _elPressures;
00230 
00231     std::vector<BasicSensorSp *>         _sensors;
00232 
00233     int                                  _subIterations;
00234 };
00235 
00236 #endif

Generated on Fri Aug 24 13:02:34 2007 for Virtual Test Facility Coupled Applications by  doxygen 1.4.7