Sorry, disregard that last sentence which was supposed to have been edited out.
On Wednesday, February 4, 2015 at 11:46:09 AM UTC-5, Josh Langsfeld wrote: > > 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 >> >> >> >> >> >>