-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix offset of interpolation and use second order interpolation in x and y #570
Fix offset of interpolation and use second order interpolation in x and y #570
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks! see comments below.
src/fields/Fields.cpp
Outdated
const amrex::IntVect refinement_ratio = m_ref_ratio; | ||
|
||
const int interpol_order = 2; | ||
const int nguards_xy = std::max(1, Hipace::m_depos_order_xy); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this has to be the same value as m_slices_nguards, so it is dangerous to re-define it (if the other definition changes, this code might break). Could you use directly m_slices_nguards[0]
and m_slices_nguards[1]
? Or just
AMREX_ALWAYS_ASSERT(m_slices_nguards[0] == m_slices_nguards[1]);
const int nguards_xy = m_slices_nguards[0];
src/fields/Fields.cpp
Outdated
if (i==nx_fine_low) { | ||
x = plo[0] + (i+lo[0]+nguards_xy-0.5_rt)*dx[0]; | ||
} else if (i== nx_fine_high) { | ||
x = plo[0] + (i+lo[0]+nguards_xy+1.5_rt)*dx[0]; | ||
} else { | ||
x = plo[0] + (i+lo[0]+nguards_xy+0.5_rt)*dx[0]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add some comments to explain these values? Why always add guard cells? Why -0.5/+1.5? In particular, what puzzled me is that:
i x
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
nx_fine_low plo[0] + (nx_fine_low+lo[0]+nguards_xy-0.5_rt)*dx[0];
nx_fine_low+1 plo[0] + (nx_fine_low+lo[0]+nguards_xy+1.5_rt)*dx[0]; # the one above + 2*dx
nx_fine_low+2 plo[0] + (nx_fine_low+lo[0]+nguards_xy+2.5_rt)*dx[0]; # the one above + 1*dx
nx_fine_low+3 plo[0] + (nx_fine_low+lo[0]+nguards_xy+3.5_rt)*dx[0]; # the one above + 1*dx
etc.
Is this expected? Same question around nx_fine_high
, and for the y direction.
src/fields/Fields.cpp
Outdated
const int j_cell = compute_shape_factor<interpol_order>(sx_cell, | ||
xmid+nguards_xy-0.5_rt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain why this is xmid+nguards_xy-0.5_rt
? And maybe add a comment to clarify?
This PR fixes an issue in the interpolation:
Not the value of the position of the boundary of the fine grid must be interpolated from the coarse grid to fine grid, but the value at the position of the guard cell (on the fine grid) must be interpolated from the coarse to the fine grid.
A second order interpolation in x and y via a stencil was implemented. It is much clearer to read and will allow for a simplification in the upcoming longitudinal refinement in #565.
By fixing the guard cells, this PR is now correct for all deposition orders. Additionally, in the definition of the Poisson solver, the length of the problem was assessed in a level-agnostic way, which gave the wrong result for level 1, leading to the ripples we saw at the boundary. Using the correct length resolves this issue.
It can be seen, that there is still some very slight shift. This is caused by the imperfection in rho. If I hard-code rho to 1, it gives flawless results:
The correct handling of rho at the boundaries will be fixed in an upcoming PR.
const
isconst
)