Full-order model (FOM) adapter API
The FOM adapter is the layer standardizing how pressio queries operators from an application.
It is one of the most important features and a pivotal design in pressio.
Steady API
Intended for when your FOM application is expressed as
where is your FOM state, and is the residual todo finish.
Synopsis
class SteadyAdapter: def createResidual(self): return np.zeros(...) def createApplyJacobianResult(self, operand): return np.zeros_like(operand) def residual(self, stateIn, R): # compute residual def applyJacobian(self, stateIn, operand, C): # compute apply Jacobian # for example: # J = self.jacobian(stateIn) # C[:] = J.dot(operand)
Notes
The steady adapter can ONLY be used for doing steady LSPG ROMs.
See the following examples: \toadd
Continuous-time API: RHS only
Intended for when your FOM application is expressed in time-continuous form as
where is the full-order model (FOM) state, is what we call the FOM velocity (or RHS), and is time, and, for some reason, you can/want to only expose the right-hand-side (or velocity) of your FOM application. todo finish.
Synopsis
class ContTimeFomAdapterVelocityOnly: # create f(y,t,...) def createVelocity(): # say N is the total number of of unknowns return np.zeros(N) # compute velocity, f(y,t;...), for a given state, y, and time, t def velocity(self, y, t, f): f[:] = #compute velocity as needed
Notes
This adapter can ONLY be used for doing Galerkin ROMs with explicit time stepping.
Continuous-time API: RHS and Jacobian action
This API is intended for any system expressible in time-continuous form as above, but you expose both the right-hand-side of your FOM application as well as the action of the velocity's Jacobian on some operand (more on this later).
Synopsis
class ContTimeFomAdapterWithApplyJacobian # create f(y,t,...) def createVelocity(): # say N is the total number of of unknowns return np.zeros(N) # create result of df/dy*B # B is typically a skinny dense matrix (e.g. POD modes) def createApplyJacobianResult(self, B): return np.zeros((N, B.shape[1])) # compute velocity, f(y,t;...), for a given state, y def velocity(self, y, t, f): f[:] = #compute velocity as needed # given current state y(t): # compute A=df/dy*B, where B is a skinny dense matrix # Note that we just require the *action* of the Jacobian. def applyJacobian(self, y, B, t, A): A[:,:] = # compute A = df/dy * B as needed
Notes
- Can be used for doing Galerkin ROMs with explicit and implicit time stepping
- Can be used for LSPG and WLS (note that LSPG and WLS only make sense for implicit time integration).
Discrete-time API
This API is intended for any system expressible in a discrete-time form as
where is the full-order model (FOM) state, is time, and is the residual. todo finish.
Synopsis
class DiscreteTimeFomAdapter # create R(...) def createDiscreteTimeResidual(self): return np.zeros(...) def createApplyDiscreteTimeJacobianResult(self, B): return np.zeros((..., B.shape[1])) def discreteTimeResidual(self, step, time, dt, R, y_np1, y_n, y_nm1 [, y_nm2]): R[:] = # compute discrete-time residual def applyDiscreteTimeJacobian(self, step, time, dt, B, A, y_np1, y_n, y_nm1 [, y_nm2]): A[:,:] = # compute the action A = dR/dy_np1 B
Notes
- For doing Galerkin implicit time stepping.
- For doing LSPG and WLS.
What can you use where?
As anticipated, not all adapters can be used for all supported ROM methods. The following table illustrates which APIs are admissible for each method.
Steady API | Continuous Time API (RHS only) | Continuous Time API (RHS, Jacobian action) | Discrete Time API | |
---|---|---|---|---|
Galerkin Explicit Stepping | NA | supported | supported | NA |
Galerkin Implicit Stepping | NA | NA | supported | supported |
LSPG Unsteady | NA | NA | supported | supported |
LSPG Steady | supported | NA | NA | NA |
WLS Explicit Stepping | NA | supported | supported | NA |
WLS Implicit Stepping | NA | NA | supported | supported |
Note: for LSPG there is no distinction between explicit and implicit because LSPG only makes sense for implicit time stepping. Actually, it can be shown that explicit LSPG is equivalent to explicit Galerkin.