Skip to content

Commit 5d46977

Browse files
author
Ben Prather
committed
Merge branch 'fix/papercuts' into parthenon-bump
2 parents 0d12e3a + f3e376d commit 5d46977

21 files changed

Lines changed: 452 additions & 265 deletions
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
diff --git a/src/utils/communication_buffer.hpp b/src/utils/communication_buffer.hpp
2+
index edfc04f1..b2c44091 100644
3+
--- a/src/utils/communication_buffer.hpp
4+
+++ b/src/utils/communication_buffer.hpp
5+
@@ -327,8 +327,8 @@ bool CommBuffer<T>::TryReceive() noexcept {
6+
*comm_type_ == BuffCommType::sparse_receiver) {
7+
#ifdef MPI_PARALLEL
8+
(*nrecv_tries_)++;
9+
- PARTHENON_REQUIRE(*nrecv_tries_ < 1e8,
10+
- "MPI probably hanging after 1e8 receive tries.");
11+
+ //PARTHENON_REQUIRE(*nrecv_tries_ < 1e8,
12+
+ // "MPI probably hanging after 1e8 receive tries.");
13+
14+
TryStartReceive();
15+

kharma/b_cleanup/b_cleanup.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
/*
1+
/*
22
* File: b_cleanup.cpp
3-
*
3+
*
44
* BSD 3-Clause License
5-
*
5+
*
66
* Copyright (c) 2020, AFD Group at UIUC
77
* All rights reserved.
8-
*
8+
*
99
* Redistribution and use in source and binary forms, with or without
1010
* modification, are permitted provided that the following conditions are met:
11-
*
11+
*
1212
* 1. Redistributions of source code must retain the above copyright notice, this
1313
* list of conditions and the following disclaimer.
14-
*
14+
*
1515
* 2. Redistributions in binary form must reproduce the above copyright notice,
1616
* this list of conditions and the following disclaimer in the documentation
1717
* and/or other materials provided with the distribution.
18-
*
18+
*
1919
* 3. Neither the name of the copyright holder nor the names of its
2020
* contributors may be used to endorse or promote products derived from
2121
* this software without specific prior written permission.
22-
*
22+
*
2323
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2424
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2525
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -210,7 +210,7 @@ TaskStatus B_Cleanup::CleanupDivergence(std::shared_ptr<MeshData<Real>>& md)
210210
}
211211

212212
// Calculate/print inital max divB exactly as we would during run
213-
double divb_start;
213+
double divb_start;
214214
if (use_b_ct) {
215215
divb_start = B_CT::GlobalMaxDivB(md.get());
216216
} else {
@@ -282,7 +282,7 @@ TaskStatus B_Cleanup::CleanupDivergence(std::shared_ptr<MeshData<Real>>& md)
282282
// Synchronize to update cons.B's ghost zones
283283
KHARMADriver::SyncAllBounds(md);
284284
// Make sure prims.B reflects solution
285-
B_CT::MeshUtoP(md.get(), IndexDomain::entire, false);
285+
B_CT::MeshUtoP(md.get(), IndexDomain::entire);
286286
// Recalculate divB max for one last check
287287
divb_end = B_CT::GlobalMaxDivB(md.get());
288288
} else {
@@ -291,7 +291,7 @@ TaskStatus B_Cleanup::CleanupDivergence(std::shared_ptr<MeshData<Real>>& md)
291291
// Synchronize to update cons.B's ghost zones
292292
KHARMADriver::SyncAllBounds(md);
293293
// Make sure prims.B reflects solution
294-
B_FluxCT::MeshUtoP(md.get(), IndexDomain::entire, false);
294+
B_FluxCT::MeshUtoP(md.get(), IndexDomain::entire);
295295
// Recalculate divB max for one last check
296296
divb_end = B_FluxCT::GlobalMaxDivB(md.get());
297297
}

kharma/b_ct/b_ct.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ std::shared_ptr<KHARMAPackage> B_CT::Initialize(ParameterInput *pin, std::shared
7373
if (lazy_prolongation && pin->GetString("parthenon/mesh", "refinement") == "adaptive")
7474
throw std::runtime_error("Cannot use non-divergence-preserving prolongation in AMR!");
7575

76+
// TODO don't set this unless we're reconnecting at boundaries (can't just check, we load Boundaries pkg later)
77+
int reconnection_outer_buffer = pin->GetOrAddInteger("b_field", "reconnection_outer_buffer", 10);
78+
params.Add("reconnection_outer_buffer", reconnection_outer_buffer);
79+
7680
// FIELDS
7781

7882
// Flags for B fields on faces.
@@ -385,7 +389,7 @@ TaskStatus B_CT::CalculateEMF(MeshData<Real> *md)
385389
);
386390
} else if (scheme == "gs05_c" || scheme == "sg07") {
387391
auto& rho = md->PackVariablesAndFluxes(std::vector<std::string>{"cons.rho"});
388-
pmb0->par_for("B_CT_emf_GS05_c", block.s, block.e, b1.ks, b1.ke, b1.js, b1.je, b1.is, b1.ie,
392+
pmb0->par_for("B_CT_emf_SG07", block.s, block.e, b1.ks, b1.ke, b1.js, b1.je, b1.is, b1.ie,
389393
KOKKOS_LAMBDA (const int &bl, const int &k, const int &j, const int &i) {
390394
// Following adapted closely from AthenaK, including clever use of the mass flux for the
391395
// sign of the contact mode.
@@ -528,6 +532,11 @@ TaskStatus B_CT::DerefinePoles(MeshData<Real> *md)
528532
const int offset = (binner) ? 1 : -1; // offset to read the physical face values
529533
const int point_out = offset; // if F2 B field at j_f + offset face is positive when pointing out of the cell, +1.
530534

535+
// Should we allow flux through the pole?
536+
auto &bpars = pmesh->packages.Get("Boundaries")->AllParams();
537+
const bool allow_flux = binner ? bpars.Get<bool>("excise_flux_inner_x2"):
538+
bpars.Get<bool>("excise_flux_outer_x2");
539+
531540
// F1 average
532541
pmb->par_for("B_CT_derefine_poles_avg_F1", bCC.ks, bCC.ke, j_p.s, j_p.e, bF1.is, bF1.ie,
533542
KOKKOS_LAMBDA (const int &k, const int &j, const int &i) {
@@ -554,7 +563,7 @@ TaskStatus B_CT::DerefinePoles(MeshData<Real> *md)
554563
// starting k-index of the coarse cell
555564
const int k_start = k - k_fine;
556565

557-
if (j == j_f) {
566+
if (!allow_flux && j == j_f) {
558567
// The fine cells have 0 fluxes through the physical-ghost boundaries.
559568
B_avg(F2, 0, k, j, i) = 0.;
560569
} else { // average the fine cells

kharma/b_ct/b_ct_boundaries.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ void B_CT::ReconnectBoundaryB3(MeshBlockData<Real> *rc, IndexDomain domain, cons
299299

300300
const Real gam = pmb->packages.Get("GRMHD")->Param<Real>("gamma");
301301

302+
const int reconnection_outer_buffer = pmb->packages.Get("B_CT")->Param<int>("reconnection_outer_buffer");
303+
302304
const Floors::Prescription floors = pmb->packages.Get("Floors")->Param<Floors::Prescription>("prescription");
303305
// Don't be fooled, this function does *not* support/preserve EMHD values
304306
const EMHD::EMHD_parameters& emhd_params = EMHD::GetEMHDParameters(pmb->packages);
@@ -308,7 +310,7 @@ void B_CT::ReconnectBoundaryB3(MeshBlockData<Real> *rc, IndexDomain domain, cons
308310
IndexRange3 bi = KDomain::GetRange(rc, IndexDomain::interior, F3, coarse);
309311
const int jf = (binner) ? bi.js : bi.je; // j index of last zone next to pole
310312
parthenon::par_for_outer(DEFAULT_OUTER_LOOP_PATTERN, "reduce_B3_" + bname, pmb->exec_space,
311-
0, 1, 0, fpack.GetDim(4)-1, b.is, b.ie,
313+
0, 1, 0, fpack.GetDim(4)-1, b.is + 6, b.ie - reconnection_outer_buffer,
312314
KOKKOS_LAMBDA(parthenon::team_mbr_t member, const int &v, const int& i) {
313315
// Sum the first rank of B3
314316
double B3_sum = 0.;
@@ -339,8 +341,9 @@ void B_CT::ReconnectBoundaryB3(MeshBlockData<Real> *rc, IndexDomain domain, cons
339341

340342
// Recover primitive GRMHD variables from our modified U
341343
Inverter::u_to_p<Inverter::Type::kastaun>(G, U, m_u, gam, k, jf, i, P, m_p, Loci::center,
342-
25, 1e-12);
344+
25, 1e-12, false);
343345
// Floor them
346+
// TODO THIS IS IN FLUID FRAME
344347
int fflag = Floors::apply_geo_floors(G, P, m_p, gam, k, jf, i, floors, floors, Loci::center);
345348
// Recalculate U on anything we floored
346349
if (fflag)

kharma/boundaries/boundaries.cpp

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,13 @@ std::shared_ptr<KHARMAPackage> KBoundaries::Initialize(ParameterInput *pin, std:
6767
// Option to excise a bit at the poles when calculating fluxes
6868
bool excise_polar_flux = pin->GetOrAddBoolean("boundaries", "excise_polar_flux", false);
6969
params.Add("excise_polar_flux", excise_polar_flux);
70-
if (excise_polar_flux) { // These options are *completely* incompatible
71-
pin->SetBoolean("boundaries", "zero_polar_flux", false);
72-
}
7370
// Otherwise, those fluxes should be zero
74-
bool zero_polar_flux = pin->GetOrAddBoolean("boundaries", "zero_polar_flux", spherical);
71+
bool zero_polar_flux = pin->GetOrAddBoolean("boundaries", "zero_polar_flux", spherical && !excise_polar_flux);
7572
params.Add("zero_polar_flux", zero_polar_flux);
73+
// Throw an error if both are set
74+
if (excise_polar_flux && zero_polar_flux) {
75+
throw std::runtime_error("Cannot set both boundaries/excise_polar_flux and boundaries/zero_polar_flux!");
76+
}
7677

7778
// Apply physical boundaries to conserved GRMHD variables rho u^r, T^mu_nu
7879
// Probably inadvisable?
@@ -174,8 +175,7 @@ std::shared_ptr<KHARMAPackage> KBoundaries::Initialize(ParameterInput *pin, std:
174175
// Ensure fluxes through the zero-size face at the pole are zero
175176
bool zero_flux = pin->GetOrAddBoolean("boundaries", "zero_flux_" + bname, zero_polar_flux && bdir == X2DIR);
176177
params.Add("zero_flux_" + bname, zero_flux);
177-
178-
// Ensure fluxes through the zero-size face at the pole are zero
178+
// OR allow them via faux-excision
179179
bool excise_flux = pin->GetOrAddBoolean("boundaries", "excise_flux_" + bname, excise_polar_flux && bdir == X2DIR);
180180
params.Add("excise_flux_" + bname, excise_flux);
181181

@@ -194,11 +194,12 @@ std::shared_ptr<KHARMAPackage> KBoundaries::Initialize(ParameterInput *pin, std:
194194
bool clean_face_B = pin->GetOrAddBoolean("boundaries", "clean_face_B_" + bname, (btype == "outflow"));
195195
params.Add("clean_face_B_"+bname, clean_face_B);
196196
// Forcibly reconnect field loops that get trapped around the polar boundary
197-
bool reconnect_B3 = pin->GetOrAddBoolean("boundaries", "reconnect_B3_" + bname, false);
197+
// Needed to keep excised-flux transmitting boundaries stable
198+
bool reconnect_B3 = pin->GetOrAddBoolean("boundaries", "reconnect_B3_" + bname, excise_flux);
198199
params.Add("reconnect_B3_"+bname, reconnect_B3);
199200

200-
// Special EMF averaging. Allows B slippage, e.g. around pole for transmitting conditions
201-
// Useful for certain dirichlet conditions e.g. multizone
201+
// Special EMF averaging. Allows B3 to "slip" around the pole
202+
// Also useful to allow coherent motion even with Dirichlet boundaries, for e.g. multizone
202203
bool average_EMF = pin->GetOrAddBoolean("boundaries", "average_EMF_" + bname, (btype == "transmitting"));
203204
params.Add("average_EMF_"+bname, average_EMF);
204205
// Otherwise, always zero EMFs to prevent B field escaping the domain in polar/dirichlet bounds
@@ -705,6 +706,10 @@ TaskStatus KBoundaries::FixFlux(MeshData<Real> *md)
705706
if (pmb->boundary_flag[bface] == BoundaryFlag::user) {
706707
if (bdir != 2) throw std::runtime_error("Excised polar fluxes only fully implemented in X2!");
707708

709+
// Pack w/B to match indices with the `Flux.X` below
710+
// We won't *update* B field though
711+
auto &F = rc->PackVariablesAndFluxes({Metadata::WithFluxes}, cons_map);
712+
708713
// Going to need the primitive vars
709714
PackIndexMap prims_map;
710715
std::vector<MetadataFlag> prims_flags = {Metadata::GetUserFlag("Primitive"), Metadata::Cell};
@@ -771,7 +776,8 @@ TaskStatus KBoundaries::FixFlux(MeshData<Real> *md)
771776

772777
// Use LLF flux
773778
PLOOP {
774-
F.flux(dir, ip, k, j, i) = Flux::llf(Fl_all(ip, k, j, i), Fr_all(ip, k, j, i),
779+
if (ip != m_u.B1 && ip != m_u.B2 && ip != m_u.B3)
780+
F.flux(dir, ip, k, j, i) = Flux::llf(Fl_all(ip, k, j, i), Fr_all(ip, k, j, i),
775781
cmax(dir-1, k, j, i), cmin(dir-1, k, j, i),
776782
Ul_all(ip, k, j, i), Ur_all(ip, k, j, i)) * 0.5;
777783
}
@@ -818,21 +824,19 @@ TaskStatus KBoundaries::FixFlux(MeshData<Real> *md)
818824

819825
// Use LLF flux
820826
PLOOP {
821-
F.flux(bdir, ip, k, j, i) = Flux::llf(Fl_all(ip, k, j, i), Fr_all(ip, k, j, i),
822-
cmax(bdir-1, k, j, i), cmin(bdir-1, k, j, i),
823-
Ul_all(ip, k, j, i), Ur_all(ip, k, j, i));
824-
// Reduce the X1 flux in a semi-consistent way
825-
const int jc = (binner) ? j_cell + 1 : j_cell;
826-
F.flux(X1DIR, ip, k, j_cell, i) *= 0.5
827-
* (G.gdet(Loci::face1, j_cell, i) + G.gdet(Loci::corner, jc, i)) / 2 / G.gdet(Loci::face1, j_cell, i);
828-
// This is also a decent guess, but less accurate than recalculating as above
829-
// F.flux(X3DIR, ip, k, j_cell, i) *= 0.5
830-
// * G.gdet(loc, j_cell, i) / G.gdet(Loci::center, j_cell, i);
827+
if (ip != m_u.B1 && ip != m_u.B2 && ip != m_u.B3) {
828+
F.flux(bdir, ip, k, j, i) = Flux::llf(Fl_all(ip, k, j, i), Fr_all(ip, k, j, i),
829+
cmax(bdir-1, k, j, i), cmin(bdir-1, k, j, i),
830+
Ul_all(ip, k, j, i), Ur_all(ip, k, j, i));
831+
// Reduce the X1 flux in a semi-consistent way
832+
const int jc = (binner) ? j_cell + 1 : j_cell;
833+
F.flux(X1DIR, ip, k, j_cell, i) *= 0.5
834+
* (G.gdet(Loci::face1, j_cell, i) + G.gdet(Loci::corner, jc, i)) / 2 / G.gdet(Loci::face1, j_cell, i);
835+
// This is also a decent guess, but less accurate than recalculating as above
836+
// F.flux(X3DIR, ip, k, j_cell, i) *= 0.5
837+
// * G.gdet(loc, j_cell, i) / G.gdet(Loci::center, j_cell, i);
838+
}
831839
}
832-
833-
// Account for the half-size in the timestep later
834-
cmax(bdir-1, k, j, i) *= 2;
835-
cmin(bdir-1, k, j, i) *= 2;
836840
}
837841
);
838842
// Then average to make absolutely sure fluxes match
@@ -904,7 +908,9 @@ void KBoundaries::AddSource(MeshData<Real> *md, MeshData<Real> *mdudt, IndexDoma
904908
b.ks = b.ke = (binner) ? bi.ks : bi.ke;
905909
}
906910

907-
auto &dUdt = rc->PackVariables({Metadata::WithFluxes});
911+
// The magnetic field is probably defined at faces; even if it's defined in cells,
912+
// we shouldn't be monkeying with it. We just do not adjust it here.
913+
auto &dUdt = rc->PackVariables({Metadata::GetUserFlag("HD"), Metadata::WithFluxes});
908914
const auto& G = pmb->coords;
909915
const Loci loc = (binner) ? Loci::outer_half : Loci::inner_half;
910916

kharma/driver/imex_step.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ TaskCollection KHARMADriver::MakeImExTaskCollection(BlockList_t &blocks, int sta
8383
// TODO these can now be reduced by including the var lists/flags which actually need to be allocated
8484
// TODO except the Copy they can be run on step 1 only
8585
if (stage == 1) {
86-
auto &base = pmesh->mesh_data.Get();
86+
auto &base = pmesh->mesh_data.Get("base");
8787
// Fluxes
8888
pmesh->mesh_data.Add("dUdt", base);
8989
for (int i = 1; i < integrator->nstages; i++)

kharma/driver/kharma_driver.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,9 @@ TaskID KHARMADriver::AddStateUpdate(TaskID& t_start, TaskList& tl, MeshData<Real
378378
auto t_copy_prims = t_update;
379379
auto pmb0 = md_full_step_init->GetBlockData(0)->GetBlockPointer();
380380
auto& pkgs = pmb0->packages.AllPackages();
381-
if (!pkgs.at("GRMHD")->Param<bool>("implicit")) {
381+
// If we're explicitly evolving, UtoP needs a guess (except Kastaun inverter)
382+
if (!pkgs.at("GRMHD")->Param<bool>("implicit") &&
383+
pkgs.at("Inverter")->Param<Inverter::Type>("inverter_type") != Inverter::Type::kastaun) {
382384
t_copy_prims = tl.AddTask(t_start, Copy<MeshData<Real>>,
383385
std::vector<MetadataFlag>({Metadata::GetUserFlag("HD"), Metadata::GetUserFlag("Primitive")}),
384386
md_sub_step_init, md_update);

kharma/driver/simple_step.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ TaskCollection KHARMADriver::MakeSimpleTaskCollection(BlockList_t &blocks, int s
4444
auto& flux_pkg = pkgs.at("Fluxes")->AllParams();
4545
auto& inverter_pkg = pkgs.at("Inverter")->AllParams();
4646
PARTHENON_REQUIRE(!pkgs.count("B_CT"), "Face-centered B not compatible with simple driver!");
47+
// TODO require we're not using B_Cleanup as transport too
4748
PARTHENON_REQUIRE(!pkgs.count("Electrons"), "Electrons not compatible with simple driver!");
4849
PARTHENON_REQUIRE(!flux_pkg.Get<bool>("use_fofc"), "Flux corrections not compatible with simple driver!");
4950
PARTHENON_REQUIRE(inverter_pkg.Get<Inverter::Type>("inverter_type") == Inverter::Type::kastaun,

kharma/floors/floors.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class Prescription {
102102
// Constant sanity limits
103103
Real rho_min_const, u_min_const;
104104
// Purely geometric limits
105-
Real rho_min_geom, u_min_geom, r_char;
105+
Real rho_min_geom, u_min_geom, r_char, floors_switch_r;
106106
// Dynamic limits on magnetization/temperature
107107
Real bsq_over_rho_max, bsq_over_u_max, u_over_rho_max;
108108
// Limit entropy
@@ -113,7 +113,8 @@ class Prescription {
113113
bool use_r_char, temp_adjust_u, adjust_k;
114114
// Radius dependent floors?
115115
bool radius_dependent_floors;
116-
Real floors_switch_r;
116+
// Add density to respect the gamma ceiling?
117+
bool use_rho_to_slow;
117118
};
118119

119120
inline Prescription MakePrescription(parthenon::ParameterInput *pin, std::string block="floors")
@@ -163,6 +164,8 @@ inline Prescription MakePrescription(parthenon::ParameterInput *pin, std::string
163164
p.radius_dependent_floors = pin->GetOrAddBoolean("floors", "radius_dependent_floors", false);
164165
p.floors_switch_r = pin->GetOrAddReal("floors", "floors_switch_r", 50.);
165166

167+
p.use_rho_to_slow = pin->GetOrAddBoolean("floors", "use_rho_to_slow", true);
168+
166169
return p;
167170
}
168171

0 commit comments

Comments
 (0)