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
00145
00146
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
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
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
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
00210 const double radius = 0.020195;
00211 const double z0 = 0.4566;
00212
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
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