vtf-logo

SolverControl.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2002 Ralf Deiterding
00004 // Brandenburgische Universitaet Cottbus
00005 //
00006 // Copyright (C) 2003-2007 California Institute of Technology
00007 // Ralf Deiterding, ralf@amroc.net
00008 
00009 #ifndef AMROC_SOLVER_CONTROL_H
00010 #define AMROC_SOLVER_CONTROL_H
00011 
00019 #if ! defined __PGI
00020 # if defined(LINUX_387_DOUBLE) || defined(LINUX_387_EXTENDED)
00021 #  include <fpu_control.h>
00022 # endif
00023 #endif
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>        /* check config for unistd.h header */
00027 #endif
00028 
00029 #if defined(HAVE_UNISTD_H)
00030 #include <unistd.h>        /* for chdir() declaration */
00031 #else
00032 extern "C" {
00033 extern int chdir(const char *);
00034 }
00035 #endif
00036 
00037 #define MaxStepControls  10
00038 #define FACTOR 1.0e5
00039 
00040 #include "Solver.h"
00041 
00042 #ifndef DAGH_NO_MPI 
00043 #include <mpi.h>
00044 #endif 
00045 
00046 #include <iostream>
00047 #include <string>
00048 #include <cstdio>
00049 #include <cstdlib>
00050 #include <cfloat>
00051 
00052 class StepControl : public controlable {
00053 public:
00054   StepControl() : LastTime(0.0), Outputs(0), OutputEvery(0), CheckPointEvery(0) {}
00055 
00056   virtual ~StepControl() {}
00057 
00058   virtual void register_at(ControlDevice& Ctrl) {}
00059   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00060     LocCtrl = Ctrl.getSubDevice(prefix+"Control");
00061     RegisterAt(LocCtrl,"LastTime",LastTime);
00062     RegisterAt(LocCtrl,"Outputs",Outputs);
00063     RegisterAt(LocCtrl,"OutputEvery",OutputEvery);
00064     RegisterAt(LocCtrl,"CheckEvery",CheckPointEvery);
00065   }
00066   
00067 public: 
00068   double LastTime;
00069   int Outputs, OutputEvery, CheckPointEvery;
00070   ControlDevice LocCtrl;     
00071 };
00072 
00073 
00080 class SolverControl : public controlable {
00081 public:
00082   typedef Solver solver_type;
00083 
00084   SolverControl(solver_type& solver) : InitOutput(1), Restart(0), 
00085      _Solver(solver), NStepControls(1), allow_solve(false) {}
00086   
00087   virtual ~SolverControl() {}
00088   
00089   virtual void register_at(ControlDevice& Ctrl) {
00090     register_at(Ctrl,"");
00091   }
00092   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00093     LocCtrl = Ctrl.getSubDevice(prefix+"SolverControl");
00094     Step[0].register_at(LocCtrl,"");    
00095     for (int cs=0; cs<MaxStepControls; cs++) {
00096       char text[5];
00097       std::sprintf(text,"%d-",cs+1);
00098       Step[cs].register_at(LocCtrl,std::string(text));
00099     }
00100     RegisterAt(LocCtrl,"Controls",NStepControls); 
00101     RegisterAt(LocCtrl,"Restart",Restart);  
00102     RegisterAt(LocCtrl,"InitOutput",InitOutput);      
00103     Solver_().register_at(Ctrl,"");
00104   }
00105 
00106   virtual void init() {     
00107     Solver_().init(); 
00108   }
00109 
00110   virtual void init(int argc, char *argv[]) {     
00111 #if ! defined __PGI
00112 # if defined(LINUX_387_DOUBLE) || defined(LINUX_387_EXTENDED)
00113     fpu_control_t cw;
00114     _FPU_GETCW(cw);
00115     cw &=  ~(_FPU_EXTENDED | _FPU_DOUBLE | _FPU_SINGLE);
00116   // cw &=  ~(_FPU_EXTENDED | _FPU_DOUBLE | _FPU_SINGLE | _FPU_MASK_ZM );
00117 #  ifdef LINUX_387_DOUBLE
00118     cw |= _FPU_DOUBLE;
00119 #  else
00120     cw |= _FPU_EXTENDED;
00121 #  endif
00122     _FPU_SETCW(cw);
00123 # endif
00124 #endif
00125    
00126 #ifndef DAGH_NO_MPI
00127     std::cout << "Initializing MPI\n" << std::flush;
00128     MPI_Init( &argc, &argv );
00129 #endif  
00130     if (argc>1 && std::strlen(argv[1])>0)
00131       chdir((const char *)argv[1]);
00132 
00133     init();
00134 
00135     std::string sname = "solver.in";
00136     std::ifstream infile;
00137     infile.open(sname.c_str(), std::ios::in);
00138     if (!infile) {
00139       std::cerr << sname << " not found. Aborting." << std::endl;
00140       std::exit(-1);
00141     } 
00142     infile.close();
00143 
00144     MainCtrl = ControlDevice(GetFileControlDevice("solver.in",""));
00145     register_at(MainCtrl);
00146     MainCtrl.update();   
00147 
00148     update();
00149 
00150     allow_solve = Solver_().setup(); 
00151   }
00152 
00153   virtual void update() { 
00154     Solver_().update(); 
00155   }
00156   
00157   virtual void finish() {
00158     Solver_().finish();
00159 #ifndef DAGH_NO_MPI
00160     std::cout << "Finalizing MPI\n" << std::flush;
00161     MPI_Finalize();
00162 #endif  
00163   } 
00164 
00165   virtual void solve() {
00166     if (!allow_solve) return;
00167 
00168     double t=0., dt=0.;
00169     int CStepControl = 0;
00170 
00171     if (Restart) 
00172       Solver_().Restart(t,dt);
00173 
00174     if (!Restart || (t==0. && dt==0.))
00175       Solver_().Initialize(t,dt);     
00176     
00177     while (t>=Step[CStepControl].LastTime && CStepControl<NStepControls)
00178       CStepControl++;  
00179     
00180     double tout = (CStepControl>0 ? Step[CStepControl-1].LastTime : 0.0);
00181     double dtout = Step[CStepControl].LastTime - 
00182       (CStepControl>0 ? Step[CStepControl-1].LastTime : 0.0);
00183     if (Step[CStepControl].Outputs > 0)
00184       dtout /= Step[CStepControl].Outputs;
00185     while (t+DBL_EPSILON*FACTOR > tout+dtout)
00186       tout += dtout;
00187     
00188     if (InitOutput && (Step[CStepControl].Outputs>0 ||
00189                        Step[CStepControl].OutputEvery>0))
00190       Solver_().Output();       
00191 
00192     while (Step[NStepControls-1].LastTime-tout > DBL_EPSILON*FACTOR) {   
00193       while (tout+dtout-t > DBL_EPSILON*FACTOR) {   
00194         if (Step[CStepControl].OutputEvery==0)
00195           dt = std::min(dt,tout+dtout-t);
00196         if (t+dt > Step[NStepControls-1].LastTime) 
00197           dt = Step[NStepControls-1].LastTime-t;
00198         Solver_().Advance(t,dt);
00199         if (Step[CStepControl].OutputEvery > 0) 
00200           if (Solver_().NSteps() % Step[CStepControl].OutputEvery == 0) 
00201             Solver_().Output();
00202         if (Step[CStepControl].CheckPointEvery > 0) 
00203           if (Solver_().NSteps() % Step[CStepControl].CheckPointEvery == 0) 
00204             Solver_().Checkpointing();
00205       }
00206       Solver_().Output(); 
00207       tout += dtout;
00208       if (Step[CStepControl].LastTime-tout < DBL_EPSILON*FACTOR) {
00209         CStepControl++;     
00210         if (CStepControl<NStepControls) {   
00211           dtout = Step[CStepControl].LastTime - Step[CStepControl-1].LastTime;
00212           if (Step[CStepControl].Outputs > 0)
00213             dtout /= Step[CStepControl].Outputs;
00214         }
00215       }
00216     }
00217         
00218     Solver_().Output(); 
00219     Solver_().Checkpointing();
00220   } 
00221 
00222   inline solver_type& Solver_() { return _Solver; }
00223   inline const solver_type& Solver_() const { return _Solver; }
00224   
00225 protected:
00226   int InitOutput;
00227   int Restart;  
00228   solver_type& _Solver; 
00229   int NStepControls;    
00230   bool allow_solve;
00231   StepControl Step[MaxStepControls];
00232   ControlDevice MainCtrl, LocCtrl;
00233 };
00234 
00235 
00236 #endif
00237 

Generated on Fri Aug 24 13:00:53 2007 for AMROC Fluid-solver Framework - by  doxygen 1.4.7