diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 5da369e..466b667 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-10-30T16:27:13","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-10-30T16:49:44","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/dev/fitting-eft/index.html b/dev/fitting-eft/index.html index 1f64b17..764c5bd 100644 --- a/dev/fitting-eft/index.html +++ b/dev/fitting-eft/index.html @@ -45,4 +45,4 @@ set_params!(fm, c)

Evaluating the Friction Model

The trained friction model can be used to evaluate the friction tensor ${\bm \Gamma}$ and diffusion coeccifient matrix ${\bm \Sigma}$ at configurations as follows

at = fdata["test"][1].atoms # extract atomic configuration from the test set
 Gamma(fm, at) # evaluate the friction tensor
 Σ = Sigma(fm, at) # evaluate the diffusion coeffcient matrix

To simulate a Langevin equation, typically, both the friction coefficient and the diffusion coefficient matrix must be evaluated. Instead of evaluating them seperately it is more efficient to first evaluate the diffusion coefficient matrix and then evaluate the friction tensor from the the pre-computed diffusion coefficient matrix:

Σ = Sigma(fm, at) # evaluate the diffusion coeffcient matrix
-Gamma(fm, Σ) # compute the friction tensor from the pre-computeed diffusion coefficient matrix.

The diffusion coefficient matrix $\Sigma$ can also be used to efficiently generate Gaussian pseudo random numbers ${\rm Normal}(0,{\bf \Gamma})$ as

R = randf(fm,Σ)
+Gamma(fm, Σ) # compute the friction tensor from the pre-computeed diffusion coefficient matrix.

The diffusion coefficient matrix $\Sigma$ can also be used to efficiently generate Gaussian pseudo random numbers ${\rm Normal}(0,{\bf \Gamma})$ as

R = randf(fm,Σ)
diff --git a/dev/fitting-mbdpd/index.html b/dev/fitting-mbdpd/index.html index 517f358..c99f02c 100644 --- a/dev/fitting-mbdpd/index.html +++ b/dev/fitting-mbdpd/index.html @@ -37,4 +37,4 @@ push!(loss_traj[tt], weighted_l2_loss(ffm,flux_data[tt])) end println("Epoch: $epoch, Abs avg Training Loss: $(loss_traj["train"][end]/n_train)), Test Loss: $(loss_traj["test"][end]/n_test))") -end

After training for 2000 epochs, the resulting model is almost a perfect fit:

True vs fitted entries of the friction tensor

Multi-Body Dissipative Particle Dynamics

By specifying maxorder=1 in the above construction of the friction model, we restrict the underlying ACE-basis to only incorporate pair-wise interactions. This is fine for the here considered sythentic data as the underlying toy model is in fact based on only pair-wise interactions. However, in more complex systems the random force and the dissipative force may not decompose to pairwise interactions. To incorporate higher body-order interactions in the friction model, say interactions up to body order 4, we can change the underlying ACE-basis expansion to incorporate correlation terms up to order 3 by setting maxorder=3.

+end

After training for 2000 epochs, the resulting model is almost a perfect fit:

True vs fitted entries of the friction tensor

Multi-Body Dissipative Particle Dynamics

By specifying maxorder=1 in the above construction of the friction model, we restrict the underlying ACE-basis to only incorporate pair-wise interactions. This is fine for the here considered sythentic data as the underlying toy model is in fact based on only pair-wise interactions. However, in more complex systems the random force and the dissipative force may not decompose to pairwise interactions. To incorporate higher body-order interactions in the friction model, say interactions up to body order 4, we can change the underlying ACE-basis expansion to incorporate correlation terms up to order 3 by setting maxorder=3.

diff --git a/dev/function-manual/index.html b/dev/function-manual/index.html index 4f21a52..6d14c53 100644 --- a/dev/function-manual/index.html +++ b/dev/function-manual/index.html @@ -1,4 +1,4 @@ Function Manual · ACEds.jl

Function Manual

ACEds.FrictionModels.jl

A friction model is a wrapper around a named tuple of matrix models, i.e.

struct FrictionModel{MODEL_IDS} <: AbstractFrictionModel
     matrixmodels::NamedTuple{MODEL_IDS} 
-end

The symbols contained in the tuple MODEL_IDS are referred to as "IDs" of the corresponding matrix models. When evaluated at an atomic configuration, the resulting friction tensor is the sum of the friction tensors of all matrix models in the friction model, whereas diffusion coefficient matrices are evaluated seperately for each matrix model and returned in the form of a named tuple of the same signature. The following functions act on structures of type FrictionModel:

ACEds.FrictionModels.GammaFunction
Gamma(fm::FrictionModel, at::Atoms; filter=(_,_)->true, T=Float64)

Evaluates the friction tensor according to the friction model fm at the atomic configuration at::Atoms. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.

Arguments:

  • fm – the friction model of which the friction tensor is evaluated.
  • at – the atomic configuration at which the basis is evaluated
  • filter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. Only atoms at[i] for which filter(i,at) returns true are included in the evaluation of the friction tensor.

Output:

A friction tensor in the form of a sparse 3N x 3N matrix, where N is the number of atoms in the atomic configuration at.

source
Gamma(fm::FrictionModel{MODEL_IDS}, Σ_vec::NamedTuple{MODEL_IDS}) where {MODEL_IDS}

Computes the friction tensor from a pre-computed collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all diffusion coefficient matrices in the collection.

Arguments:

  • fm – the friction model of which the friction tensor is evaluated. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.
  • Σ – a collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all matrices in Σ.

Output:

A friction tensor in the form of a sparse 3N x 3N matrix, where N is the number of atoms in the atomic configuration at. The friction tensor is the sum of the symmetric squares $\Sigma\Sigma^T$ of all diffusion coefficient matrices $\Sigma$ in Σ_vec.

source
ACEds.FrictionModels.SigmaFunction
Sigma(fm::FrictionModel{MODEL_IDS}, at::Atoms; filter=(_,_)->true, T=Float64) where {MODEL_IDS}

Computes the diffusion coefficient matrices for all matrix models in the friction model at a given configuration.

Arguments:

  • fm – the friction model of which the diffusion coefficient matrices are evaluated
  • at – the atomic configuration at which the diffusion coefficient matrices are evaluated
  • filter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. Only atoms at[i] for which filter(i,at) returns true are included in the evaluation of the diffusion coefficient matrices.

Output:

A NamedTuple of diffusion coefficient matrices, where the keys are the IDs of the matrix models in the friction model.

source
ACEds.MatrixModels.randfFunction
randf(fm::FrictionModel{MODEL_IDS}, Σ::NamedTuple{MODEL_IDS}) where {MODEL_IDS}

Generates a ${\rm Normal}({\bm 0}, {\bm \Gamma})$-distributed Gaussian pseudo random number from a precomputed diffusion coeffiient matrices.

Arguments:

  • fm – the friction model of which the friction tensor is evaluated. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.
  • Σ – a collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all matrices in Σ.

Output:

A ${\rm Normal}({\bm 0}, {\bm \Gamma})$-distributed Gaussian vector R::Vector{3,Float64} of length N, where N is the number of atoms in the configuration for which Σ was evaluated.

source
ACEds.MatrixModels.basisFunction
basis(fm::FrictionModel{MODEL_IDS}, at::Atoms; join_sites=false, filter=(_,_)->true, T=Float64) where {MODEL_IDS}

Evaluates the ACE-basis functions of the friction model fm at the atomic configuration at::Atoms.

Arguments:

  • fm – the friction model of which the basis is evaluated
  • at – the atomic configuration at which the basis is evaluated
  • join_sites – (optional, default: false) if true, the basis evaulations of all matrix models are concatenated into a single array. If false, the basis evaluations are returned as a named tuple of the type NamedTuple{MODEL_IDS}.
  • filter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. The atom at[i] will be included in the basis iff filter(i,at) returns true.
source

Setter and getter functions for model parameters

ACE.paramsFunction
params(fm::FrictionModel{MODEL_IDS}) where {MODEL_IDS}

Returns the parameters of all matrix models in the FrictionModel object as a NamedTuple.

source
ACE.nparamsFunction
nparams(fm::FrictionModel{MODEL_IDS}) where {MODEL_IDS}

Returns the total number of scalar parameters of all matrix models in the FrictionModel object.

source
ACE.set_params!Function
set_params!(fm::FrictionModel, θ::NamedTuple)

Sets the parameters of all matrix models in the FrictionModel object whose ID is contained in θ::NamedTuple to the values specified therein.

source

ACEds.MatrixModels.jl

ACEds.FrictionFit.jl

+end

The symbols contained in the tuple MODEL_IDS are referred to as "IDs" of the corresponding matrix models. When evaluated at an atomic configuration, the resulting friction tensor is the sum of the friction tensors of all matrix models in the friction model, whereas diffusion coefficient matrices are evaluated seperately for each matrix model and returned in the form of a named tuple of the same signature. The following functions act on structures of type FrictionModel:

ACEds.FrictionModels.GammaFunction
Gamma(fm::FrictionModel, at::Atoms; filter=(_,_)->true, T=Float64)

Evaluates the friction tensor according to the friction model fm at the atomic configuration at::Atoms. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.

