Right now we have monstrosities like (this one is a bit extreme)
Nx, Ny, Nz = model.grid.Nx, model.grid.Ny, model.grid.Nz
Lx, Ly, Lz = model.grid.Lx, model.grid.Ly, model.grid.Lz
Δx, Δy, Δz = model.grid.Δx, model.grid.Δy, model.grid.Δz
grid = model.grid
cfg = model.configuration
bcs = model.boundary_conditions
clock = model.clock
G = model.G
Gp = model.Gp
constants = model.constants
eos = model.eos
U = model.velocities
tr = model.tracers
pr = model.pressures
forcing = model.forcing
poisson_solver = model.poisson_solver
δρ = model.stepper_tmp.fC1
RHS = model.stepper_tmp.fCC1
ϕ = model.stepper_tmp.fCC2
gΔz = model.constants.g * model.grid.Δz
fCor = model.constants.f
uvw = U.u.data, U.v.data, U.w.data
TS = tr.T.data, tr.S.data
Guvw = G.Gu.data, G.Gv.data, G.Gw.data
# Source terms at current (Gⁿ) and previous (G⁻) time steps.
Gⁿ = G.Gu.data, G.Gv.data, G.Gw.data, G.GT.data, G.GS.data
G⁻ = Gp.Gu.data, Gp.Gv.data, Gp.Gw.data, Gp.GT.data, Gp.GS.data
Would be nice to prettify or abstract away this unpacking.
@charleskawczynski I noticed you used some @unpack macros in the code you showed on Monday, is it up on GitHub by any chance?
I think Parameters.jl implements an @unpack macro, might be good to look at.
I think it's as simple as something like
macro unpack_model(model)
esc(quote
forcing = $(model).forcing
# etc
end # quote
)
end
@unpack_model model # pastes forcing=model.forcing, etc
I think? Maybe there's a way to make it more automated though.
I've also implemented a similar idea with a function, which is more explicit so maybe better:
function unpack_model(model)
return model.forcing, model.velocities
end
forcing, U = unpack_model(model)
Although I prefer being explicit I'm a big fan of the macro you suggested as it collapses 20+ lines into a single elegant statement (and buries the ugly unpacking) whereas the unpack_model function still requires a comma separate list of 20+ variables.
I think I'll go with the simple macro. If the unpacking variables have descriptive names, e.g. grid, source_terms, velocities, etc. then I think it'll still be understandable without being explicit.
quite!
with a function you can do some automated stuff, like
function unpack_model(model)
names = propertynames(model)
return (getproperty(model, name) for name in names)
end
which will unpack every single field in model.
There's also something like
macro unpack(obj, names...)
exprs = [ :($name = getproperty($obj, $name)) for name in names ]
esc(quote
$(exprs...)
end
)
end
which then would have the syntax
@unpack model forcing velocities
but then you can't rename the fields; they just get spit into the namespace as is.
for this line:
Gⁿ = G.Gu.data, G.Gv.data, G.Gw.data, G.GT.data, G.GS.data
you might want to do something like
data(field) = field.data
function data(fields...)
(data(field) for field in fields)
end
then you can write Gⁿ = data(G...), provided that typeof(G) <: Collection (I think... should check, but I think its something like that) --- which is true if G is a FieldVector (which I'd advocate).
By the way, I think the fields of G should be u, v, etc. rather than Gu, Gv, etc --- if the names of the fields of these FieldVector like quantities are the same when they refer to the same solution field (u or v or etc) that might enable some generic programming later (because we can relate G.u = ... to solution.u, or whatever).
@charleskawczynski I noticed you used some @unpack macros in the code you showed on Monday, is it up on GitHub by any chance?
It's not, but it is simple (credit @peterahrens ):
macro unpack(stuff, syms...)
thunk = Expr(:block)
for sym in syms
push!(thunk.args, :($(esc(sym)) = $(esc(stuff))[$(QuoteNode(sym))]))
end
push!(thunk.args, nothing)
return thunk
end
I've mostly been using this to unpack light-weight parameters via the input argument params::NamedTuple.
@ali-ramadhan do we need this anymore?
Hmmm, not for the model and the tuples you added help a lot so I'll close this.
I defined an @unpack for the Grid which has been useful, and we can define more in the future if we need them.