@@ -278,25 +278,46 @@ void linear_interpolate_to_particle_z (const P& p,
278278 amrex::ignore_unused (ly);
279279 int const j = p.idata (0 );
280280
281- amrex::Real hlo_xlo = amrex::Real (0.25 )
282- * ( height_arr (i0 , j , k)
283- + height_arr (i0 + (!(is_nodal[d][0 ])) , j , k)
284- + height_arr (i0 , j + (!is_nodal[d][1 ]) , k)
285- + height_arr (i0 + (!(is_nodal[d][0 ])) , j + (!is_nodal[d][1 ]) , k) );
286-
287- amrex::Real hlo_xhi = amrex::Real (0.25 )
288- * ( height_arr (i0 + 1 , j , k )
289- + height_arr (i0 + 1 + (!(is_nodal[d][0 ])) , j , k )
290- + height_arr (i0 + 1 , j + (!is_nodal[d][1 ]), k )
291- + height_arr (i0 + 1 + (!(is_nodal[d][0 ])) , j + (!is_nodal[d][1 ]), k ) );
292-
281+ int j0 = j;
293282
294283 amrex::Real const xint = lx - static_cast <Real>(i0);
295284 amrex::Real sx[] = { amrex::Real (1 .) - xint, xint};
296- amrex::Real height_at_px = sx[0 ] * hlo_xlo + sx[1 ] * hlo_xhi;
297285
298- int const j0 = (amrex::Real (p.pos (1 )) >= height_at_px) ? j : j-1 ;
286+ // hlo holds the height of the face-based velocity at the relevant face center, e.g.
287+ // for u it holds the height of the x-face centers of the two cells that will contribute
288+ // for v it holds the height of the y-face centers of the two cells that will contribute
289+ //
290+ // height_at_px is then the value of hlo interpolated to the (i) of the particle location
291+ //
292+ // We only use height_at_px to determine which cells (in the j-direction) we should use for interpolation
293+ // -- but ONLY for the lateral velocities because otherwise we risk using vertical velocity below the sfc
294+ //
295+ if (d != AMREX_SPACEDIM-1 ) {
296+ amrex::Real hlo_xlo = amrex::Real (0.25 )
297+ * ( height_arr (i0 , j , k)
298+ + height_arr (i0 + (!(is_nodal[d][0 ])) , j , k)
299+ + height_arr (i0 , j + (!is_nodal[d][1 ]) , k)
300+ + height_arr (i0 + (!(is_nodal[d][0 ])) , j + (!is_nodal[d][1 ]) , k) );
301+
302+ amrex::Real hlo_xhi = amrex::Real (0.25 )
303+ * ( height_arr (i0 + 1 , j , k )
304+ + height_arr (i0 + 1 + (!(is_nodal[d][0 ])) , j , k )
305+ + height_arr (i0 + 1 , j + (!is_nodal[d][1 ]), k )
306+ + height_arr (i0 + 1 + (!(is_nodal[d][0 ])) , j + (!is_nodal[d][1 ]), k ) );
299307
308+ amrex::Real height_at_px = sx[0 ] * hlo_xlo + sx[1 ] * hlo_xhi;
309+
310+ if (amrex::Real (p.pos (1 )) < height_at_px) {j0 = j-1 ;}
311+
312+ } // if not vertical direction
313+
314+ // ht holds the heights of the face-based velocity at the relevant face centers, e.g.
315+ // for u it holds the height of the x-face centers of the four cells that will contribute
316+ // for v it holds the height of the y-face centers of the four cells that will contribute
317+ //
318+ // ht differs from hlo in that it uses the correct j0 which may be different from k above
319+ // AND it computes all 4 values needed for 2D interpolation (hlo held only the lower 2)
320+ //
300321 int yctr = 0 ;
301322 amrex::Real ht[4 ];
302323 for (int ii=0 ; ii < 2 ; ++ii) {
@@ -324,28 +345,52 @@ void linear_interpolate_to_particle_z (const P& p,
324345 amrex::Real sx[] = { amrex::Real (1 .) - xint, xint};
325346 amrex::Real sy[] = { amrex::Real (1 .) - yint, yint};
326347
327- amrex::Real hlo[4 ];
328- int ilo = 0 ;
329- amrex::Real height_at_pxy = 0 .;
330- for (int ii = 0 ; ii < 2 ; ++ii) {
331- for (int jj = 0 ; jj < 2 ; ++jj) {
332- hlo[ilo] = amrex::Real (0.125 )
333- * ( height_arr (i0 + ii , j0 + jj , k )
334- + height_arr (i0 + ii + (!is_nodal[d][0 ]), j0 + jj , k )
335- + height_arr (i0 + ii , j0 + jj + (!is_nodal[d][1 ]), k )
336- + height_arr (i0 + ii + (!is_nodal[d][0 ]), j0 + jj + (!is_nodal[d][1 ]), k )
337- + height_arr (i0 + ii , j0 + jj , k + (!is_nodal[d][2 ]))
338- + height_arr (i0 + ii + (!is_nodal[d][0 ]), j0 + jj , k + (!is_nodal[d][2 ]))
339- + height_arr (i0 + ii , j0 + jj + (!is_nodal[d][1 ]), k + (!is_nodal[d][2 ]))
340- + height_arr (i0 + ii + (!is_nodal[d][0 ]), j0 + jj + (!is_nodal[d][1 ]), k + (!is_nodal[d][2 ]))
341- );
342- height_at_pxy += hlo[ilo] * sx[ii] * sy[jj];
343- ++ilo;
348+ int k0 = k;
349+
350+ // hlo holds the height of the face-based velocity at the relevant face center, e.g.
351+ // for u it holds the height of the x-face centers of the four cells that will contribute
352+ // for v it holds the height of the y-face centers of the four cells that will contribute
353+ // for w it holds the height of the z-face centers of the four cells that will contribute
354+ //
355+ // height_at_pxy is then the value of hlo interpolated to the (i,j) of the particle location
356+ //
357+ // We use height_at_pxy to determine which cells (in the k-direction) we should use for interpolation
358+ // -- but ONLY for the lateral velocities because otherwise we risk using vertical velocity below the sfc
359+ //
360+
361+ if (d != AMREX_SPACEDIM-1 ) {
362+ amrex::Real hlo[4 ];
363+ int ilo = 0 ;
364+ amrex::Real height_at_pxy = 0 .;
365+ for (int ii = 0 ; ii < 2 ; ++ii) {
366+ for (int jj = 0 ; jj < 2 ; ++jj) {
367+ hlo[ilo] = amrex::Real (0.125 )
368+ * ( height_arr (i0 + ii , j0 + jj , k )
369+ + height_arr (i0 + ii + (!is_nodal[d][0 ]), j0 + jj , k )
370+ + height_arr (i0 + ii , j0 + jj + (!is_nodal[d][1 ]), k )
371+ + height_arr (i0 + ii + (!is_nodal[d][0 ]), j0 + jj + (!is_nodal[d][1 ]), k )
372+ + height_arr (i0 + ii , j0 + jj , k + (!is_nodal[d][2 ]))
373+ + height_arr (i0 + ii + (!is_nodal[d][0 ]), j0 + jj , k + (!is_nodal[d][2 ]))
374+ + height_arr (i0 + ii , j0 + jj + (!is_nodal[d][1 ]), k + (!is_nodal[d][2 ]))
375+ + height_arr (i0 + ii + (!is_nodal[d][0 ]), j0 + jj + (!is_nodal[d][1 ]), k + (!is_nodal[d][2 ]))
376+ );
377+ height_at_pxy += hlo[ilo] * sx[ii] * sy[jj];
378+ ++ilo;
379+ }
344380 }
345- }
346381
347- int const k0 = (amrex::Real (p.pos (2 )) >= height_at_pxy ) ? k : k-1 ;
382+ if (amrex::Real (p.pos (2 )) < height_at_pxy ) {k0 = k-1 ;}
383+
384+ } // if not vertical direction
348385
386+ // ht holds the heights of the face-based velocity at the relevant face centers, e.g.
387+ // for u it holds the height of the x-face centers of the eight cells that will contribute
388+ // for v it holds the height of the y-face centers of the eight cells that will contribute
389+ // for w it holds the height of the z-face centers of the eight cells that will contribute
390+ //
391+ // ht differs from hlo in that it uses the correct k0 which may be different from k above
392+ // AND it computes all 8 values needed for 3D interpolation (hlo held only the lower 4)
393+ //
349394 int zctr = 0 ;
350395 amrex::Real ht[8 ];
351396 for (int ii = 0 ; ii < 2 ; ++ii) {
0 commit comments