00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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
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
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
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
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
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
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
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
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