Skip to content

Commit eef2476

Browse files
authored
Merge branch 'main' into data-save
2 parents 4ef86fe + e721b84 commit eef2476

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+669
-327
lines changed

.github/workflows/Tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
uses: julia-actions/setup-julia@latest
4040
with:
4141
# The Julia version to download (if necessary) and use.
42-
version: 1.8
42+
version: 1.11
4343
# Display InteractiveUtils.versioninfo() after installing
4444
show-versioninfo: true # optional, default is false
4545
- run: |

.github/workflows/documentation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
push:
55
branches:
66
- main # update to match your development branch (master, main, dev, trunk, ...)
7-
tags: 'v0.0.01'
7+
tags: 'v0.1.0'
88
pull_request:
99

1010
jobs:

Project.toml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
name = "ACEfriction"
22
uuid = "986aa7fc-b7ff-4dfb-8e8f-cd394e358ae2"
33
authors = ["Matthias Sachs <e.matthias.sachs@gmail.com> and Christoph Ortner <c.ortner@warwick.ac.uk>"]
4-
version = "0.0.2"
4+
version = "0.1.2"
55

66
[deps]
7-
ACE = "3e8ccfd2-c8b0-11ea-32f1-f3a5990fd77a"
87
ACEbase = "14bae519-eb20-449c-a949-9c58ed33163e"
9-
ACEbonds = "d0dfcdf4-f9d4-4d39-8ac7-72ac73934171"
8+
ACEfrictionCore = "78da5da9-a47b-43cd-ab26-de0acd0e91ff"
109
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
1110
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
1211
Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
@@ -25,11 +24,18 @@ Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
2524
cuDNN = "02a925ec-e4fe-4b08-9a7e-0d78e3d38ccd"
2625

2726
[compat]
28-
ACE = "0.12.45"
29-
ACEbonds = "0.0.8"
30-
JuLIP = "0.14"
27+
ACEfrictionCore = "0.1.1"
28+
CUDA = "5.5"
29+
Flux = "0.14, 0.15, 0.16"
30+
HDF5 = "0.17"
31+
JuLIP = "0.16"
32+
KernelAbstractions = "0.9"
33+
NeighbourLists = "0.5"
34+
ProgressMeter = "1.11"
3135
StaticArrays = "1.0"
32-
julia = "1.7"
36+
Tullio = "0.3"
37+
Zygote = "0.6"
38+
julia = "1.11"
3339

3440
[extras]
3541
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

docs/make.jl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,17 @@ makedocs(;
2929
"Fitting an Electronic Friction Tensor" => "fitting-eft.md",
3030
"Fitting a Dissipative Particle Dynamics Friction Model" => "fitting-mbdpd.md"
3131
],
32-
"Function Manual" => Any[
33-
"function-manual.md",
32+
# "Importing & Exporting Friction Data" => Any[
33+
# "data-import-export.md",
34+
# ],
35+
# "Function Manual" => Any[
36+
# "function-manual.md"
37+
# ]
38+
"Function Manual" => Any[
39+
"ACEfriction.FrictionModels" => "./function-manual/ACEfriction.FrictionModels.md",
40+
"ACEfriction.MatrixModels" => "./function-manual/ACEfriction.MatrixModels.md",
41+
"ACEfriction.FrictionFit" => "./function-manual/ACEfriction.FrictionFit.md",
42+
"ACEfriction.DataUtils" => "./function-manual/ACEfriction.DataUtils.md"
3443
]
3544
]
3645
)

docs/runLiveServer.jl

Whitespace-only changes.

