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
00019 #include "mpi.h"
00020 #include "elc/LagrangianComm.h"
00021
00022 #include "shells/driverCC/ShellManagerBasic.h"
00023 #include "shells/parallel/ShellManagerParallel.h"
00024 #include "shells/utilities/BasicSensor.h"
00025 #include "shells/utilities/MakeUniqueName.h"
00026 #include "shells/utilities/PropertiesParser.h"
00027 #include "shells/driverCC/SVertexFunctors.h"
00028
00029
00030 typedef shells::ShellManagerParallel<shells::ShellManagerBasic> SMP;
00031
00032
00033 class ShellManagerSpecific : public SMP {
00034 private:
00035 typedef utilities::BasicSensor<shells::SVertexDisplacement> BasicSensorSp;
00036
00037 public:
00038 ShellManagerSpecific(const std::string& controlFileName, MPI_Comm solidComm,
00039 int numFluidNodes, int firstFluidNode) :
00040 SMP(controlFileName, solidComm), _sensor0(NULL), _sensor1(NULL),
00041 _subIterations(1) {
00042
00043 #ifdef DEBUG_PRINT
00044 int myRank;
00045 MPI_Comm_rank(solidComm, &myRank);
00046
00047 std::stringstream nameStr;
00048 nameStr << "S";
00049 nameStr << myRank;
00050 nameStr << ".log";
00051 std::string name;
00052 nameStr >> name;
00053 _olog = new std::ofstream(name.c_str());
00054 #endif
00055 computeMassPrepareAdvance();
00056
00057
00058 _elcLag = new elc::LagrangianComm<DIM, double>(MPI_COMM_WORLD, solidComm, numFluidNodes,
00059 firstFluidNode, elc::GlobalIdentifiers);
00060
00061 #ifdef DEBUG_PRINT_ELC
00062 (*_olog << "*** LagrangianComm created.\n").flush();
00063 #endif
00064
00065
00066 utilities::PropertiesParser *prop = new utilities::PropertiesParser;
00067 prop->registerPropertiesVar("SubIterations", _subIterations);
00068
00069 std::ifstream inputFile("./shellInput.dat");
00070 if (!inputFile.is_open()) assert(false);
00071 prop->readValues(inputFile);
00072 delete prop;
00073 inputFile.close();
00074
00075 #ifdef DEBUG_PRINT
00076 (*_olog << "*** ShellManagerSpecific created.\n").flush();
00077 #endif
00078 if (_subIterations<1)
00079 _subIterations = 1;
00080 };
00081
00082
00083 ~ShellManagerSpecific() {
00084 if (_sensor0!=NULL) delete _sensor0;
00085 if (_sensor1!=NULL) delete _sensor1;
00086 if (_elcLag!=NULL) delete _elcLag;
00087 if (_olog!=NULL) delete _olog;
00088 if (_gnuplotFile0!=NULL) {
00089 _gnuplotFile0->close();
00090 delete _gnuplotFile0;
00091 }
00092 if (_gnuplotFile1!=NULL) {
00093 _gnuplotFile1->close();
00094 delete _gnuplotFile1;
00095 }
00096 }
00097
00098
00099 void sendBoundaryReceivePressure() {
00100 double *elCoordinates = NULL;
00101 double *elVelocities = NULL;
00102 int *elGlobalNodeIDs = NULL;
00103 int elNumNodes;
00104 int *elConnectivity = NULL;
00105 int elNumElements;
00106
00107 SMP::decode(&elCoordinates, &elVelocities, &elGlobalNodeIDs,
00108 &elNumNodes, &elConnectivity, &elNumElements);
00109
00110
00111 _elPressures.resize(elNumElements);
00112 std::fill(_elPressures.begin(), _elPressures.end(), 0.0);
00113
00114 #ifdef DEBUG_PRINT_ELC
00115 ( *_olog << "*** ShellManagerSpecific::sendBoundaryReceivePressure" ).flush();
00116 #endif
00117
00118 _elcLag->sendMesh(elNumNodes, reinterpret_cast<void*>(elGlobalNodeIDs),
00119 reinterpret_cast<void*>(elCoordinates),
00120 reinterpret_cast<void*>(elVelocities),
00121 elNumElements, reinterpret_cast<void*>(elConnectivity));
00122 _elcLag->waitForMesh();
00123 _elcLag->receivePressure(elNumElements, reinterpret_cast<void*>(&(_elPressures[0])));
00124 _elcLag->waitForPressure();
00125
00126
00127 for (unsigned n=0; n<_elPressures.size(); n++) {
00128 if (_elPressures[n] == std::numeric_limits<double>::max()) {
00129 _elPressures[n] = 0.0;
00130 }
00131 }
00132
00133
00134 encodePressure(&(_elPressures[0]), _elPressures.size(), element);
00135
00136 #ifdef DEBUG_PRINT_ELC
00137 ( *_olog << " done.\n" ).flush();
00138 #endif
00139 }
00140
00141
00142 virtual void advanceSp(double& t, double& dt){
00143 dt /= _subIterations;
00144 setTimeStep(dt);
00145
00146 predictAndEnforceBC();
00147 sendBoundaryReceivePressure();
00148 internalExternalForces();
00149 correct();
00150 incrementCurrentTimeAndStep();
00151
00152 for (int n=1; n<_subIterations; ++n) {
00153 predictAndEnforceBC();
00154 internalExternalForces();
00155 correct();
00156 incrementCurrentTimeAndStep();
00157 }
00158
00159
00160 dt = stableTimeStep()*_subIterations;
00161 t = getCurrentTime();
00162
00163
00164 assert (_sensor0!=NULL);
00165 assert (_sensor1!=NULL);
00166 const int stepNum = getCurrentStepNum();
00167 if (!(stepNum%5)) {
00168 _sensor0->printData(t);
00169 _sensor1->printData(t);
00170 }
00171 }
00172
00173
00174 void initialize(double& t, double& dt){
00175 sendBoundaryReceivePressure();
00176 dt = stableTimeStep()*_subIterations;
00177 t = getCurrentTime();
00178
00179
00180
00181 utilities::PropertiesParser *prop = new utilities::PropertiesParser;
00182 std::string sensorFileName;
00183 prop->registerPropertiesVar("sensorFileName", sensorFileName);
00184 std::ifstream inputFile("./shellInput.dat");
00185 if (!inputFile.is_open()) assert(false);
00186 prop->readValues(inputFile);
00187
00188 const int myRank = communicatorRank();
00189 std::string nameGnuplot0 =
00190 utilities::makeUniqueName(0, myRank, sensorFileName.c_str(), "dat");
00191 std::string nameGnuplot1 =
00192 utilities::makeUniqueName(1, myRank, sensorFileName.c_str(), "dat");
00193
00194 const double zPosition = 0.210;
00195 _gnuplotFile0 = new std::ofstream(nameGnuplot0.c_str(), std::ios::app);
00196 double attachPoint0[3]={0.019506872061907737, 0.005226850615845407, zPosition};
00197
00198 _gnuplotFile1 = new std::ofstream(nameGnuplot1.c_str(), std::ios::app);
00199 double attachPoint1[3]={-0.01428002144606233, -0.01428002144606233, zPosition};
00200
00201 delete prop;
00202 inputFile.close();
00203
00204 _sensor0 = new BasicSensorSp(*_gnuplotFile0, ShellManagerBasic::mShell(),
00205 attachPoint0);
00206 assert(_sensor0!=NULL);
00207
00208 _sensor1 = new BasicSensorSp(*_gnuplotFile1, ShellManagerBasic::mShell(),
00209 attachPoint1);
00210 assert(_sensor1!=NULL);
00211 }
00212
00213
00214 void output() {
00215 printDataParallel(true);
00216
00217 #ifdef DEBUG_PRINT
00218 ( *_olog << " Printing interface mesh and pressure.\n" ).flush();
00219 printIFaceMeshPressureParallel();
00220 #endif
00221 }
00222
00223
00224 int nSteps() {
00225 return getCurrentStepNum()/_subIterations;
00226 }
00227
00228
00229 void checkpointing() {
00230 checkPointingParallel();
00231 }
00232
00233 void restartSp(double& t, double& dt) {
00234 restartParallel();
00235 t = getCurrentTime();
00236 dt = stableTimeStep()*_subIterations;
00237
00238 sendBoundaryReceivePressure();
00239 return;
00240 }
00241
00242
00243 private:
00244 ShellManagerSpecific(const ShellManagerSpecific &);
00245 const ShellManagerSpecific & operator=(const ShellManagerSpecific &);
00246
00247 private:
00248 elc::LagrangianComm<DIM, double> *_elcLag;
00249 std::ofstream *_olog;
00250
00251 std::ofstream *_gnuplotFile0;
00252 std::ofstream *_gnuplotFile1;
00253
00254 std::vector<double> _elPressures;
00255
00256 BasicSensorSp *_sensor0;
00257 BasicSensorSp *_sensor1;
00258
00259 int _subIterations;
00260 };
00261
00262 #endif