Arguments:

  • fm – the friction model of which the friction tensor is evaluated.
  • at – the atomic configuration at which the basis is evaluated
  • filter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. Only atoms at[i] for which filter(i,at) returns true are included in the evaluation of the friction tensor.

Output:

A friction tensor in the form of a sparse 3N x 3N matrix, where N is the number of atoms in the atomic configuration at.

source
Gamma(fm::FrictionModel{MODEL_IDS}, Σ_vec::NamedTuple{MODEL_IDS}) where {MODEL_IDS}

Computes the friction tensor from a pre-computed collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all diffusion coefficient matrices in the collection.

Arguments:

  • fm – the friction model of which the friction tensor is evaluated. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.
  • Σ – a collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all matrices in Σ.

Output:

A friction tensor in the form of a sparse 3N x 3N matrix, where N is the number of atoms in the atomic configuration at. The friction tensor is the sum of the symmetric squares $\Sigma\Sigma^T$ of all diffusion coefficient matrices $\Sigma$ in Σ_vec.

source
ACEds.FrictionModels.SigmaFunction
Sigma(fm::FrictionModel{MODEL_IDS}, at::Atoms; filter=(_,_)->true, T=Float64) where {MODEL_IDS}

Computes the diffusion coefficient matrices for all matrix models in the friction model at a given configuration.

Arguments:

  • fm – the friction model of which the diffusion coefficient matrices are evaluated
  • at – the atomic configuration at which the diffusion coefficient matrices are evaluated
  • filter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. Only atoms at[i] for which filter(i,at) returns true are included in the evaluation of the diffusion coefficient matrices.

Output:

A NamedTuple of diffusion coefficient matrices, where the keys are the IDs of the matrix models in the friction model.

source
ACEds.MatrixModels.randfFunction
randf(fm::FrictionModel{MODEL_IDS}, Σ::NamedTuple{MODEL_IDS}) where {MODEL_IDS}

Generates a ${\rm Normal}({\bm 0}, {\bm \Gamma})$-distributed Gaussian pseudo random number from a precomputed diffusion coeffiient matrices.

Arguments:

  • fm – the friction model of which the friction tensor is evaluated. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.
  • Σ – a collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all matrices in Σ.

Output:

A ${\rm Normal}({\bm 0}, {\bm \Gamma})$-distributed Gaussian vector R::Vector{3,Float64} of length N, where N is the number of atoms in the configuration for which Σ was evaluated.

source
ACEds.MatrixModels.basisFunction
basis(fm::FrictionModel{MODEL_IDS}, at::Atoms; join_sites=false, filter=(_,_)->true, T=Float64) where {MODEL_IDS}

Evaluates the ACE-basis functions of the friction model fm at the atomic configuration at::Atoms.

Arguments:

  • fm – the friction model of which the basis is evaluated
  • at – the atomic configuration at which the basis is evaluated
  • join_sites – (optional, default: false) if true, the basis evaulations of all matrix models are concatenated into a single array. If false, the basis evaluations are returned as a named tuple of the type NamedTuple{MODEL_IDS}.
  • filter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. The atom at[i] will be included in the basis iff filter(i,at) returns true.
source

Setter and getter functions for model parameters

ACE.paramsFunction
params(fm::FrictionModel{MODEL_IDS}) where {MODEL_IDS}

Returns the parameters of all matrix models in the FrictionModel object as a NamedTuple.

source
ACE.nparamsFunction
nparams(fm::FrictionModel{MODEL_IDS}) where {MODEL_IDS}

Returns the total number of scalar parameters of all matrix models in the FrictionModel object.

source
ACE.set_params!Function
set_params!(fm::FrictionModel, θ::NamedTuple)

Sets the parameters of all matrix models in the FrictionModel object whose ID is contained in θ::NamedTuple to the values specified therein.

source
ACEds.MatrixModels.set_zero!Function
set_zero!(fm::FrictionModel, model_ids)

Sets the parameters of all matrix models in the FrictionModel object to zero.

source

ACEds.MatrixModels.jl

ACEds.FrictionFit.jl

diff --git a/dev/index.html b/dev/index.html index 29d312c..0d7c8a3 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · ACEds.jl

Introduction

ACEds.jl facilitates simulation and machine learning of configuration-dependent friction tensor models from data. The models are based on an equivariant Atomic Cluster Expansion (ACE) and as such highly efficient and size transferable. The underlying framework of model construction is described in detail in Sachs et al., (2024).

For a quick start, we recommend reading the installation instructions and the Overview section followed by the workflow examples. Detailed documentation of front end facing functions can be found in the function manual.

References

If you are using ACEds.jl in your work, please cite the following article:

  • Sachs, M., Stark, W. G., Maurer, R. J., & Ortner, C. (2024). Equivariant Representation of Configuration-Dependent Friction Tensors in Langevin Heatbaths. [arxiv]
+Home · ACEds.jl

Introduction

The julia package ACEds.jl facilitates simulation and machine learning of configuration-dependent friction tensor models from data. The models are based on an equivariant Atomic Cluster Expansion (ACE) and, as such, are computationally highly efficient and size transferable. The underlying framework of model construction is described in detail in Sachs et al., (2024).

For a quick start, we recommend reading the Installation Instructions and the Overview section, followed by the workflow examples. Detailed documentation of front-end-facing functions can be found in the function manual.

References

If you are using ACEds.jl in your work, please cite the following article:

  • Sachs, M., Stark, W. G., Maurer, R. J., & Ortner, C. (2024). Equivariant Representation of Configuration-Dependent Friction Tensors in Langevin Heatbaths. [arxiv]
diff --git a/dev/installation/index.html b/dev/installation/index.html index 9587c26..635ac46 100644 --- a/dev/installation/index.html +++ b/dev/installation/index.html @@ -1,4 +1,4 @@ Installation Guide · ACEds.jl

Prerequisites

You will need to have Julia (v1.7 or newer) installed. The latest release and installation instruction for Julia are available here here.

Warning

If you are running Julia for the first time, there is a chance that the General Registrity is not added to you installation. To install the General Registry run the following code from within a Julia REPL.

using Pkg
 Pkg.Registry.add("General")  

Installation

The package ACEds and some required dependencies can be downloaded from ACEregistry. To add this registry and install ACEds execute the following steps from within a Julia REPL.

  1. Add the ACEregistry registry:

    using Pkg
    -Pkg.Registry.add(RegistrySpec(url="https://github.com/ACEsuit/ACEregistry"))
  2. Install ACEds:

    Pkg.add("ACEds")

Done! Now you can use the functionality of ACEds in your project by running using ACEds.

Note

It is recommended to install ACEds within a dedicated julia environment, where approriate version bounds can be set within the Project.toml file, and versions of dependencies are tracked in a Manifest.toml file.

To create a new project, simply create a new directory, navigate to that directory and run

Pkg.activate(".")

Then, execute sthe teps 1. and 2. from within the project directory.

