00001
00002
00003
00004
00005
00006 #ifndef AMROC_PROBLEM_H
00007 #define AMROC_PROBLEM_H
00008
00009 #include "eulerrhok2.h"
00010 #define NEQUATIONS 10
00011 #define NEQUSED 9
00012 #define NFIXUP 8
00013 #define NAUX 4
00014
00015 #define GLOBALMAXIMA 5
00016
00017 #include "ClpProblem.h"
00018
00019 #define OWN_FLAGGING
00020 #define OWN_AMRSOLVER
00021 #include "ClpStdProblem.h"
00022 #include "F77Interfaces/F77UpdateLevelTransfer.h"
00023 #include "SpecialOutput/AMRGridAccumulation.h"
00024
00025 #define f_rcveloc FORTRAN_NAME(rcveloc, RCVELOC)
00026 extern "C" {
00027 void f_rcveloc(const DOUBLE v[]);
00028 }
00029
00030 class FlaggingSpecific :
00031 public AMRFlagging<VectorType,FixupType,FlagType,DIM> {
00032 typedef AMRFlagging<VectorType,FixupType,FlagType,DIM> base;
00033 public:
00034 FlaggingSpecific(base::solver_type& solver) : base(solver) {
00035 base::AddCriterion(new ScaledGradient<VectorType,FlagType,DIM>());
00036 base::AddCriterion(new LimiterType<VectorType,FlagType,DIM>());
00037 base::AddCriterion(new AbsoluteError<VectorType,FixupType,FlagType,DIM>(solver));
00038 base::AddCriterion(new RelativeError<VectorType,FixupType,FlagType,DIM>(solver));
00039 base::AddCriterion(new F77ScaledGradient<VectorType,FlagType,DIM>(f_flg));
00040 base::AddCriterion(new F77LimiterType<VectorType,FlagType,DIM>(f_flg));
00041 base::AddCriterion(new F77AbsoluteError<VectorType,FixupType,FlagType,DIM>(solver,f_flg));
00042 base::AddCriterion(new F77RelativeError<VectorType,FixupType,FlagType,DIM>(solver,f_flg));
00043 }
00044 ~FlaggingSpecific() { DeleteAllCriterions(); }
00045 };
00046
00047 class SolverSpecific :
00048 public AMRSolver<VectorType,FixupType,FlagType,DIM> {
00049 typedef VectorType::InternalDataType DataType;
00050 typedef AMRSolver<VectorType,FixupType,FlagType,DIM> base;
00051 typedef AMRGridAccumulation<DataType,DIM> accumulation_type;
00052 typedef F77FileOutput<VectorType,DIM> output_type;
00053 public:
00054 typedef base::vec_grid_data_type vec_grid_data_type;
00055 typedef base::grid_data_type grid_data_type;
00056
00057 SolverSpecific(IntegratorSpecific& integ,
00058 base::initial_condition_type& init,
00059 base::boundary_conditions_type& bc) : base(integ, init, bc) {
00060 SetLevelTransfer(new F77UpdateLevelTransfer<VectorType,DIM>(f_prolong, f_restrict, f_tupdate));
00061 SetFileOutput(new F77FileOutput<VectorType,DIM>(f_out));
00062 SetFixup(new FixupSpecific(integ));
00063 SetFlagging(new FlaggingSpecific(*this));
00064 _Accumulation = new accumulation_type(f_rcveloc);
00065 MaxType = 1;
00066 TrackLevel = -1;
00067 TrackMin = 0.1;
00068 TrackMax = 1.e4;
00069 TrackOutputSingleFile = 1;
00070 TrackOutputEvery = 1;
00071 for (register int i=0; i<GLOBALMAXIMA; i++)
00072 TrackMaxima[i] = -1;
00073 }
00074
00075 ~SolverSpecific() {
00076 delete _LevelTransfer;
00077 delete _Flagging;
00078 delete _Fixup;
00079 delete _FileOutput;
00080 delete _Accumulation;
00081 }
00082
00083 virtual void register_at(ControlDevice& Ctrl) { base::register_at(Ctrl); }
00084 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00085 base::register_at(Ctrl, prefix);
00086 TrackCtrl = base::LocCtrl.getSubDevice("TrackFront");
00087 RegisterAt(TrackCtrl,"Level",TrackLevel);
00088 RegisterAt(TrackCtrl,"Min",TrackMin);
00089 RegisterAt(TrackCtrl,"Max",TrackMax);
00090 RegisterAt(TrackCtrl,"OutputSingleFile",TrackOutputSingleFile);
00091 RegisterAt(TrackCtrl,"OutputEvery",TrackOutputEvery);
00092 RegisterAt(base::LocCtrl,"MaxType",MaxType);
00093 char VariableName[32];
00094 for (register int i=0; i<GLOBALMAXIMA; i++) {
00095 std::sprintf(VariableName,"Maximum(%d)",i+1);
00096 RegisterAt(TrackCtrl,VariableName,TrackMaxima[i]);
00097 }
00098 _Accumulation->register_at(base::LocCtrl, prefix);
00099 }
00100
00101 virtual void SetupData() {
00102 base::SetupData();
00103 _Accumulation->SetupData(base::PGH(), base::NGhosts());
00104 if (TrackLevel>MaxLevel(base::GH()))
00105 TrackLevel=MaxLevel(base::GH());
00106 }
00107
00108 virtual void Initialize_(const double& dt_start) {
00109 base::Initialize_(dt_start);
00110 _Accumulation->Initialize();
00111 }
00112
00113 virtual void Output() {
00114 int Time = CurrentTime(base::GH(),0);
00115 if (Time == base::LastOutputTime()) return;
00116 _Accumulation->GridCombine(VizServer);
00117 int me = MY_PROC;
00118 if (me == VizServer) {
00119 int Level = _Accumulation->AccLevel();
00120 base::FileOutput_().WriteOut(_Accumulation->AccGrid(),_Accumulation->AccName(),
00121 Time,Level,base::t[0]);
00122 }
00123 base::Output();
00124 }
00125
00126 virtual void Checkpointing_(const char* CheckpointFile) {
00127 base::Checkpointing_(CheckpointFile);
00128 _Accumulation->GridCombine(VizServer);
00129 if (MY_PROC == VizServer)
00130 _Accumulation->Checkpointing();
00131 }
00132
00133 virtual bool Restart_(const char* CheckpointFile) {
00134 if (base::Restart_(CheckpointFile)) {
00135 if (MY_PROC == VizServer)
00136 _Accumulation->Restart();
00137 else
00138 _Accumulation->Initialize();
00139 return true;
00140 }
00141 else
00142 return false;
00143 }
00144
00145 inline DataType sgn(const DataType& v) const {
00146 return (v>0. ? 1. : -1.);
00147 }
00148
00149 virtual void AdvanceLevel(const int Level, int RegridEvery, bool RegridDone,
00150 bool ShadowAllowed, bool DoFixup,
00151 bool RecomposeBaseLev, bool RecomposeHighLev) {
00152
00153 base::AdvanceLevel(Level,RegridEvery,RegridDone,ShadowAllowed,
00154 DoFixup,RecomposeBaseLev,RecomposeHighLev);
00155
00156 int Time = CurrentTime(base::GH(),Level);
00157 int TStep = TimeStep(base::U(),Level);
00158 if (MaxType) {
00159 AdaptiveBoundaryUpdate(base::U(),Time,Level);
00160 Sync(base::U(),Time,Level);
00161 ExternalBoundaryUpdate(base::U(),Time,Level);
00162
00163 int irho = 1;
00164 int iu = NEQUSED-DIM-2;
00165 int iv = NEQUSED-DIM-1;
00166 ((output_type*) base::_FileOutput)->Transform(base::U(), base::Work(), Time+TStep,
00167 Level, irho, base::t[Level]);
00168 forall (base::U(),Time,Level,c)
00169 Coords ss(base::U()(Time,Level,c).bbox().stepsize());
00170 BBox bbi(base::U().interiorbbox(Time,Level,c));
00171 BeginFastIndex2(U, base::U()(Time,Level,c).bbox(),
00172 base::U()(Time,Level,c).data(), VectorType);
00173 BeginFastIndex2(Work, Work()(Time,Level,c).bbox(),
00174 Work()(Time,Level,c).data(), DataType);
00175 BeginFastIndex2(WorkN, Work()(Time+TStep,Level,c).bbox(),
00176 Work()(Time+TStep,Level,c).data(), DataType);
00177 DataType uy, vx;
00178 DCoords dx = base::GH().worldStep(ss);
00179 for_2 (i, j, bbi, ss)
00180 vx = (FastIndex2(U,i+ss(0),j)(iv)/FastIndex2(WorkN,i+ss(0),j)-
00181 FastIndex2(U,i-ss(0),j)(iv)/FastIndex2(WorkN,i-ss(0),j))/(2.0*dx(0));
00182 uy = (FastIndex2(U,i,j+ss(1))(iu)/FastIndex2(WorkN,i,j+ss(1))-
00183 FastIndex2(U,i,j-ss(1))(iu)/FastIndex2(WorkN,i,j-ss(1)))/(2.0*dx(1));
00184 FastIndex2(Work,i,j) = std::fabs(vx-uy);
00185 end_for
00186 EndFastIndex2(U);
00187 EndFastIndex2(Work);
00188 EndFastIndex2(WorkN);
00189 end_forall
00190 }
00191 else {
00192 int ipress = base::Dim()+4;
00193 ((output_type*) base::_FileOutput)->Transform(base::U(), base::Work(), Time, Level,
00194 ipress, base::t[Level]);
00195 }
00196
00197 _Accumulation->Accumulate(base::Work(), Time, Level, base::t[Level]);
00198 }
00199
00200 virtual double Tick(int VariableTimeStepping, const double dtv[],
00201 const double cflv[], int& Rejections) {
00202
00203 double cfl = base::Tick(VariableTimeStepping,dtv,cflv,Rejections);
00204 if (TrackLevel<0) return cfl;
00205
00206 int TimeZero = CurrentTime(base::GH(),0);
00207 TimeZero /= RefinedBy(base::GH(),MaxLevel(base::GH()));
00208 if (TimeZero % TrackOutputEvery != 0) return cfl;
00209
00210 int Level = std::min(TrackLevel,FineLevel(base::GH()));
00211 int Time = CurrentTime(base::GH(),Level);
00212 int TStep = TimeStep(base::U(),Level);
00213
00214 BBox wholebb(base::GH().wholebbox());
00215 wholebb.refine(base::GH().refinedby(Level));
00216 int idxl = wholebb.extents(1);
00217
00218 {
00219
00220
00221
00222 int fds = base::Dim();
00223 DataType* front_data = new DataType[(base::NEquations()+fds)*idxl];
00224 VectorType* front_val = (VectorType *)(front_data+fds*idxl);
00225 for (register int j=0;j<idxl; j++) {
00226 for (register int i=0;i<fds; i++)
00227 front_data[fds*j+i] = -1.e37;
00228 front_val[j] = -1.e37;
00229 }
00230
00231 int ipress = base::Dim()+4;
00232 ((output_type*) base::_FileOutput)->Transform(base::U(), base::Work(), Time, Level,
00233 ipress, base::t[Level]);
00234 forall (base::Work(),Time,Level,c)
00235 Coords ss(base::Work()(Time,Level,c).bbox().stepsize());
00236 BBox bbi(base::Work()(Time,Level,c).bbox());
00237 bbi.upper(0) -= bbi.stepsize(0);
00238 BeginFastIndex2(P, Work()(Time,Level,c).bbox(),
00239 Work()(Time,Level,c).data(), DataType);
00240 BeginFastIndex2(dP, Work()(Time+TStep,Level,c).bbox(),
00241 Work()(Time+TStep,Level,c).data(), DataType);
00242 DCoords dx = base::GH().worldStep(ss);
00243
00244 for_2 (i, j, bbi, ss)
00245 FastIndex2(dP,i,j) = (FastIndex2(P,i+ss(0),j)-FastIndex2(P,i,j))/dx(0);
00246 end_for
00247 bbi.lower(0) += bbi.stepsize(0);
00248 grid_data_type DataddP(bbi);
00249 BeginFastIndex2(ddP, DataddP.bbox(), DataddP.data(), DataType);
00250
00251 for_2 (i, j, bbi, ss)
00252 FastIndex2(ddP,i,j) = (FastIndex2(dP,i,j)-FastIndex2(dP,i-ss(0),j))/dx(0);
00253 end_for
00254 bbi.upper(0) -= bbi.stepsize(0);
00255
00256 for_2 (i, j, bbi, ss)
00257 FastIndex2(dP,i,j) = (FastIndex2(ddP,i+ss(0),j)-FastIndex2(ddP,i,j))/dx(0);
00258 end_for
00259 bbi = base::U().interiorbbox(Time,Level,c);
00260 for_2 (i, j, bbi, ss)
00261 if (FastIndex2(P,i,j)>=TrackMin && FastIndex2(P,i,j)<=TrackMax &&
00262 FastIndex2(ddP,i,j)<0. &&
00263 sgn(FastIndex2(dP,i,j))!=sgn(FastIndex2(dP,i-ss(0),j))) {
00264 DCoords fc = base::GH().worldCoords(Coords(2,i,j),ss);
00265 fc(0) *= (1.+dx(0)/(FastIndex2(dP,i-ss(0),j)-FastIndex2(dP,i,j)));
00266 int jj = (j-wholebb.lower(1))/ss(1);
00267 if (fc(0) > front_data[2*jj]) {
00268 front_data[fds*jj] = fc(0);
00269 front_data[fds*jj+1] = fc(1)+0.5*dx(1);
00270 front_val[jj] = base::U()(Time,Level,c)(i,j);
00271 DataType pmax = FastIndex2(P,i,j);
00272 for (int ii=i-base::NGhosts()*ss(0); ii<=i+base::NGhosts()*ss(0); ii+=ss(0)) {
00273 if (FastIndex2(P,ii,j) > pmax) {
00274 front_val[jj] = base::U()(Time,Level,c)(ii,j);
00275 pmax = FastIndex2(P,ii,j);
00276 }
00277 }
00278 }
00279 }
00280 end_for
00281 EndFastIndex2(P);
00282 EndFastIndex2(dP);
00283 EndFastIndex2(ddP);
00284 end_forall
00285
00286 #ifdef DAGH_NO_MPI
00287 #else
00288 if (comm_service::dce() && comm_service::proc_num() > 1) {
00289 int num = comm_service::proc_num();
00290 MPI_Status status;
00291 int R;
00292 int size = sizeof(DataType)*(NEquations()+fds)*idxl;
00293 int tag = 10000;
00294 if (MY_PROC!=VizServer) {
00295 R = MPI_Send((void *)front_data, size, MPI_BYTE, VizServer, tag, comm_service::comm());
00296 if ( MPI_SUCCESS != R )
00297 comm_service::error_die( "Tick", "MPI_Send", R );
00298 }
00299 else
00300 for (int proc=0; proc<num; proc++) {
00301 if (proc==VizServer) continue;
00302 DataType* dat = new DataType[(NEquations()+fds)*idxl];
00303 VectorType* datv = (VectorType *)(dat+fds*idxl);
00304 R = MPI_Recv((void *)dat, size, MPI_BYTE, proc, tag, comm_service::comm(), &status);
00305 if ( MPI_SUCCESS != R )
00306 comm_service::error_die( "Tick", "MPI_Recv", R );
00307 for (register int j=0; j<idxl; j++)
00308 if (dat[fds*j] > front_data[fds*j]) {
00309 for (register int i=0;i<fds; i++)
00310 front_data[fds*j+i] = dat[fds*j+i];
00311 front_val[j] = datv[j];
00312 }
00313 delete [] dat;
00314 }
00315 }
00316 #endif
00317
00318 int me = MY_PROC;
00319 if (me == VizServer) {
00320 DataType* output_data = new DataType[_FileOutput->Ncnt()*idxl];
00321 BBox bb(2,0,0,idxl-1,0,1,1);
00322 vec_grid_data_type val(bb,front_val);
00323 for (int cnt=1;cnt<=_FileOutput->Ncnt(); cnt++) {
00324 if (_FileOutput->OutputName(cnt-1).c_str()[0] == '-') continue;
00325 grid_data_type output(bb,output_data+(cnt-1)*idxl);
00326 ((output_type::out_2_func_type) (((output_type*) base::_FileOutput)->GetOutFunc()))
00327 (FA(2,val),FA(2,output),BOUNDING_BOX(bb),base::NEquations(),cnt,base::t[Level]);
00328 DataType* dummy;
00329 output.deallocate(dummy);
00330 }
00331 std::ofstream outfile;
00332 std::ostream* out;
00333 char name[256];
00334 if (TrackOutputSingleFile)
00335 sprintf(name,"front.txt");
00336 else
00337 sprintf(name,"front_%d.txt",Time);
00338 std::string fname = name;
00339 outfile.open(fname.c_str(), std::ios::out | std::ios::app);
00340 out = new std::ostream(outfile.rdbuf());
00341 if (TrackOutputSingleFile)
00342 *out << "********** t=" << base::t[Level] << " Step:"
00343 << Time << " **********" << std::endl;
00344 for (register int j=0;j<idxl; j++) {
00345 *out << front_data[fds*j] << " " << front_data[fds*j+1];
00346 for (int cnt=0;cnt<_FileOutput->Ncnt(); cnt++)
00347 if (_FileOutput->OutputName(cnt).c_str()[0] != '-')
00348 *out << " " << output_data[cnt*idxl+j];
00349 *out << std::endl;
00350 }
00351 val.deallocate(front_val);
00352 delete [] output_data;
00353 outfile.close();
00354 delete out;
00355 }
00356 }
00357
00358
00359 for (register int im=0; im<GLOBALMAXIMA; im++)
00360 if (TrackMaxima[im]>=0) {
00361 int fds = base::Dim()+1;
00362 DataType* front_data = new DataType[(base::NEquations()+fds)*idxl];
00363 VectorType* front_val = (VectorType *)(front_data+fds*idxl);
00364 for (register int j=0;j<idxl; j++) {
00365 for (register int i=0;i<fds; i++)
00366 front_data[fds*j+i] = -1.e37;
00367 front_val[j] = -1.e37;
00368 }
00369
00370 ((output_type*) base::_FileOutput)->Transform(base::U(), base::Work(), Time, Level,
00371 TrackMaxima[im], base::t[Level]);
00372 forall (base::Work(),Time,Level,c)
00373 Coords ss(base::Work()(Time,Level,c).bbox().stepsize());
00374 BBox bbi(base::Work()(Time,Level,c).bbox());
00375 bbi.upper(0) -= bbi.stepsize(0);
00376 BeginFastIndex2(V, Work()(Time,Level,c).bbox(),
00377 Work()(Time,Level,c).data(), DataType);
00378 DCoords dx = base::GH().worldStep(ss);
00379 bbi = base::U().interiorbbox(Time,Level,c);
00380 for_2 (i, j, bbi, ss)
00381 int jj = (j-wholebb.lower(1))/ss(1);
00382 if (FastIndex2(V,i,j)>front_data[fds*jj]) {
00383 front_data[fds*jj] = FastIndex2(V,i,j);
00384 DCoords fc = base::GH().worldCoords(Coords(2,i,j),ss);
00385 front_data[fds*jj+1] = fc(0)+0.5*dx(0);
00386 front_data[fds*jj+2] = fc(1)+0.5*dx(1);
00387 front_val[jj] = base::U()(Time,Level,c)(i,j);
00388 }
00389 end_for
00390 EndFastIndex2(V);
00391 end_forall
00392
00393 #ifdef DAGH_NO_MPI
00394 #else
00395 if (comm_service::dce() && comm_service::proc_num() > 1) {
00396 int num = comm_service::proc_num();
00397 MPI_Status status;
00398 int R;
00399 int size = sizeof(DataType)*(NEquations()+fds)*idxl;
00400 int tag = 10000;
00401 if (MY_PROC!=VizServer) {
00402 R = MPI_Send((void *)front_data, size, MPI_BYTE, VizServer, tag, comm_service::comm());
00403 if ( MPI_SUCCESS != R )
00404 comm_service::error_die( "Tick", "MPI_Send", R );
00405 }
00406 else
00407 for (int proc=0; proc<num; proc++) {
00408 if (proc==VizServer) continue;
00409 DataType* dat = new DataType[(NEquations()+fds)*idxl];
00410 VectorType* datv = (VectorType *)(dat+fds*idxl);
00411 R = MPI_Recv((void *)dat, size, MPI_BYTE, proc, tag, comm_service::comm(), &status);
00412 if ( MPI_SUCCESS != R )
00413 comm_service::error_die( "Tick", "MPI_Recv", R );
00414 for (register int j=0; j<idxl; j++)
00415 if (dat[fds*j] > front_data[fds*j]) {
00416 for (register int i=0;i<fds; i++)
00417 front_data[fds*j+i] = dat[fds*j+i];
00418 front_val[j] = datv[j];
00419 }
00420 delete [] dat;
00421 }
00422 }
00423 #endif
00424
00425 int me = MY_PROC;
00426 if (me == VizServer) {
00427 DataType* output_data = new DataType[_FileOutput->Ncnt()*idxl];
00428 BBox bb(2,0,0,idxl-1,0,1,1);
00429 vec_grid_data_type val(bb,front_val);
00430 for (int cnt=1;cnt<=_FileOutput->Ncnt(); cnt++) {
00431 if (_FileOutput->OutputName(cnt-1).c_str()[0] == '-') continue;
00432 grid_data_type output(bb,output_data+(cnt-1)*idxl);
00433 ((output_type::out_2_func_type) (((output_type*) base::_FileOutput)->GetOutFunc()))
00434 (FA(2,val),FA(2,output),BOUNDING_BOX(bb),base::NEquations(),cnt,base::t[Level]);
00435 DataType* dummy;
00436 output.deallocate(dummy);
00437 }
00438 std::ofstream outfile;
00439 std::ostream* out;
00440 char name[256];
00441 if (TrackOutputSingleFile)
00442 sprintf(name,"max_%d.txt",TrackMaxima[im]);
00443 else
00444 sprintf(name,"max_%d_%d.txt",TrackMaxima[im],Time);
00445 std::string fname = name;
00446 outfile.open(fname.c_str(), std::ios::out | std::ios::app);
00447 out = new std::ostream(outfile.rdbuf());
00448 if (TrackOutputSingleFile)
00449 *out << "********** t=" << base::t[Level] << " Step:"
00450 << Time << " **********" << std::endl;
00451 for (register int j=0;j<idxl; j++) {
00452 *out << front_data[fds*j+1] << " " << front_data[fds*j+2];
00453 for (int cnt=0;cnt<_FileOutput->Ncnt(); cnt++)
00454 if (_FileOutput->OutputName(cnt).c_str()[0] != '-')
00455 *out << " " << output_data[cnt*idxl+j];
00456 *out << std::endl;
00457 }
00458 val.deallocate(front_val);
00459 delete [] output_data;
00460 outfile.close();
00461 delete out;
00462 }
00463 delete [] front_data;
00464 }
00465
00466 return cfl;
00467 }
00468
00469 protected:
00470 int MaxType, TrackLevel, TrackOutputEvery, TrackOutputSingleFile;
00471 int TrackMaxima[GLOBALMAXIMA];
00472 double TrackMin, TrackMax;
00473 accumulation_type* _Accumulation;
00474 ControlDevice TrackCtrl;