Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize no-subcycling AMR #2505

Merged
merged 25 commits into from
Jul 9, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
934ab9d
Finish developing wrapper functions for CTU advance
maxpkatz Jun 17, 2023
cb066c0
Guard against true SDC build
maxpkatz Jun 17, 2023
2f740b3
Fix true SDC gravity interface
maxpkatz Jun 18, 2023
35714a9
First draft of optimal subcycling preparation
maxpkatz Jun 18, 2023
1e270d6
Simplify for only subcycling_mode = None
maxpkatz Jun 18, 2023
0fd0d32
Merge branch 'development' into optimal_subcycling_prep
maxpkatz Jun 18, 2023
8ce6a0a
IO formatting
maxpkatz Jun 18, 2023
f61b05d
Merge branch 'development' into optimal_subcycling_prep
zingale Jun 18, 2023
9fc438e
Add some more stdout timers for gravity
maxpkatz Jun 18, 2023
ac201e1
Fix FOM print
maxpkatz Jun 18, 2023
5f923c1
Fix when reflux occurs
maxpkatz Jun 18, 2023
586d905
Fix reflux location again
maxpkatz Jun 18, 2023
0bc0e26
Merge branch 'development' into optimal_subcycling_prep
maxpkatz Jun 18, 2023
62f11dc
Merge branch 'development' into optimal_subcycling_prep
maxpkatz Jul 4, 2023
7b92b4c
Merge branch 'development' into optimal_subcycling_prep
zingale Jul 4, 2023
1396465
add a bit more to the abundance failure FAQ (#2517)
zingale Jul 4, 2023
3d097bb
update the docs for reactions (#2475)
zingale Jul 4, 2023
2b86c08
Merge branch 'development' into optimal_subcycling_prep
maxpkatz Jul 4, 2023
8ffe346
Merge branch 'development' into optimal_subcycling_prep
maxpkatz Jul 8, 2023
3c5f0c7
Make some prints more informative
maxpkatz Jul 9, 2023
f5ff8b8
Fix an SDC-specific issue
maxpkatz Jul 9, 2023
e317c70
Update sdc_iteration on all levels
maxpkatz Jul 9, 2023
9ccc1bb
CHANGES
maxpkatz Jul 9, 2023
a948c40
Merge branch 'development' into optimal_subcycling_prep
maxpkatz Jul 9, 2023
395bdfd
Add explanatory comment to reflux()
maxpkatz Jul 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# 23.08

* Time evolution without subcycling on the fine levels, which is enabled via
the runtime parameter amr.subcycling_mode = "None", has been significantly
rewritten to improve computational performance for certain cases. When the
fine levels do not subcycle, the evolution can be done by processing all
of the hydro updates on the fine level together and then immediately doing
the flux correction to sync the coarse and fine level fluxes at the
boundary between levels. This is how many AMR codes that do not subcycle
are written. Castro now does this when the user chooses not to subcycle.
The benefit of this approach is most evidence for problems with Poisson
gravity that use a multigrid solve, as we can significantly reduce the
number of Poisson solves per step, performing only a single composite
(multi-level) solve at the new-time simultaneously for all levels. (#2505)

# 23.07

* The parameter castro.state_nghost, which allowed State_Type to have ghost
Expand Down
4 changes: 2 additions & 2 deletions Source/diffusion/Castro_diffusion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Castro::construct_old_diff_source(MultiFab& source, MultiFab& state_in, Real tim
#endif
ParallelDescriptor::ReduceRealMax(run_time,IOProc);

amrex::Print() << "Castro::construct_old_diff_source() time = " << run_time << "\n" << "\n";
amrex::Print() << "Castro::construct_old_diff_source() time = " << run_time << " on level " << level << "\n" << "\n";
#ifdef BL_LAZY
});
#endif
Expand Down Expand Up @@ -68,7 +68,7 @@ Castro::construct_new_diff_source(MultiFab& source, MultiFab& state_old, MultiFa
#endif
ParallelDescriptor::ReduceRealMax(run_time,IOProc);

amrex::Print() << "Castro::construct_new_diff_source() time = " << run_time << "\n" << "\n";
amrex::Print() << "Castro::construct_new_diff_source() time = " << run_time << " on level " << level << "\n" << "\n";
#ifdef BL_LAZY
});
#endif
Expand Down
3 changes: 2 additions & 1 deletion Source/driver/Castro.H
Original file line number Diff line number Diff line change
Expand Up @@ -1036,8 +1036,9 @@ public:
///
/// @param crse_level
/// @param fine_level
/// @param in_post_timestep
///
void reflux (int crse_level, int fine_level);
void reflux (int crse_level, int fine_level, bool in_post_timestep);


///
Expand Down
22 changes: 12 additions & 10 deletions Source/driver/Castro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1951,7 +1951,9 @@ Castro::post_timestep (int iteration_local)
// will also do the sync solve associated with the reflux.

if (do_reflux && level < parent->finestLevel()) {
reflux(level, level+1);
if (parent->subcyclingMode() != "None") {
reflux(level, level+1, true);
}
}

// Ensure consistency with finer grids.
Expand Down Expand Up @@ -2616,7 +2618,7 @@ Castro::FluxRegFineAdd() {


void
Castro::reflux(int crse_level, int fine_level)
Castro::reflux (int crse_level, int fine_level, bool in_post_timestep)
zingale marked this conversation as resolved.
Show resolved Hide resolved
{
BL_PROFILE("Castro::reflux()");

Expand All @@ -2630,7 +2632,7 @@ Castro::reflux(int crse_level, int fine_level)
Vector<std::unique_ptr<MultiFab> > drho(nlevs);
Vector<std::unique_ptr<MultiFab> > dphi(nlevs);

if (do_grav && gravity->get_gravity_type() == "PoissonGrav" && gravity->NoSync() == 0) {
if (do_grav && gravity->get_gravity_type() == "PoissonGrav" && gravity->NoSync() == 0 && in_post_timestep) {

for (int lev = crse_level; lev <= fine_level; ++lev) {

Expand Down Expand Up @@ -2783,7 +2785,7 @@ Castro::reflux(int crse_level, int fine_level)
// Update the coarse fluxes MultiFabs using the reflux data. This should only make
// a difference if we re-evaluate the source terms later.

if (update_sources_after_reflux) {
if (update_sources_after_reflux || !in_post_timestep) {

MultiFab::Add(*crse_lev.fluxes[idir], temp_fluxes[idir], 0, 0, crse_lev.fluxes[idir]->nComp(), 0);

Expand All @@ -2803,7 +2805,7 @@ Castro::reflux(int crse_level, int fine_level)
#ifdef GRAVITY
int ilev = lev - crse_level - 1;

if (do_grav && gravity->get_gravity_type() == "PoissonGrav" && gravity->NoSync() == 0) {
if (do_grav && gravity->get_gravity_type() == "PoissonGrav" && gravity->NoSync() == 0 && in_post_timestep) {
reg->Reflux(*drho[ilev], crse_lev.volume, 1.0, 0, URHO, 1, crse_lev.geom);
amrex::average_down(*drho[ilev + 1], *drho[ilev], 0, 1, getLevel(lev).crse_ratio);
}
Expand All @@ -2826,7 +2828,7 @@ Castro::reflux(int crse_level, int fine_level)

reg->Reflux(crse_state, dr, 1.0, 0, UMX, 1, crse_lev.geom);

if (update_sources_after_reflux) {
if (update_sources_after_reflux || !in_post_timestep) {

MultiFab tmp_fluxes(crse_lev.P_radial.boxArray(),
crse_lev.P_radial.DistributionMap(),
Expand Down Expand Up @@ -2863,7 +2865,7 @@ Castro::reflux(int crse_level, int fine_level)

reg->Reflux(crse_lev.get_new_data(Rad_Type), crse_lev.volume, 1.0, 0, 0, Radiation::nGroups, crse_lev.geom);

if (update_sources_after_reflux) {
if (update_sources_after_reflux || !in_post_timestep) {

for (int idir = 0; idir < AMREX_SPACEDIM; ++idir) {

Expand Down Expand Up @@ -2893,7 +2895,7 @@ Castro::reflux(int crse_level, int fine_level)
#endif

#ifdef GRAVITY
if (do_grav && gravity->get_gravity_type() == "PoissonGrav" && gravity->NoSync() == 0) {
if (do_grav && gravity->get_gravity_type() == "PoissonGrav" && gravity->NoSync() == 0 && in_post_timestep) {

reg = &getLevel(lev).phi_reg;

Expand Down Expand Up @@ -2922,7 +2924,7 @@ Castro::reflux(int crse_level, int fine_level)
// Do the sync solve across all levels.

#ifdef GRAVITY
if (do_grav && gravity->get_gravity_type() == "PoissonGrav" && gravity->NoSync() == 0) {
if (do_grav && gravity->get_gravity_type() == "PoissonGrav" && gravity->NoSync() == 0 && in_post_timestep) {
gravity->gravity_sync(crse_level, fine_level, amrex::GetVecOfPtrs(drho), amrex::GetVecOfPtrs(dphi));
}
#endif
Expand All @@ -2938,7 +2940,7 @@ Castro::reflux(int crse_level, int fine_level)
// ghost zone fills like diffusion depend on the data in the
// coarser levels.

if (update_sources_after_reflux &&
if (update_sources_after_reflux && in_post_timestep &&
(time_integration_method == CornerTransportUpwind ||
time_integration_method == SimplifiedSpectralDeferredCorrections)) {

Expand Down
69 changes: 52 additions & 17 deletions Source/driver/Castro_advance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ Castro::advance (Real time,
// amr_ncycle : the number of subcycles at this level

{
if (parent->subcyclingMode() == "None" && level > 0) {
amrex::Print() << "\n Advance at this level has already been completed.\n\n";
return dt;
}

BL_PROFILE("Castro::advance()");

// Save the wall time when we started the step.
Expand All @@ -48,7 +53,15 @@ Castro::advance (Real time,

Real dt_new = dt;

initialize_advance(time, dt, amr_iteration);
int max_level_to_advance = level;

if (parent->subcyclingMode() == "None" && level == 0) {
max_level_to_advance = parent->finestLevel();
}

for (int lev = level; lev <= max_level_to_advance; ++lev) {
getLevel(lev).initialize_advance(time, dt, amr_iteration);
}

// Do the advance.

Expand Down Expand Up @@ -87,27 +100,29 @@ Castro::advance (Real time,
post_step_regrid = 1;
}

for (int lev = level; lev <= max_level_to_advance; ++lev) {
#ifdef AUX_UPDATE
advance_aux(time, dt);
getLevel(lev).advance_aux(time, dt);
#endif

#ifdef GRAVITY
// Update the point mass.
if (use_point_mass == 1) {
pointmass_update(time, dt);
}
// Update the point mass.
if (use_point_mass == 1) {
getLevel(lev).pointmass_update(time, dt);
}
#endif

#ifdef RADIATION
MultiFab& S_new = get_new_data(State_Type);
final_radiation_call(S_new, amr_iteration, amr_ncycle);
MultiFab& S_new = getLevel(lev).get_new_data(State_Type);
getLevel(lev).final_radiation_call(S_new, amr_iteration, amr_ncycle);
#endif

#ifdef AMREX_PARTICLES
advance_particles(amr_iteration, time, dt);
getLevel(lev).advance_particles(amr_iteration, time, dt);
#endif

finalize_advance();
getLevel(lev).finalize_advance();
}

return dt_new;
}
Expand Down Expand Up @@ -574,7 +589,7 @@ Castro::finalize_advance()
{
BL_PROFILE("Castro::finalize_advance()");

if (do_reflux == 1) {
if (do_reflux == 1 && parent->subcyclingMode() != "None") {
FluxRegCrseInit();
FluxRegFineAdd();
}
Expand All @@ -584,7 +599,7 @@ Castro::finalize_advance()
// the fluxes from the full timestep (this will be used
// later during the reflux operation).

if (do_reflux == 1 && update_sources_after_reflux == 1) {
if (do_reflux == 1 && update_sources_after_reflux == 1 && parent->subcyclingMode() != "None") {
for (int idir = 0; idir < AMREX_SPACEDIM; ++idir) {
MultiFab::Copy(*mass_fluxes[idir], *fluxes[idir], URHO, 0, 1, 0);
}
Expand Down Expand Up @@ -628,14 +643,34 @@ Castro::finalize_advance()

// Record how many zones we have advanced.

num_zones_advanced += static_cast<Real>(grids.numPts()) / static_cast<Real>(getLevel(0).grids.numPts());
int max_level_to_advance = level;

if (parent->subcyclingMode() == "None") {
max_level_to_advance = parent->finestLevel();
}

long num_pts_advanced = 0;

for (int lev = level; lev <= max_level_to_advance; ++lev) {
num_pts_advanced += getLevel(lev).grids.numPts();
}

num_zones_advanced += static_cast<Real>(num_pts_advanced) / static_cast<Real>(getLevel(0).grids.numPts());

Real wall_time = ParallelDescriptor::second() - wall_time_start;
Real fom_advance = static_cast<Real>(grids.numPts()) / wall_time / 1.e6;

Real fom_advance = static_cast<Real>(num_pts_advanced) / wall_time / 1.e6;

if (verbose >= 1) {
amrex::Print() << " Zones advanced per microsecond at this level: "
<< fom_advance << std::endl << std::endl;
if (max_level_to_advance > 0) {
if (level == 0) {
amrex::Print() << " Zones advanced per microsecond from level " << level << " to level "
<< max_level_to_advance << ": " << fom_advance << std::endl << std::endl;
}
}
else {
amrex::Print() << " Zones advanced per microsecond at this level: "
<< fom_advance << std::endl << std::endl;
}
}

}
Loading
Loading