00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef AMROC_AMRSOLVER_H
00010 #define AMROC_AMRSOLVER_H
00011
00019 #include "AMRSolverBase.h"
00020 #include "DAGHCluster.h"
00021
00022 #include <iostream>
00023 #include <sstream>
00024 #include <string>
00025 #include <cstdio>
00026 #include <cstdlib>
00027
00028 #define AMRSolverRegridFalse (0)
00029 #define VERY_LARGE_CFL (1.5)
00030 #define MAXOVERLAPWIDTH (100)
00031
00038
00039
00040
00041
00042
00043
00044
00045
00046 template <class VectorType, class FixupType, class FlagType, int dim>
00047 class AMRSolver : public AMRSolverBase<VectorType,FixupType,FlagType,dim> {
00048 typedef AMRSolverBase<VectorType,FixupType,FlagType,dim> base;
00049
00050 typedef Vector<FlagType,1> VFlagType;
00051 typedef GridData<VFlagType,dim> vflag_grid_data_type;
00052
00053 public:
00054 typedef GridData<FlagType,dim> flag_data_type;
00055 typedef typename base::vec_grid_fct_type vec_grid_fct_type;
00056 typedef typename base::vec_grid_data_type vec_grid_data_type;
00057 typedef typename base::grid_fct_type grid_fct_type;
00058 typedef typename base::grid_data_type grid_data_type;
00059
00060 typedef typename base::integrator_type integrator_type;
00061 typedef typename base::initial_condition_type initial_condition_type;
00062 typedef typename base::boundary_conditions_type boundary_conditions_type;
00063 typedef typename base::leveltransfer_type leveltransfer_type;
00064 typedef typename base::flagging_type flagging_type;
00065 typedef typename base::fixup_type fixup_type;
00066
00067 AMRSolver(integrator_type& integ, initial_condition_type& init,
00068 boundary_conditions_type& bc) : base(integ, init, bc),
00069 FixupPar(1), RegridEvery(1), MinEfficiency(0.7),
00070 BlockWidth(4), OverlapWidth(0), BufferWidth(2), NestingBuffer(1), NoTimeRefine(0),
00071 PlotFlags(0) {
00072
00073 t = (double *)NULL; dt = (double *)NULL; cfl_new = (double *)NULL;
00074 AllocError::SetTexts("AMRSolver","Constructor");
00075 }
00076
00077 virtual ~AMRSolver() {
00078 if (t) delete [] t;
00079 if (dt) delete [] dt;
00080 if (cfl_new) delete [] cfl_new;
00081 }
00082
00083 virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00084 base::LocCtrl = Ctrl.getSubDevice(prefix+"AMRSolver");
00085 RegisterAt(base::LocCtrl,"DoFixup",FixupPar);
00086 RegisterAt(base::LocCtrl,"NoTimeRefine",NoTimeRefine);
00087 RegisterAt(base::LocCtrl,"RegridEvery",RegridEvery);
00088 RegisterAt(base::LocCtrl,"MinEfficiency",MinEfficiency);
00089 RegisterAt(base::LocCtrl,"BufferWidth",BufferWidth);
00090 RegisterAt(base::LocCtrl,"BlockWidth",BlockWidth);
00091 RegisterAt(base::LocCtrl,"OverlapWidth",OverlapWidth);
00092 RegisterAt(base::LocCtrl,"NestingBuffer",NestingBuffer);
00093 RegisterAt(base::LocCtrl,"OutputFlags",PlotFlags);
00094 base::register_at(base::LocCtrl,"");
00095 }
00096 virtual void register_at(ControlDevice& Ctrl) {
00097 register_at(Ctrl, "");
00098 }
00099
00100 virtual void SetupData() {
00101 base::SetupData();
00102
00103 if (base::_Flagging && MaxLevel(base::GH())>=1)
00104 base::Flagging_().SetBufferwidth(std::min(std::max(BufferWidth,OverlapWidth-1),
00105 MAXOVERLAPWIDTH));
00106 else
00107 RegridEvery = 0;
00108 if (FixupPar == 0)
00109 base::SetFixup((fixup_type*) 0);
00110
00111 t = new double[MaxLevel(base::GH())+1];
00112 dt = new double[MaxLevel(base::GH())+1];
00113 cfl_new = new double[MaxLevel(base::GH())+1];
00114
00115 if (FixupPar && NestingBuffer<1 && RegridEvery!=AMRSolverRegridFalse) {
00116 if (MY_PROC == VizServer)
00117 std::cout << " Fixup requires a NestingBuffer>0 ! Using Default." << std::endl;
00118 NestingBuffer = 1;
00119 }
00120 base::GH().DAGH_SetNestingBuffer(NestingBuffer);
00121
00122 if (base::_Flagging)
00123 base::_Flagging->SetGridFunctions(base::_u, base::_u_sh, base::_work, base::_work_sh);
00124 if (base::_Fixup)
00125 base::_Fixup->SetGridFunctions(base::_u);
00126 }
00127
00128 virtual void Initialize_(const double& dt_start) {
00129 START_WATCH
00130
00131 t[0] = 0.0; dt[0] = dt_start; cfl_new[0] = 0.0;
00132 for (register int l=1; l<=MaxLevel(base::GH()); l++) {
00133 t[l] = 0.0;
00134 cfl_new[l] = 0.0;
00135 }
00136
00137 base::U().GF_DeleteStorage(1);
00138 if (base::ErrorEstimation())
00139 base::Ush().GF_DeleteStorage(1);
00140
00141
00142
00143
00144 int lev = 0;
00145 if (RegridEvery != AMRSolverRegridFalse) {
00146 while (lev<=FineLevel(base::GH()) && lev<MaxLevel(base::GH())) {
00147
00148
00149
00150 #ifdef DEBUG_PRINT_AMRSOLVER
00151 ( comm_service::log() << " *** Setting flags at Level: " << lev << "\n" ).flush();
00152 #endif
00153
00154
00155
00156 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00157 base::InitialCondition_().Set(base::U(), base::Work(), l);
00158 SetBndry(base::U(),0,lev,0.0);
00159 if (base::ErrorEstimation()) {
00160 base::InitialCondition_().Set(base::Ush(), base::Worksh(), l);
00161 SetBndry(base::Ush(),0,lev,0.0);
00162 }
00163 }
00164 BBoxList bblist;
00165 RegridLevel(0, 0, bblist, false);
00166
00167 END_WATCH_INITIALIZATION
00168 START_WATCH
00169 RecomposeHierarchy(base::GH());
00170 END_WATCH_RECOMPOSING_WHOLE
00171 START_WATCH
00172 lev++;
00173 }
00174
00175 if (FineLevel(base::GH())>0) {
00176 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00177 base::InitialCondition_().Set(base::U(), base::Work(), l);
00178 SetBndry(base::U(),0,l,0.0);
00179 if (base::ErrorEstimation()) {
00180 base::InitialCondition_().Set(base::Ush(), base::Worksh(), l);
00181 SetBndry(base::Ush(),0,l,0.0);
00182 }
00183 }
00184 BBoxList bblist;
00185 forall (base::U(),0,FineLevel(base::GH()),c)
00186 bblist.add(coarsen(base::U().interiorbbox(0,FineLevel(base::GH()),c),
00187 RefineFactor(base::GH(),FineLevel(base::GH())-1)));
00188 end_forall
00189 RegridLevel(0, 0, bblist, true);
00190 END_WATCH_INITIALIZATION
00191 START_WATCH
00192 RecomposeHierarchy(base::GH());
00193 END_WATCH_RECOMPOSING_WHOLE
00194 START_WATCH
00195 }
00196 }
00197
00198 base::U().GF_CreateStorage(1);
00199 if (base::ErrorEstimation())
00200 base::Ush().GF_CreateStorage(1);
00201
00202 for (lev=0; lev<=FineLevel(base::GH()); lev++) {
00203 #ifdef DEBUG_PRINT_AMRSOLVER
00204 ( comm_service::log() << " *** Initializing Level: " << lev << " *** \n" ).flush();
00205 #endif
00206 t[lev] = 0.0;
00207 base::InitialCondition_().Set(base::U(), base::Work(), lev);
00208 SetBndry(base::U(),0,lev,t[lev]);
00209 if (base::ErrorEstimation()) {
00210 base::InitialCondition_().Set(base::Ush(), base::Worksh(), lev);
00211 SetBndry(base::Ush(),0,lev,t[lev]);
00212 }
00213 }
00214
00215 SetTimeSpecs(base::GH(), 0.0, dt_start, 2);
00216
00217 for (lev=FineLevel(base::GH()); lev>=1; lev--) {
00218 Restrict(base::U(), 0, lev, 0, lev-1);
00219 if (base::ErrorEstimation())
00220 Restrict(base::Ush(), 0, lev, 0, lev-1);
00221 }
00222
00223 END_WATCH_INITIALIZATION
00224 }
00225
00226 virtual bool Restart_(const char* CheckpointFile) {
00227 START_WATCH
00228 bool ret = RecomposeHierarchy(base::GH(), CheckpointFile);
00229 if (ret) {
00230 double NextTime;
00231 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00232 base::GH().DAGH_GetTimeSpecs(t[l], NextTime);
00233 int Time = CurrentTime(base::GH(),l);
00234 SetPhysicalTime(base::U(),Time,l,t[l]);
00235 if (base::ErrorEstimation()) SetPhysicalTime(base::Ush(),Time,l,t[l]);
00236 }
00237 }
00238 END_WATCH_INITIALIZATION
00239 return ret;
00240 }
00241
00242 virtual void Checkpointing_(const char* CheckpointFile) {
00243 Checkpoint(base::GH(), CheckpointFile);
00244 }
00245
00246 virtual double Tick(int VariableTimeStepping, const double dtv[],
00247 const double cflv[], int& Rejections) {
00248
00249 double told = t[0];
00250 double cfl_max;
00251 Rejections = 0;
00252 do {
00253 std::stringstream* RestartStorage = (std::stringstream *)NULL;
00254 if (VariableTimeStepping==AutomaticTimeStepsRestart) {
00255 AllocError::SetTexts("AMRSolver","Memory for restart");
00256 RestartStorage = new std::stringstream;
00257 base::GH().DAGH_Checkpoint(*RestartStorage);
00258 }
00259
00260 #ifdef DEBUG_PRINT_AMRSOLVER
00261 double Current_Time, Next_Time;
00262 base::GH().DAGH_GetTimeSpecs(Current_Time, Next_Time);
00263 ( comm_service::log() << " --- Iteration: " << StepsTaken(base::GH(),0)+1 << " ---"
00264 << " t = " << Current_Time << " dt = "
00265 << DeltaT(base::GH(), 0) << "\n" ).flush();
00266 #endif
00267 #ifdef DEBUG_PROFILE
00268 ( std::cout << "\n" ).flush();
00269 #endif
00270
00271 for (register int l=1; l<=MaxLevel(base::GH()); l++)
00272 t[l] = t[0];
00273
00274 AdvanceLevel(0, RegridEvery,
00275 !(RegridEvery != AMRSolverRegridFalse ?
00276 (StepsTaken(base::GH(),0)%RegridEvery==0 && StepsTaken(base::GH(),0)>0) : true),
00277 base::ErrorEstimation() && (RegridEvery != AMRSolverRegridFalse ?
00278 (StepsTaken(base::GH(),0)+1)%RegridEvery==0 : false), FixupPar > 0,
00279 !(base::RedistributeEvery>0 && StepsTaken(base::GH(),0)%base::RedistributeEvery!=0),
00280 base::RedistributeEvery<=0);
00281
00282 cfl_max = 0.0;
00283 for (register int l=0; l<=FineLevel(base::GH()); l++)
00284 cfl_max = cfl_max > cfl_new[l] ? cfl_max : cfl_new[l];
00285
00286 #ifdef DAGH_NO_MPI
00287 #else
00288 if (comm_service::dce() && comm_service::proc_num() > 1) {
00289
00290 int num = comm_service::proc_num();
00291
00292 int R;
00293 int size = sizeof(double);
00294 void *values = (void *) new char[size*num];
00295
00296 R = MPI_Allgather(&cfl_max, size, MPI_BYTE, values, size, MPI_BYTE,
00297 comm_service::comm(base::U().GF_Id()));
00298 if ( MPI_SUCCESS != R )
00299 comm_service::error_die( "AMRSolver::cfl_max", "MPI_Allgather", R );
00300
00301 for (int i=0;i<num;i++) {
00302 double tmax = *((double *)values + i);
00303 cfl_max = cfl_max > tmax ? cfl_max : tmax;
00304 }
00305 if (values) delete [] (char *)values;
00306 }
00307 #endif
00308
00309 #ifdef DEBUG_PRINT_AMRSOLVER
00310 ( comm_service::log() << " Levels = " << FineLevel(base::GH())+1
00311 << " max. CFL = " << cfl_max << "\n" ).flush();
00312 #endif
00313 #ifdef DEBUG_PROFILE
00314 ( std::cout << "\n" ).flush();
00315 #endif
00316
00317 if (cfl_max > cflv[0])
00318 if (VariableTimeStepping==AutomaticTimeStepsRestart) {
00319 if (RestartStorage!=(std::stringstream *)NULL) {
00320 base::GH().DAGH_RecomposeHierarchy(*RestartStorage);
00321 for (int lev=0; lev<=FineLevel(base::GH()); lev++)
00322 t[lev] = told;
00323 Rejections++;
00324 }
00325 else
00326 std::cerr << " Restart failure!" << std::endl << std::flush ;
00327 if (cfl_max > VERY_LARGE_CFL)
00328 std::cerr << " CFL>" << (double)VERY_LARGE_CFL << " " << std::flush;
00329 }
00330 else if (cfl_max > 1.0)
00331 std::cerr << " CFL>1.0 " << std::flush;
00332
00333 if (VariableTimeStepping!=FixedTimeSteps)
00334 if (cfl_max == 0.0)
00335 SetTimeSpecs(base::GH(), t[0], t[0]+dtv[1], 2);
00336 else {
00337 double dt_predict = (DeltaT(base::GH(), 0) / cfl_max) * cflv[1];
00338 SetTimeSpecs(base::GH(), t[0], t[0] +
00339 (dtv[1] < dt_predict ? dtv[1] : dt_predict), 2);
00340 }
00341 else
00342 SetTimeSpecs(base::GH(), t[0], t[0]+dtv[0], 2);
00343
00344 if (RestartStorage != (std::stringstream *)NULL)
00345 delete RestartStorage;
00346
00347 } while (t[0] <= told);
00348
00349 return cfl_max;
00350 }
00351
00352 virtual double IntegrateLevel(vec_grid_fct_type& u, const int Time, const int Level,
00353 double t, double dt, bool DoFixup, double tc,
00354 const int which) {
00355
00356 double cfl = 0, cfl_step;
00357 int mpass = 0;
00358 int TStep = TimeStep(u,Level);
00359 if (base::Integrator_().MaxIntegratorPasses() > 0) mpass = 1;
00360 do {
00361
00362 cfl_step = UpdateLevel(u,Time,Level,t,dt,DoFixup,tc,which,mpass);
00363 cfl = (cfl > cfl_step ? cfl : cfl_step);
00364
00365
00366
00367 if (mpass>0 && mpass<base::Integrator_().MaxIntegratorPasses()) {
00368 SwapTimeLevels(u,Level,Time,Time+TStep);
00369 SetBndry(u,Time,Level,t);
00370 SwapTimeLevels(u,Level,Time,Time+TStep);
00371 }
00372
00373 mpass++;
00374 } while (mpass <= base::Integrator_().MaxIntegratorPasses());
00375
00376 #ifdef DEBUG_PRINT_AMRSOLVER
00377 ( comm_service::log() << "IntegrateLevel(): Level" << Level << " local CFL = " << cfl << "\n" ).flush();
00378 #endif
00379 return cfl;
00380 }
00381
00382
00383
00384
00385
00386 virtual double UpdateLevel(vec_grid_fct_type& u, const int& Time, const int& Level,
00387 double t, double dt, bool DoFixup, double tc,
00388 const int& which, const int& mpass) {
00389
00390 char errtext[256], whichtext[16];
00391 if (which<=0 || which>2) std::sprintf(whichtext,"Main");
00392 else if (which==1) std::sprintf(whichtext,"Estimate");
00393 else std::sprintf(whichtext,"Shadow");
00394 std::sprintf(errtext,"Flux allocation for %s",whichtext);
00395 AllocError::SetTexts("AMRSolver<dim>",errtext);
00396 base::Integrator_().SetGridFunction(&u);
00397
00398 int TStep = TimeStep(u,Level);
00399 double cfl = 0, cfl_grid;
00400
00401 forall (u,Time,Level,c)
00402 vec_grid_data_type& u_old = u(Time, Level, c);
00403 vec_grid_data_type& u_new = u(Time+TStep, Level, c);
00404
00405 vec_grid_data_type** f;
00406 base::Integrator_().AllocGridFluxes(u_old.bbox(), f);
00407
00408 #ifdef DEBUG_PRINT_INTEGRATOR
00409 if (mpass<=1) ( comm_service::log() << " " << which << ": " ).flush();
00410 #endif
00411 START_WATCH
00412 cfl_grid = base::Integrator_().CalculateGrid(u_new, u_old, f, Level, t, dt, mpass);
00413 END_WATCH_INTEGRATION(which)
00414 #ifdef DEBUG_PROFILE
00415 if (mpass<=1) ( std::cout << "." ).flush();
00416 #endif
00417
00418 cfl = (cfl > cfl_grid ? cfl : cfl_grid);
00419
00420 if (Level>0 && DoFixup && cfl_grid>0 && cfl_grid<=VERY_LARGE_CFL) {
00421
00422
00423
00424 START_WATCH
00425 base::Fixup_().AddFluxes(Time, Level, c, f, tc, t, dt, mpass);
00426 END_WATCH(FIXUP_WHOLE)
00427 }
00428
00429 if (Level<FineLevel(base::GH()) && DoFixup) {
00430 START_WATCH
00431
00432 if (!(cfl_grid>0 && cfl_grid<=VERY_LARGE_CFL))
00433 base::Integrator_().ResetGridFluxes(f);
00434 base::Fixup_().SaveFluxes(Time, Level, c, f , dt, mpass);
00435 END_WATCH(FIXUP_WHOLE)
00436 }
00437
00438 base::Integrator_().DeAllocGridFluxes(f);
00439 end_forall
00440
00441 #ifdef DEBUG_PRINT_AMRSOLVER
00442 ( comm_service::log() << "UpdateLevel(): Level" << Level
00443 << " mpass = " << mpass << " local CFL = " << cfl << "\n" ).flush();
00444 #endif
00445 return cfl;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471 virtual void SetBndry(vec_grid_fct_type& u, const int Time,
00472 const int Level, double t) {
00473 START_WATCH
00474 AdaptiveBoundaryUpdate(u,Time,Level);
00475 END_WATCH(BOUNDARIES_INTERPOLATION)
00476 START_WATCH
00477 Sync(u,Time,Level);
00478 END_WATCH(BOUNDARIES_SYNC)
00479 START_WATCH
00480 ExternalBoundaryUpdate(u,Time,Level);
00481 END_WATCH(BOUNDARIES_EXTERNAL)
00482 #ifdef DEBUG_AMR
00483 CheckLevel(u,Time,Level,t,"AMRSolver<dim>.SetBndry::after SetBndry");
00484 #endif
00485 }
00486
00487 public:
00488 inline const int& Bufferwidth() const { return BufferWidth; }
00489 inline int Bufferwidth() { return BufferWidth; }
00490
00491 protected:
00492 virtual void RegridLevel(const int Time, const int BaseLevel,
00493 BBoxList& bblist, bool TakeListOnFinestLevel) {
00494
00495 #ifdef DEBUG_PRINT_AMRSOLVER
00496 ( comm_service::log() << " *** Regridding at Level: " << BaseLevel
00497 << " t: " << Time << " Max: " << MaxLevel(base::GH()) << " fine: "
00498 << FineLevel(base::GH()) << "\n" ).flush();
00499 #endif
00500
00501 int l;
00502 int flev = FineLevel(base::GH());
00503 if (flev == 0) l = 0;
00504 else if (flev >= MaxLevel(base::GH())) l = MaxLevel(base::GH())-1;
00505 else l = flev;
00506 if (TakeListOnFinestLevel) {
00507 Refine(base::GH(),bblist,l);
00508 l--;
00509 }
00510
00511 for (;l>=BaseLevel;l--) {
00512
00513
00514
00515 START_WATCH
00516
00517 #ifdef DEBUG_AMR
00518 CheckLevel(base::U(),Time,l,t[l],"AMRSolver.RegridLevel::before Flagging");
00519 #endif
00520 base::Flagging_().SetFlags(Time, l, t[l], dt[l]);
00521
00522
00523 forall (base::Flagging_().Flags(),Time,l,c)
00524 for (BBox *_b = bblist.first();_b;_b=bblist.next())
00525 if (!_b->empty()) {
00526 BBox wb = base::Flagging_().Flags().interiorbbox(Time,l,c);
00527 if(wb.stepsize(0)>_b->stepsize(0))
00528 _b->coarsen(wb.stepsize(0)/_b->stepsize(0));
00529 base::Flagging_().Flags()(Time,l,c).plus(200,*_b);
00530 }
00531 end_forall
00532
00533
00534
00535
00536
00537
00538 START_WATCH
00539 Sync(base::Flagging_().Flags(), Time, l);
00540 END_WATCH(BOUNDARIES_SYNC)
00541 END_WATCH_FLAGGING
00542
00543 if (PlotFlags && base::LastOutputTime()==Time) {
00544 char flagname[DAGHBktGFNameWidth+16];
00545 std::sprintf(flagname,"flags");
00546 forall (base::Work(),Time,l,c)
00547 flag_data_type& flag = base::Flagging_().Flags()(Time,l,c);
00548 vflag_grid_data_type vflag_help(flag.bbox(),(VFlagType*) flag.data());
00549 equals_from(base::Work()(Time,l,c), vflag_help, 0);
00550 VFlagType* databuf;
00551 vflag_help.deallocate(databuf);
00552 end_forall
00553 base::FileOutput_().WritePlain(base::Work(), flagname, Time, l, t[l]);
00554 }
00555
00556
00557
00558
00559 #ifdef DEBUG_PRINT_INTEGRATOR
00560 ( comm_service::log() << " *** Clustering at Level: " << l << "\n" ).flush();
00561 #endif
00562 START_WATCH
00563 BBoxList bblexclude, bblcut;
00564 for (BBox *bbi=base::GH().wholebaselist()->first();bbi;
00565 bbi=base::GH().wholebaselist()->next())
00566 bblexclude.add(refine(*bbi,base::GH().refinedby(l)));
00567 base::GH().glb_bboxlist(bblcut,l);
00568 bblexclude -= bblcut;
00569
00570
00571 DAGHCluster(base::Flagging_().Flags(), Time, l,
00572 BlockWidth, OverlapWidth, BufferWidth,
00573 MinEfficiency, (FlagType)GoodPoint,
00574 bblist, bblist, bblexclude);
00575 END_WATCH_CLUSTERING
00576
00577 if (bblist.isempty()) {
00578 BBox empty_box;
00579 bblist.add(empty_box);
00580 }
00581
00582 #ifdef DEBUG_PRINT_RG_REFINE
00583 ( comm_service::log() << "\n************* New refine list at level "
00584 << l << " *************\n" << bblist
00585 << "\n************* ***************** *************\n"
00586 ).flush();
00587 #endif
00588
00589 Refine(base::GH(),bblist,l);
00590 }
00591 }
00592
00593 virtual void RecomposeGridHierarchy(const int Time, const int Level,
00594 bool ShadowAllowed, bool DoFixup,
00595 bool RecomposeBaseLev, bool RecomposeHighLev) {
00596
00597 if (DoFixup)
00598 base::Fixup_().SetMaxRecomposeLevel(Level);
00599 register int lev;
00600 for (lev=Level; lev<=MaxLevel(base::GH()); lev++) {
00601 base::U().GF_DeleteStorage(1,lev);
00602 if (ShadowAllowed) base::Ush().GF_DeleteStorage(1,lev);
00603 }
00604 #ifdef DEBUG_AMR
00605 if (base::Integrator_().Abort())
00606 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00607 int time = CurrentTime(base::GH(),l);
00608 int tstep = TimeStep(base::U(),l);
00609 CheckLevel(base::U(),time,l,t[l],"AMRSolver.AdvanceLevel::before Recompose");
00610 if (l<Level)
00611 CheckLevel(base::U(),time+tstep,l,t[l],
00612 "AMRSolver.AdvanceLevel::before Recompose for Time+TStep");
00613 if (ShadowAllowed && l<MaxLevel(base::GH())) {
00614 int shtstep = TimeStep(base::Ush(),l);
00615 CheckLevel(base::Ush(),time,l,t[l],
00616 "AMRSolver.AdvanceLevel::before Recompose for Shadow");
00617 if (l<Level)
00618 CheckLevel(base::Ush(),time+shtstep,l,t[l],
00619 "AMRSolver.AdvanceLevel::before Recompose for Time+TStep for Shadow");
00620 }
00621 }
00622 #endif
00623 RecomposeHierarchy(base::GH(), (Level==0 && RecomposeBaseLev) ||
00624 (Level>0 && RecomposeHighLev) ? DAGHTrue : DAGHFalse);
00625 #ifdef DEBUG_AMR
00626 if (base::Integrator_().Abort())
00627 for (register int l=0; l<=FineLevel(base::GH()); l++) {
00628 int time = CurrentTime(base::GH(),l);
00629 int tstep = TimeStep(base::U(),l);
00630 CheckLevel(base::U(),time,l,t[l],"AMRSolver.AdvanceLevel::after Recompose");
00631 if (l<Level)
00632 CheckLevel(base::U(),time+tstep,l,t[l],
00633 "AMRSolver.AdvanceLevel::after Recompose for Time+TStep");
00634 if (ShadowAllowed && l<MaxLevel(base::GH())) {
00635 int shtstep = TimeStep(base::Ush(),l);
00636 CheckLevel(base::Ush(),time,l,t[l],
00637 "AMRSolver.AdvanceLevel::after Recompose for Shadow");
00638 if (l<Level)
00639 CheckLevel(base::Ush(),time+shtstep,l,t[l],
00640 "AMRSolver.AdvanceLevel::after Recompose for Time+TStep for Shadow");
00641 }
00642 }
00643 #endif
00644
00645 for (lev=Level; lev<=MaxLevel(base::GH()); lev++) {
00646 base::U().GF_CreateStorage(1,lev);
00647 if (ShadowAllowed && lev<MaxLevel(base::GH()))
00648 base::Ush().GF_CreateStorage(1,lev);
00649 }
00650 }
00651
00652 virtual void AfterLevelStep(const int Level) {}
00653
00654 virtual void AdvanceLevel(const int Level, int RegridEvery, bool RegridDone,
00655 bool ShadowAllowed, bool DoFixup,
00656 bool RecomposeBaseLev, bool RecomposeHighLev) {
00657
00658
00659
00660 int NoIterations = 0;
00661 if (Level==0 || NoTimeRefine==1) {
00662 NoIterations = 1;
00663 dt[Level] = DeltaT(base::GH(), 0);
00664 }
00665 else {
00666 NoIterations = RefineFactor(base::GH(),Level-1);
00667 dt[Level] = dt[Level-1] / RefineFactor(base::GH(),Level-1);
00668 }
00669
00670 for (int l=Level+1; l<=MaxLevel(base::GH()); l++)
00671 if (NoTimeRefine==1) dt[l]=dt[l-1];
00672 else dt[l] = dt[l-1] / RefineFactor(base::GH(),l-1);
00673
00674 int Time;
00675 int TStep = TimeStep(base::U(),Level);
00676 double cfl;
00677 cfl_new[Level] = 0.0;
00678
00679 for (int k=0; k<NoIterations; k++) {
00680 Time = CurrentTime(base::GH(),Level);
00681
00682 #ifdef DEBUG_PRINT_AMRSOLVER
00683 ( comm_service::log() << "AdvanceLevel(): Level" << Level
00684 << " Time = " << Time << " Iteration = " << k << "\n" ).flush();
00685 #endif
00686
00687 SetPhysicalTime(base::U(),Time+TStep,Level,t[Level]+dt[Level]);
00688 if (ShadowAllowed)
00689 SetPhysicalTime(base::Ush(),Time+TimeStep(base::Ush(),Level),Level,
00690 t[Level]+dt[Level]*base::Ush().factor());
00691
00692 bool DoRegrid = (RegridEvery!= AMRSolverRegridFalse ?
00693 Level<MaxLevel(base::GH()) && k%RegridEvery==0 &&
00694 !RegridDone && t[Level]>0.0 : false);
00695
00696 if (Level==0 || !RegridDone)
00697 SetBndry(base::U(),Time,Level,t[Level]);
00698
00699
00700
00701
00702 if (DoRegrid) {
00703
00704
00705
00706 BBoxList bblist;
00707 RegridLevel(Time, Level, bblist, false);
00708
00709
00710
00711
00712 START_WATCH
00713 RecomposeGridHierarchy(Time,Level,ShadowAllowed,DoFixup,
00714 RecomposeBaseLev,RecomposeHighLev);
00715 END_WATCH_RECOMPOSING_WHOLE
00716 RegridDone = true;
00717 }
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 cfl = IntegrateLevel(base::U(), Time, Level, t[Level], dt[Level],
00728 DoFixup, (Level>0 ? t[Level-1] : 0.0), 0);
00729 cfl_new[Level] = cfl_new[Level] > cfl ? cfl_new[Level] : cfl;
00730
00731
00732
00733
00734
00735
00736
00737
00738 if (RegridEvery != AMRSolverRegridFalse ?
00739 Level<MaxLevel(base::GH()) && ShadowAllowed &&
00740 (Level>0 ? (k+1)%RegridEvery==0 : true) : false) {
00741
00742 double dt_sh = dt[Level] * base::Ush().factor();
00743 SetPhysicalTime(base::Ush(),Time,Level,t[Level]);
00744
00745
00746
00747
00748 forall (base::U(),Time,Level,cm)
00749 vec_grid_data_type& u_main = base::U()(Time, Level, cm);
00750 forall (base::Ush(),Time,Level,cs)
00751 vec_grid_data_type& u_shadow = base::Ush()(Time, Level, cs);
00752 BBox bb = u_shadow.bbox()*u_main.bbox();
00753 if (!bb.empty())
00754 base::LevelTransfer_().Restrict(u_main,Level,u_shadow,Level,bb);
00755 end_forall
00756 end_forall
00757
00758 SetBndry(base::Ush(),Time,Level,t[Level]);
00759 IntegrateLevel(base::Ush(), Time, Level, t[Level], dt_sh, false, 0.0, 2);
00760
00761 }
00762
00763
00764
00765
00766
00767 #ifdef DEBUG_PRINT_FIXUP
00768 VectorType mass_old;
00769 int d;
00770 DCoords dx = base::GH().worldStep(base::U().GF_StepSize(Level));
00771 if (Level == 0) {
00772 mass_old = Sum(base::U(),Time+TStep,Level);
00773 for (d=0; d<dim; d++) mass_old *= dx(d);
00774 }
00775 #endif
00776
00777 if (Level < MaxLevel(base::GH())) {
00778
00779
00780
00781 SetBndry(base::U(),Time+TStep,Level,t[Level]+dt[Level]);
00782
00783
00784 AdvanceLevel(Level+1, RegridEvery, RegridDone,
00785 ShadowAllowed, DoFixup, RecomposeBaseLev,
00786 RecomposeHighLev);
00787
00788 #ifdef DEBUG_AMR
00789 CheckLevel(base::U(),Time+TStep,Level,t[Level],
00790 "AMRSolver.AdvanceLevel::before Restrict and Fixup");
00791 #endif
00792
00793 if (DoFixup) {
00794 START_WATCH
00795 base::Fixup_().Correction(Time+TStep, Time, Level);
00796 END_WATCH(FIXUP_CORRECTION)
00797 }
00798
00799
00800
00801 Restrict(base::U(), Time+TStep, Level+1, Time+TStep, Level);
00802
00803 #ifdef DEBUG_AMR
00804 CheckLevel(base::U(),Time+TStep,Level,t[Level],
00805 "AMRSolver.AdvanceLevel::after Restrict and Fixup");
00806 #endif
00807 }
00808 #ifdef DEBUG_PROFILE
00809 ( std::cout << "\n" ).flush();
00810 #endif
00811
00812 #ifdef DEBUG_PRINT_FIXUP
00813 VectorType mass_new;
00814 if (Level == 0) {
00815 ( comm_service::log()
00816 << "\n*********** Difference in state variables at level "
00817 << Level << " after fixup ********\n" ).flush();
00818
00819
00820 mass_new = Sum(base::U(),Time+TStep,Level);
00821 for (d=0; d<dim; d++) mass_new *= dx(d);
00822 ( comm_service::log() << mass_old << "-"
00823 << mass_new << "=" << mass_old - mass_new ).flush();
00824 ( comm_service::log()
00825 << "\n**************************************************************"
00826 << "***********\n" ).flush();
00827 }
00828 #endif
00829
00830
00831
00832
00833 CycleTimeLevels(base::U(),Level);
00834 if (ShadowAllowed)
00835 CycleTimeLevels(base::Ush(),Level);
00836
00837
00838
00839
00840
00841
00842
00843 t[Level] += dt[Level];
00844 IncrCurrentTime(base::GH(),Level);
00845 if (NoTimeRefine==1 && Level>0)
00846 for (int kk=1; kk<RefineFactor(base::GH(),Level-1); kk++)
00847 IncrCurrentTime(base::GH(),Level);
00848 Time = CurrentTime(base::GH(),Level);
00849 SetPhysicalTime(base::U(),Time,Level,t[Level]);
00850 if (ShadowAllowed)
00851 SetPhysicalTime(base::Ush(),Time,Level,t[Level]+
00852 dt[Level]*(base::Ush().factor()-1));
00853 RegridDone = false;
00854
00855 AfterLevelStep(Level);
00856 }
00857 }
00858
00859 void CheckLevel(vec_grid_fct_type &u, const int& time, const int& level,
00860 const double& t, const char *text) {
00861 if (base::Integrator_().Abort()) {
00862 char wtext[1024];
00863 std::sprintf(wtext,"\non Level=%d at Time=%d: %s\n",level,time,text);
00864 forall (u,time,level,c)
00865 vec_grid_data_type& uw = u(time,level,c);
00866 base::Integrator_().CheckGrid(uw, level, uw.bbox(), t, wtext);
00867 end_forall
00868 }
00869 }
00870
00871 BBox BoundaryBBox(const BBox& whole, const int s) {
00872 int d = s/2;
00873 #ifdef DEBUG_PRINT
00874 assert (d>=0 && d<dim);
00875 #endif
00876 BBox bb(whole);
00877 if (s%2 == 0)
00878 bb.upper(d) = bb.lower(d)+(base::NGhosts()-1)*bb.stepsize(d);
00879 else
00880 bb.lower(d) = bb.upper(d)-(base::NGhosts()-1)*bb.stepsize(d);
00881 return bb;
00882 }
00883
00884 int FixupPar;
00885 int RegridEvery;
00886 double MinEfficiency;
00887 int BlockWidth, OverlapWidth, BufferWidth, NestingBuffer;
00888 int NoTimeRefine;
00889 int PlotFlags;
00890
00891 double *t, *dt;
00892 double *cfl_new;
00893 };
00894
00895
00896 #endif