use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SeAConfig {
pub rcut: f64,
pub rcut_smth: f64,
pub sel: Vec<usize>,
#[serde(default = "default_embedding_neuron")]
pub neuron: Vec<usize>,
#[serde(default = "default_axis_neuron")]
pub axis_neuron: usize,
#[serde(default)]
pub resnet_dt: bool,
#[serde(default = "default_type_one_side")]
pub type_one_side: bool,
#[serde(default = "default_activation")]
pub activation_function: String,
#[serde(default)]
pub type_map: Option<Vec<String>>,
}
fn default_embedding_neuron() -> Vec<usize> {
vec![24, 48, 96]
}
fn default_axis_neuron() -> usize {
8
}
fn default_type_one_side() -> bool {
true
}
fn default_activation() -> String {
"tanh".into()
}
impl SeAConfig {
pub fn ntypes(&self) -> usize {
self.sel.len()
}
pub fn nnei(&self) -> usize {
self.sel.iter().sum()
}
pub fn ng(&self) -> usize {
*self
.neuron
.last()
.expect("se_e2_a: neuron list must be non-empty")
}
pub fn dim_out(&self) -> usize {
self.ng() * self.axis_neuron
}
pub fn sel_cumsum(&self) -> Vec<usize> {
let mut acc = Vec::with_capacity(self.sel.len() + 1);
let mut s = 0usize;
acc.push(0);
for &n in &self.sel {
s += n;
acc.push(s);
}
acc
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct EnerFittingConfig {
pub ntypes: usize,
pub dim_descrpt: usize,
#[serde(default = "default_dim_out")]
pub dim_out: usize,
#[serde(default = "default_fitting_neuron")]
pub neuron: Vec<usize>,
#[serde(default = "default_resnet_dt")]
pub resnet_dt: bool,
#[serde(default)]
pub numb_fparam: usize,
#[serde(default)]
pub numb_aparam: usize,
#[serde(default)]
pub dim_case_embd: usize,
#[serde(default = "default_activation")]
pub activation_function: String,
#[serde(default = "default_mixed_types_fitting")]
pub mixed_types: bool,
}
fn default_dim_out() -> usize {
1
}
fn default_fitting_neuron() -> Vec<usize> {
vec![120, 120, 120]
}
fn default_resnet_dt() -> bool {
true
}
fn default_mixed_types_fitting() -> bool {
true
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DPModelConfig {
pub descriptor: SeAConfig,
pub fitting_net: EnerFittingConfig,
#[serde(default)]
pub type_map: Option<Vec<String>>,
}
impl DPModelConfig {
pub fn new(rcut: f64, rcut_smth: f64, sel: Vec<usize>) -> Self {
let ntypes = sel.len();
let descriptor = SeAConfig {
rcut,
rcut_smth,
sel,
neuron: default_embedding_neuron(),
axis_neuron: default_axis_neuron(),
resnet_dt: false,
type_one_side: true,
activation_function: default_activation(),
type_map: None,
};
let fitting_net = EnerFittingConfig {
ntypes,
dim_descrpt: descriptor.dim_out(),
dim_out: 1,
neuron: default_fitting_neuron(),
resnet_dt: true,
numb_fparam: 0,
numb_aparam: 0,
dim_case_embd: 0,
activation_function: default_activation(),
mixed_types: true,
};
Self {
descriptor,
fitting_net,
type_map: None,
}
}
}