conatus.Model

class conatus.Model(geometry, *, name='model', **parameters)[source]

Bases: object

A PDE model on a geometry, declared as on paper.

Model(geometry, name=..., **parameters): parameters by keyword (Ra=2500, Pr=1), each becoming a named Parameter of the equations. Unknowns, given fields, equations and boundary conditions are then declared on the model; resolution, scheme and time step are given later to simulate, eigenvalues or compile.

Parameters:
  • geometry (Geometry)

  • name (str)

  • parameters (Any)

scalar(name)[source]

A scalar unknown (temperature, concentration, streamfunction…).

Parameters:

name (str)

Return type:

Unknown

vector(name)[source]

A vector unknown.

Parameters:

name (str)

Return type:

Unknown

velocity(name='u')[source]

A velocity (a vector unknown; the role is only printed).

Parameters:

name (str)

Return type:

Unknown

pressure(name='p')[source]

A pressure: a scalar that must have the structure of one (only grad(p), no condition, a div constraint); checked at compilation, never assumed.

Parameters:

name (str)

Return type:

Unknown

dye(name, *, velocity, kappa)[source]

A numerical dye: the passive scalar name advected by the vector unknown velocity, with its own diffusivity kappa (a number >= 0 or the name of a declared parameter). Declares the unknown and its equation in conservative form dt(c) - kappa*lap(c) = -div(c*u), with no-flux walls dz(c) = 0 on the wall axis when kappa > 0; kappa=0 is pure advection (no diffusion, no filter, no wall condition). May follow m.equations (nothing else uses the dye). Cartesian boxes; printed by explain(); written with its mass and variance by sim.dye(...) (conatus.model.dye).

Parameters:
  • name (str)

  • velocity (str)

  • kappa (Any)

Return type:

Unknown

given(name=None, value=None, *, rank=0, **named)[source]

Known fields: m.given(U=lambda y: 1 - y**2) (argument names = coordinates it depends on); rank=1 for a vector (the callable returns the components).

Parameters:
  • name (str | None)

  • value (Any)

  • rank (int)

  • named (Any)

Return type:

Given | tuple[Given, …]

function(name, f, *, derivative=None, parity='none')[source]

A pointwise function of a scalar field usable in the equations by its name (m.function("g", np.tanh, derivative=lambda u: 1 - np.tanh(u)**2), then dt(u) - lap(u) = -g(u)): the role of Dedalus’ GeneralFunction for pointwise functions (conatus.ir.pointwise: evaluated on the dealiased grid, not alias-free, declared; without derivative linearization and Newton are refused). f takes and returns arrays (CuPy arrays on the GPU backend).

Parameters:
  • name (str)

  • f (Any)

  • derivative (Any)

  • parity (str)

Return type:

Any

define(text)[source]

A named operator used in the equations: m.define("L2(f) = dy(dy(f)) - alpha**2*f") (the body is parsed at each use with its arguments bound: pure substitution).

Parameters:

text (str)

Return type:

None

eigenvalue(name='s', *, growth=None)[source]

Declare the model an eigenvalue problem in name (complex); returns the name.

growth: which part of the eigenvalue measures growth, used by critical and least_stable: "real" for a mode exp(s t), "imag" for a phase speed c of exp(i alpha (x - c t)) (or exp(-i omega t)), or a callable of the eigenvalue. Printed by explain(); it ranks the modes (res.order()) and selects the least stable one.

Declare it: m.eigenvalue("c", growth="imag"). Left out, v0.1 keeps the former guess from the name (s, sigma, lam -> real, c -> imag; conatus.solvers.parametric.GROWTH_BY_NAME; any other name: order() ranks by the real part and critical refuses) with a DefaultChoiceWarning naming the rule guessed: a c of a temporal problem (c*T = ...) was ranked by Im c. Required from v0.2.

Parameters:
  • name (str)

  • growth (Any)

Return type:

str

equations(*texts, **named)[source]

Equations as on paper, one per line or one per argument (or label=... keywords, or label: ... prefixes). Terms may sit on either side: the split is automatic (explain()).

Parameters:
  • texts (str)

  • named (str)

Return type:

Model

at(boundary, *conditions, into=None, **values)[source]

Boundary conditions at a named boundary: m.at("bottom", u=0, T=0.5), or as text m.at("walls", "v = 0", "dy(v) = 0") (texts first, then keywords, in order). into= names the equation that receives the taus when the rule cannot decide.

Parameters:
  • boundary (str)

  • conditions (str)

  • into (Any)

  • values (Any)

