-
Notifications
You must be signed in to change notification settings - Fork 95
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 Field3D::setBoundaryTo parallel boundary conditions #2962
base: next
Are you sure you want to change the base?
Conversation
Didn't handle parallel boundaries correctly. Now handles input arguments with and without parallelslices. If the input doesn't have parallel slices then they should be cleared in the target field, and to/fromFieldAligned used to set Y boundaries in field-aligned coordinates.
Must clear P parallel slices or Grad_par will use them. Alternatively, setBoundaryTo should clear the parallel slices if they are not set in the argument.
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.
clang-tidy made some suggestions
src/field/field3d.cxx
Outdated
ASSERT1(hasParallelSlices()); | ||
|
||
for (auto& bndry : fieldmesh->getBoundariesPar()) { | ||
const Field3D& f3d_next = f3d.ynext(bndry->dir); |
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.
warning: no member named 'x' in 'BoundaryRegionPar' [clang-diagnostic-error]
const int x = bndry->x;
^
src/field/field3d.cxx
Outdated
|
||
for (auto& bndry : fieldmesh->getBoundariesPar()) { | ||
const Field3D& f3d_next = f3d.ynext(bndry->dir); | ||
Field3D& this_next = ynext(bndry->dir); |
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.
warning: no member named 'y' in 'BoundaryRegionPar' [clang-diagnostic-error]
const int y = bndry->y;
^
for (auto& bndry : fieldmesh->getBoundariesPar()) { | ||
const Field3D& f3d_next = f3d.ynext(bndry->dir); | ||
Field3D& this_next = ynext(bndry->dir); | ||
|
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.
warning: no member named 'z' in 'BoundaryRegionPar' [clang-diagnostic-error]
const int z = bndry->z;
^
clearParallelSlices(); | ||
|
||
// Shift into field-aligned coordinates to apply Y boundary conditions. | ||
|
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.
warning: loop variable name 'r' is too short, expected at least 2 characters [readability-identifier-length]
for (RangeIterator r = fieldmesh->iterateBndryLowerY(); !r.isDone(); r++) {
^
src/field/field3d.cxx
Outdated
for (RangeIterator r = fieldmesh->iterateBndryLowerY(); !r.isDone(); r++) { | ||
for (int jz = 0; jz < fieldmesh->LocalNz; jz++) { | ||
BoutReal val = 0.5 | ||
* (f3d_fa(r.ind, fieldmesh->ystart, jz) |
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.
warning: loop variable name 'r' is too short, expected at least 2 characters [readability-identifier-length]
for (RangeIterator r = fieldmesh->iterateBndryUpperY(); !r.isDone(); r++) {
^
src/field/field3d.cxx
Outdated
BoutReal val = 0.5 | ||
* (f3d_fa(r.ind, fieldmesh->ystart, jz) | ||
+ f3d_fa(r.ind, fieldmesh->ystart - 1, jz)); | ||
(*this)(r.ind, fieldmesh->ystart - 1, jz) = |
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.
warning: variable 'val' of type 'BoutReal' (aka 'double') can be declared 'const' [misc-const-correctness]
(*this)(r.ind, fieldmesh->ystart - 1, jz) = | |
BoutReal const val = 0.5 * (f3d_fa(r.ind, fieldmesh->yend, jz) + f3d_fa(r.ind, fieldmesh->yend + 1, jz)); |
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.
I thought the yboundary iterator had changed, but if it compiles it seems that has not yet been merged.
On a more general question, what is the purpose of this function? I do understand what it does, but why would one want to use it? Why not simply copy the boundaries? In what cases is this useful?
src/field/field3d.cxx
Outdated
for (auto& bndry : fieldmesh->getBoundariesPar()) { | ||
const Field3D& f3d_next = f3d.ynext(bndry->dir); | ||
Field3D& this_next = ynext(bndry->dir); | ||
|
||
for (bndry->first(); !bndry->isDone(); bndry->next()) { | ||
const int x = bndry->x; | ||
const int y = bndry->y; | ||
const int z = bndry->z; | ||
BoutReal val = 0.5 * (f3d(x, y, z) + f3d_next(x, y, z)); | ||
this_next(x, y, z) = 2. * val - (*this)(x, y, z); | ||
} | ||
} |
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.
I think this should be roughly the new syntax:
for (auto& bndry : fieldmesh->getBoundariesPar()) { | |
const Field3D& f3d_next = f3d.ynext(bndry->dir); | |
Field3D& this_next = ynext(bndry->dir); | |
for (bndry->first(); !bndry->isDone(); bndry->next()) { | |
const int x = bndry->x; | |
const int y = bndry->y; | |
const int z = bndry->z; | |
BoutReal val = 0.5 * (f3d(x, y, z) + f3d_next(x, y, z)); | |
this_next(x, y, z) = 2. * val - (*this)(x, y, z); | |
} | |
} | |
for (auto& region : fieldmesh->getBoundariesPar()) { | |
for (auto& pnt: region) { | |
pnt.dirichlet_o1(*this, pnt.interpolate_sheath_o1(f3d)); | |
} | |
} |
Co-authored-by: David Bold <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: David Bold <[email protected]>
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.
clang-tidy made some suggestions
for (int jy = fieldmesh->ystart; jy <= fieldmesh->yend; ++jy) { | ||
for (int jz = 0; jz < fieldmesh->LocalNz; jz++) { | ||
BoutReal const val = | ||
0.5 * (f3d(fieldmesh->xstart, jy, jz) + f3d(fieldmesh->xstart - 1, jy, jz)); |
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.
warning: expression result unused [clang-diagnostic-unused-value]
0.5 * (f3d(fieldmesh->xstart, jy, jz) + f3d(fieldmesh->xstart - 1, jy, jz));
^
} | ||
} | ||
} | ||
if (fieldmesh->lastX()) { |
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.
warning: use of undeclared identifier 'jy' [clang-diagnostic-error]
BoutReal const val = 0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz));
^
} | ||
} | ||
} | ||
if (fieldmesh->lastX()) { |
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.
warning: use of undeclared identifier 'jz' [clang-diagnostic-error]
BoutReal const val = 0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz));
^
} | ||
} | ||
} | ||
if (fieldmesh->lastX()) { |
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.
warning: use of undeclared identifier 'jy' [clang-diagnostic-error]
BoutReal const val = 0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz));
^
} | ||
} | ||
} | ||
if (fieldmesh->lastX()) { |
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.
warning: use of undeclared identifier 'jz' [clang-diagnostic-error]
BoutReal const val = 0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz));
^
if (fieldmesh->lastX()) { | ||
BoutReal const val = | ||
0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz)); | ||
for (int jz = 0; jz < fieldmesh->LocalNz; jz++) { | ||
BoutReal val = |
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.
warning: use of undeclared identifier 'jy' [clang-diagnostic-error]
(*this)(fieldmesh->xend + 1, jy, jz) =
^
// Set to this value | ||
(*this)(reg->x, reg->y, z) = | ||
2. * val - (*this)(reg->x - reg->bx, reg->y - reg->by, z); | ||
0.5 * (f3d(fieldmesh->xend, jy, jz) + f3d(fieldmesh->xend + 1, jy, jz)); |
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.
warning: use of undeclared identifier 'jy' [clang-diagnostic-error]
2. * val - (*this)(fieldmesh->xend, jy, jz);
^
} | ||
} | ||
} | ||
} | ||
|
||
// Y boundaries |
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.
warning: expected unqualified-id [clang-diagnostic-error]
if (f3d.hasParallelSlices()) {
^
BoutReal val = 0.5 * (f3d(x, y, z) + f3d_next(x, y + bndr->dir, z)); | ||
this_next(x, y + bndry->dir, z) = 2. * val - (*this)(x, y, z); | ||
} | ||
} |
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.
warning: expected unqualified-id [clang-diagnostic-error]
} else {
^
(*this)(r.ind, fieldmesh->yend + 1, jz) = | ||
2. * val - (*this)(r.ind, fieldmesh->yend, jz); | ||
} | ||
} |
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.
warning: extraneous closing brace ('}') [clang-diagnostic-error]
}
^
Thanks @dschwoerer ! What is being done is:
One option is to just copy the boundary cells, but then the boundary condition would be slightly different. I'm not sure which would be better behaved numerically. |
I see, so the assumption is that both fields are very similar. I have pushed a fix, either as an additional commit (https://github.com/boutproject/BOUT-dev/tree/fix-setboundaryto-fixup) or squashed to remove the broken commits from history, for easier bisecting in the future (https://github.com/boutproject/BOUT-dev/tree/fix-setboundaryto-rebase) |
One test is failing as it triggers the assertion about parallel slices:
|
Didn't handle parallel boundaries correctly. Now handles input arguments with and without parallelslices. If the input doesn't have parallel slices then they should be cleared in the target field, and to/fromFieldAligned used to set Y boundaries in field-aligned coordinates.
See discussion here of issue caused by previous implementation: bendudson/hermes-3@97a21fd