-
Notifications
You must be signed in to change notification settings - Fork 11
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
Introduce wrappers and separate transport from time discretisations #382
Conversation
… vector invariant types
gusto/common_forms.py
Outdated
(u.∇)q = (∇×q)×u + (1/2)∇(u.q) | ||
|
||
The form returned by this function corresponds to the (∇×q)×u circulation | ||
term. An an upwind discretisation is used when integrating by parts. |
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.
Need to remove part about upwind discretisation.
gusto/common_forms.py
Outdated
ubar (:class:`ufl.Expr`): the transporting velocity. | ||
|
||
Raises: | ||
NotImplementedError: the specified integration by parts is not 'once'. |
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.
no longer raises error
gusto/spatial_methods.py
Outdated
Args: | ||
equation (:class:`PrognosticEquation`): the equation, which includes | ||
the original type of this term. | ||
variable (str): name of the variable to set the transport scheme for |
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.
not just transport
gusto/spatial_methods.py
Outdated
self.field = equation.X | ||
self.test = equation.test | ||
|
||
# Find the original transport term to be used, which we use to extract |
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.
not just transport
gusto/timeloop.py
Outdated
residual = equation.residual.label_map( | ||
lambda t: t.has_label(term_label), map_if_false=drop | ||
) | ||
active_variables = [t.get(prognostic) for t in residual.terms] |
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.
is "active" the right word here?
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.
Fantastic - thanks @tommbendall
This PR:
Wrapper
object for time discretisationsSpatialMethod
object to describe specific spatial discretisations, similar to physics schemes.This allows a bunch of specific code to be pulled out from the time discretisations, and gives us new ways of combining and specifying our different options.
Breakdown of changes
Wrapper
object is introduced inwrappers.py
, which has pre- and post- apply methods. There are three applications of this:EmbeddedDGWrapper
RecoveryWrapper
SUPGWrapper
(which does nothing in pre- and post- apply methods, but does introduce a different test function to be used)I have tried to keep all of this code the same, but we should instantly gain the functionality to apply these wrappers to physics and diffusion terms.
TimeDiscretisation
objects can now set up aWrapper
object when they are passed wrapper options. All of the specific wrapper code is now completely pulled out oftime_discretisation.py
.SpatialMethod
object is defined inspatial_methods.py
, which is the base object for specifying a spatial discretisation of some term. Why bother to introduce this? It allows us to separate the generic term in an equation [e.g.test*dot(u,grad(q))*dx
], from its discretisation [e.g. an upwind discretisation]. When thestepper
sets up all of the methods/schemes, it will replace the term in the equation with the discretisation in theSpatialMethod
.SpatialMethod
have been introduced:TransportMethod
intransport_methods.py
andDiffusionMethod
indiffusion_methods.py
. These are very simple and pretty much just call the methods ofSpatialMethod
but with the specifictransport
/diffusion
labels. However theTransportMethod
requires more care as it needs to ensure that thetransporting_velocity
is replaced correctly.diffusion.py
has been removed, and code for theInteriorPenaltyDiffusion
method has been moved todiffusion_methods.py
TransportMethod
have been implemented:DGUpwind
(which is basically our work-horse at the moment) andDefaultTransport
(which calls the basic form originally set up in the equation -- I'm open to better names for this!). The forms used inDGUpwind
are stored intransport_methods.py
DGUpwind
, so this has been implemented as aWrapper
(to ensure that the test function in the time discretisation gets replaced). The appropriateIntegrateByParts
option should be passed to theDGUpwind
object.transport_forms.py
has been renamed ascommon_forms.py
, and the intention is that this should contain forms that are used byPrognosticEquation
s and notSpatialMethod
s. The basic transport and diffusion forms have been added to this.transporting_velocity
label. I have however fixed thelinear_advection_form
(issue Linear transport forms need fixing #332).circulation
form of the vector transport equation. I was a bit confused by what was happening before, and hopefully this clears things up:"vector_invariant"
: (u.∇)u = (∇×u)×u + (1/2)∇(u.u), implemented as a single transport term, with separate transported and transporting velocities"circulation"
: (u.∇)u = (∇×u)×u + (1/2)∇(u.u), implemented as two terms, a transport term (∇×u)×u and a K.E. term (1/2)∇(u.u) [which would now be evaluated as a forcing rather than as a transport term]transport_methods = [DGUpwind(eqn, variable_name), ...]
to all of these, and ensuring that it is passed to the time stepper.