Use templates in index_derivs.cxx - #1290
Conversation
Advective and flux derivatives, which take v and f as inputs, had cases using yup/ydown fields for one of v and f, but not the other. These do not make sense as multiplication of a field in field-aligned coordinates with another in non-field-aligned coordinates is incorrect. Delete these cases and fall back to converting both v and f to field-aligned if either does not have yup/ydown fields.
Remove the intermediate variable result_fa in branch of interp_to that transforms to field-aligned variables. Just store the intermediate result in 'result' instead, to save memory.
In several y-derivatives where we have to convert the input to field-aligned coordinates, the result was not transformed back to the original coordinates.
In the unstaggered case, only the value of v is used, so yup/ydown fields for v are not needed.
Was previously a typo that resulted in using non-field-aligned f in VDDY, which is incorrect.
Previously these were incorrectly setting the location of their result to the location of the input variable. This commit changes this to use the specified output location. This probably did not cause bugs as the location was overridden in DDX/DDY/DDZ, etc.
The location of the result needs to be set before shifting it from field-aligned coordinates, if this is necessary. So it is safer to set the location to diffloc (or outloc where diffloc is not yet set) as soon as 'Field3D result' is declared. There are a couple of exceptions where the location is set after calling apply*diff (which should not be necessary, but does not hurt, except that it may hide errors setting location in apply*diff) where the location of 'result' would not be used anyway earlier in the method.
Add region arguments (where it is valid to give RGN_NOX or RGN_NOBNDRY) so functions like toFieldAligned/fromFieldAligned can be used both when y-guard cells have been set and when they have not. e.g. when using fromFieldAligned on the results of interpolation or derivatives, y-guard cells cannot be included, but when using toFieldAligned on the inputs to interpolation or derivatives, y-guard cells must be included.
This was used to set yup/ydown to point to the field itself. Used by ParallelTransformIdentity. It is unnecessary because there are field-aligned versions of all the operators, which can be used when hasYupYdown()==false. Removing the method simplifies several tests, which can now be just 'var.hasYupYdown()' where previously they also had to check 'var.yup() != var' and 'var.ydown() != var'. Also rename 'splitYupYdown()' to 'createYupYdown()' since it no longer makes sense to contrast 'split' with 'merge'.
Allows this method to be used for fields that do not have yup/ydown.
In interp_to() if region!=RGN_NOBNRDY there is a fudge to copy the guard cells from the input. We allow this, so don't invalidate the guard cells unless region==RGN_NOBNDRY. This commit also adds the invalidateGuards() to interp_to(Field2D) for consistency.
Previously if the 'loc' argument was CELL_DEFAULT, there could have been a problem with result.setLocation(loc).
Make sure the result is actually at the specified outloc argument, and
throw an exception if the combination of {vloc, inloc, outloc} is not
handled.
Remove intermediate 'result' field where it is not necessary.
|
Oops, created this before writing the description. Sorry! Since location was implemented fully for The set of changes in e9eeb5e seem like a straightforward win to me: they don't require any changes elsewhere in the code. Templating some of the y-derivatives (426b91a) required The changes to Field2D caused a bit of complication. I had to move the call to Finally, in a670e14 I found some template goodness that lets templated functions like |
Changes to enable using templates for more y-derivatives. Add methods hasYupYdown(), yup() and ydown() to Field2D. Add toFieldAligned(Field2D) and fromFieldAligned(Field2D) methods to ParallelTransform and Mesh.
The call to geometry() may require the ParallelTransform to be initialized, but the ParallelTransform (e.g. FCITransform) may require a Coordinates object in its constructor. However, the ParallelTransform does not require geometry() to have been called, so we can remove the circular dependency: (i) remove the call to geometry() from Coordinates::Coordinates() (ii) in Mesh::coordinates where the Coordinates objects are constructed, call the Coordinates constructor (iii) then call setParallelTransform() (iv) finally call geometry() This way by the time a Coordinates object is returned from Mesh, everything is set up properly.
Allows finding out from the Mesh* whether the ParallelTransform supports yup/ydown fields. This is used so that Field2D::hasYupYdown() returns true if yup/ydown are supported for Field3D and false if not; derivative operators on Field2Ds can then use the yup/ydown branch if supported for Field3D (so only 3 point stencils are required/allowed) and the to/fromFieldAligned branch otherwise.
Use std::conditional and std::is_same to define a promoteField template which can give the return type for templated functions with 2 field arguments that could be either Field2D or Field3D. The return type is Field2D if both arguments are Field2D and Field3D otherwise.
68fa467 to
a670e14
Compare
3e7b005 to
ab43f72
Compare
545aae5 to
79b5157
Compare
|
#1384 makes this PR redundant. |
No description provided.