@@ -336,9 +336,19 @@ std::shared_ptr<StateDescriptor> Initialize(ParameterInput *pin) {
336336 // packages.
337337 const bool mhd = pin->GetString (" hydro" , " fluid" ) == " glmmhd" ;
338338
339- PARTHENON_REQUIRE_THROWS (
340- pin->GetString (" parthenon/mesh" , " refinement" ) != " adaptive" ,
341- " Tracers/swarms currently only supported on non-adaptive meshes." );
339+ // Check if tracers/swarms are compatible with the mesh refinement type
340+ const std::string mesh_refinement = pin->GetString (" parthenon/mesh" , " refinement" );
341+ const bool is_adaptive = (mesh_refinement == " adaptive" );
342+
343+ bool is_cubic_refinement = false ;
344+ if (is_adaptive) {
345+ const std::string refinement_type = pin->GetString (" refinement" , " type" );
346+ is_cubic_refinement = (refinement_type == " cubic" );
347+ }
348+
349+ PARTHENON_REQUIRE_THROWS (!is_adaptive || is_cubic_refinement,
350+ " Tracers/swarms currently only supported on non-adaptive "
351+ " meshes or with cubic adaptive refinement." );
342352
343353 if (mhd) {
344354 tracers_pkg->AddSwarmValue (" B_x" , swarm_name, real_swarmvalue_metadata);
@@ -347,6 +357,12 @@ std::shared_ptr<StateDescriptor> Initialize(ParameterInput *pin) {
347357 tracers_pkg->AddSwarmValue (" rot_B_x" , swarm_name, real_swarmvalue_metadata);
348358 tracers_pkg->AddSwarmValue (" rot_B_y" , swarm_name, real_swarmvalue_metadata);
349359 tracers_pkg->AddSwarmValue (" rot_B_z" , swarm_name, real_swarmvalue_metadata);
360+ tracers_pkg->AddSwarmValue (" tens_B_x" , swarm_name, real_swarmvalue_metadata);
361+ tracers_pkg->AddSwarmValue (" tens_B_y" , swarm_name, real_swarmvalue_metadata);
362+ tracers_pkg->AddSwarmValue (" tens_B_z" , swarm_name, real_swarmvalue_metadata);
363+ tracers_pkg->AddSwarmValue (" grad_B2_x" , swarm_name, real_swarmvalue_metadata);
364+ tracers_pkg->AddSwarmValue (" grad_B2_y" , swarm_name, real_swarmvalue_metadata);
365+ tracers_pkg->AddSwarmValue (" grad_B2_z" , swarm_name, real_swarmvalue_metadata);
350366 }
351367
352368 auto nscalars = pin->GetOrAddInteger (" hydro" , " nscalars" , 0 );
@@ -1010,13 +1026,25 @@ TaskStatus FillTracers(MeshData<Real> *md, parthenon::SimTime &tm) {
10101026 auto rot_B_x = vel_x.Get ();
10111027 auto rot_B_y = vel_x.Get ();
10121028 auto rot_B_z = vel_x.Get ();
1029+ auto tens_B_x = vel_x.Get ();
1030+ auto tens_B_y = vel_x.Get ();
1031+ auto tens_B_z = vel_x.Get ();
1032+ auto grad_B2_x = vel_x.Get ();
1033+ auto grad_B2_y = vel_x.Get ();
1034+ auto grad_B2_z = vel_x.Get ();
10131035 if (mhd) {
10141036 B_x = swarm->Get <Real>(" B_x" ).Get ();
10151037 B_y = swarm->Get <Real>(" B_y" ).Get ();
10161038 B_z = swarm->Get <Real>(" B_z" ).Get ();
10171039 rot_B_x = swarm->Get <Real>(" rot_B_x" ).Get ();
10181040 rot_B_y = swarm->Get <Real>(" rot_B_y" ).Get ();
10191041 rot_B_z = swarm->Get <Real>(" rot_B_z" ).Get ();
1042+ tens_B_x = swarm->Get <Real>(" tens_B_x" ).Get ();
1043+ tens_B_y = swarm->Get <Real>(" tens_B_y" ).Get ();
1044+ tens_B_z = swarm->Get <Real>(" tens_B_z" ).Get ();
1045+ grad_B2_x = swarm->Get <Real>(" grad_B2_x" ).Get ();
1046+ grad_B2_y = swarm->Get <Real>(" grad_B2_y" ).Get ();
1047+ grad_B2_z = swarm->Get <Real>(" grad_B2_z" ).Get ();
10201048 }
10211049
10221050 auto &density = swarm->Get <Real>(" density" ).Get ();
@@ -1136,6 +1164,61 @@ TaskStatus FillTracers(MeshData<Real> *md, parthenon::SimTime &tm) {
11361164 rot_B_x (n) = rotBx;
11371165 rot_B_y (n) = rotBy;
11381166 rot_B_z (n) = rotBz;
1167+
1168+ // --- Magnetic pressure gradient: -grad(B^2 / 2) ---
1169+ const Real dB2_dx =
1170+ ((prim_pack (b, IB1, k, j, i + 1 ) * prim_pack (b, IB1, k, j, i + 1 ) +
1171+ prim_pack (b, IB2, k, j, i + 1 ) * prim_pack (b, IB2, k, j, i + 1 ) +
1172+ ((ndim == 3 ) ? prim_pack (b, IB3, k, j, i + 1 ) *
1173+ prim_pack (b, IB3, k, j, i + 1 )
1174+ : 0.0 )) -
1175+ (prim_pack (b, IB1, k, j, i - 1 ) * prim_pack (b, IB1, k, j, i - 1 ) +
1176+ prim_pack (b, IB2, k, j, i - 1 ) * prim_pack (b, IB2, k, j, i - 1 ) +
1177+ ((ndim == 3 ) ? prim_pack (b, IB3, k, j, i - 1 ) *
1178+ prim_pack (b, IB3, k, j, i - 1 )
1179+ : 0.0 ))) /
1180+ (2.0 * dx);
1181+
1182+ const Real dB2_dy =
1183+ ((prim_pack (b, IB1, k, j + 1 , i) * prim_pack (b, IB1, k, j + 1 , i) +
1184+ prim_pack (b, IB2, k, j + 1 , i) * prim_pack (b, IB2, k, j + 1 , i) +
1185+ ((ndim == 3 ) ? prim_pack (b, IB3, k, j + 1 , i) *
1186+ prim_pack (b, IB3, k, j + 1 , i)
1187+ : 0.0 )) -
1188+ (prim_pack (b, IB1, k, j - 1 , i) * prim_pack (b, IB1, k, j - 1 , i) +
1189+ prim_pack (b, IB2, k, j - 1 , i) * prim_pack (b, IB2, k, j - 1 , i) +
1190+ ((ndim == 3 ) ? prim_pack (b, IB3, k, j - 1 , i) *
1191+ prim_pack (b, IB3, k, j - 1 , i)
1192+ : 0.0 ))) /
1193+ (2.0 * dy);
1194+
1195+ const Real dB2_dz = (ndim == 3 ) ? ((prim_pack (b, IB1, k + 1 , j, i) *
1196+ prim_pack (b, IB1, k + 1 , j, i) +
1197+ prim_pack (b, IB2, k + 1 , j, i) *
1198+ prim_pack (b, IB2, k + 1 , j, i) +
1199+ prim_pack (b, IB3, k + 1 , j, i) *
1200+ prim_pack (b, IB3, k + 1 , j, i)) -
1201+ (prim_pack (b, IB1, k - 1 , j, i) *
1202+ prim_pack (b, IB1, k - 1 , j, i) +
1203+ prim_pack (b, IB2, k - 1 , j, i) *
1204+ prim_pack (b, IB2, k - 1 , j, i) +
1205+ prim_pack (b, IB3, k - 1 , j, i) *
1206+ prim_pack (b, IB3, k - 1 , j, i))) /
1207+ (2.0 * dz)
1208+ : 0.0 ;
1209+
1210+ grad_B2_x (n) = dB2_dx;
1211+ grad_B2_y (n) = dB2_dy;
1212+ grad_B2_z (n) = dB2_dz;
1213+
1214+ // --- Magnetic tension: (B · ∇)B ---
1215+ const Real tens_x = Bx * dBx_dx + By * dBx_dy + Bz * dBx_dz;
1216+ const Real tens_y = Bx * dBy_dx + By * dBy_dy + Bz * dBy_dz;
1217+ const Real tens_z = Bx * dBz_dx + By * dBz_dy + Bz * dBz_dz;
1218+
1219+ tens_B_x (n) = tens_x;
1220+ tens_B_y (n) = tens_y;
1221+ tens_B_z (n) = tens_z;
11391222 }
11401223
11411224 // Central differences using neighbors
0 commit comments