Code Organization

lancejnelson
Fri, 29 Mar 2024 22:57:03 +0000
New to Julia

I’m having a really hard time finding a code structure that works for me. I’m building a pretty big library of interatomic potentials. I’ve broken the code up into several files:

One for each of the following sets of tasks:

1. Reading in crystal structure information and building associated datasets

2. Processing calculation files and extracting information.

3. Functions associated with Metropolis-Hastings algorithm and other machine learning stuff.

4. A Lennard Jones library (I know, simplistic… for now) that calculates energies and forces.

5. A Stillinger-Weber library that also calculates energies and forces.

6. A nested-sampling library for performing thermodynamic simulations.

Most of these separate files are just files of functions, not modules. But the LennardJones file and the Stillinger Weber files need to be modules because they both have functions named “totalEnergy” and “getForce” so I need them to be in separate namespaces. (i.e. I’d like to be able to do LJ.totalEnergy() and SW.totalEnergy()).

So I’ve built a parent module that looks like this:

module matsim
using StaticArrays
using Printf
using LinearAlgebra
using StatsBase
using Distributions

include("types/data_types.jl")  # Load abstract data types.
include("libraries/Crystal.jl")  # Load methods used to load and manipulate crystals.
include("libraries/dataset.jl")  # Load methods used to load and manipulate entire data sets.
include("libraries/vaspUtils.jl")  # Load methods used to interface with vasp
include("libraries/metrop.jl")  # Load metropolis-hastings sampling files.
include("modules/LennardJones.jl") # Load Lennard Jones processing files.
include("modules/StillingerWeber.jl") # Load Stillinger-Weber processing files.
include("libraries/nestedSampling.jl")  # Load nested sampling code
end

And then I load this module from the outer script. The problem I’m facing is that functions inside the LennardJones module use abstracttype “Crystal”. But since the functions inside LennardJones are in a separate namespace it doesn’t recognize that type (which was imported in the outer scope). In other words, there is a function inside of LennardJones like this

function totalEnergy(crystal::Crystal,params::Array{Float64,2})
    energy = sum(-params[:,1] .* params[:,2] .^6 .* crystal.ljvals[:,1] + params[:,1] .* params[:,2] .^12 .* crystal.ljvals[:,2] )
    return energy
end

and it doesn’t recognize the function type because it wants to use the “Crystal” type from within the LJ scope, not the outer scope from which it was originally imported.

I know this isn’t a working example and I’m happy to include more code. I’m just having a hard time building a mental framework for organizing big code in Julia… Any help is appreciated.

21 posts - 5 participants