@@ -38,12 +38,19 @@ ShiftedMetricInterp::ShiftedMetricInterp(Mesh& mesh, CELL_LOC location_in,
3838 Options* opt)
3939 : ParallelTransform(mesh, opt), location(location_in), zShift(std::move(zShift_in)),
4040 zlength(zlength_in), ydown_index(mesh.ystart) {
41+
42+ if (mesh.getNZPE () > 1 ) {
43+ throw BoutException (" ShiftedMetricInterp only works with 1 processor in Z" );
44+ }
45+
4146 // check the coordinate system used for the grid data source
4247 ShiftedMetricInterp::checkInputGrid ();
4348
4449 // Allocate space for interpolator cache: y-guard cells in each direction
4550 parallel_slice_interpolators.resize (mesh.ystart * 2 );
4651
52+ const BoutReal z_factor = static_cast <BoutReal>(mesh.GlobalNzNoBoundaries ) / zlength;
53+
4754 // Create the Interpolation objects and set whether they go up or down the
4855 // magnetic field
4956 auto & interp_options = options[" zinterpolation" ];
@@ -62,26 +69,25 @@ ShiftedMetricInterp::ShiftedMetricInterp(Mesh& mesh, CELL_LOC location_in,
6269
6370 // Find the index positions where the magnetic field line intersects the x-z plane
6471 // y_offset points up
65- Field3D zt_prime_up (&mesh), zt_prime_down (&mesh);
72+ Field3D zt_prime_up (&mesh);
73+ Field3D zt_prime_down (&mesh);
6674 zt_prime_up.allocate ();
6775 zt_prime_down.allocate ();
6876
6977 for (const auto & i : zt_prime_up.getRegion (RGN_NOY)) {
7078 // Field line moves in z by an angle zShift(i,j+1)-zShift(i,j) when going
7179 // from j to j+1, but we want the shift in index-space
72- zt_prime_up[i] = static_cast <BoutReal>(i.z ())
73- + (zShift[i.yp (y_offset + 1 )] - zShift[i])
74- * static_cast <BoutReal>(mesh.GlobalNz ) / zlength;
80+ zt_prime_up[i] = static_cast <BoutReal>(mesh.getGlobalZIndexNoBoundaries (i.z ()))
81+ + ((zShift[i.yp (y_offset + 1 )] - zShift[i]) * z_factor);
7582 }
7683
7784 parallel_slice_interpolators[yup_index + y_offset]->calcWeights (zt_prime_up);
7885
7986 for (const auto & i : zt_prime_down.getRegion (RGN_NOY)) {
8087 // Field line moves in z by an angle -(zShift(i,j)-zShift(i,j-1)) when going
8188 // from j to j-1, but we want the shift in index-space
82- zt_prime_down[i] = static_cast <BoutReal>(i.z ())
83- - (zShift[i] - zShift[i.ym (y_offset + 1 )])
84- * static_cast <BoutReal>(mesh.GlobalNz ) / zlength;
89+ zt_prime_down[i] = static_cast <BoutReal>(mesh.getGlobalZIndexNoBoundaries (i.z ()))
90+ - ((zShift[i] - zShift[i.ym (y_offset + 1 )]) * z_factor);
8591 }
8692
8793 parallel_slice_interpolators[ydown_index + y_offset]->calcWeights (zt_prime_down);
@@ -93,15 +99,16 @@ ShiftedMetricInterp::ShiftedMetricInterp(Mesh& mesh, CELL_LOC location_in,
9399 interp_from_aligned =
94100 ZInterpolationFactory::getInstance ().create (&interp_options, 0 , &mesh);
95101
96- Field3D zt_prime_to (&mesh), zt_prime_from (&mesh);
102+ Field3D zt_prime_to (&mesh);
103+ Field3D zt_prime_from (&mesh);
97104 zt_prime_to.allocate ();
98105 zt_prime_from.allocate ();
99106
100107 for (const auto & i : zt_prime_to) {
101108 // Field line moves in z by an angle zShift(i,j) when going
102109 // from y0 to y(j), but we want the shift in index-space
103- zt_prime_to[i] = static_cast <BoutReal>(i.z ())
104- + zShift[i] * static_cast <BoutReal>(mesh. GlobalNz ) / zlength ;
110+ zt_prime_to[i] = static_cast <BoutReal>(mesh. getGlobalZIndexNoBoundaries ( i.z () ))
111+ + ( zShift[i] * z_factor) ;
105112 }
106113
107114 interp_to_aligned->calcWeights (zt_prime_to);
@@ -110,8 +117,8 @@ ShiftedMetricInterp::ShiftedMetricInterp(Mesh& mesh, CELL_LOC location_in,
110117 // Field line moves in z by an angle zShift(i,j) when going
111118 // from y0 to y(j), but we want the shift in index-space.
112119 // Here we reverse the shift, so subtract zShift
113- zt_prime_from[i] = static_cast <BoutReal>(i.z ())
114- - zShift[i] * static_cast <BoutReal>(mesh. GlobalNz ) / zlength ;
120+ zt_prime_from[i] = static_cast <BoutReal>(mesh. getGlobalZIndexNoBoundaries ( i.z () ))
121+ - ( zShift[i] * z_factor) ;
115122 }
116123
117124 interp_from_aligned->calcWeights (zt_prime_from);
0 commit comments