00001
00002
00003
00004
00005
00006
00007
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>
00027 #endif
00028
00029 #if defined(HAVE_UNISTD_H)
00030 #include <unistd.h>
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
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