Skip to content

Parent/child initialization patterns? #259

@wpbonelli

Description

@wpbonelli

The classic flopy 3.x way of relating parent/child components is to create the simulation top-down, starting with the simulation, which is passed into models/simulation-scoped packages, which are passed into model-scoped packages. For instance

sim = MFSimulation(sim_name=sim_name, sim_ws=sim_ws, exe_name="mf6")
tdis = ModflowTdis(sim, nper=nper, perioddata=tdis_ds, time_units=time_units)
gwf = ModflowGwf(sim, modelname=sim_name, save_flows=True)
dis = ModflowGwfdis(
    gwf,
    length_units=length_units,
    nlay=nlay,
    nrow=nrow,
    ncol=ncol,
    delr=delr,
    delc=delc,
    top=top,
    botm=botm,
)
...

imod-python developers suggest supporting only one way to connect parent/child components, in particular the reverse of the above, which instead requires a bottom-up approach to constructing the simulation, e.g. something like

dis = ...
chd = ...
gwf = Gwf(
    dis=dis,
    chd=chd,
    ...
)
sim = Simulation(models=[gwf], ...)

Currently we support both (although there may be bugs lurking).

The latter allows packages to be created independently of a model/simulation and the corresponding grid/time discretizations (cf #226). This is a frequently-enough requested feature to be considered a requirement IMO. But it does mean packages can't presume to know their own dimensions at initialization time, so any shape-checking/expansion needs to be deferred until dimensions are known.

Dropping support for the former would be a pretty big departure from 3.x, though, and would make it harder for people to migrate. Personally I think a reasonable compromise might be to encourage the latter, e.g. by showing it that way more or less exclusively in 4.x docs, but continue supporting the former not only for backwards compatibility but for flexibility. It does seem convenient in certain situations, when creating a package, to say, as it were, "you are part of this model, inherit its dimensions and make sure any arrays I pass into you are shaped appropriately."

Of course we probably (definitely?) also want to support e.g. gwf.dis = Dis(...). I'm less sure about e.g. dis.parent = gwf but it also seems convenient. Care will be required to correctly manage both sides of the relation (i.e. update dis.parent in the first case and gwf.dis in the second). Maybe this deserves a separate issue as it concerns post-init modification.

Metadata

Metadata

Assignees

No one assigned

    Labels

    frontendRelated to the user-facing APIquestionInformation or decisions requiredrequirementCore requirement

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions