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), HitLastTime(1),
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 RegisterAt(LocCtrl,"HitLastTime",HitLastTime);
00104 Solver_().register_at(Ctrl,"");
00105 }
00106
00107 virtual void init() {
00108 Solver_().init();
00109 }
00110
00111 virtual void init(int argc, char *argv[]) {
00112 #if ! defined __PGI
00113 # if defined(LINUX_387_DOUBLE) || defined(LINUX_387_EXTENDED)
00114 fpu_control_t cw;
00115 _FPU_GETCW(cw);
00116 cw &= ~(_FPU_EXTENDED | _FPU_DOUBLE | _FPU_SINGLE);
00117
00118 # ifdef LINUX_387_DOUBLE
00119 cw |= _FPU_DOUBLE;
00120 # else
00121 cw |= _FPU_EXTENDED;
00122 # endif
00123 _FPU_SETCW(cw);
00124 # endif
00125 #endif
00126
00127 #ifndef DAGH_NO_MPI
00128 std::cout << "Initializing MPI\n" << std::flush;
00129 MPI_Init( &argc, &argv );
00130 #endif
00131 if (argc>1 && std::strlen(argv[1])>0) {
00132 chdir((const char *)argv[1]);
00133 }
00134
00135 init();
00136
00137 std::string sname = "solver.in";
00138 std::ifstream infile;
00139 infile.open(sname.c_str(), std::ios::in);
00140 if (!infile) {
00141 std::cerr << sname << " not found. Aborting." << std::endl;
00142 std::exit(-1);
00143 }
00144 infile.close();
00145
00146 MainCtrl = ControlDevice(GetFileControlDevice("solver.in",""));
00147 register_at(MainCtrl);
00148 MainCtrl.update();
00149
00150 update();
00151
00152 allow_solve = Solver_().setup();
00153 }
00154
00155 virtual void update() {
00156 Solver_().update();
00157 }
00158
00159 virtual void finish() {
00160 Solver_().finish();
00161 #ifndef DAGH_NO_MPI
00162 std::cout << "Finalizing MPI\n" << std::flush;
00163 MPI_Finalize();
00164 #endif
00165 }
00166
00167 virtual void solve() {
00168 if (!allow_solve) return;
00169
00170 double t=0., dt=0.;
00171 int CStepControl = 0;
00172
00173 if (Restart)
00174 Solver_().Restart(t,dt);
00175
00176 if (!Restart || (t==0. && dt==0.))
00177 Solver_().Initialize(t,dt);
00178
00179 while (t>=Step[CStepControl].LastTime && CStepControl<NStepControls)
00180 CStepControl++;
00181
00182 double tout = (CStepControl>0 ? Step[CStepControl-1].LastTime : 0.0);
00183 double dtout = Step[CStepControl].LastTime -
00184 (CStepControl>0 ? Step[CStepControl-1].LastTime : 0.0);
00185 if (Step[CStepControl].Outputs > 0)
00186 dtout /= Step[CStepControl].Outputs;
00187 if (dtout>0.0)
00188 while ((t-(tout+dtout))/t > DBL_EPSILON*FACTOR)
00189 tout += dtout;
00190
00191 if (InitOutput && (Step[CStepControl].Outputs>0 ||
00192 Step[CStepControl].OutputEvery>0))
00193 Solver_().Output();
00194
00195 while ((Step[NStepControls-1].LastTime-tout)/Step[NStepControls-1].LastTime > DBL_EPSILON*FACTOR) {
00196 while ((tout+dtout-t)/(tout+dtout) > DBL_EPSILON*FACTOR) {
00197 if (Step[CStepControl].OutputEvery==0 && HitLastTime>0)
00198 dt = std::min(dt,tout+dtout-t);
00199 if (t+dt > Step[NStepControls-1].LastTime && HitLastTime>0)
00200 dt = Step[NStepControls-1].LastTime-t;
00201 Solver_().Advance(t,dt);
00202 if (Step[CStepControl].OutputEvery > 0)
00203 if (Solver_().NSteps() % Step[CStepControl].OutputEvery == 0)
00204 Solver_().Output();
00205 if (Step[CStepControl].CheckPointEvery > 0)
00206 if (Solver_().NSteps() % Step[CStepControl].CheckPointEvery == 0)
00207 Solver_().Checkpointing();
00208 }
00209 if (Step[NStepControls-1].Outputs>0 || Step[NStepControls-1].OutputEvery>0)
00210 Solver_().Output();
00211 tout += dtout;
00212 if ((Step[CStepControl].LastTime-tout)/tout < DBL_EPSILON*FACTOR) {
00213 CStepControl++;
00214 if (CStepControl<NStepControls) {
00215 dtout = Step[CStepControl].LastTime - Step[CStepControl-1].LastTime;
00216 if (Step[CStepControl].Outputs > 0)
00217 dtout /= Step[CStepControl].Outputs;
00218 }
00219 }
00220 }
00221
00222 if (Step[NStepControls-1].Outputs>0 || Step[NStepControls-1].OutputEvery>0)
00223 Solver_().Output();
00224 if (Step[NStepControls-1].CheckPointEvery>=0)
00225 Solver_().Checkpointing();
00226 }
00227
00228 inline solver_type& Solver_() { return _Solver; }
00229 inline const solver_type& Solver_() const { return _Solver; }
00230
00231 protected:
00232 int InitOutput, Restart, HitLastTime;
00233 solver_type& _Solver;
00234 int NStepControls;
00235 bool allow_solve;
00236 StepControl Step[MaxStepControls];
00237 ControlDevice MainCtrl, LocCtrl;
00238 };
00239
00240
00241 #endif
00242