Vecops consistent cell default add more checking on location - #1308
Conversation
Ensure location of result set in vecops routines
| CELL_LOC outloc = (outloc_x == outloc_y && outloc_x == outloc_z) | ||
| ? result.x.getLocation() | ||
| : CELL_VSHIFT; | ||
| result.setLocation(outloc); |
There was a problem hiding this comment.
Do we also need to make sure the individual components are now all at the same/consistent location as well? (or result.y at least?)
There was a problem hiding this comment.
Nope, result.setLocation sets the location on each of the components.
| // The following probably belongs in the FDD? routines rather than here | ||
| // as we don't directly interact v and f. Note also no equivalent in Field3D | ||
| // version of this routine. | ||
| ASSERT1(outloc == f.getLocation()); |
There was a problem hiding this comment.
Could you say why the Field3D version doesn't have this?
There was a problem hiding this comment.
I don't know why -- it's just an observation to motivate why we might want to remove/move this!
There was a problem hiding this comment.
This is checked by indexFDD*, so we can remove it from here 👍
| result += FDDZ(metric->J * vcn.z, f, outloc); | ||
| result /= metric->J; | ||
|
|
||
| result.setLocation(outloc); |
There was a problem hiding this comment.
This is not necessary, result.location is set already by FDDX. In the Field*D difops this is just skipped, but we could put an ASSERT1(result.getLocation()==outloc) if you want to double-check?
There was a problem hiding this comment.
Ah yes the return is a Field not a vector -- I was busy adding these for the routines which return vectors and must have got carried away!
There was a problem hiding this comment.
Actually (at least in this branch) FDDX (and indexFDDX) on field2D doesn't set the location as far as I can tell.
There was a problem hiding this comment.
@ZedThree, @johnomotani should I fix this missing setLocation here or in a separate PR?
There was a problem hiding this comment.
Should note the 2D/3D DDX versions shouldn't need the location setting in vecops either as these are both set in either indexDDX and/or applyXDiff. It's just indexFDDX(Field2D) that doesn't set a location currently.
| result += FDDZ(metric->J * vcn.z, f, outloc, method); | ||
| result /= metric->J; | ||
|
|
||
| result.setLocation(outloc); |
There was a problem hiding this comment.
As above, this is not necessary.
|
Just to note that this requires #1306 to ensure location of |
|
|
||
| result.x = DDX(f, outloc); | ||
| result.y = DDY(f, outloc); | ||
| result.z = DDZ(f, outloc); |
There was a problem hiding this comment.
I think we need to handle outloc=CELL_VSHIFT here. I guess it wasn't needed before because Field2D could only have location CELL_CENTRE so Vector2D couldn't support CELL_VSHIFT. We also need to handle CELL_DEFAULT because we need to use outloc to set the location of result below. I'd do something like:
CELL_LOC outloc_x, outloc_y, outloc_z;
if (outloc == CELL_DEFAULT) {
outloc = f.getLocation();
}
if (outloc == CELL_VSHIFT) {
outloc_x = CELL_XLOW;
outloc_y = CELL_YLOW;
outloc_z = CELL_ZLOW;
} else {
outloc_x = outloc;
outloc_y = outloc;
outloc_z = outloc;
}
and then pass outloc_* through to DDX/DDY/DDZ below. I'd be inclined to do the same in Vector3D Grad() and get rid of the version with 3 outloc arguments.
There was a problem hiding this comment.
Vector2D can indeed have VSHIFT but there is no handling of it anywhere currently.
We could just use result.setLocation(result.x.getLocation()); to set the location at the end in the meantime. Currently VSHIFT isn't supported for this routine (it should throw if you try) -- changing this may be regarded as a bug fix or it may be a feature!
There was a problem hiding this comment.
I agree about trying to get rid of the three argument versions.
| Coordinates *metric_z = f.getCoordinates(outloc_z); | ||
|
|
||
| result.x = DDX(f, outloc_x) - | ||
| metric_x->g_12 * DDY(f, outloc_x) / SQ(metric_x->J * metric_x->Bxy); |
There was a problem hiding this comment.
This is going to fail for CELL_VSHIFT (actually in any case unless all the locations are the same) because DDY is not supported for CELL_CENTRE->CELL_XLOW, etc. (can't interpolate the input to a derivative because the input wouldn't have guard cells set, and can't interpolate the output because the output doesn't have guard cells set).
Maybe Grad_perp shouldn't have an outloc argument at all, since it can only produce output at f's location?
There was a problem hiding this comment.
That's a pain. Maybe a check with a nice exception message to say that setting the location is currently unsupported?
EDIT: and to put John's message in the documentation for this function
There was a problem hiding this comment.
Have just pushed a commit that tries to address this.
There was a problem hiding this comment.
Actually, this is more than a pain, it means CELL_VSHIFT is not terribly useful. Unfortunately, numerically, it is a useful staggering option. Sounds like we will need to put some future work into trying to support interpolating to orthogonal directions in order to better support CELL_VSHIFT
| const Vector2D V_dot_Grad(const Vector2D &v, const Vector2D &a, CELL_LOC outloc) { | ||
| TRACE("V_dot_Grad( Vector2D , Vector2D )"); | ||
|
|
||
| ASSERT1(outloc != CELL_VSHIFT); |
There was a problem hiding this comment.
agree with this one, we can't support outloc==CELL_VSHIFT.
| ASSERT1(outloc != CELL_VSHIFT); | ||
| if (outloc == CELL_DEFAULT) { | ||
| ASSERT1(outloc == v.getLocation() && outloc == a.getLocation()); | ||
| outloc = v.getLocation(); |
There was a problem hiding this comment.
Should these lines be the other way around? at the moment the ASSERT will always fail if outloc == CELL_DEFAULT. If the other way round, only need to check outloc==a.getLocation().
There was a problem hiding this comment.
Hmm, that does look strange I think it should perhaps be ?
if (outloc == CELL_DEFAULT) {
ASSERT1(v.getLocation() == a.getLocation());
outloc = v.getLocation();
}
There was a problem hiding this comment.
and we probably need to assert that v.getLocation isn't VSHIFT
There was a problem hiding this comment.
(possibly just move the outloc assert after the if block?)
There was a problem hiding this comment.
What combination of three locations are supported?
vandaat the same location, andoutloc == CELL_DEFAULT-- this should be fine- everything at
CELL_CENTRE-- this should be fine - everything at other locations? -- presumably fine?
vandaatCELL_CENTRE,outloc == CELL_?LOW? vice-versa? -- don't knowvatCELL_CENTRE,astaggered (and vice-versa),outloc == CELL_DEFAULT? -- don't know
If just first two, bring the assert above the if. Not sure about other cases yet.
There was a problem hiding this comment.
0669941 should address this. Essentially v and a have to be at the same location and outloc has to also refer to this location (or CELL_DEFAULT).
There was a problem hiding this comment.
Just to clarify, just the first three combinations above are supported?
There's a fair bit of information about supported locations coming out of the woodwork in this PR -- can some of it go in the doxygen comments?
There was a problem hiding this comment.
v and a at the same location, and outloc == CELL_DEFAULT or outloc==v.getLocation().
There was a problem hiding this comment.
I've just added some brief doxygen comments.
| ASSERT1(outloc != CELL_VSHIFT); | ||
| if (outloc == CELL_DEFAULT) { | ||
| ASSERT1(outloc == v.getLocation() && outloc == a.getLocation()); | ||
| outloc = v.getLocation(); |
There was a problem hiding this comment.
other way round again?
| ASSERT1(outloc != CELL_VSHIFT); | ||
| if (outloc == CELL_DEFAULT) { | ||
| ASSERT1(outloc == v.getLocation() && outloc == a.getLocation()); | ||
| outloc = v.getLocation(); |
There was a problem hiding this comment.
other way round again?
| ASSERT1(outloc != CELL_VSHIFT); | ||
| if (outloc == CELL_DEFAULT) { | ||
| ASSERT1(outloc == v.getLocation() && outloc == a.getLocation()); | ||
| outloc = v.getLocation(); |
There was a problem hiding this comment.
other way round again?
|
I've just pushed something that demos adding CELL_VSHIFT support to Grad(Field2D) and deprecates the three arg version of Grad(Field3D). I'll try to deprecate the other three arg routines, but let me know if you have any comments on these most recent changes. |
|
|
||
| const Vector3D Grad(const Field3D &f, CELL_LOC outloc_x, CELL_LOC outloc_y, | ||
| CELL_LOC outloc_z) { | ||
| const Vector3D DEPRECATED(Grad(const Field3D &f, CELL_LOC outloc_x, CELL_LOC outloc_y, |
There was a problem hiding this comment.
This should go on the declaration in the header rather than the implementation.
Also, the single-arg version needs to go in the header. Note that I think you'll need to remove the default values for the three-arg version and add one for the single-arg.
EDIT: sorry, latter paragraph applies to Grad_perp not this!
There was a problem hiding this comment.
Ah, forgot the header.
Should I remove deprecated from the source file and just put it on header?
There was a problem hiding this comment.
Also doesn't removing the default values break backwards compatibility?
ZedThree
left a comment
There was a problem hiding this comment.
DEPRECATED on declaration in header; add single-arg Grad_perp to header
|
Turns out the Does this mean we can remove it from the implementation without breaking anything? |
|
If I understand correctly, it basically doesn't make sense for This also highlights that we don't have any tests for |
Currently impossible to handle
|
Some big changes here. @johnomotani @d7919 are you both happy with the current state? I'm sure we've missed some edge cases, but vecops is lacking tests -- needs to be remedied for 4.3 |
|
I'm going to merge this shortly into the branch for #1293 and then we can review that PR in its entirety. |
Provides bugfixes to ensure the vector result has location set.
Also ensure copy/assignment of vectors updates the location of the result.