Skip to content

calcYupYdown as needed? #1309

Description

@johnomotani

In #1306 @d7919 commented

we're transforming both input fields and then transforming back because one or other don't have yup/ydown -- would we rather call calcYupYdown on one or more of the inputs instead? This would avoid having to duplicate code and should avoid the need to transform the result field so I think might be faster (assuming toFieldAligned costs about the same as a calcYup/down)?

toFieldAligned and fromFieldAligned cost 1 FFT/rFFT of a Field3D each. calcYupYdown is 2 but doesn't need the transform back so if one field had yup/ydown already it would be cheaper (2FFTs vs 3) to call calcYupYdown.

I think it would be a nice feature to have something smarter for when to calculate yup/ydown fields. Opening an issue to discuss since it's a longer-term issue than just a bugfix.

At the moment calcYupYdown() is called only as part of Mesh::communicate(). If we have 2 fields that have yup/ydown and then do some arithmetic with them (e.g. p=n*T), at the moment you have to either communicate p or do p.splitYupYdown();p.yup()=n.yup()*T.yup();p.ydown()=n.ydown()*T.ydown() by hand for every operation.

sub-issues:

  • you might not want to call calcYupYdown() on a field if you aren't going to take a y-derivative. Actually this is already possible by using communicateXZ() instead of communicate(), but I don't think we've documented this feature in the manual.
  • I don't think we document that it's possible to do things like p.splitYupYdown();p.yup()=n.yup()*T.yup();p.ydown()=n.ydown()*T.ydown() if you need them.
  • It might be nice to include yup/ydown fields in arithmetic, e.g. if both arguments to an operator have yup/ydown fields, then calculate yup/ydown for the result as well. The downside for optimizing is that which fields are getting yup/ydown calculated is maybe too well hidden from the user; it would be rather obscure to deal with. Also, you might not want all arithmetic operations to do the same thing, e.g. I calculate both p and nu from n and T and I want p to have yup/ydown, but don't need them for nu.
  • A nice compromise might be to call calcYupYdown 'on demand' as @d7919 suggested, then we definitely aren't carrying around yup/ydown fields when we don't need them, even if doing yup/ydown arithmetic might be more efficient sometimes. I think I'd be in favour of this even if it isn't actually faster: doing parallel derivatives with two different schemes makes me slightly uneasy (although I have no logical basis for it). I'd be happier if the code defaulted to doing either all yup/ydown derivatives or all to/fromFieldAligned derivatives.
    • could we have some kind of 'optimize warnings', maybe only active when CHECK>0? I'm thinking that if calcYupYdown() needs to be called in a derivative, it probably means that the user could speed things up by adding by hand calculations for yup/ydown, like that p.splitYupYdown();p.yup()=n.yup()*T.yup();p.ydown()=n.ydown()*T.ydown(). Then a user could write the simplest code to start with, and get hints for where to start optimizing without having to have a deep understanding of the ShiftedMetric and yup/ydown architecture already. In New shifted metric #1177 I added functionality for caching the field-aligned version of a field which has a similar effect to calling calcYupYdown on demand, since toFieldAligned() was already called whenever it was needed, I also added a message suggesting optimization might be possible (although a shinier system for collecting them and presenting them to the user would be nice), see
      const Field3D ShiftToFieldAligned::toFieldAligned(const Field3D &f, const REGION region) {

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions