vtf-logo

fsi/sfc-amroc/TubeCJBurnFlaps/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         // functors for fixing nodes at the flaps 
00145         
00146         // define a bounding box for nodes to be fixed
00147         double low0[3]={-100., 0.014 , 0.43};
00148         double upp0[3]={ 0., 0.0145, 0.46};
00149         typedef shells::CheckSVtxFieldInBox<shells::SVertexCoordinate> CoordinateCheck;
00150         CoordinateCheck check0(low0, upp0);
00151 
00152         // set displacements to zero
00153         typedef shells::PrescribeSVtxField<shells::SVertexDisplacement> PrescribeDisp;    
00154         double bdisp[3]={0., 0., 0.};
00155         PrescribeDisp prd(bdisp);
00156         
00157         typedef shells::CheckPrescribeSVtxField<PrescribeDisp, CoordinateCheck> CheckPrescribeDisp;
00158         CheckPrescribeDisp checkpr0(prd, check0);
00159 
00160         double low1[3]={0., 0.014, 0.43};
00161         double upp1[3]={100.,0.0145, 0.46};
00162         CoordinateCheck check1(low1, upp1);
00163         CheckPrescribeDisp checkpr1(prd,check1);
00164         
00165         predictAndEnforceBC();
00166         mShell()->iterateOverVertices(checkpr0);
00167         mShell()->iterateOverVertices(checkpr1);
00168 
00169         sendBoundaryReceivePressure();
00170         internalExternalForces();       
00171         correct();      
00172         incrementCurrentTimeAndStep();
00173 
00174         for (int n=1; n<_subIterations; n++) {      
00175             predictAndEnforceBC();       
00176             mShell()->iterateOverVertices(checkpr0);
00177             mShell()->iterateOverVertices(checkpr1);
00178 
00179             internalExternalForces();   
00180             correct();  
00181             incrementCurrentTimeAndStep();
00182         }
00183 
00184         dt = stableTimeStep()*_subIterations;
00185         t = getCurrentTime();
00186         
00187         // print sensors
00188         const int stepNum  = getCurrentStepNum();
00189         std::for_each(_sensors.begin(), _sensors.end(), 
00190                       std::bind2nd(std::mem_fun(&BasicSensorSp::printData), t));
00191     }
00192     
00193     
00194     void addSensors(double xyz[3]) {
00195         // open a file and instantiate a sensor
00196         const int myRank = communicatorRank();
00197         std::string nameGnuplot = utilities::makeUniqueName(_sensors.size(), myRank, "./dispSensor-", "dat");
00198         std::ofstream *gnuplotFile = new std::ofstream(nameGnuplot.c_str(), std::ofstream::app);
00199         BasicSensorSp *s = new BasicSensorSp(*gnuplotFile, ShellManagerBasic::mShell(), xyz);   
00200         _sensors.push_back(s);
00201     }
00202 
00203          
00204     void initialize(double& t, double& dt){
00205         sendBoundaryReceivePressure();
00206         dt = stableTimeStep()*_subIterations;
00207         t = getCurrentTime();
00208         
00209         // add sensors
00210         const double radius = 0.020195;
00211         const double z0 = 0.4566;
00212         // const double z1 = 0.4314;
00213         
00214         double first[3] = {-0.008, radius, z0};
00215         double second[3] = {0.0, radius, z0};
00216         addSensors(first);
00217         addSensors(second);
00218 
00219         double third[3] = {-0.008, radius, z0};
00220         double fourth[3] = {0.0, radius, z0};
00221         addSensors(third);
00222         addSensors(fourth);
00223     }
00224 
00225  
00226     void output() {
00227         printDataParallel(true);
00228 
00229 #ifdef DEBUG_PRINT
00230         ( *_olog << " Printing interface mesh and pressure.\n" ).flush();
00231         printIFaceMeshPressureParallel();
00232 #endif
00233     }
00234 
00235 
00236     int nSteps() {
00237         return getCurrentStepNum()/_subIterations;
00238     }
00239 
00240 
00241     void checkpointing() {
00242         checkPointingParallel();
00243     }
00244 
00245     void restartSp(double& t, double& dt) {
00246         restartParallel();
00247         t = getCurrentTime();
00248         dt = stableTimeStep()*_subIterations;
00249         
00250         sendBoundaryReceivePressure();
00251         return;
00252     }
00253 
00254     
00255 // copy and assignment constructors - not implemented
00256 private:
00257     ShellManagerSpecific(const ShellManagerSpecific &);
00258     const ShellManagerSpecific & operator=(const ShellManagerSpecific &);   
00259     
00260 private:
00261     elc::LagrangianComm<DIM, double>     *_elcLag;
00262 
00263     std::ostream                         *_olog;
00264     std::ofstream                         oflog; 
00265 
00266     std::ofstream                        *_gnuplotFile;
00267         
00268     std::vector<double>                  _elPressures;
00269 
00270     std::vector<BasicSensorSp *>         _sensors;
00271 
00272     int                                  _subIterations;
00273 };
00274 
00275 #endif

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