For me, option 1 looks the most Julian. Maybe the clunkiness is arising
because the calc object shouldn't be a field of Atoms? Fields are just
suppose to store data, not logic or methods. If a certain subtype of
AbstractAtoms always uses the same calc object, then dispatching just on
the atoms should be sufficient. If it can vary, maybe it would be more
elegant to associate them together in some other way than a type field and
then directly dispatch on both values.
Also, for option 2, why couldn't you give both AbstractAtoms and its
subtypes just a single type parameter for the calculator?
and now it looks like proper Julian code where you pass objects to methods.
On Wednesday, February 4, 2015 at 10:16:02 AM UTC-5, Christoph Ortner wrote:
>
>
> 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
>
>
>
>
>
>