00001
00002
00003
00004
00005
00006 #ifndef ADLIB_COUPLED_SOLVER3_H
00007 #define ADLIB_COUPLED_SOLVER3_H
00008
00016 #define FACTOR_ADLIB 1.0e2
00017 #include <cfloat>
00018 #include <cmath>
00019
00020 #include "Solver.h"
00021
00022
00023 #include "mesher3d/mesher3d.h"
00024 #include "mechanics/mechanics.h"
00025 #include "materials/matlib.h"
00026 #include "mechanics/readmesh.h"
00027 #include "mesher3d/importmesh.h"
00028 #include "mechanics/initialconditions.h"
00029 #include "external_coupling_3d/external_coupling_3d.h"
00030 #include "external_coupling_3d/boundaryconditions.h"
00031 #include "mpi_adlib/mpi_adlib.h"
00032 #include "external_coupling/AdlibTiming.h"
00033
00040
00041
00042
00043
00044 template <>
00045 class AdlibCoupledSolver<3> : public Solver {
00046 typedef Solver base;
00047 public:
00048 AdlibCoupledSolver(MPI_Comm solidComm) : base(), SubIterations(1), _olog(0) {
00049
00050 setCurrentTime(0.);
00051 setCurrentTimeStep(0.);
00052 setCurrentStepCount(0);
00053 renameOldCheckpointedFiles=false;
00054
00055
00056 MPI_Comm_rank(solidComm, &myRank);
00057 #ifdef DEBUG_PRINT
00058 std::ostringstream obuf;
00059 obuf << "S" << myRank << ".log" << static_cast<char>(0);
00060 oflog.open(obuf.str().c_str());
00061 _olog = new std::ostream(oflog.rdbuf());
00062 #endif
00063
00064
00065 adlib::AdlibSetMechanicsCommunicator(solidComm);
00066
00067 fsBoundary=NULL;
00068
00069 scaleBoundary = false;
00070 xCenter = 0.;
00071 yCenter = 0.;
00072 zCenter = 0.;
00073 ratioXPos = 1.;
00074 ratioXNeg = 1.;
00075 ratioYPos = 1.;
00076 ratioYNeg = 1.;
00077 ratioZPos = 1.;
00078 ratioZNeg = 1.;
00079
00080 }
00081
00082 ~AdlibCoupledSolver() {
00083 if (_olog) delete _olog;
00084 if (fsBoundary) delete fsBoundary;
00085 }
00086
00087
00088
00089
00090 virtual void sendBoundaryReceivePressure() = 0;
00091
00092
00093
00094 virtual bool setup() {
00095
00096 #ifdef DEBUG_PRINT
00097 ( log() << "Enter setup\n" ).flush();
00098 #endif
00099 #ifdef DEBUG
00100
00101 adlib::prt = 1;
00102 #else
00103 adlib::prt = 0;
00104 #endif
00105
00106
00107 adlib::dimensions("dimensions.dat");
00108
00109
00110 std::ifstream in("inp");
00111 in.getline(meshFile,80);
00112 in.getline(listMatFile,80);
00113 in.getline(listTypeFile,80);
00114 in.getline(listBoundBBFile,80);
00115 in.getline(listScaleBoundaryFile,80);
00116 in.getline(materialFile,80);
00117 in >> time_factor;
00118 in >> subdivisions;
00119 in >> SubIterations;
00120 in >> gamma_newmark;
00121 in.getline(outdir,80);
00122 in.close();
00123
00124 if (gamma_newmark < 0.5)
00125 gamma_newmark = 0.5;
00126 if (gamma_newmark > 1.5)
00127 gamma_newmark = 1.5;
00128 if (SubIterations<=0)
00129 SubIterations=1;
00130
00131 #ifdef DEBUG_PRINT
00132 ( log() << "Gamma Newmark = " << gamma_newmark << "\n").flush();
00133 ( log() << "Spectral radius at bifurcation = " << 1.-4.*(gamma_newmark-0.5)/(gamma_newmark+0.5)/(gamma_newmark+0.5) << "\n").flush();
00134 #endif
00135
00136 ADLIB_START_WATCH_WHOLE
00137
00138 return true;
00139 }
00140
00141 virtual void finish() {
00142 ADLIB_END_WATCH_WHOLE
00143 AdlibTiming::collect(*adlib::AdlibGetMechanicsCommunicator());
00144 #ifdef DEBUG_PRINT
00145 AdlibTiming::print_local(log());
00146 #endif
00147 if (adlib::AdlibMechanicsProcId() == 0)
00148 AdlibTiming::print(std::cout);
00149 }
00150
00151 virtual bool readMeshFiles(bool isARestart)
00152 {
00153 if(!isARestart) {
00154
00155 double * coordinates=NULL;
00156 int * connectivities=NULL;
00157 int * elementMaterials=NULL;
00158 int nbNodesElementRead=0;
00159
00160 adlib::readMeshFromTextFile(meshFile,
00161 &nbNodesElementRead,
00162 &adlib::nodes,
00163 &adlib::elements,
00164 &coordinates,
00165 &connectivities);
00166
00167 if (strcmp(listMatFile,"default"))
00168 adlib::readElementMaterialsFromTextFile(listMatFile,
00169 adlib::elements,
00170 &elementMaterials);
00171
00172 if (strcmp(listTypeFile,"default"))
00173 adlib::readElementTypesFromTextFile(listTypeFile,
00174 adlib::elements,
00175 &adlib::element_type);
00176
00177 adlib::importMesh(nbNodesElementRead,
00178 adlib::nodes,
00179 adlib::elements,
00180 coordinates,
00181 connectivities,
00182 elementMaterials,
00183 0,
00184 NULL,
00185 NULL);
00186
00187
00188 std::memset(adlib::boundary, 0, sizeof(int)*(adlib::nodes));
00189 std::memset(adlib::forces, 0,
00190 sizeof(double)*(adlib::nodes)*(adlib::dof_node));
00191
00192
00193
00194
00195
00196 #ifdef DEBUG_PRINT
00197 ( log() << "Total number of elements:" << adlib::elements << "\n").flush();
00198 #endif
00199
00200
00201 if (nProcessors > 1)
00202 adlib::PartitionMesh(nProcessors,myPId,subdivisions,"metis");
00203
00204 #ifdef DEBUG_PRINT
00205 ( log() << "Partioning in " << adlib::elements << "\n" ).flush();
00206 #endif
00207 }
00208
00209
00210 adlib::profile();
00211 adlib::shape_functions();
00212
00213 if(!isARestart)
00214 adlib::initialize_strains();
00215
00216
00217 adlib::ReadMaterialClasses(materialFile);
00218 adlib::assemble("mass","deformation");
00219
00220
00221 if (strcmp(listBoundBBFile,"default"))
00222 adlib::readAndImportFixationInBoxFromTextFile(listBoundBBFile);
00223
00224
00225 if (strcmp(listScaleBoundaryFile,"default"))
00226 readScalingBoundaryFile();
00227
00228
00229 if(!isARestart) {
00230
00231 if(!fsBoundary) fsBoundary = new adlib::Boundary;
00232 *fsBoundary = adlib::AdlibBoundaryGenerate(adlib::solidFluid);
00233
00234 #ifdef DEBUG_PRINT
00235 ( log() << "Solid fluid boundary created\n" ).flush();
00236 #endif
00237
00238
00239 char name[80];
00240 std::sprintf(name,"fs-boundary-%03d.tec",myRank);
00241 adlib::AdlibBoundaryTecplot(name, fsBoundary);
00242 }
00243 return true;
00244 }
00245
00246 virtual void Initialize(double& t, double& dt) {
00247 ADLIB_START_WATCH
00248 readMeshFiles(false);
00249 sendBoundaryReceivePressure();
00250 dt = NextTimeStep()*SubIterations;
00251 t = CurrentTime();
00252 ADLIB_END_WATCH(INITIALIZATION)
00253 }
00254
00255 virtual void Advance(double& t, double& dt) {
00256
00257 double tf = t+dt;
00258 dt /= SubIterations;
00259
00260 sendBoundaryReceivePressure();
00261
00262 #ifdef DEBUG_PRINT
00263 ( log() << "--- Iteration: " << CurrentStepCount()
00264 << " t = " << t
00265 << " dt = " << dt <<"\n" ).flush();
00266 #endif
00267
00268 while (tf-t > DBL_EPSILON*FACTOR_ADLIB) {
00269 Update(dt);
00270 t = CurrentTime();
00271 dt = NextTimeStep();
00272 if (dt > tf-t) dt = tf-t;
00273 }
00274
00275 setCurrentStepCount(CurrentStepCount() + SubIterations);
00276 dt = NextTimeStep()*SubIterations;
00277 t = tf;
00278 setCurrentTime(tf);
00279 }
00280
00281
00282 virtual void Update(const double& dt) {
00283
00284 setCurrentTimeStep(dt);
00285 ADLIB_START_WATCH
00286
00287 adlib::newmark("expl",0.,gamma_newmark);
00288 ADLIB_END_WATCH(INTEGRATION)
00289 ADLIB_START_WATCH
00290 adlib::assemble("explicit","deformation");
00291 ADLIB_END_WATCH(ASSEMBLE)
00292 ADLIB_START_WATCH
00293
00294 adlib::newmark("accel",0.,gamma_newmark);
00295 ADLIB_END_WATCH(INTEGRATION)
00296 setCurrentTime(CurrentTime()+dt);
00297 }
00298
00299 const double& CurrentTime() const { return adlib::time_n; }
00300 void setCurrentTime(double _time) { adlib::time_n = _time; }
00301
00302 const double& CurrentTimeStep() const { return adlib::time_step; }
00303 void setCurrentTimeStep(double _dt) { adlib::time_step = _dt; }
00304
00305 const int& CurrentStepCount() const { return adlib::step_number; }
00306 void setCurrentStepCount(int _step) { adlib::step_number = _step; }
00307
00308 double NextTimeStep() const {
00309 return time_factor*(1./(0.5+gamma_newmark))*adlib::StableTimeStep("deformation");
00310 }
00311
00312 virtual void Output() {
00313 ADLIB_START_WATCH
00314
00315
00316 int sN=CurrentStepCount()/SubIterations;
00317
00318
00319 char name[80];
00320 std::sprintf(name,"solidBoundary-%07d-%03d.tec",sN,myRank);
00321 adlib::AdlibBoundaryTecplot(name, fsBoundary);
00322
00323
00324 std::sprintf(name,"internal-%07d-%03d",sN,myRank);
00325 char timeChar[16];
00326 std::sprintf(timeChar,"%f*s",adlib::time_n);
00327 adlib::tecplot("both",name,"internal",0,1,timeChar,1.,"ascii");
00328
00329
00330 std::sprintf(name,"stresses-%07d-%03d",sN,myRank);
00331 adlib::tecplot("both",name,"stresses",0,1,timeChar,1.,"ascii");
00332
00333 if (sN == 0)
00334 {
00335 std::sprintf(name,"material-%03d",myRank);
00336 adlib::materialOutput(name);
00337 }
00338
00339 ADLIB_END_WATCH(OUTPUT)
00340 }
00341
00342 virtual int NSteps() {
00343 return CurrentStepCount()/SubIterations;
00344 }
00345
00346 virtual void Restart(double& t, double& dt) {
00347
00348 #ifdef DEBUG_PRINT
00349 ( log() << "Entering restart. \n" ).flush();
00350 #endif
00351
00352
00353 char nameRestartMesh[80];
00354 sprintf(nameRestartMesh,"adlib-mesh.res.%03d.cp",myPId);
00355 adlib::RestartFileRead(nameRestartMesh,1);
00356
00357
00358 if (nProcessors > 1) {
00359 char nameRestartCom[80];
00360 sprintf(nameRestartCom,"adlib-com.res.%03d.cp",myPId);
00361 adlib::PMechRestartRead(myPId,nameRestartCom);
00362 }
00363
00364
00365 char nameRestartBound[80];
00366 sprintf(nameRestartBound,"adlib-bound.res.%03d.cp",myPId);
00367 if(!fsBoundary) fsBoundary = new adlib::Boundary;
00368 *fsBoundary=adlib::AdlibBoundaryRead(nameRestartBound);
00369
00370 readMeshFiles(true);
00371
00372
00373 t = CurrentTime();
00374 dt = NextTimeStep()*SubIterations;
00375 sendBoundaryReceivePressure();
00376
00377
00378 char name[80];
00379 std::sprintf(name,"solidBoundaryRestart-%03d.tec",myRank);
00380 adlib::AdlibBoundaryTecplot(name, fsBoundary);
00381
00382
00383 std::sprintf(name,"internalRestart-%03d",myRank);
00384 char timeChar[16];
00385 std::sprintf(timeChar,"%f*s",adlib::time_n);
00386 adlib::tecplot("both",name,"internal",0,1,timeChar,1.,"ascii");
00387
00388 }
00389
00390 virtual void Checkpointing() {
00391 ADLIB_START_WATCH
00392
00393
00394 char nameRestartMesh[80];
00395 sprintf(nameRestartMesh,"adlib-mesh.res.%03d.cp",myPId);
00396 if(renameOldCheckpointedFiles)
00397 {
00398 char oldNameRestartMesh[80];
00399 sprintf(oldNameRestartMesh,".adlib-mesh.res.%03d.cp",myPId);
00400 rename(nameRestartMesh,oldNameRestartMesh);
00401 }
00402
00403 adlib::RestartFileWrite(nameRestartMesh,1);
00404
00405
00406 if (nProcessors > 1) {
00407 char nameRestartCom[80];
00408 sprintf(nameRestartCom,"adlib-com.res.%03d.cp",myPId);
00409 if(renameOldCheckpointedFiles)
00410 {
00411 char oldNameRestartCom[80];
00412 sprintf(oldNameRestartCom,".adlib-com.res.%03d.cp",myPId);
00413 rename(nameRestartCom,oldNameRestartCom);
00414 }
00415 adlib::PMechRestartWrite(nameRestartCom);
00416 }
00417
00418 char nameRestartBound[80];
00419 sprintf(nameRestartBound,"adlib-bound.res.%03d.cp",myPId);
00420 if(renameOldCheckpointedFiles)
00421 {
00422 char oldNameRestartBound[80];
00423 sprintf(oldNameRestartBound,".adlib-bound.res.%03d.cp",myPId);
00424 rename(nameRestartBound,oldNameRestartBound);
00425 }
00426 adlib::AdlibBoundaryWrite(nameRestartBound, fsBoundary);
00427
00428 renameOldCheckpointedFiles=true;
00429
00430 ADLIB_END_WATCH(OUTPUT)
00431 }
00432
00433 virtual void readScalingBoundaryFile()
00434 {
00435 scaleBoundary = true;
00436 std::ifstream in(listScaleBoundaryFile);
00437 in >> xCenter;
00438 in >> ratioXPos;
00439 in >> ratioXNeg;
00440 in >> yCenter;
00441 in >> ratioYPos;
00442 in >> ratioYNeg;
00443 in >> zCenter;
00444 in >> ratioZPos;
00445 in >> ratioZNeg;
00446
00447 #ifdef DEBUG_PRINT
00448 ( log() << "Scaling boundary:\n" ).flush();
00449 ( log() << " around x = " << xCenter << " by a factor " << ratioXPos
00450 << " for x > " << xCenter << " and by a factor " << ratioXNeg
00451 << " for x < " << xCenter << "\n" ).flush();
00452 ( log() << " around y = " << yCenter << " by a factor " << ratioYPos
00453 << " for y > " << yCenter << " and by a factor " << ratioYNeg
00454 << " for y < " << yCenter << "\n" ).flush();
00455 ( log() << " around z = " << zCenter << " by a factor " << ratioZPos
00456 << " for z > " << zCenter << " and by a factor " << ratioZNeg
00457 << " for z < " << zCenter << "\n" ).flush();
00458 #endif
00459
00460 }
00461
00462
00463 inline const adlib::Boundary& Boundary() const { return *fsBoundary; }
00464 inline adlib::Boundary& Boundary() { return *fsBoundary; }
00465
00466 inline std::ostream& log() { return *_olog; }
00467
00468 protected:
00469 int SubIterations;
00470 std::ostream* _olog;
00471 std::ofstream oflog;
00472 int myRank;
00473
00474
00475 char meshFile[80];
00476 char listMatFile[80];
00477 char listTypeFile[80];
00478 char listBoundBBFile[80];
00479 char listScaleBoundaryFile[80];
00480 char materialFile[80];
00481 int subdivisions;
00482 char outdir[80];
00483 bool renameOldCheckpointedFiles;
00484
00485
00486 bool scaleBoundary;
00487 double xCenter, yCenter, zCenter;
00488 double ratioXPos, ratioXNeg;
00489 double ratioYPos, ratioYNeg;
00490 double ratioZPos, ratioZNeg;
00491
00492
00493 private:
00494
00495 double time_factor;
00496 double gamma_newmark;
00497 adlib::Boundary* fsBoundary;
00498 };
00499
00500 #endif