+Pkg.Registry.add(RegistrySpec(url="https://github.com/ACEsuit/ACEregistry"))
  • Install ACEds:

    Pkg.add("ACEds")
  • Done! Now you can use the functionality of ACEds in your project by running using ACEds.

    Note

    It is recommended to install ACEds within a dedicated julia environment, where approriate version bounds can be set within the Project.toml file, and versions of dependencies are tracked in a Manifest.toml file.

    To create a new project, simply create a new directory, navigate to that directory and run

    Pkg.activate(".")

    Then, execute sthe teps 1. and 2. from within the project directory.

    diff --git a/dev/overview/index.html b/dev/overview/index.html index 00e584f..f8192e3 100644 --- a/dev/overview/index.html +++ b/dev/overview/index.html @@ -2,4 +2,4 @@ Overview · ACEds.jl

    Model Overview

    The package ACEds provides an ACE-based implementation of the size-transferrable, E(3)-equivariant models introduced in Sachs et al., (2024) for configuration-dependent friction or diffusion tensors.

    In a nutshell, the package provides utilities to efficiently learn and evaluate E(3)-equivariant symmetric positive semi-definite matrix functions of the form

    \[{\bm \Gamma} \left ( ({\bm r}_{i},z_i)_{i=1}^{N_{\rm at}} \right ) \in \mathbb{R}^{3 N_{\rm at} \times 3N_{\rm at}},\]

    where the ${\bm r}_{i}$s are the positions and the $z_{i}$s are the atomic element types of atoms in an atomic configuration comprised of $N_{\rm at}$ atoms.

    The underlying model is based on an equivariance-preserving matrix square root decomposition,

    \[{\bm \Gamma} = {\bm \Sigma}{\bm \Sigma}^T,\]

    where block entries of the matrix square root ${\bm \Sigma}\left ( ({\bm r}_{i},z_i)_{i=1}^{N_{\rm at}} \right ) \in \mathbb{R}^{3 N_{\rm at} \times m}$ with some $m \in \mathbb{N}$, are linearly expanded using an equivariant linear atomic cluster expansion.

    Code Overview

    The package ACEds is comprised of three main sub-modules:

    1. The sub-module FrictionModels implements the structure FrictionModel, which facilitates the specification of and evaluation of friction models. The module implements the functions Gamma(fm::FrictionModel, at::Atoms), Sigma(fm::FrictionModel, at::Atoms) which evaluate the friction model fm at the atomic configuration at to the correspong friction tensor ${\bm \Gamma}$ and diffusion coefficient matrix ${\bm \Sigma}$, respectively. Moreover, it provides the functions Gamma(fm::FrictionModel, Σ), randf(fm::FrictionModel, Σ) for efficient computation of the friction tensor and generation of ${\rm Normal}({\bm 0}, {\bm \Gamma})$-distributed Gaussian random numbers from a precomputed diffusion coeffiient matrix Σ.

    2. The sub-module MatrixModels implements various matrix models, which make up a friction model and, in essence, specify (i) properties of the ACE-basis used to evaluate blocks ${\bm \Sigma}_{ij}$ of the difffusion matrix, and (ii) how blocks ${\bm \Sigma}_{ij}$ are combined in the assembly of the friction tensor ${\bm \Gamma}$. The assembly of the friction tensor is governed by what is referred to in Sachs et al., (2024) as the coupling scheme and implements versions of the the pair-wise coupling and row-wise coupling described therein.

    3. The sub-module FrictionFit provides utility functions for training of friction models using the julia machine learning library Flux.jl.

    Prototypical Applications

    Learned models of ${\bm \Gamma}$ (and the corresponding matrix root ${\bm \Sigma}$) can be used to parametrize tensor-valued coefficients in an Itô diffusion process such as a configuration-dependent friction tensor in a kinetic Langevin equation,

    \[\begin{aligned} \dot{{\bm r}} &= - M^{-1}{\bm p},\\ \dot{{\bm p}} &= - \nabla U({\bm r}) - {\bm \Gamma}({\bm r})M^{-1}{\bm p} + \sqrt{2 \beta^{-1}} {\bm \Sigma} \dot{{\bm W}}, -\end{aligned}\]

    or a configuration-dependent diffusion tensor in an overdamped Langevin equation,

    \[\dot{{\bm r}} = - {\bm\Gamma}({\bm r}) \nabla U({\bm r}) + \sqrt{2 \beta^{-1}} {\bm\Sigma}\circ \dot{{\bm W}}. %+ \beta^{-1}{\rm div}({\bm \Gamma}(r)).\]

    The model and code allows imposing additional symmetry constraints on the matrix ${\bm \Gamma}$. In particular, the learned friction-tensor ${\bm \Gamma}$ can be specified to satisfy relevant symmetries for the dynamics (1) to be momentum-conserving, thus enabling learning and simulation Multi-Body Dissipative Particle Dynamics (MD-DPD).

    +\end{aligned}\]

    or a configuration-dependent diffusion tensor in an overdamped Langevin equation,

    \[\dot{{\bm r}} = - {\bm\Gamma}({\bm r}) \nabla U({\bm r}) + \sqrt{2 \beta^{-1}} {\bm\Sigma}\circ \dot{{\bm W}}. %+ \beta^{-1}{\rm div}({\bm \Gamma}(r)).\]

    The model and code allows imposing additional symmetry constraints on the matrix ${\bm \Gamma}$. In particular, the learned friction-tensor ${\bm \Gamma}$ can be specified to satisfy relevant symmetries for the dynamics (1) to be momentum-conserving, thus enabling learning and simulation Multi-Body Dissipative Particle Dynamics (MD-DPD).

    diff --git a/dev/search_index.js b/dev/search_index.js index bf8e9d8..bfc4332 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"fitting-mbdpd/#Fitting-a-Friction-Tensor-for-Simulation-of-(Multi-Body)-Dissipative-Particle-Dynamics","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Friction Tensor for Simulation of (Multi-Body) Dissipative Particle Dynamics","text":"","category":"section"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"In this workflow example we demonstrate how ACEds.jl can be used to fit a momentum-conserving friction tensor as used in Dissipative Particle Dynamics. ","category":"page"},{"location":"fitting-mbdpd/#Background-on-Dissipative-Particle-Dynamics","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Background on Dissipative Particle Dynamics","text":"","category":"section"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"Dissipative particle dynamics can be considered as a special version of the Langevin equation @ref, where the friction tensor Gamma is such that the total momentuum","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"sum_i p_i(t) ","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"is conserved. In order for this to be the case, the friction tensor must satisfy the constraint","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"sum_iGamma_ij = bf 0 text for every j=1dots N_rm at","category":"page"},{"location":"fitting-mbdpd/#Momentum-conserving-Friction-Models-in-ACEds.jl","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Momentum-conserving Friction Models in ACEds.jl","text":"","category":"section"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"ACEds.jl provides utility functions for the construction of momentum-conserving friction models. Namely, the function mbdpd_matrixmodel yields a pair-wise coupled matrix model with additional symmetries such that resulting friction model satisfies the above constraints. For example, ","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"m_cov = mbdpd_matrixmodel(EuclideanVector(), [:X], [:X];\n maxorder=1, \n maxdeg=5, \n rcutbond = 5.0, \n rcutenv = 5.0,\n zcutenv = 5.0,\n n_rep = 1, \n )\nfm= FrictionModel((m_cov=m_cov,)); ","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"results in a momentum-conserving friction model with vector-equivariant blocks in the diffusion matrix. Here, the model is specified for the artifical atom element type :X.","category":"page"},{"location":"fitting-mbdpd/#Fit-Friction-Model-to-Synthetic-DPD-Friction-Data","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fit Friction Model to Synthetic DPD Friction Data","text":"","category":"section"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"The following code loads training and test data comprised of particle configurations and corresponding friction tensors:","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"rdata_train = ACEds.DataUtils.load_h5fdata(\"./data/input/dpd-train-x.h5\"); \nrdata_test = ACEds.DataUtils.load_h5fdata(\"./data/input/dpd-test-x.h5\"); \n\nfdata = Dict(\"train\" => FrictionData.(rdata_train), \n \"test\"=> FrictionData.(rdata_test));\n(n_train, n_test) = length(fdata[\"train\"]), length(fdata[\"test\"])","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"Here the training data is contains friction tensors of 50 configurations each comprised of 64 particles, and the test data contains friction tensors of 10 configurations each comprised of 216 particles. The underlying friction tensors were synthetically generated using the following simple friction model, which is a smooth version of the standard DPD model used in the literature: ","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"Gamma_ij = begincases\ngamma(r_ij) hatbf r_ij otimes hatbf r_ji i neq j \n-sum_k neq i Gamma_ki i = j\nendcases","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"To fit the model we execute exactly the same steps as in the previous example:","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"ffm = FluxFrictionModel(params(fm;format=:matrix, joinsites=true))\nflux_data = Dict( \"train\"=> flux_assemble(fdata[\"train\"], fm, ffm),\n \"test\"=> flux_assemble(fdata[\"test\"], fm, ffm));\n\n\nloss_traj = Dict(\"train\"=>Float64[], \"test\" => Float64[])\nepoch = 0\nbatchsize = 10\nnepochs = 100\nopt = Flux.setup(Adam(1E-2, (0.99, 0.999)),ffm)\ndloader = DataLoader(flux_data[\"train\"], batchsize=batchsize, shuffle=true)\n\nfor _ in 1:nepochs\n epoch+=1\n @time for d in dloader\n ∂L∂m = Flux.gradient(weighted_l2_loss,ffm, d)[1]\n Flux.update!(opt,ffm, ∂L∂m) # method for \"explicit\" gradient\n end\n for tt in [\"test\",\"train\"]\n push!(loss_traj[tt], weighted_l2_loss(ffm,flux_data[tt]))\n end\n println(\"Epoch: $epoch, Abs avg Training Loss: $(loss_traj[\"train\"][end]/n_train)), Test Loss: $(loss_traj[\"test\"][end]/n_test))\")\nend","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"After training for 2000 epochs, the resulting model is almost a perfect fit:","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"(Image: True vs fitted entries of the friction tensor)","category":"page"},{"location":"fitting-mbdpd/#Multi-Body-Dissipative-Particle-Dynamics","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Multi-Body Dissipative Particle Dynamics","text":"","category":"section"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"By specifying maxorder=1 in the above construction of the friction model, we restrict the underlying ACE-basis to only incorporate pair-wise interactions. This is fine for the here considered sythentic data as the underlying toy model is in fact based on only pair-wise interactions. However, in more complex systems the random force and the dissipative force may not decompose to pairwise interactions. To incorporate higher body-order interactions in the friction model, say interactions up to body order 4, we can change the underlying ACE-basis expansion to incorporate correlation terms up to order 3 by setting maxorder=3. ","category":"page"},{"location":"fitting-eft/#Fitting-an-Electronic-Friction-Tensor","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"In this workflow example we demonstrate how ACEds.jl can be used to fit a simple 6 x 6 Electronic friction tensor modeling the non-adiabitic interactions of a hydrogen-atom on a copper surface. ","category":"page"},{"location":"fitting-eft/#Load-Electronic-Friction-Tensor-Data","page":"Fitting an Electronic Friction Tensor","title":"Load Electronic Friction Tensor Data","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"We first use the function load_h5fdata to load the data of friction tensors from a custom-formated hdf5 file and convert the data to the internal data format [FrictionData].","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"using ACEds\n# Load data \nrdata = ACEds.DataUtils.load_h5fdata( \"./test/test-data-100.h5\"); \n# Specify size of training and test data\nn_train = Int(ceil(.8 * length(rdata)))\nn_test = length(rdata) - n_train\n# Partition data into train and test set and convert the data \nfdata = Dict(\"train\" => FrictionData.(rdata[1:n_train]), \n \"test\"=> FrictionData.(rdata[n_train+1:end]));","category":"page"},{"location":"fitting-eft/#Specify-the-Friction-Model","page":"Fitting an Electronic Friction Tensor","title":"Specify the Friction Model","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Next, we specify the matrix models that will make up our friction model. In this case we only specify the single matrix model m_equ, which being of the type RWCMatrixModel is based on a row-wise coupling. ","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"property = EuclideanMatrix()\nspecies_friction = [:H]\nspecies_env = [:Cu]\nm_equ = RWCMatrixModel(property, species_friction, species_env;\n species_substrat = [:Cu],\n rcut = 5.0, \n maxorder = 2, \n maxdeg = 5,\n);","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"The first argument, property, of the constructor, RWCMatrixModel, specifies the equivariance symmetry of blocks. Here, property is of type EuclideanMatrix specifying each block to transform like an Euclidean Matrix. In this modeling application, only hydrogen atoms feel friction, which we specify by setting the second argument species_friction to [:H]. Yet, the friction felt by an hydrogen atom is affected by the presence of both hydrogen atoms and copper atoms in its vicinty, which we specify by setting species_env to [:H, :Cu]. Furthermore, the physics is such that hydrogen models only feel friction if they are in contact with the metal surface. We specify this by setting species_substrat = [:Cu]. For further details and information on the remaining optional arguments see the docomentation of the constructor of RWCMatrixModel.","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Next we build a friction model from the matrix model(s),","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"fm= FrictionModel((mequ=m_equ,)); #fm= FrictionModel((cov=m_cov,equ=m_equ));","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Here, the mequ serves as the \"ID\" of the friction model m_equ within the friction model. The function get_ids returns the model IDs Wof all matrix model makig up a friction model, i.e.,","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"model_ids = get_ids(fm)","category":"page"},{"location":"fitting-eft/#Set-up-the-Training-Pipeline","page":"Fitting an Electronic Friction Tensor","title":"Set up the Training Pipeline","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"To train our model we first extract the parameters from the friction model, which we use to initialize a structure of type FluxFrictionModel, which serves as a wrapper for the parameters","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"c=params(fm) \nffm = FluxFrictionModel(c)","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Next, the function flux_assemble is used to prepare data for training. This includes evaluating the ACE-basis functions of the matrix models in fm on all configurations in the data set. Since the loss function of our model is quartic polynomial in the parameters, we don't need to reevaluate the ACE-basis functions at later stages of the training process.","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"flux_data = Dict( \"train\"=> flux_assemble(fdata[\"train\"], fm, ffm; ),\n \"test\"=> flux_assemble(fdata[\"test\"], fm, ffm));","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Before starting the training we randomize the parameter values of our model and, if CUDA is available on our device, transform parameters to CUDA compatible cuarrays.","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"set_params!(ffm; sigma=1E-8)\n\nusing CUDA\ncuda = CUDA.functional()\n\nif cuda\n ffm = fmap(cu, ffm)\nend","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Finally, we set up the optimizer and data loader, and import the loss functions weighted_l2_loss, which evaluates the training and test loss as","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"mathcalL(c) = Gamma_rm true - W odot Gamma_rm fit(c) _2^2","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"where odot is the entry-wise Hademard product, and W is a weight matrix assembled during the call of flux_assemble.","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"opt = Flux.setup(Adam(1E-3, (0.99, 0.999)),ffm)\ndloader = cuda ? DataLoader(flux_data[\"train\"] |> gpu, batchsize=10, shuffle=true) : DataLoader(flux_data[\"train\"], batchsize=10, shuffle=true)\nusing ACEds.FrictionFit: weighted_l2_loss","category":"page"},{"location":"fitting-eft/#Running-the-Optimizer","page":"Fitting an Electronic Friction Tensor","title":"Running the Optimizer","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Then, we train the model taking 200 passes through the training data: ","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"loss_traj = Dict(\"train\"=>Float64[], \"test\" => Float64[])\nepoch = 0\nnepochs = 100\nfor _ in 1:nepochs\n epoch+=1\n @time for d in dloader\n ∂L∂m = Flux.gradient(weighted_l2_loss,ffm, d)[1]\n Flux.update!(opt,ffm, ∂L∂m) # method for \"explicit\" gradient\n end\n for tt in [\"test\",\"train\"]\n push!(loss_traj[tt], weighted_l2_loss(ffm,flux_data[tt]))\n end\n println(\"Epoch: $epoch, Abs avg Training Loss: $(loss_traj[\"train\"][end]/n_train)), Test Loss: $(loss_traj[\"test\"][end]/n_test))\")\nend\nprintln(\"Epoch: $epoch, Abs Training Loss: $(loss_traj[\"train\"][end]), Test Loss: $(loss_traj[\"test\"][end])\")\nprintln(\"Epoch: $epoch, Avg Training Loss: $(loss_traj[\"train\"][end]/n_train), Test Loss: $(loss_traj[\"test\"][end]/n_test)\")","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Once the training is complete we can extract the updated parameters from the wrapper ffm to parametrize the friction model. ","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"c = params(ffm)\nset_params!(fm, c)","category":"page"},{"location":"fitting-eft/#Evaluating-the-Friction-Model","page":"Fitting an Electronic Friction Tensor","title":"Evaluating the Friction Model","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"The trained friction model can be used to evaluate the friction tensor bm Gamma and diffusion coeccifient matrix bm Sigma at configurations as follows ","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"at = fdata[\"test\"][1].atoms # extract atomic configuration from the test set\nGamma(fm, at) # evaluate the friction tensor\nΣ = Sigma(fm, at) # evaluate the diffusion coeffcient matrix","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"To simulate a Langevin equation, typically, both the friction coefficient and the diffusion coefficient matrix must be evaluated. Instead of evaluating them seperately it is more efficient to first evaluate the diffusion coefficient matrix and then evaluate the friction tensor from the the pre-computed diffusion coefficient matrix:","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Σ = Sigma(fm, at) # evaluate the diffusion coeffcient matrix\nGamma(fm, Σ) # compute the friction tensor from the pre-computeed diffusion coefficient matrix.","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"The diffusion coefficient matrix Sigma can also be used to efficiently generate Gaussian pseudo random numbers rm Normal(0bf Gamma) as ","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"R = randf(fm,Σ)","category":"page"},{"location":"overview/#Model-Overview","page":"Overview","title":"Model Overview","text":"","category":"section"},{"location":"overview/","page":"Overview","title":"Overview","text":"The package ACEds provides an ACE-based implementation of the size-transferrable, E(3)-equivariant models introduced in Sachs et al., (2024) for configuration-dependent friction or diffusion tensors.","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"In a nutshell, the package provides utilities to efficiently learn and evaluate E(3)-equivariant symmetric positive semi-definite matrix functions of the form","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"bm Gamma left ( (bm r_iz_i)_i=1^N_rm at right ) in mathbbR^3 N_rm at times 3N_rm at","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"where the bm r_is are the positions and the z_is are the atomic element types of atoms in an atomic configuration comprised of N_rm at atoms.","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"The underlying model is based on an equivariance-preserving matrix square root decomposition,","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"bm Gamma = bm Sigmabm Sigma^T","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"where block entries of the matrix square root bm Sigmaleft ( (bm r_iz_i)_i=1^N_rm at right ) in mathbbR^3 N_rm at times m with some m in mathbbN, are linearly expanded using an equivariant linear atomic cluster expansion.","category":"page"},{"location":"overview/#Code-Overview","page":"Overview","title":"Code Overview","text":"","category":"section"},{"location":"overview/","page":"Overview","title":"Overview","text":"The package ACEds is comprised of three main sub-modules:","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"The sub-module FrictionModels implements the structure FrictionModel, which facilitates the specification of and evaluation of friction models. The module implements the functions Gamma(fm::FrictionModel, at::Atoms), Sigma(fm::FrictionModel, at::Atoms) which evaluate the friction model fm at the atomic configuration at to the correspong friction tensor bm Gamma and diffusion coefficient matrix bm Sigma, respectively. Moreover, it provides the functions Gamma(fm::FrictionModel, Σ), randf(fm::FrictionModel, Σ) for efficient computation of the friction tensor and generation of rm Normal(bm 0 bm Gamma)-distributed Gaussian random numbers from a precomputed diffusion coeffiient matrix Σ.\nThe sub-module MatrixModels implements various matrix models, which make up a friction model and, in essence, specify (i) properties of the ACE-basis used to evaluate blocks bm Sigma_ij of the difffusion matrix, and (ii) how blocks bm Sigma_ij are combined in the assembly of the friction tensor bm Gamma. The assembly of the friction tensor is governed by what is referred to in Sachs et al., (2024) as the coupling scheme and implements versions of the the pair-wise coupling and row-wise coupling described therein.\nThe sub-module FrictionFit provides utility functions for training of friction models using the julia machine learning library Flux.jl. ","category":"page"},{"location":"overview/#Prototypical-Applications","page":"Overview","title":"Prototypical Applications","text":"","category":"section"},{"location":"overview/","page":"Overview","title":"Overview","text":"Learned models of bm Gamma (and the corresponding matrix root bm Sigma) can be used to parametrize tensor-valued coefficients in an Itô diffusion process such as a configuration-dependent friction tensor in a kinetic Langevin equation,","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"beginaligned\ndotbm r = - M^-1bm p\ndotbm p = - nabla U(bm r) - bm Gamma(bm r)M^-1bm p + sqrt2 beta^-1 bm Sigma dotbm W\nendaligned","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"or a configuration-dependent diffusion tensor in an overdamped Langevin equation,","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"dotbm r = - bmGamma(bm r) nabla U(bm r) + sqrt2 beta^-1 bmSigmacirc dotbm W + beta^-1rm div(bm Gamma(r))","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"The model and code allows imposing additional symmetry constraints on the matrix bm Gamma. In particular, the learned friction-tensor bm Gamma can be specified to satisfy relevant symmetries for the dynamics (1) to be momentum-conserving, thus enabling learning and simulation Multi-Body Dissipative Particle Dynamics (MD-DPD).","category":"page"},{"location":"installation/#Prerequisites","page":"Installation Guide","title":"Prerequisites","text":"","category":"section"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"You will need to have Julia (v1.7 or newer) installed. The latest release and installation instruction for Julia are available here here.","category":"page"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"warning: Warning\nIf you are running Julia for the first time, there is a chance that the General Registrity is not added to you installation. To install the General Registry run the following code from within a Julia REPL.using Pkg\nPkg.Registry.add(\"General\") ","category":"page"},{"location":"installation/#Installation","page":"Installation Guide","title":"Installation","text":"","category":"section"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"The package ACEds and some required dependencies can be downloaded from ACEregistry. To add this registry and install ACEds execute the following steps from within a Julia REPL. ","category":"page"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"Add the ACEregistry registry:\nusing Pkg\nPkg.Registry.add(RegistrySpec(url=\"https://github.com/ACEsuit/ACEregistry\"))\nInstall ACEds:\nPkg.add(\"ACEds\")","category":"page"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"Done! Now you can use the functionality of ACEds in your project by running using ACEds.","category":"page"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"note: Note\nIt is recommended to install ACEds within a dedicated julia environment, where approriate version bounds can be set within the Project.toml file, and versions of dependencies are tracked in a Manifest.toml file. To create a new project, simply create a new directory, navigate to that directory and runPkg.activate(\".\")Then, execute sthe teps 1. and 2. from within the project directory. ","category":"page"},{"location":"function-manual/#Function-Manual","page":"Function Manual","title":"Function Manual","text":"","category":"section"},{"location":"function-manual/#ACEds.FrictionModels.jl","page":"Function Manual","title":"ACEds.FrictionModels.jl","text":"","category":"section"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"CurrentModule = ACEds.FrictionModels","category":"page"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"A friction model is a wrapper around a named tuple of matrix models, i.e. ","category":"page"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"struct FrictionModel{MODEL_IDS} <: AbstractFrictionModel\n matrixmodels::NamedTuple{MODEL_IDS} \nend","category":"page"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"The symbols contained in the tuple MODEL_IDS are referred to as \"IDs\" of the corresponding matrix models. When evaluated at an atomic configuration, the resulting friction tensor is the sum of the friction tensors of all matrix models in the friction model, whereas diffusion coefficient matrices are evaluated seperately for each matrix model and returned in the form of a named tuple of the same signature. The following functions act on structures of type FrictionModel: ","category":"page"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"Gamma","category":"page"},{"location":"function-manual/#ACEds.FrictionModels.Gamma","page":"Function Manual","title":"ACEds.FrictionModels.Gamma","text":"Gamma(fm::FrictionModel, at::Atoms; filter=(_,_)->true, T=Float64)\n\nEvaluates the friction tensor according to the friction model fm at the atomic configuration at::Atoms. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.\n\nArguments:\n\nfm – the friction model of which the friction tensor is evaluated.\nat – the atomic configuration at which the basis is evaluated\nfilter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. Only atoms at[i] for which filter(i,at) returns true are included in the evaluation of the friction tensor. \n\nOutput:\n\nA friction tensor in the form of a sparse 3N x 3N matrix, where N is the number of atoms in the atomic configuration at. \n\n\n\n\n\nGamma(fm::FrictionModel{MODEL_IDS}, Σ_vec::NamedTuple{MODEL_IDS}) where {MODEL_IDS}\n\nComputes the friction tensor from a pre-computed collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all diffusion coefficient matrices in the collection.\n\nArguments:\n\nfm – the friction model of which the friction tensor is evaluated. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.\nΣ – a collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all matrices in Σ.\n\nOutput:\n\nA friction tensor in the form of a sparse 3N x 3N matrix, where N is the number of atoms in the atomic configuration at. The friction tensor is the sum of the symmetric squares SigmaSigma^T of all diffusion coefficient matrices Sigma in Σ_vec.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"Sigma","category":"page"},{"location":"function-manual/#ACEds.FrictionModels.Sigma","page":"Function Manual","title":"ACEds.FrictionModels.Sigma","text":"Sigma(fm::FrictionModel{MODEL_IDS}, at::Atoms; filter=(_,_)->true, T=Float64) where {MODEL_IDS}\n\nComputes the diffusion coefficient matrices for all matrix models in the friction model at a given configuration.\n\nArguments:\n\nfm – the friction model of which the diffusion coefficient matrices are evaluated\nat – the atomic configuration at which the diffusion coefficient matrices are evaluated\nfilter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. Only atoms at[i] for which filter(i,at) returns true are included in the evaluation of the diffusion coefficient matrices.\n\nOutput:\n\nA NamedTuple of diffusion coefficient matrices, where the keys are the IDs of the matrix models in the friction model.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"randf","category":"page"},{"location":"function-manual/#ACEds.MatrixModels.randf","page":"Function Manual","title":"ACEds.MatrixModels.randf","text":"randf(fm::FrictionModel{MODEL_IDS}, Σ::NamedTuple{MODEL_IDS}) where {MODEL_IDS}\n\nGenerates a rm Normal(bm 0 bm Gamma)-distributed Gaussian pseudo random number from a precomputed diffusion coeffiient matrices.\n\nArguments:\n\nfm – the friction model of which the friction tensor is evaluated. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.\nΣ – a collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all matrices in Σ.\n\nOutput:\n\nA rm Normal(bm 0 bm Gamma)-distributed Gaussian vector R::Vector{3,Float64} of length N, where N is the number of atoms in the configuration for which Σ was evaluated.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"basis","category":"page"},{"location":"function-manual/#ACEds.MatrixModels.basis","page":"Function Manual","title":"ACEds.MatrixModels.basis","text":"basis(fm::FrictionModel{MODEL_IDS}, at::Atoms; join_sites=false, filter=(_,_)->true, T=Float64) where {MODEL_IDS}\n\nEvaluates the ACE-basis functions of the friction model fm at the atomic configuration at::Atoms.\n\nArguments:\n\nfm – the friction model of which the basis is evaluated\nat – the atomic configuration at which the basis is evaluated\njoin_sites – (optional, default: false) if true, the basis evaulations of all matrix models are concatenated into a single array. If false, the basis evaluations are returned as a named tuple of the type NamedTuple{MODEL_IDS}.\nfilter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. The atom at[i] will be included in the basis iff filter(i,at) returns true. \n\n\n\n\n\n","category":"function"},{"location":"function-manual/#Setter-and-getter-functions-for-model-parameters","page":"Function Manual","title":"Setter and getter functions for model parameters","text":"","category":"section"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"params","category":"page"},{"location":"function-manual/#ACE.params","page":"Function Manual","title":"ACE.params","text":"params(fm::FrictionModel{MODEL_IDS}) where {MODEL_IDS}\n\nReturns the parameters of all matrix models in the FrictionModel object as a NamedTuple.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"nparams","category":"page"},{"location":"function-manual/#ACE.nparams","page":"Function Manual","title":"ACE.nparams","text":"nparams(fm::FrictionModel{MODEL_IDS}) where {MODEL_IDS}\n\nReturns the total number of scalar parameters of all matrix models in the FrictionModel object.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"set_params!","category":"page"},{"location":"function-manual/#ACE.set_params!","page":"Function Manual","title":"ACE.set_params!","text":"set_params!(fm::FrictionModel, θ::NamedTuple)\n\nSets the parameters of all matrix models in the FrictionModel object whose ID is contained in θ::NamedTuple to the values specified therein.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"set_zero!","category":"page"},{"location":"function-manual/#ACEds.MatrixModels.set_zero!","page":"Function Manual","title":"ACEds.MatrixModels.set_zero!","text":"set_zero!(fm::FrictionModel, model_ids)\n\nSets the parameters of all matrix models in the FrictionModel object to zero.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/#ACEds.MatrixModels.jl","page":"Function Manual","title":"ACEds.MatrixModels.jl","text":"","category":"section"},{"location":"function-manual/#ACEds.FrictionFit.jl","page":"Function Manual","title":"ACEds.FrictionFit.jl","text":"","category":"section"},{"location":"#Introduction","page":"Home","title":"Introduction","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"ACEds.jl facilitates simulation and machine learning of configuration-dependent friction tensor models from data. The models are based on an equivariant Atomic Cluster Expansion (ACE) and as such highly efficient and size transferable. The underlying framework of model construction is described in detail in Sachs et al., (2024). ","category":"page"},{"location":"","page":"Home","title":"Home","text":"For a quick start, we recommend reading the installation instructions and the Overview section followed by the workflow examples. Detailed documentation of front end facing functions can be found in the function manual. ","category":"page"},{"location":"#ACEds-paper","page":"Home","title":"References","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you are using ACEds.jl in your work, please cite the following article: ","category":"page"},{"location":"","page":"Home","title":"Home","text":"Sachs, M., Stark, W. G., Maurer, R. J., & Ortner, C. (2024). Equivariant Representation of Configuration-Dependent Friction Tensors in Langevin Heatbaths. [arxiv]","category":"page"}] +[{"location":"fitting-mbdpd/#Fitting-a-Friction-Tensor-for-Simulation-of-(Multi-Body)-Dissipative-Particle-Dynamics","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Friction Tensor for Simulation of (Multi-Body) Dissipative Particle Dynamics","text":"","category":"section"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"In this workflow example we demonstrate how ACEds.jl can be used to fit a momentum-conserving friction tensor as used in Dissipative Particle Dynamics. ","category":"page"},{"location":"fitting-mbdpd/#Background-on-Dissipative-Particle-Dynamics","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Background on Dissipative Particle Dynamics","text":"","category":"section"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"Dissipative particle dynamics can be considered as a special version of the Langevin equation @ref, where the friction tensor Gamma is such that the total momentuum","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"sum_i p_i(t) ","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"is conserved. In order for this to be the case, the friction tensor must satisfy the constraint","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"sum_iGamma_ij = bf 0 text for every j=1dots N_rm at","category":"page"},{"location":"fitting-mbdpd/#Momentum-conserving-Friction-Models-in-ACEds.jl","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Momentum-conserving Friction Models in ACEds.jl","text":"","category":"section"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"ACEds.jl provides utility functions for the construction of momentum-conserving friction models. Namely, the function mbdpd_matrixmodel yields a pair-wise coupled matrix model with additional symmetries such that resulting friction model satisfies the above constraints. For example, ","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"m_cov = mbdpd_matrixmodel(EuclideanVector(), [:X], [:X];\n maxorder=1, \n maxdeg=5, \n rcutbond = 5.0, \n rcutenv = 5.0,\n zcutenv = 5.0,\n n_rep = 1, \n )\nfm= FrictionModel((m_cov=m_cov,)); ","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"results in a momentum-conserving friction model with vector-equivariant blocks in the diffusion matrix. Here, the model is specified for the artifical atom element type :X.","category":"page"},{"location":"fitting-mbdpd/#Fit-Friction-Model-to-Synthetic-DPD-Friction-Data","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fit Friction Model to Synthetic DPD Friction Data","text":"","category":"section"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"The following code loads training and test data comprised of particle configurations and corresponding friction tensors:","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"rdata_train = ACEds.DataUtils.load_h5fdata(\"./data/input/dpd-train-x.h5\"); \nrdata_test = ACEds.DataUtils.load_h5fdata(\"./data/input/dpd-test-x.h5\"); \n\nfdata = Dict(\"train\" => FrictionData.(rdata_train), \n \"test\"=> FrictionData.(rdata_test));\n(n_train, n_test) = length(fdata[\"train\"]), length(fdata[\"test\"])","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"Here the training data is contains friction tensors of 50 configurations each comprised of 64 particles, and the test data contains friction tensors of 10 configurations each comprised of 216 particles. The underlying friction tensors were synthetically generated using the following simple friction model, which is a smooth version of the standard DPD model used in the literature: ","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"Gamma_ij = begincases\ngamma(r_ij) hatbf r_ij otimes hatbf r_ji i neq j \n-sum_k neq i Gamma_ki i = j\nendcases","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"To fit the model we execute exactly the same steps as in the previous example:","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"ffm = FluxFrictionModel(params(fm;format=:matrix, joinsites=true))\nflux_data = Dict( \"train\"=> flux_assemble(fdata[\"train\"], fm, ffm),\n \"test\"=> flux_assemble(fdata[\"test\"], fm, ffm));\n\n\nloss_traj = Dict(\"train\"=>Float64[], \"test\" => Float64[])\nepoch = 0\nbatchsize = 10\nnepochs = 100\nopt = Flux.setup(Adam(1E-2, (0.99, 0.999)),ffm)\ndloader = DataLoader(flux_data[\"train\"], batchsize=batchsize, shuffle=true)\n\nfor _ in 1:nepochs\n epoch+=1\n @time for d in dloader\n ∂L∂m = Flux.gradient(weighted_l2_loss,ffm, d)[1]\n Flux.update!(opt,ffm, ∂L∂m) # method for \"explicit\" gradient\n end\n for tt in [\"test\",\"train\"]\n push!(loss_traj[tt], weighted_l2_loss(ffm,flux_data[tt]))\n end\n println(\"Epoch: $epoch, Abs avg Training Loss: $(loss_traj[\"train\"][end]/n_train)), Test Loss: $(loss_traj[\"test\"][end]/n_test))\")\nend","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"After training for 2000 epochs, the resulting model is almost a perfect fit:","category":"page"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"(Image: True vs fitted entries of the friction tensor)","category":"page"},{"location":"fitting-mbdpd/#Multi-Body-Dissipative-Particle-Dynamics","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Multi-Body Dissipative Particle Dynamics","text":"","category":"section"},{"location":"fitting-mbdpd/","page":"Fitting a Dissipative Particle Dynamics Friction Model","title":"Fitting a Dissipative Particle Dynamics Friction Model","text":"By specifying maxorder=1 in the above construction of the friction model, we restrict the underlying ACE-basis to only incorporate pair-wise interactions. This is fine for the here considered sythentic data as the underlying toy model is in fact based on only pair-wise interactions. However, in more complex systems the random force and the dissipative force may not decompose to pairwise interactions. To incorporate higher body-order interactions in the friction model, say interactions up to body order 4, we can change the underlying ACE-basis expansion to incorporate correlation terms up to order 3 by setting maxorder=3. ","category":"page"},{"location":"fitting-eft/#Fitting-an-Electronic-Friction-Tensor","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"In this workflow example we demonstrate how ACEds.jl can be used to fit a simple 6 x 6 Electronic friction tensor modeling the non-adiabitic interactions of a hydrogen-atom on a copper surface. ","category":"page"},{"location":"fitting-eft/#Load-Electronic-Friction-Tensor-Data","page":"Fitting an Electronic Friction Tensor","title":"Load Electronic Friction Tensor Data","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"We first use the function load_h5fdata to load the data of friction tensors from a custom-formated hdf5 file and convert the data to the internal data format [FrictionData].","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"using ACEds\n# Load data \nrdata = ACEds.DataUtils.load_h5fdata( \"./test/test-data-100.h5\"); \n# Specify size of training and test data\nn_train = Int(ceil(.8 * length(rdata)))\nn_test = length(rdata) - n_train\n# Partition data into train and test set and convert the data \nfdata = Dict(\"train\" => FrictionData.(rdata[1:n_train]), \n \"test\"=> FrictionData.(rdata[n_train+1:end]));","category":"page"},{"location":"fitting-eft/#Specify-the-Friction-Model","page":"Fitting an Electronic Friction Tensor","title":"Specify the Friction Model","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Next, we specify the matrix models that will make up our friction model. In this case we only specify the single matrix model m_equ, which being of the type RWCMatrixModel is based on a row-wise coupling. ","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"property = EuclideanMatrix()\nspecies_friction = [:H]\nspecies_env = [:Cu]\nm_equ = RWCMatrixModel(property, species_friction, species_env;\n species_substrat = [:Cu],\n rcut = 5.0, \n maxorder = 2, \n maxdeg = 5,\n);","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"The first argument, property, of the constructor, RWCMatrixModel, specifies the equivariance symmetry of blocks. Here, property is of type EuclideanMatrix specifying each block to transform like an Euclidean Matrix. In this modeling application, only hydrogen atoms feel friction, which we specify by setting the second argument species_friction to [:H]. Yet, the friction felt by an hydrogen atom is affected by the presence of both hydrogen atoms and copper atoms in its vicinty, which we specify by setting species_env to [:H, :Cu]. Furthermore, the physics is such that hydrogen models only feel friction if they are in contact with the metal surface. We specify this by setting species_substrat = [:Cu]. For further details and information on the remaining optional arguments see the docomentation of the constructor of RWCMatrixModel.","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Next we build a friction model from the matrix model(s),","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"fm= FrictionModel((mequ=m_equ,)); #fm= FrictionModel((cov=m_cov,equ=m_equ));","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Here, the mequ serves as the \"ID\" of the friction model m_equ within the friction model. The function get_ids returns the model IDs Wof all matrix model makig up a friction model, i.e.,","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"model_ids = get_ids(fm)","category":"page"},{"location":"fitting-eft/#Set-up-the-Training-Pipeline","page":"Fitting an Electronic Friction Tensor","title":"Set up the Training Pipeline","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"To train our model we first extract the parameters from the friction model, which we use to initialize a structure of type FluxFrictionModel, which serves as a wrapper for the parameters","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"c=params(fm) \nffm = FluxFrictionModel(c)","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Next, the function flux_assemble is used to prepare data for training. This includes evaluating the ACE-basis functions of the matrix models in fm on all configurations in the data set. Since the loss function of our model is quartic polynomial in the parameters, we don't need to reevaluate the ACE-basis functions at later stages of the training process.","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"flux_data = Dict( \"train\"=> flux_assemble(fdata[\"train\"], fm, ffm; ),\n \"test\"=> flux_assemble(fdata[\"test\"], fm, ffm));","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Before starting the training we randomize the parameter values of our model and, if CUDA is available on our device, transform parameters to CUDA compatible cuarrays.","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"set_params!(ffm; sigma=1E-8)\n\nusing CUDA\ncuda = CUDA.functional()\n\nif cuda\n ffm = fmap(cu, ffm)\nend","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Finally, we set up the optimizer and data loader, and import the loss functions weighted_l2_loss, which evaluates the training and test loss as","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"mathcalL(c) = Gamma_rm true - W odot Gamma_rm fit(c) _2^2","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"where odot is the entry-wise Hademard product, and W is a weight matrix assembled during the call of flux_assemble.","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"opt = Flux.setup(Adam(1E-3, (0.99, 0.999)),ffm)\ndloader = cuda ? DataLoader(flux_data[\"train\"] |> gpu, batchsize=10, shuffle=true) : DataLoader(flux_data[\"train\"], batchsize=10, shuffle=true)\nusing ACEds.FrictionFit: weighted_l2_loss","category":"page"},{"location":"fitting-eft/#Running-the-Optimizer","page":"Fitting an Electronic Friction Tensor","title":"Running the Optimizer","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Then, we train the model taking 200 passes through the training data: ","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"loss_traj = Dict(\"train\"=>Float64[], \"test\" => Float64[])\nepoch = 0\nnepochs = 100\nfor _ in 1:nepochs\n epoch+=1\n @time for d in dloader\n ∂L∂m = Flux.gradient(weighted_l2_loss,ffm, d)[1]\n Flux.update!(opt,ffm, ∂L∂m) # method for \"explicit\" gradient\n end\n for tt in [\"test\",\"train\"]\n push!(loss_traj[tt], weighted_l2_loss(ffm,flux_data[tt]))\n end\n println(\"Epoch: $epoch, Abs avg Training Loss: $(loss_traj[\"train\"][end]/n_train)), Test Loss: $(loss_traj[\"test\"][end]/n_test))\")\nend\nprintln(\"Epoch: $epoch, Abs Training Loss: $(loss_traj[\"train\"][end]), Test Loss: $(loss_traj[\"test\"][end])\")\nprintln(\"Epoch: $epoch, Avg Training Loss: $(loss_traj[\"train\"][end]/n_train), Test Loss: $(loss_traj[\"test\"][end]/n_test)\")","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Once the training is complete we can extract the updated parameters from the wrapper ffm to parametrize the friction model. ","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"c = params(ffm)\nset_params!(fm, c)","category":"page"},{"location":"fitting-eft/#Evaluating-the-Friction-Model","page":"Fitting an Electronic Friction Tensor","title":"Evaluating the Friction Model","text":"","category":"section"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"The trained friction model can be used to evaluate the friction tensor bm Gamma and diffusion coeccifient matrix bm Sigma at configurations as follows ","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"at = fdata[\"test\"][1].atoms # extract atomic configuration from the test set\nGamma(fm, at) # evaluate the friction tensor\nΣ = Sigma(fm, at) # evaluate the diffusion coeffcient matrix","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"To simulate a Langevin equation, typically, both the friction coefficient and the diffusion coefficient matrix must be evaluated. Instead of evaluating them seperately it is more efficient to first evaluate the diffusion coefficient matrix and then evaluate the friction tensor from the the pre-computed diffusion coefficient matrix:","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"Σ = Sigma(fm, at) # evaluate the diffusion coeffcient matrix\nGamma(fm, Σ) # compute the friction tensor from the pre-computeed diffusion coefficient matrix.","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"The diffusion coefficient matrix Sigma can also be used to efficiently generate Gaussian pseudo random numbers rm Normal(0bf Gamma) as ","category":"page"},{"location":"fitting-eft/","page":"Fitting an Electronic Friction Tensor","title":"Fitting an Electronic Friction Tensor","text":"R = randf(fm,Σ)","category":"page"},{"location":"overview/#Model-Overview","page":"Overview","title":"Model Overview","text":"","category":"section"},{"location":"overview/","page":"Overview","title":"Overview","text":"The package ACEds provides an ACE-based implementation of the size-transferrable, E(3)-equivariant models introduced in Sachs et al., (2024) for configuration-dependent friction or diffusion tensors.","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"In a nutshell, the package provides utilities to efficiently learn and evaluate E(3)-equivariant symmetric positive semi-definite matrix functions of the form","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"bm Gamma left ( (bm r_iz_i)_i=1^N_rm at right ) in mathbbR^3 N_rm at times 3N_rm at","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"where the bm r_is are the positions and the z_is are the atomic element types of atoms in an atomic configuration comprised of N_rm at atoms.","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"The underlying model is based on an equivariance-preserving matrix square root decomposition,","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"bm Gamma = bm Sigmabm Sigma^T","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"where block entries of the matrix square root bm Sigmaleft ( (bm r_iz_i)_i=1^N_rm at right ) in mathbbR^3 N_rm at times m with some m in mathbbN, are linearly expanded using an equivariant linear atomic cluster expansion.","category":"page"},{"location":"overview/#Code-Overview","page":"Overview","title":"Code Overview","text":"","category":"section"},{"location":"overview/","page":"Overview","title":"Overview","text":"The package ACEds is comprised of three main sub-modules:","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"The sub-module FrictionModels implements the structure FrictionModel, which facilitates the specification of and evaluation of friction models. The module implements the functions Gamma(fm::FrictionModel, at::Atoms), Sigma(fm::FrictionModel, at::Atoms) which evaluate the friction model fm at the atomic configuration at to the correspong friction tensor bm Gamma and diffusion coefficient matrix bm Sigma, respectively. Moreover, it provides the functions Gamma(fm::FrictionModel, Σ), randf(fm::FrictionModel, Σ) for efficient computation of the friction tensor and generation of rm Normal(bm 0 bm Gamma)-distributed Gaussian random numbers from a precomputed diffusion coeffiient matrix Σ.\nThe sub-module MatrixModels implements various matrix models, which make up a friction model and, in essence, specify (i) properties of the ACE-basis used to evaluate blocks bm Sigma_ij of the difffusion matrix, and (ii) how blocks bm Sigma_ij are combined in the assembly of the friction tensor bm Gamma. The assembly of the friction tensor is governed by what is referred to in Sachs et al., (2024) as the coupling scheme and implements versions of the the pair-wise coupling and row-wise coupling described therein.\nThe sub-module FrictionFit provides utility functions for training of friction models using the julia machine learning library Flux.jl. ","category":"page"},{"location":"overview/#Prototypical-Applications","page":"Overview","title":"Prototypical Applications","text":"","category":"section"},{"location":"overview/","page":"Overview","title":"Overview","text":"Learned models of bm Gamma (and the corresponding matrix root bm Sigma) can be used to parametrize tensor-valued coefficients in an Itô diffusion process such as a configuration-dependent friction tensor in a kinetic Langevin equation,","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"beginaligned\ndotbm r = - M^-1bm p\ndotbm p = - nabla U(bm r) - bm Gamma(bm r)M^-1bm p + sqrt2 beta^-1 bm Sigma dotbm W\nendaligned","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"or a configuration-dependent diffusion tensor in an overdamped Langevin equation,","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"dotbm r = - bmGamma(bm r) nabla U(bm r) + sqrt2 beta^-1 bmSigmacirc dotbm W + beta^-1rm div(bm Gamma(r))","category":"page"},{"location":"overview/","page":"Overview","title":"Overview","text":"The model and code allows imposing additional symmetry constraints on the matrix bm Gamma. In particular, the learned friction-tensor bm Gamma can be specified to satisfy relevant symmetries for the dynamics (1) to be momentum-conserving, thus enabling learning and simulation Multi-Body Dissipative Particle Dynamics (MD-DPD).","category":"page"},{"location":"installation/#Prerequisites","page":"Installation Guide","title":"Prerequisites","text":"","category":"section"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"You will need to have Julia (v1.7 or newer) installed. The latest release and installation instruction for Julia are available here here.","category":"page"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"warning: Warning\nIf you are running Julia for the first time, there is a chance that the General Registrity is not added to you installation. To install the General Registry run the following code from within a Julia REPL.using Pkg\nPkg.Registry.add(\"General\") ","category":"page"},{"location":"installation/#Installation","page":"Installation Guide","title":"Installation","text":"","category":"section"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"The package ACEds and some required dependencies can be downloaded from ACEregistry. To add this registry and install ACEds execute the following steps from within a Julia REPL. ","category":"page"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"Add the ACEregistry registry:\nusing Pkg\nPkg.Registry.add(RegistrySpec(url=\"https://github.com/ACEsuit/ACEregistry\"))\nInstall ACEds:\nPkg.add(\"ACEds\")","category":"page"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"Done! Now you can use the functionality of ACEds in your project by running using ACEds.","category":"page"},{"location":"installation/","page":"Installation Guide","title":"Installation Guide","text":"note: Note\nIt is recommended to install ACEds within a dedicated julia environment, where approriate version bounds can be set within the Project.toml file, and versions of dependencies are tracked in a Manifest.toml file. To create a new project, simply create a new directory, navigate to that directory and runPkg.activate(\".\")Then, execute sthe teps 1. and 2. from within the project directory. ","category":"page"},{"location":"function-manual/#Function-Manual","page":"Function Manual","title":"Function Manual","text":"","category":"section"},{"location":"function-manual/#ACEds.FrictionModels.jl","page":"Function Manual","title":"ACEds.FrictionModels.jl","text":"","category":"section"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"CurrentModule = ACEds.FrictionModels","category":"page"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"A friction model is a wrapper around a named tuple of matrix models, i.e. ","category":"page"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"struct FrictionModel{MODEL_IDS} <: AbstractFrictionModel\n matrixmodels::NamedTuple{MODEL_IDS} \nend","category":"page"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"The symbols contained in the tuple MODEL_IDS are referred to as \"IDs\" of the corresponding matrix models. When evaluated at an atomic configuration, the resulting friction tensor is the sum of the friction tensors of all matrix models in the friction model, whereas diffusion coefficient matrices are evaluated seperately for each matrix model and returned in the form of a named tuple of the same signature. The following functions act on structures of type FrictionModel: ","category":"page"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"Gamma","category":"page"},{"location":"function-manual/#ACEds.FrictionModels.Gamma","page":"Function Manual","title":"ACEds.FrictionModels.Gamma","text":"Gamma(fm::FrictionModel, at::Atoms; filter=(_,_)->true, T=Float64)\n\nEvaluates the friction tensor according to the friction model fm at the atomic configuration at::Atoms. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.\n\nArguments:\n\nfm – the friction model of which the friction tensor is evaluated.\nat – the atomic configuration at which the basis is evaluated\nfilter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. Only atoms at[i] for which filter(i,at) returns true are included in the evaluation of the friction tensor. \n\nOutput:\n\nA friction tensor in the form of a sparse 3N x 3N matrix, where N is the number of atoms in the atomic configuration at. \n\n\n\n\n\nGamma(fm::FrictionModel{MODEL_IDS}, Σ_vec::NamedTuple{MODEL_IDS}) where {MODEL_IDS}\n\nComputes the friction tensor from a pre-computed collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all diffusion coefficient matrices in the collection.\n\nArguments:\n\nfm – the friction model of which the friction tensor is evaluated. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.\nΣ – a collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all matrices in Σ.\n\nOutput:\n\nA friction tensor in the form of a sparse 3N x 3N matrix, where N is the number of atoms in the atomic configuration at. The friction tensor is the sum of the symmetric squares SigmaSigma^T of all diffusion coefficient matrices Sigma in Σ_vec.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"Sigma","category":"page"},{"location":"function-manual/#ACEds.FrictionModels.Sigma","page":"Function Manual","title":"ACEds.FrictionModels.Sigma","text":"Sigma(fm::FrictionModel{MODEL_IDS}, at::Atoms; filter=(_,_)->true, T=Float64) where {MODEL_IDS}\n\nComputes the diffusion coefficient matrices for all matrix models in the friction model at a given configuration.\n\nArguments:\n\nfm – the friction model of which the diffusion coefficient matrices are evaluated\nat – the atomic configuration at which the diffusion coefficient matrices are evaluated\nfilter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. Only atoms at[i] for which filter(i,at) returns true are included in the evaluation of the diffusion coefficient matrices.\n\nOutput:\n\nA NamedTuple of diffusion coefficient matrices, where the keys are the IDs of the matrix models in the friction model.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"randf","category":"page"},{"location":"function-manual/#ACEds.MatrixModels.randf","page":"Function Manual","title":"ACEds.MatrixModels.randf","text":"randf(fm::FrictionModel{MODEL_IDS}, Σ::NamedTuple{MODEL_IDS}) where {MODEL_IDS}\n\nGenerates a rm Normal(bm 0 bm Gamma)-distributed Gaussian pseudo random number from a precomputed diffusion coeffiient matrices.\n\nArguments:\n\nfm – the friction model of which the friction tensor is evaluated. The friction tensor is the sum of the friction tensors of all matrix models in fm.matrixmodels.\nΣ – a collection of diffusion coefficient matrices. The friction tensor is the sum of the squares of all matrices in Σ.\n\nOutput:\n\nA rm Normal(bm 0 bm Gamma)-distributed Gaussian vector R::Vector{3,Float64} of length N, where N is the number of atoms in the configuration for which Σ was evaluated.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"basis","category":"page"},{"location":"function-manual/#ACEds.MatrixModels.basis","page":"Function Manual","title":"ACEds.MatrixModels.basis","text":"basis(fm::FrictionModel{MODEL_IDS}, at::Atoms; join_sites=false, filter=(_,_)->true, T=Float64) where {MODEL_IDS}\n\nEvaluates the ACE-basis functions of the friction model fm at the atomic configuration at::Atoms.\n\nArguments:\n\nfm – the friction model of which the basis is evaluated\nat – the atomic configuration at which the basis is evaluated\njoin_sites – (optional, default: false) if true, the basis evaulations of all matrix models are concatenated into a single array. If false, the basis evaluations are returned as a named tuple of the type NamedTuple{MODEL_IDS}.\nfilter – (optional, default: (_,_)->true) a filter function of the generic form (i::Int,at::Atoms) -> Bool. The atom at[i] will be included in the basis iff filter(i,at) returns true. \n\n\n\n\n\n","category":"function"},{"location":"function-manual/#Setter-and-getter-functions-for-model-parameters","page":"Function Manual","title":"Setter and getter functions for model parameters","text":"","category":"section"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"params","category":"page"},{"location":"function-manual/#ACE.params","page":"Function Manual","title":"ACE.params","text":"params(fm::FrictionModel{MODEL_IDS}) where {MODEL_IDS}\n\nReturns the parameters of all matrix models in the FrictionModel object as a NamedTuple.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"nparams","category":"page"},{"location":"function-manual/#ACE.nparams","page":"Function Manual","title":"ACE.nparams","text":"nparams(fm::FrictionModel{MODEL_IDS}) where {MODEL_IDS}\n\nReturns the total number of scalar parameters of all matrix models in the FrictionModel object.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"set_params!","category":"page"},{"location":"function-manual/#ACE.set_params!","page":"Function Manual","title":"ACE.set_params!","text":"set_params!(fm::FrictionModel, θ::NamedTuple)\n\nSets the parameters of all matrix models in the FrictionModel object whose ID is contained in θ::NamedTuple to the values specified therein.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/","page":"Function Manual","title":"Function Manual","text":"set_zero!","category":"page"},{"location":"function-manual/#ACEds.MatrixModels.set_zero!","page":"Function Manual","title":"ACEds.MatrixModels.set_zero!","text":"set_zero!(fm::FrictionModel, model_ids)\n\nSets the parameters of all matrix models in the FrictionModel object to zero.\n\n\n\n\n\n","category":"function"},{"location":"function-manual/#ACEds.MatrixModels.jl","page":"Function Manual","title":"ACEds.MatrixModels.jl","text":"","category":"section"},{"location":"function-manual/#ACEds.FrictionFit.jl","page":"Function Manual","title":"ACEds.FrictionFit.jl","text":"","category":"section"},{"location":"#Introduction","page":"Home","title":"Introduction","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The julia package ACEds.jl facilitates simulation and machine learning of configuration-dependent friction tensor models from data. The models are based on an equivariant Atomic Cluster Expansion (ACE) and, as such, are computationally highly efficient and size transferable. The underlying framework of model construction is described in detail in Sachs et al., (2024). ","category":"page"},{"location":"","page":"Home","title":"Home","text":"For a quick start, we recommend reading the Installation Instructions and the Overview section, followed by the workflow examples. Detailed documentation of front-end-facing functions can be found in the function manual. ","category":"page"},{"location":"#ACEds-paper","page":"Home","title":"References","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you are using ACEds.jl in your work, please cite the following article: ","category":"page"},{"location":"","page":"Home","title":"Home","text":"Sachs, M., Stark, W. G., Maurer, R. J., & Ortner, C. (2024). Equivariant Representation of Configuration-Dependent Friction Tensors in Langevin Heatbaths. [arxiv]","category":"page"}] }