### Fixed
- Renamed `AngularSymmetryFunction9` to `AngularSymmetryFunction3` in the code.
No changes to input.nn are necessary.
- the weight initialization (see "changed" for more details).
- 3G and Hirshfeld prediction via LAMMPS interface are working correctly (again).
- Segfaults in `LayerDense` get_parameters and `set_parameters` for the latest
ifx and gfortran compilers were fixed by using `present_and_true`.
- 4G stress is now working correctly again. It was previously false for all but
the first atom for some (rather unusual) training datasets.
- 3G training is using the correct feature calculator setup and weight
initialization again.
- Fixed calculation of long-range contributions for 3G training.
- 2G training update order was fixed to retain the same behavior as RuNNer 1.3.
- Fixed various compiler warnings with gfortran, ifort, and ifx.
- All 2G and 4G regression tests in the examples repo are now compatible with
the latest version of RuNNer again.
- The number of updates during parallel training is now counted correctly.
- Fixed array bound mismatches and an index bug during neighbor list transfer
in the LAMMPS interface.
- `energy_fraction` keyword is functional again.
- writing of features to a binary dump or an ASCII file has been fixed.
- the calculation of loss and loss gradients during energy and force training
for `batchsize_structure` > 1 has been fixed.
- A double-counting mistake in `calculate_feature_derivatives_towards_atom` has
been fixed.
### Added
- This CHANGELOG file.
- Angular SF type 9 according to the RuNNer documentation, called
`AngularSymmetryFunction9` in the code and corresponding unit tests.
Request it in input.nn with e.g. `symfunction_short H 9 O O ...`.
- Add the option to turn `calculate_forces` and/or `calculate_stress` on during
training.
- This enables the user to calculate the force RMSE during energy training
without using forces for an update.
- By default, both keywords are turned off. `use_forces` will implicitely
turn on `calculate_forces`.
- Turning on `calculate_stress` is possible, but no additional output files
will be written at this point.
- If either option is turned on, a warning message will automatically be added
to the global warning handler.
- `NeighborGrid` type for handling gridwise loops over neighbors in a
single structure
- application of `NeighborGrid` type in `find_neighbors_grid`, the PPPM solver
real-space contribution and all Ewald summation real-space contributions.
- LAMMPS interface:
- 4G prediction
- unit conversion read from LAMMPS input file. The keywords are `cflength` and
`cfenergy`. They work exactly as in n2p2.
- new keyword `dir` for specifying the path to the RuNNer input files. This
works the same as in n2p2.
- additional CI stage that catches all compiler warnings.
- all regression tests in the examples repo now run as part of the CI pipeline
(has to be manually triggered and is required for any merge to main).
- New unittest for results sort routine.
- d_chain_d_features is now OMP-parallelized.
- During training, the code now prints the elapsed time since the last RMSE was
calculated (with default settings, this is the time for a single epoch).
### Changed
- separated the `AbstractOptimizer` and `AbstractMLModel` classes from each other.
- removed the `AbstractMLModel` class
- makes the hierarchy of the model classes much more flat.
- The previously type-bound procedures are translated into a set of more
generic `initialize_array` routines in `mod_initialize_array`.
- modified the `get_parameters`, `set_parameters`, and
`get_gradients_wrt_parameters` interfaces of the `AbstractPropertyModel` class.
They now take the `atomic_numbers` and `optimizer_idx` as additional optional
arguments.
- This allowed us to completely remove the `trainable_models` variable
(which was messy).
- changed the `update_optimizers` building block accordingly. The interfaces
should new be much clearer and work for a single and multiple models.
- the optimizers are read from input.nn in a different format. Instead of
```
optimizer_types 4 4
kalman_nue 0.98
...
```
it is now
```
optimizer 1 kalman nue=...
opt_short 28 1
```
This works for all optimizers. This makes it very easy to train models with
different combinations of optimizers and models.
- the `gradient_divisor` keyword now also takes the value `num_atoms` in
input.nn (previously only `num_backward_passes`).
The default is `num_atoms`, which is the behavior of RuNNer 1.
- many bugs in the weight initilization were fixed. The weight initialization is
now much more stable and should work for most cases.
- the syntax for the weight initialization in input.nn was changed. Use
```
initialization_method <method for hidden layers> <method for output layer>
```
supported values for `<method for hidden layers>` are:
- 'read': Read weights from file. Turns of preconditioning.
- 'xavier' or 'glorot': Xavier initialization
- 'xavier_modified' or 'glorot_modified': Modified Xavier initialization
- 'nguyen_widrow': Nguyen-Widrow initialization
- 'nguyen_widrow_legacy' or 'nguyen_widrow_runner1': Nguyen-Widrow
initialization as in RuNNer 1
- 'uniform': Uniform initialization
- 'normal' or 'gaussian': Normal initialization
- 'zero': Initialize all weights and biases to zero
supported values for `<method for output layer>` are:
- 'eckhoff': As described in J. Chem. Phys. 153, 164107 (2020)
- 'eckhoff_modified': As described in J. Chem. Phys. 153, 164107 (2020)
- 'uniform': Draw values from a uniform distribution.
- 'normal' or 'gaussian': Draw values from a normal distribution.
- 'nw_last_layer_runner1', 'uniform05' or 'nw_last_layer_legacy':
Uniform initialization from -0.5 to 0.5 as it was done in RuNNer 1
if Nguyen-Widrow was applied.
- 'zero': Initialize all weights and biases to zero
- 'precondition_anyway': Only allowed if `<method for hidden layers>` is
`read`. Preconditioning is applied even if the weights are read from file.
- the syntax for the preconditioning in input.nn was changed. Use
```
precondition_method <method>
```
the only currently supported value for `<method>` is `default` which is the
behavior of RuNNer 1.
- old initialization keywords (use_old_weights, precondition_weights...) were
removed and will throw an error if used.
This is more consistent with the other keywords in input.nn.
- energy.out prints an additional column for the vdw energy and for the sum of
total energy and VDW contribution. This will be changed again in the near
future.
- Significant improvement of the prediction and training performance, most
importantly for the LAMMPS interface.
- FeatureMap interfaces were all changed from functions to subroutines.
- sorting of features and feature derivatives is now only applied during
packing or chaining, not directly during the calculation. This dramatically
improves the ability of the compiler to vectorize the angular symmetry function
derivative calculations for type 3 and type 9 which results in an almost 300%
performance increase for predictions through the LAMMPS interface.
- All loops were checked and possibly rearranged for optimal speedup.
- Additional bottlenecks in large-scale LAMMPS simulations were identified
and resolved.
- removed the `DynamicFeatureMapArray` class (which caused an ICE with ifort
2021.7.0)
- p_initial (Kalman correlation matrix initialization) defaults to 1.0
- The results class has been generalized and allows for storage, MPI collecation
and summation of arbitrary atomic and structural properties.