Skip to content

Use templates in index_derivs.cxx - #1290

Closed
johnomotani wants to merge 31 commits into
shiftedmetric-updatesfrom
index_derivs-templates
Closed

Use templates in index_derivs.cxx#1290
johnomotani wants to merge 31 commits into
shiftedmetric-updatesfrom
index_derivs-templates

Conversation

@johnomotani

Copy link
Copy Markdown
Contributor

No description provided.

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.
@johnomotani

johnomotani commented Sep 28, 2018

Copy link
Copy Markdown
Contributor Author

Oops, created this before writing the description. Sorry!

Since location was implemented fully for Field2D, the Field2D and Field3D versions of derivatives in index_derivs.cxx are basically identical. This PR uses templates to remove this duplication.

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 Field2D to have yup/ydown methods. Field2D::yup() and Field2D::ydown() just return a reference to the field itself. This seems sensible for ShiftedMetric, but possibly not for FCI? I guess FCI probably shouldn't use Field2D much anyway, although test-fci-slab does take derivatives of Field2D metric components in geometry(); I don't know if these will be correct?

The changes to Field2D caused a bit of complication. I had to move the call to geometry() out of the Coordinates constructor, because Field2D derivatives now need a ParallelTransform. Calling Coordinates() then setParallelTransform() then geometry() in Mesh::coordinates() where the Coordinates objects are created gets around this though.
The Field2D derivatives do need #1287 to get into the right branch though: #1287 removes the conditionals like ((&v.yup() != &v) || (&v.ydown() != &v)) which is needed since Field2D returns itself for yup and ydown, so any derivative with a Field2D would fall through to the to/fromFieldAligned branch otherwise.

Finally, in a670e14 I found some template goodness that lets templated functions like indexVDDX specialize to mixed Field2D/Field3D arguments, like indexVDDX(Field2D, Field3D) without converting Field2D->Field3D and with the return type being Field2D if both arguments are Field2D and Field3D otherwise. This uses the template promoteField<T1,T2> defined in field3d.hxx to get the right return type.

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.
@johnomotani
johnomotani force-pushed the index_derivs-templates branch from 68fa467 to a670e14 Compare September 28, 2018 16:07
@johnomotani johnomotani added the work in progress Not ready for merging label Oct 9, 2018
@johnomotani

johnomotani commented Oct 9, 2018

Copy link
Copy Markdown
Contributor Author

Just to note: this PR will need re-jigging for changes in #1302, #1306 before we can merge. (if we want this template stuff at all...)

@johnomotani
johnomotani force-pushed the shiftedmetric-updates branch from 3e7b005 to ab43f72 Compare October 9, 2018 15:07
@johnomotani
johnomotani force-pushed the shiftedmetric-updates branch 2 times, most recently from 545aae5 to 79b5157 Compare October 26, 2018 13:05
@johnomotani

Copy link
Copy Markdown
Contributor Author

#1384 makes this PR redundant.

@ZedThree
ZedThree deleted the index_derivs-templates branch November 27, 2018 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

work in progress Not ready for merging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant