@@ -173,8 +173,7 @@ std::shared_ptr<KHARMAPackage> KBoundaries::Initialize(ParameterInput *pin, std:
173173 // Ensure fluxes through the zero-size face at the pole are zero
174174 bool zero_flux = pin->GetOrAddBoolean (" boundaries" , " zero_flux_" + bname, zero_polar_flux && bdir == X2DIR);
175175 params.Add (" zero_flux_" + bname, zero_flux);
176-
177- // Ensure fluxes through the zero-size face at the pole are zero
176+ // OR allow them via faux-excision
178177 bool excise_flux = pin->GetOrAddBoolean (" boundaries" , " excise_flux_" + bname, excise_polar_flux && bdir == X2DIR);
179178 params.Add (" excise_flux_" + bname, excise_flux);
180179
@@ -196,8 +195,8 @@ std::shared_ptr<KHARMAPackage> KBoundaries::Initialize(ParameterInput *pin, std:
196195 bool reconnect_B3 = pin->GetOrAddBoolean (" boundaries" , " reconnect_B3_" + bname, false );
197196 params.Add (" reconnect_B3_" +bname, reconnect_B3);
198197
199- // Special EMF averaging. Allows B slippage, e.g. around pole for transmitting conditions
200- // Useful for certain dirichlet conditions e.g. multizone
198+ // Special EMF averaging. Allows B3 to "slip" around the pole
199+ // Also useful to allow coherent motion even with Dirichlet boundaries, for e.g. multizone
201200 bool average_EMF = pin->GetOrAddBoolean (" boundaries" , " average_EMF_" + bname, (btype == " transmitting" ));
202201 params.Add (" average_EMF_" +bname, average_EMF);
203202 // Otherwise, always zero EMFs to prevent B field escaping the domain in polar/dirichlet bounds
@@ -704,6 +703,10 @@ TaskStatus KBoundaries::FixFlux(MeshData<Real> *md)
704703 if (pmb->boundary_flag [bface] == BoundaryFlag::user) {
705704 if (bdir != 2 ) throw std::runtime_error (" Excised polar fluxes only fully implemented in X2!" );
706705
706+ // Pack w/B to match indices with the `Flux.X` below
707+ // We won't *update* B field though
708+ auto &F = rc->PackVariablesAndFluxes ({Metadata::WithFluxes}, cons_map);
709+
707710 // Going to need the primitive vars
708711 PackIndexMap prims_map;
709712 std::vector<MetadataFlag> prims_flags = {Metadata::GetUserFlag (" Primitive" ), Metadata::Cell};
@@ -770,7 +773,8 @@ TaskStatus KBoundaries::FixFlux(MeshData<Real> *md)
770773
771774 // Use LLF flux
772775 PLOOP {
773- F.flux (dir, ip, k, j, i) = Flux::llf (Fl_all (ip, k, j, i), Fr_all (ip, k, j, i),
776+ if (ip != m_u.B1 && ip != m_u.B2 && ip != m_u.B3 )
777+ F.flux (dir, ip, k, j, i) = Flux::llf (Fl_all (ip, k, j, i), Fr_all (ip, k, j, i),
774778 cmax (dir-1 , k, j, i), cmin (dir-1 , k, j, i),
775779 Ul_all (ip, k, j, i), Ur_all (ip, k, j, i)) * 0.5 ;
776780 }
@@ -817,21 +821,19 @@ TaskStatus KBoundaries::FixFlux(MeshData<Real> *md)
817821
818822 // Use LLF flux
819823 PLOOP {
820- F.flux (bdir, ip, k, j, i) = Flux::llf (Fl_all (ip, k, j, i), Fr_all (ip, k, j, i),
821- cmax (bdir-1 , k, j, i), cmin (bdir-1 , k, j, i),
822- Ul_all (ip, k, j, i), Ur_all (ip, k, j, i));
823- // Reduce the X1 flux in a semi-consistent way
824- const int jc = (binner) ? j_cell + 1 : j_cell;
825- F.flux (X1DIR, ip, k, j_cell, i) *= 0.5
826- * (G.gdet (Loci::face1, j_cell, i) + G.gdet (Loci::corner, jc, i)) / 2 / G.gdet (Loci::face1, j_cell, i);
827- // This is also a decent guess, but less accurate than recalculating as above
828- // F.flux(X3DIR, ip, k, j_cell, i) *= 0.5
829- // * G.gdet(loc, j_cell, i) / G.gdet(Loci::center, j_cell, i);
824+ if (ip != m_u.B1 && ip != m_u.B2 && ip != m_u.B3 ) {
825+ F.flux (bdir, ip, k, j, i) = Flux::llf (Fl_all (ip, k, j, i), Fr_all (ip, k, j, i),
826+ cmax (bdir-1 , k, j, i), cmin (bdir-1 , k, j, i),
827+ Ul_all (ip, k, j, i), Ur_all (ip, k, j, i));
828+ // Reduce the X1 flux in a semi-consistent way
829+ const int jc = (binner) ? j_cell + 1 : j_cell;
830+ F.flux (X1DIR, ip, k, j_cell, i) *= 0.5
831+ * (G.gdet (Loci::face1, j_cell, i) + G.gdet (Loci::corner, jc, i)) / 2 / G.gdet (Loci::face1, j_cell, i);
832+ // This is also a decent guess, but less accurate than recalculating as above
833+ // F.flux(X3DIR, ip, k, j_cell, i) *= 0.5
834+ // * G.gdet(loc, j_cell, i) / G.gdet(Loci::center, j_cell, i);
835+ }
830836 }
831-
832- // Account for the half-size in the timestep later
833- cmax (bdir-1 , k, j, i) *= 2 ;
834- cmin (bdir-1 , k, j, i) *= 2 ;
835837 }
836838 );
837839 // Then average to make absolutely sure fluxes match
@@ -903,7 +905,9 @@ void KBoundaries::AddSource(MeshData<Real> *md, MeshData<Real> *mdudt, IndexDoma
903905 b.ks = b.ke = (binner) ? bi.ks : bi.ke ;
904906 }
905907
906- auto &dUdt = rc->PackVariables ({Metadata::WithFluxes});
908+ // The magnetic field is probably defined at faces; even if it's defined in cells,
909+ // we shouldn't be monkeying with it. We just do not adjust it here.
910+ auto &dUdt = rc->PackVariables ({Metadata::GetUserFlag (" HD" ), Metadata::WithFluxes});
907911 const auto & G = pmb->coords ;
908912 const Loci loc = (binner) ? Loci::outer_half : Loci::inner_half;
909913
0 commit comments