vtf-logo

AdlibCoupledSolver3.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2007 California Institute of Technology
00004 // Ludovic Noels, Ralf Deiterding
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 // adlib header files
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 // There is in fact nothing dimension-specific in this class. Specializing with dim=3 is only
00041 // necessary, because the directories adlib/external_coupling_2d and adlib/mesher_2d are in a 
00042 // very old state and need to be brought up to date. 
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     // initialize solid processor logfile
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     // initialize adlib solid mechanics communicator
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   // Abstract class interface
00089   //******************************************************************************
00090   virtual void sendBoundaryReceivePressure() = 0;  
00091   //******************************************************************************
00092 
00093   // Read input files, etc.
00094   virtual bool setup() {
00095 
00096 #ifdef DEBUG_PRINT
00097     ( log() << "Enter setup\n" ).flush();
00098 #endif
00099 #ifdef DEBUG
00100     // set diagnostic output level
00101     adlib::prt = 1;
00102 #else
00103     adlib::prt = 0;
00104 #endif
00105 
00106     // read adlib dimensions
00107     adlib::dimensions("dimensions.dat");
00108  
00109     // read input control parameters from inp
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       // read in solid mesh and material data
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       // initialize boundary and forces to zero by hand
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       // output mesh statistics and dump imported mesh
00193       //adlib::TetrahedraStatistics();
00194       //adlib::tecplot("both","mesh","mesh",0,0,"initialMesh",1.,"ascii");
00195 
00196 #ifdef DEBUG_PRINT
00197       ( log() << "Total number of elements:" << adlib::elements << "\n").flush();
00198 #endif
00199 
00200       // partition imported solid mesh
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     // adlib initialization tasks
00210     adlib::profile();
00211     adlib::shape_functions();
00212 
00213     if(!isARestart) 
00214       adlib::initialize_strains();
00215 
00216     // read material model parameters and assemble mass
00217     adlib::ReadMaterialClasses(materialFile);
00218     adlib::assemble("mass","deformation");
00219     
00220     // read boundary conditions
00221     if (strcmp(listBoundBBFile,"default"))
00222       adlib::readAndImportFixationInBoxFromTextFile(listBoundBBFile);
00223 
00224     // read scaling boundary
00225     if (strcmp(listScaleBoundaryFile,"default"))
00226       readScalingBoundaryFile();
00227 
00228     // boundary
00229     if(!isARestart) {
00230       // generate solid/fluid boundary
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       // dump solid/fluid boundary
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   // Numerical Update
00282   virtual void Update(const double& dt) {
00283 
00284     setCurrentTimeStep(dt);
00285     ADLIB_START_WATCH
00286       //adlib::explicitIntegration("cdif","pred");
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       //adlib::explicitIntegration("cdif","corr");
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     // Write data files
00316     int sN=CurrentStepCount()/SubIterations;
00317     // boundary
00318 
00319     char name[80];
00320     std::sprintf(name,"solidBoundary-%07d-%03d.tec",sN,myRank);
00321     adlib::AdlibBoundaryTecplot(name, fsBoundary);
00322 
00323     // internal
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     // stresses
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     // Read solid mesh 
00353     char nameRestartMesh[80];
00354     sprintf(nameRestartMesh,"adlib-mesh.res.%03d.cp",myPId);
00355     adlib::RestartFileRead(nameRestartMesh,1); 
00356   
00357     // Read parallel solid mechanics communicator data 
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     // read fluid solid boundary
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     //proceed
00373     t = CurrentTime();
00374     dt = NextTimeStep()*SubIterations;
00375     sendBoundaryReceivePressure();
00376 
00377     // boundary
00378     char name[80];
00379     std::sprintf(name,"solidBoundaryRestart-%03d.tec",myRank);
00380     adlib::AdlibBoundaryTecplot(name, fsBoundary);
00381 
00382     // internal
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     // Write solid mesh
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); //or 0?
00404 
00405     // Write parallel solid mechanics communicator data
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     // Write fluid solid boundary
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   // input parameters
00475   char meshFile[80]; // solid mesh descriptor file name
00476   char listMatFile[80]; // solid mesh element materials file name
00477   char listTypeFile[80]; // solid mesh element type file name
00478   char listBoundBBFile[80]; // boundary conditions file name (bounding box)
00479   char listScaleBoundaryFile[80]; // scaling boundary file name
00480   char materialFile[80]; // solid material model parameter file name
00481   int subdivisions; // levels of subdivision of initial solid mesh
00482   char outdir[80]; // name of output directory
00483   bool renameOldCheckpointedFiles;
00484 
00485   // scaling boundary parameters
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

Generated on Fri Aug 24 12:55:26 2007 for Adlib Finite Element Solver by  doxygen 1.4.7