docs/src/data-import-export.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Friction Data
2+
3+
To train a friction tensor model in ACEfriciton.jl, friction data
4+
$D = (R_i,\Gamma_i)_{i=1}^{N_{\rm obs}}$ comprised of atomic configurations, $R_i$, and a friction tensors, $\Gamma_i$ is required.
5+
6+
`ACEfriction.jl` implements the structure `FrictionData` to store and manipulate single observations $(R_i,\Gamma_i)$ in the pre-training phase:
7+
```julia
8+
struct FrictionData
9+
atoms
10+
friction_tensor
11+
friction_indices
12+
end
13+
```
14+
where
15+
- `atoms` -- stores data of the atomic configuration ans is assumed to be of type `JuLIP.Atoms`,
16+
- `friction_tensor` -- stores data on the friction tensor and is assumed to be of type`SparseMatrix{SMatrix{3, 3, T, 9}}`, where `T<:Float` and `Ti<:Int`. That is, the friction tensor is stored in the form of sparse matrices with $3 \times 3$-matrix valued block entries,
17+
-`friction_indices` -- is a one-dimensional integer array, which contains all atom indices for which the friction tensor is defined.
18+
19+
# Importing & Exporting Friction Data
20+
21+
`ACEfriction.DataUtils` implements the function [`save_h5fdata(rdata::Vector{FrictionData}, filename::String)`](@ref) to save arrays of friction data to a custom costum formatted `hdf5` file, as well as the function [`load_h5fdata(filename::String)`](@ref) to load friction data from such costum formatted `hdf5` files.
22+
23+
24+
# Custom HDF5 File Format for Friction Data
25+
26+
The hierachical structure of such hdf5 files is as follows:
27+
28+
Each observation $(R_i,\Gamma_i)$ is saved in a separate group in named by respective index $i$, i.e., we have the following groups on root level of the hdf5 file:
29+
```
30+
├─ 📂 1
31+
├─ 📂 2
32+
├─ 📂 3
33+
│ :
34+
├─ 📂 N_obs
35+
```
36+
Within each of these groups, the data of the respective atomic configuration $R_i$ and friction tensor $\Gamma_i$ are saved in the subgroups `atoms` and `friction_tensor`, respectively:
37+
```
38+
├─ 📂 i # Index of data point
39+
├─ 📂 atoms # Atom configuration data
40+
│ ├─ 🔢 atypes
41+
│ ├─ 🔢 cell
42+
│ │ └─ 🏷️ column_major
43+
│ ├─ 🔢 pbc
44+
│ └─ 🔢 positions
45+
│ └─ 🏷️ column_major
46+
└─ 📂 friction_tensor # Friction tensor data
47+
├─ 🔢 ft_I
48+
├─ 🔢 ft_J
49+
├─ 🔢 ft_mask
50+
└─ 🔢 ft_val,
51+
└─ 🏷️ column_major
52+
```
53+
54+
[Datasets](https://support.hdfgroup.org/documentation/hdf5/latest/_h5_d__u_g.html) in the group `atoms` store the equivalent information provided by the attributes `positions`, `numbers`, `cell`, and `pbc` of [atoms objects](https://wiki.fysik.dtu.dk/ase/ase/atoms.html), i.e.,
55+
an atomic configuration of N atoms is described by the following datasets contained in the group `atoms`:
56+
- `atypes` -- A one-dimensional Integer dataset of length N. The ith entry corresponds to the atomic element number of the ith atom in the configuration. (Note: `types` corresponds to the atoms attribute `numbers` in the ase.)
57+
- `cell` -- A two-dimensional Float64 dataset of size 3 x 3.
58+
- `pbc` -- A one-dimensional Integer array of length 3 indicating the periodicity properties of the xyz dimension, e.g., `pbc = [1,0,0]` describes periodic boundary conditions in x dimension and non-periodic boundary conditions in the y and z dimensions.
59+
- `positions` -- A two-dimensional Float64 dataset of size n N x 3. The ith column corresponds to the position of the ith atom in the configuration
60+
61+
[Datasets](https://support.hdfgroup.org/documentation/hdf5/latest/_h5_d__u_g.html) in the group `friction_tensor` store the friction tensor as a N x N sparse matrix with 3x3 valued block entries, i.e., a friction tensor with m non-zero 3x3 blocks is stored
62+
- `ft_I` -- A one-dimensional Integer dataset of length m specifying the column indices of non-zero block entries of the friction tensor.
63+
- `ft_J` -- A one-dimensional Integer dataset of length m specifying the row indices of non-zero block entries of the friction tensor.
64+
- `ft_val` -- A three-dimensional Float64 dataset of size m x 3 x 3 specifying the values of the non-zero 3 x 3 block entries of the friction tensor. For example, the 3 x 3 array `ft_val[k,:,:]` corresponds to the 3 x 3 block entry of the friction tensor with column index `ft_I[k]`, and row index `ft_J[k]`.
65+
- `ft_mask` -- A one-dimensional Integer dataset/list containg the indices of atoms for which friction information is provided.
66+
67+
68+
!!! note
69+
All two or three-dimensional datasets in the groups `atoms` have an additional attribute `column_major`. If the hdf5 file is created in a language that stores matrices in column-major form (e.g., julia), this attribute must be set to 1 (True). If the hdf5 file is created in a language that stores matrices in column-major form (e.g., python), this attribute must be set to 0 (False).
70+
71+

docs/src/fitting-eft.md

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
In this workflow example we demonstrate how `ACEfriction.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.
44

55
## Load Electronic Friction Tensor Data
6-
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].
6+
We first use the function [load_h5fdata](@ref) to load the data of friction tensors from a [custom-formated](@ref costum-hdf5-format) hdf5 file and convert the data to the internal data format [FrictionData](@ref friction-data-representation).
77
```julia
88
using ACEfriction
99
# Load data
@@ -12,12 +12,12 @@ rdata = ACEfriction.DataUtils.load_h5fdata( "./test/test-data-100.h5");
1212
n_train = Int(ceil(.8 * length(rdata)))
1313
n_test = length(rdata) - n_train
1414
# Partition data into train and test set and convert the data
15-
fdata = Dict("train" => FrictionData.(rdata[1:n_train]),
16-
"test"=> FrictionData.(rdata[n_train+1:end]));
15+
fdata = Dict("train" => rdata[1:n_train],
16+
"test"=> rdata[n_train+1:end]);
1717
```
1818

1919
## Specify the Friction Model
20-
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.
20+
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](@ref) is based on a row-wise coupling. Alternative code for building a friction model with a pairwise coupling [PWCMatrixModel](@ref) is provided in [the last of section of this working example](@ref fitting-pairwise-coupling).
2121
```julia
2222
property = EuclideanMatrix()
2323
species_friction = [:H]
@@ -29,7 +29,7 @@ m_equ = RWCMatrixModel(property, species_friction, species_env;
2929
maxdeg = 5,
3030
);
3131
```
32-
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]().
32+
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](@ref).
3333

3434
Next we build a friction model from the matrix model(s),
3535
```julia
@@ -46,7 +46,7 @@ To train our model we first extract the parameters from the friction model, whic
4646
c=params(fm)
4747
ffm = FluxFrictionModel(c)
4848
```
49-
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.
49+
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.
5050
```julia
5151
flux_data = Dict( "train"=> flux_assemble(fdata["train"], fm, ffm; ),
5252
"test"=> flux_assemble(fdata["test"], fm, ffm));
@@ -119,4 +119,32 @@ The diffusion coefficient matrix $\Sigma$ can also be used to efficiently genera
119119
R = randf(fm,Σ)
120120
```
121121

122+
## [Friction Model with a Pairwise Coupling](@id fitting-pairwise-coupling)
123+
Instead of using a row-wise coupling, we can also use a pair-wise coupling to construct a friction model. The following code produces a friction model with a pair-wise coupling:
124+
```julia
125+
property = EuclideanMatrix(Float64)
126+
species_friction = [:H]
127+
species_env = [:Cu,:H]
128+
129+
m_equ = PWCMatrixModel(property, species_friction, species_env;
130+
z2sym = NoZ2Sym(),
131+
speciescoupling = SpeciesUnCoupled(),
132+
species_substrat = [:Cu],
133+
n_rep = 1,
134+
maxorder=2,
135+
maxdeg=5,
136+
rcut= 5.0,
137+
);
138+
139+
m_equ0 = OnsiteOnlyMatrixModel(property, species_friction, species_env;
140+
species_substrat=[:Cu],
141+
id=:equ0,
142+
n_rep = 1,
143+
rcut = rcut,
144+
maxorder=2,
145+
maxdeg=5
146+
);
147+
148+
fm= FrictionModel((mequ_off = m_equ, mequ_on=m_equ0));
122149

150+
```

docs/src/fitting-mbdpd.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ The following code loads training and test data comprised of particle configurat
3434
rdata_train = ACEfriction.DataUtils.load_h5fdata("./examples/data/dpd-train-x.h5");
3535
rdata_test = ACEfriction.DataUtils.load_h5fdata("./examples/data/dpd-train-x.h5");
3636

37-
fdata = Dict("train" => FrictionData.(rdata_train),
38-
"test"=> FrictionData.(rdata_test));
37+
fdata = Dict("train" => rdata_train,
38+
"test"=> rdata_test);
3939
(n_train, n_test) = length(fdata["train"]), length(fdata["test"])
4040
```
4141
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 heuristic DPD friction models commonly used in simulations:
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
```@meta
2+
CurrentModule = ACEfriction.DataUtils
3+
```
4+
5+
The submodule `ACEfriction.DataUtils.jl` provides structures to internally store friction data in `ACEfriction.jl` and functions to import and export friction data from and to custom formatted hdf5 files.
6+
7+
8+
### [Friction Data representation](@id friction-data-representation)
9+
10+
For pre-training storage and manipulation of friction data,
11+
`ACEfriction.jl` implements the structure `FrictionData` to represent a single observation $(R_i,\Gamma_i)$ of an atomic configuration $R_i$ and corresponding friction tensor $\Gamma_i$:
12+
```julia
13+
struct FrictionData
14+
atoms
15+
friction_tensor
16+
friction_indices
17+
end
18+
```
19+
where
20+
- `atoms` -- stores data of the atomic configuration ans is assumed to be of type `JuLIP.Atoms`,
21+
- `friction_tensor` -- stores data on the friction tensor and is assumed to be of type`SparseMatrix{SMatrix{3, 3, T, 9}}`, where `T<:Float` and `Ti<:Int`. That is, the friction tensor is stored in the form of sparse matrices with $3 \times 3$-matrix valued block entries,
22+
- `friction_indices` -- is a one-dimensional integer array, which contains all atom indices for which the friction tensor is defined.
23+
24+
### Importing & Exporting Friction Data
25+
26+
`ACEfriction.DataUtils` implements the function [`save_h5fdata`](@ref) to save arrays of friction data to a [custom formatted](@ref costum-hdf5-format) `hdf5` file, as well as the function [`load_h5fdata`](@ref) to load friction data from such costum formatted `hdf5` files:
27+
28+
```@docs
29+
save_h5fdata
30+
```
31+
32+
```@docs
33+
load_h5fdata
34+
```
35+
36+
37+
### [Custom HDF5 File Format for Friction Data](@id costum-hdf5-format)
38+
39+
The hierachical structure of such hdf5 files is as follows:
40+
41+
Each observation $(R_i,\Gamma_i)$ is saved in a separate group in named by respective index $i$, i.e., we have the following groups on root level of the hdf5 file:
42+
```
43+
├─ 📂 1
44+
├─ 📂 2
45+
├─ 📂 3
46+
│ :
47+
├─ 📂 N_obs
48+
```
49+
Within each of these groups, the data of the respective atomic configuration $R_i$ and friction tensor $\Gamma_i$ are saved in the subgroups `atoms` and `friction_tensor`, respectively:
50+
```
51+
├─ 📂 i # Index of data point
52+
├─ 📂 atoms # Atom configuration data
53+
│ ├─ 🔢 atypes
54+
│ ├─ 🔢 cell
55+
│ │ └─ 🏷️ column_major
56+
│ ├─ 🔢 pbc
57+
│ └─ 🔢 positions
58+
│ └─ 🏷️ column_major
59+
└─ 📂 friction_tensor # Friction tensor data
60+
├─ 🔢 ft_I
61+
├─ 🔢 ft_J
62+
├─ 🔢 ft_mask
63+
└─ 🔢 ft_val,
64+
└─ 🏷️ column_major
65+
```
66+
67+
[Datasets](https://support.hdfgroup.org/documentation/hdf5/latest/_h5_d__u_g.html) in the group `atoms` store the equivalent information provided by the attributes `positions`, `numbers`, `cell`, and `pbc` of [atoms objects](https://wiki.fysik.dtu.dk/ase/ase/atoms.html), i.e.,
68+
an atomic configuration of N atoms is described by the following datasets contained in the group `atoms`:
69+
- `atypes` -- A one-dimensional Integer dataset of length N. The ith entry corresponds to the atomic element number of the ith atom in the configuration. (Note: `types` corresponds to the atoms attribute `numbers` in the ase.)
70+
- `cell` -- A two-dimensional Float64 dataset of size 3 x 3.
71+
- `pbc` -- A one-dimensional Integer array of length 3 indicating the periodicity properties of the xyz dimension, e.g., `pbc = [1,0,0]` describes periodic boundary conditions in x dimension and non-periodic boundary conditions in the y and z dimensions.
72+
- `positions` -- A two-dimensional Float64 dataset of size n N x 3. The ith column corresponds to the position of the ith atom in the configuration
73+
74+
[Datasets](https://support.hdfgroup.org/documentation/hdf5/latest/_h5_d__u_g.html) in the group `friction_tensor` store the friction tensor as a N x N sparse matrix with 3x3 valued block entries, i.e., a friction tensor with m non-zero 3x3 blocks is stored
75+
- `ft_I` -- A one-dimensional Integer dataset of length m specifying the column indices of non-zero block entries of the friction tensor.
76+
- `ft_J` -- A one-dimensional Integer dataset of length m specifying the row indices of non-zero block entries of the friction tensor.
77+
- `ft_val` -- A three-dimensional Float64 dataset of size m x 3 x 3 specifying the values of the non-zero 3 x 3 block entries of the friction tensor. For example, the 3 x 3 array `ft_val[k,:,:]` corresponds to the 3 x 3 block entry of the friction tensor with column index `ft_I[k]`, and row index `ft_J[k]`.
78+
- `ft_mask` -- A one-dimensional Integer dataset/list containg the indices of atoms for which friction information is provided.
79+
80+
81+
!!! warning
82+
All two or three-dimensional datasets in the groups `atoms` and `friction_tensor` have an additional attribute `column_major`. If the hdf5 file is created in a language that stores matrices in column-major form (e.g., julia), this attribute must be set to 1 (True). If the hdf5 file is created in a language that stores matrices in column-major form (e.g., python), this attribute must be set to 0 (False).
83+
84+
85+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
```@meta
2+
CurrentModule = ACEfriction.FrictionFit
3+
```
4+
5+
```@docs
6+
flux_assemble
7+
```
8+
```@docs
9+
FluxFrictionModel
10+
```
11+
12+
```@docs
13+
get_ids
14+
```
15+
```@docs
16+
l2_loss
17+
```
18+
```@docs
19+
weighted_l2_loss
20+
```
21+
```@docs
22+
weighted_l1_loss
23+
```

0 commit comments

Comments
 (0)