vtf-logo

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

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00004 //  
00005 //                           Ralf Deiterding, Fehmi Cirak
00006 //                        California Institute of Technology
00007 //                           (C) 2006 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 #include <shells/driverCC/StableTimeStep.h>
00031 
00032 #include "ShellEnforceBCFunctor.h"
00033 
00034 typedef shells::ShellManagerParallel<shells::ShellManagerBasic>  SMPF; 
00035 
00036 
00037 class ShellManagerSpecific : public SMPF {  
00038 private:
00039     typedef utilities::BasicSensor<shells::SVertexDisplacement> BasicSensorSp;
00040     
00041 public:
00042     ShellManagerSpecific(const std::string& controlFileName, MPI_Comm solidComm,
00043                          int numFluidNodes, int firstFluidNode) : 
00044       SMPF(controlFileName, solidComm), _timeStepReduction(1.), _subIterations(1), 
00045       _sensoroutput(0), _panelheight(0.), _pressure(0.) {
00046         
00047 #ifdef DEBUG_PRINT
00048         int myRank;
00049         std::ostringstream obuf;
00050         MPI_Comm_rank(solidComm, &myRank);
00051         obuf << "S" << myRank << ".log" << static_cast<char>(0);
00052         oflog.open(obuf.str().c_str());         
00053         _olog = new std::ostream(oflog.rdbuf());
00054 #endif
00055         
00056         computeMassPrepareAdvance();
00057         
00058 #ifdef DEBUG_PRINT_ELC
00059         (*_olog << "*** LagrangianComm: " << numFluidNodes << "  " << firstFluidNode ).flush();
00060 #endif  
00061         // instantiate an elc object for data exchange
00062         _elcLag = new elc::LagrangianComm<DIM, double>(MPI_COMM_WORLD, solidComm, numFluidNodes,
00063                                                        firstFluidNode, elc::GlobalIdentifiers);
00064 #ifdef DEBUG_PRINT_ELC
00065         (*_olog << " created.\n").flush();
00066 #endif  
00067 
00068         // read _subIterations from input file
00069         utilities::PropertiesParser *prop = new utilities::PropertiesParser;
00070         prop->registerPropertiesVar("timeStepReduction", _timeStepReduction);
00071         prop->registerPropertiesVar("SubIterations", _subIterations);
00072         prop->registerPropertiesVar("SensorOutput", _sensoroutput);
00073         prop->registerPropertiesVar("PanelHeight", _panelheight);
00074         prop->registerPropertiesVar("Pressure", _pressure);
00075         std::ifstream inputFile("./shellInput.dat");
00076         if (!inputFile.is_open()) assert(false);
00077         prop->readValues(inputFile);    
00078         delete prop;
00079         inputFile.close();
00080         
00081 #ifdef DEBUG_PRINT
00082         (*_olog << "*** ShellManagerSpecific created.\n").flush();
00083 #endif
00084 
00085         if (_subIterations<=0) 
00086             _subIterations=1;
00087     }
00088 
00089 
00090     ~ShellManagerSpecific() {
00091         if (_elcLag!=NULL) delete _elcLag;
00092         if (_olog!=NULL) delete _olog;
00093         if (_gnuplotFile!=NULL) {
00094             _gnuplotFile->close();
00095             delete _gnuplotFile;
00096         }
00097     }
00098 
00099    
00100     void sendBoundaryReceivePressure() {
00101         double *elCoordinates = NULL;
00102         double *elVelocities = NULL;
00103         int *elGlobalNodeIDs = NULL;
00104         int elNumNodes;
00105         int *elConnectivity = NULL;
00106         int elNumElements;
00107         
00108         SMPF::decode(&elCoordinates, &elVelocities, &elGlobalNodeIDs,
00109                      &elNumNodes, &elConnectivity, &elNumElements);
00110         
00111         // allocate space for pressure and initialize
00112         _elPressures.resize(elNumElements);       
00113         std::fill(_elPressures.begin(), _elPressures.end(), 0.0);
00114         
00115 #ifdef DEBUG_PRINT_ELC
00116         ( *_olog << "*** ShellManagerSpecific::sendBoundaryReceivePressure" ).flush();
00117 #endif
00118         
00119         _elcLag->sendMesh(elNumNodes, reinterpret_cast<void*>(elGlobalNodeIDs), 
00120                           reinterpret_cast<void*>(elCoordinates), 
00121                           reinterpret_cast<void*>(elVelocities), 
00122                           elNumElements, reinterpret_cast<void*>(elConnectivity));
00123         _elcLag->waitForMesh();
00124         _elcLag->receivePressure(elNumElements, reinterpret_cast<void*>(&(_elPressures[0])));
00125         _elcLag->waitForPressure();
00126            
00127         // Necessary if solid domain larger than fluid domain
00128         for (unsigned int n=0; n<_elPressures.size(); n++) {
00129             if (_elPressures[n] == std::numeric_limits<double>::max()) {
00130                 _elPressures[n] = 0.0;
00131             }
00132             // Constant load for separate testing of shell solver
00133             if (_pressure != 0.) 
00134               _elPressures[n] = _pressure;
00135         }
00136 
00137         encodePressure(&(_elPressures[0]), _elPressures.size(), element);
00138         
00139 #ifdef DEBUG_PRINT_ELC
00140         ( *_olog << " done.\n" ).flush();
00141 #endif
00142     }
00143 
00144     virtual double stableTimeStep() {
00145       return _timeStepReduction*shells::computeStableTimeStep(SMPF::mShell(), 
00146                                                               SMPF::Thickness(), 
00147                                                               shells::MShell::active);
00148     }
00149 
00150     virtual void advanceSp(double& t, double& dt){
00151         dt /= _subIterations;
00152         setTimeStep(dt);
00153 
00154 #ifdef DEBUG_PRINT
00155         (*_olog << "*** advancing in time.\n").flush();
00156 #endif
00157 
00158         // boundary conditions functor
00159         shells::ShellEnforceBCFunctor enforceBC; 
00160         mShell()->iterateOverVertices(enforceBC);
00161         predict();
00162 
00163         sendBoundaryReceivePressure();
00164         internalExternalForces();       
00165         correct();      
00166         incrementCurrentTimeAndStep();
00167 
00168         for (int n=1; n<_subIterations; n++) {      
00169           mShell()->iterateOverVertices(enforceBC);
00170           predict();     
00171           internalExternalForces();     
00172           correct();    
00173           incrementCurrentTimeAndStep();
00174         }
00175 
00176         dt = stableTimeStep()*_subIterations;
00177         t = getCurrentTime();   
00178 
00179         // print sensors
00180         if (_sensoroutput) 
00181           std::for_each(_sensors.begin(), _sensors.end(), 
00182                         std::bind2nd(std::mem_fun(&BasicSensorSp::printData), t));
00183     }
00184     
00185    
00186     void addSensors(double xyz[3], bool restart=false) {
00187         // open a file and instantiate a sensor
00188         const int myRank = communicatorRank();
00189         std::string nameGnuplot = utilities::makeUniqueName(_sensors.size(), myRank, "./dispSensor-", "dat");
00190 
00191         std::ofstream *gnuplotFile;
00192         if (restart) {
00193             gnuplotFile = new std::ofstream(nameGnuplot.c_str(), std::ofstream::app);
00194         } else {
00195             gnuplotFile = new std::ofstream(nameGnuplot.c_str());
00196         }
00197         BasicSensorSp *s = new BasicSensorSp(*gnuplotFile, ShellManagerBasic::mShell(), xyz);
00198         
00199         _sensors.push_back(s);
00200     }
00201 
00202 
00203     void instrumentWithSensors(bool restart=false) {
00204         if (_sensoroutput<=0) return;
00205         double xyz[3] = { 0.05, 0.015, 0.};
00206         double dy = _panelheight/_sensoroutput; 
00207         for (int n=0; n<_sensoroutput; n++) {
00208           xyz[1] += dy;
00209           addSensors(xyz, restart);
00210         }
00211     }
00212 
00213 
00214     void initialize(double& t, double& dt){
00215         sendBoundaryReceivePressure();
00216         dt = stableTimeStep()*_subIterations;
00217         t = getCurrentTime();
00218         if (_sensoroutput)
00219           instrumentWithSensors(false); 
00220     }
00221 
00222  
00223     void output() {
00224         printDataParallel(true);
00225 
00226 #ifdef DEBUG_PRINT
00227         ( *_olog << " Printing interface mesh and pressure.\n" ).flush();
00228         printIFaceMeshPressureParallel();
00229 #endif
00230     }
00231 
00232 
00233     int nSteps() {
00234         return getCurrentStepNum()/_subIterations;
00235     }
00236 
00237 
00238     void checkpointing() {
00239         checkPointingParallel();
00240     }
00241 
00242     void restartSp(double& t, double& dt) {
00243         restartParallel();
00244         t = getCurrentTime();
00245         dt = stableTimeStep()*_subIterations;
00246         
00247         shells::ShellEnforceBCFunctor enforceBC;        
00248         mShell()->iterateOverVertices(enforceBC);
00249 
00250         sendBoundaryReceivePressure();
00251 
00252         if (_sensoroutput) 
00253           instrumentWithSensors(true);
00254     }
00255 
00256     
00257 // copy and assignment constructors - not implemented
00258 private:
00259     ShellManagerSpecific(const ShellManagerSpecific &);
00260     const ShellManagerSpecific & operator=(const ShellManagerSpecific &);   
00261     
00262 private:
00263     elc::LagrangianComm<DIM, double>     *_elcLag;
00264 
00265     std::ostream                         *_olog;
00266     std::ofstream                         oflog; 
00267 
00268     std::ofstream                        *_gnuplotFile;
00269         
00270     std::vector<double>                  _elPressures;
00271 
00272     double                               _timeStepReduction;
00273 
00274     int                                  _subIterations;
00275 
00276     int                                  _sensoroutput;
00277 
00278     double                               _panelheight;
00279 
00280     double                               _pressure;
00281 
00282     std::vector<BasicSensorSp *>         _sensors;
00283 };
00284 
00285 #endif

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