I am trying to re-structure a molecular simulation code I've been working
on, to make it more readily extendable. I am puzzling over how to do this
most effectively in Julia, and would appreciate any thoughts from more
experienced Julia programmers. I am roughly trying to mimic the structure
of CAMPOS ASE ( a Python package ).
The main type that contains the simulation state is
abstract AbstractAtoms
The simplest sub-type is (here a simplified version)
type Atoms
X::Array{Float64, 2} # positions of atoms
calc # calculator for computing
energies, forces, etc
neigs # neighbourlist
precon # preconditioner
end
but there could be many other sub-types that store atom positions
differently, or live on manifolds, or contain information for continuum
mechanics boundary conditions, etc.
I now need functions that depends on the type of the atoms object and on
the type of calculator object. (for example).
OPTION 1: At the moment, my thinking is that I can do
function get_forces(atoms::AbstractAtoms)
return get_forces(atoms, atoms.calc)
end
and the type of `atoms` and of `atoms.calc` will then determine which
function is called. This feels a bit clunky to be honest, but looks like
the best way to go?
OPTION 2: Another thought that I had, was to define
type Atoms{CT, NT, PT}
X::Array{Float64, 2} # positions of atoms
calc::CT # calculator for computing
energies, forces, etc
neigs::NT # neighbourlist
precon::PT # preconditioner
end
function get_forces(atoms::Atoms{MyCalculator,NT,PT})
# . . .
end
and to determine the type of the calculator this way. The problem there is
that I cannot give AbstractAtoms the parameters {CT, NT, PT} because other
sub-types might use a different, possibly longer, possibly shorter list of
parameters.
I'd be very grateful for any advise what sort of constructions would be the
most convenient / useful to try out here.
Many thanks,
Christoph