Return type:

Model

compile(N, dealias=None, *, params=None)[source]

The IR problem at resolution N with the record of every automatic decision. params: values of declared parameters for this compilation only (the model keeps its own; listed as per-call values by explain()).

Parameters:
  • N (Any)

  • dealias (Any)

  • params (Mapping[str, Any] | None)

Return type:

Compiled

discretize(N, dealias=None, **kw)[source]

conatus.discretize of the compiled problem (expert: the Plan, its matrices); a keyword naming a declared parameter (Re=3000) is its value for this call only.

Parameters:
  • N (Any)

  • dealias (Any)

  • kw (Any)

explain(N=None, dealias=None, *, full=False)[source]

The model in a few lines: geometry, unknowns, parameters, equations and conditions as written, the problem kind, which terms are explicit, the gauge, the dealiasing and every warning. full=True: every automatic decision (term-by-term split, tau names and modes, symbolic unless N is given, bases).

Parameters:
  • N (Any)

  • dealias (Any)

  • full (bool)

Return type:

str

simulate(N, *, scheme, dt, dealias=None, backend='cpu', **solver_kw)[source]

Time integration: Simulation of the compiled IVP (scheme and dt explicit).

A keyword naming a declared parameter (m.simulate(N, ..., Ra=3000)) is the value of that parameter for this run only (validated; the model keeps its own; recorded by sim.explain() and the provenance). The other keywords are options of the solver (conatus.expert.IVPSolver: check_finite, f_backend, reduced, …); an unknown one is refused with the accepted names.

Parameters:
  • N (Any)

  • scheme (str)

  • dt (float)

  • dealias (Any)

  • backend (str)

  • solver_kw (Any)

solve(N, *, dealias=None, **kw)[source]

Solution of a linear boundary-value model (LBVP: no dt(), linear in the unknowns) at resolution N: the LBVPSolution of discretize(N).solve(), given fields as data (sol.grid("u"), sol.explain() with the residual of each group).

Parameters:
  • N (Any)

  • dealias (Any)

  • kw (Any)

linearize(about, eigenvalue='s', *, period=None, base_residual='check')[source]

Linear dynamics of the model about a base state ({u: 0, T: lambda z: -z}): normal modes (eigenvalues) of a steady base; with period=P the base may depend on t ({u: lambda y, t: ...}, periodic) and is analysed by floquet and optimal_gain (transient growth, also for a steady base).

base_residual: "check" (default) evaluates the steady equations and boundary conditions at a steady base when the problem is compiled and prints the residual in explain(); above conatus.tolerances.BASE_RESIDUAL_TOL the base is not a steady solution (BaseStateWarning in v0.1, refused in v0.2). "accept" declares a base that knowingly is not one (a frozen or forced profile).

Parameters:
  • about (Mapping[Any, Any])

  • eigenvalue (str)

  • period (float | None)

  • base_residual (str)

eigenvalues(N, *, dealias=None, drift=None, k=None, n_modes=None, **kw)[source]

Eigenvalues of an EVP model (m.eigenvalue("c")); drift=N2 keeps only the modes found again at resolution N2 (tau-mode rejection, conatus.eigenvalues(drift_plan=)).

k: the wavenumber of the periodic direction(s) (one number, a tuple in coordinate order or a dict by name), as in lin.eigenvalues(N, k=): each wavenumber is its own group of modes. Required on a model with a periodic direction (the k = 0 group alone was solved without a word); left out in v0.1, the k = 0 group is solved with a GroupWarning that says so. n_modes: the number of modes of method="shift-invert" (the former meaning of an integer k on a model without a periodic direction, accepted with a DeprecationWarning until v0.2). m=, kz=, ell=: the group of a curvilinear geometry (disk, pipe, sphere).

Parameters:
  • N (Any)

  • dealias (Any)

  • drift (Any)

  • k (Any)

  • n_modes (int | None)

  • kw (Any)

parametric(N, over, *, dealias=None, drift=None, drift_tol=None, **kw)[source]

ParametricEVP of an EVP model in the parameters over (names). The model’s declared values of these parameters are used when a call leaves one out (logged), and the growth convention of the eigenvalue goes with the pencil. drift=N2 (with its required drift_tol) builds the same pencil at resolution N2: least_stable and critical then keep only the modes found again there (spurious tau modes removed), as eigenvalues(drift=).

Parameters:
  • N (Any)

  • over (Any)

  • dealias (Any)

  • drift (Any)

  • drift_tol (Any)

  • kw (Any)