Skip to content

Commit 686f38b

Browse files
Merge pull request #20 from ICAMS/feature/zbl
Add support of ZBL core-repulsion
2 parents 2b18cf9 + 8d75fb6 commit 686f38b

File tree

9 files changed

+326
-1089
lines changed

9 files changed

+326
-1089
lines changed

ML-PACE/ace-evaluator/LICENSE

Lines changed: 0 additions & 1040 deletions
This file was deleted.

ML-PACE/ace-evaluator/ace_arraynd.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,10 @@
2525
* along with this program. If not, see <http://www.gnu.org/licenses/>.
2626
*/
2727

28-
2928
//automatically generate source code
3029

3130
#ifndef ACE_MULTIARRAY_H
3231
#define ACE_MULTIARRAY_H
33-
3432
#include <cstring>
3533
#include <vector>
3634
#include <stdexcept>

ML-PACE/ace-evaluator/ace_c_basis.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,10 @@ void ACECTildeBasisSet::load(const string filename) {
755755
fclose(fptr);
756756

757757
// radial_functions->radbasename = radbasename;
758+
// pass elements to radial functions (for ZBL basis)
759+
for(int i=0;i<nelements;++i)
760+
radial_functions->elements.push_back(elements_name[i]);
761+
758762
radial_functions->setuplookupRadspline();
759763
pack_flatten_basis();
760764
}
@@ -1340,6 +1344,9 @@ void ACECTildeBasisSet::load_yaml(const string &yaml_file_name) {
13401344

13411345
//setup spherical_harmonics and radialBasis
13421346
spherical_harmonics.init(lmax);
1347+
// pass elements to radial functions (for ZBL basis)
1348+
for(int i=0;i<nelements;++i)
1349+
radial_functions->elements.push_back(elements_name[i]);
13431350
radial_functions->setuplookupRadspline();
13441351

13451352
//reading ACECTildeBasisFunctions

ML-PACE/ace-evaluator/ace_evaluator.cpp

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ ACECTildeEvaluator::compute_atom(int i, DOUBLE_TYPE **x, const SPECIES_TYPE *typ
208208
ACECTildeBasisFunction *basis = basis_set->basis[mu_i];
209209

210210
DOUBLE_TYPE rho_cut, drho_cut, fcut, dfcut;
211-
DOUBLE_TYPE dF_drho_core;
211+
DOUBLE_TYPE dF_drho_core, dF_dfcut;
212212

213213
//TODO: lmax -> lmaxi (get per-species type)
214214
const LS_TYPE lmaxi = basis_set->lmax;
@@ -233,7 +233,7 @@ ACECTildeEvaluator::compute_atom(int i, DOUBLE_TYPE **x, const SPECIES_TYPE *typ
233233
dF_drho.fill(0);
234234

235235
#ifdef EXTRA_C_PROJECTIONS
236-
if(this->compute_projections) {
236+
if (this->compute_projections) {
237237
projections.init(total_basis_size_rank1 + total_basis_size, "projections");
238238
projections.fill(0.0);
239239
}
@@ -262,6 +262,12 @@ ACECTildeEvaluator::compute_atom(int i, DOUBLE_TYPE **x, const SPECIES_TYPE *typ
262262
int jj_actual = 0;
263263
SPECIES_TYPE type_j = 0;
264264
Array1D<int> neighbour_index_mapping(jnum); // jj_actual -> jj
265+
// minimal distance, nearest neighbour
266+
int jj_min_actual = -1, j_min = -1;
267+
DOUBLE_TYPE d, dmin = basis_set->cutoffmax;
268+
bool is_zbl = basis_set->radial_functions->inner_cutoff_type == "zbl";
269+
const auto &cut_in = basis_set->radial_functions->cut_in;
270+
const auto &dcut_in = basis_set->radial_functions->dcut_in;
265271
//loop over neighbours, compute distance, consider only atoms within with r<cutoff(mu_i, mu_j)
266272
for (jj = 0; jj < jnum; ++jj) {
267273

@@ -280,7 +286,14 @@ ACECTildeEvaluator::compute_atom(int i, DOUBLE_TYPE **x, const SPECIES_TYPE *typ
280286

281287
if (r_xyz >= current_cutoff)
282288
continue;
283-
289+
if (is_zbl) {
290+
d = r_xyz - (cut_in(mu_i, mu_j) - dcut_in(mu_i, mu_j));
291+
if (d < dmin) {
292+
dmin = d;
293+
jj_min_actual = jj_actual;
294+
j_min = j;
295+
}
296+
}
284297
inv_r_norm = 1 / r_xyz;
285298

286299
r_norms(jj_actual) = r_xyz;
@@ -348,7 +361,6 @@ ACECTildeEvaluator::compute_atom(int i, DOUBLE_TYPE **x, const SPECIES_TYPE *typ
348361
//hard-core repulsion
349362
rho_core += basis_set->radial_functions->cr;
350363
DCR_cache(jj) = basis_set->radial_functions->dcr;
351-
352364
} //end loop over neighbours
353365

354366
//complex conjugate A's (for NEGATIVE (-m) terms)
@@ -390,7 +402,7 @@ ACECTildeEvaluator::compute_atom(int i, DOUBLE_TYPE **x, const SPECIES_TYPE *typ
390402
rhos(p) += func->ctildes[p] * A_cur;
391403
}
392404
#ifdef EXTRA_C_PROJECTIONS
393-
if(this->compute_projections) {
405+
if (this->compute_projections) {
394406
//aggregate C-projections separately
395407
// always take 0-th density, because Ctilde evalutor has no rotationally invariant B-projections, only A-products
396408
projections(func_rank1_ind) += func->ctildes[0] * A_cur;
@@ -465,7 +477,7 @@ ACECTildeEvaluator::compute_atom(int i, DOUBLE_TYPE **x, const SPECIES_TYPE *typ
465477
#endif
466478
}
467479
#ifdef EXTRA_C_PROJECTIONS
468-
if(this->compute_projections) {
480+
if (this->compute_projections) {
469481
//aggregate C-projections separately
470482
// always take 0-th density, because Ctilde evalutor has no rotationally invariant B-projections, only A-products
471483
projections(total_basis_size_rank1 + func_ind) += B.real_part_product(func->ctildes[ms_ind * ndensity]);
@@ -485,19 +497,39 @@ ACECTildeEvaluator::compute_atom(int i, DOUBLE_TYPE **x, const SPECIES_TYPE *typ
485497
rho_cut = basis_set->map_embedding_specifications.at(mu_i).rho_core_cutoff;
486498
drho_cut = basis_set->map_embedding_specifications.at(mu_i).drho_core_cutoff;
487499

488-
basis_set->inner_cutoff(rho_core, rho_cut, drho_cut, fcut, dfcut);
489500
basis_set->FS_values_and_derivatives(rhos, evdwl, dF_drho, mu_i);
490501
#ifdef DEBUG_ENERGY_CALCULATIONS
491502
printf("ACE = %f, rho_core = %f, fcut=%f\n",evdwl, rho_core, fcut);
492503
#endif
493-
dF_drho_core = evdwl * dfcut + 1;
504+
if (is_zbl) {
505+
DOUBLE_TYPE transition_coordinate = 0;
506+
if (j_min != -1) {
507+
SPECIES_TYPE mu_jmin = type[j_min];
508+
if (is_element_mapping)
509+
mu_jmin = element_type_mapping(mu_jmin);
510+
DOUBLE_TYPE dcutin = basis_set->radial_functions->dcut_in(mu_i, mu_jmin);
511+
transition_coordinate = dcutin - dmin; // == cutin - r_min
512+
cutoff_func_poly(transition_coordinate, dcutin, dcutin, fcut, dfcut);
513+
dfcut = -dfcut; // invert, because rho_core = cutin - r_min
514+
} else {
515+
// no neighbours
516+
fcut = 1;
517+
dfcut = 0;
518+
}
519+
evdwl_cut = evdwl * fcut + rho_core * (1 - fcut); // evdwl * fcut + rho_core_uncut - rho_core_uncut* fcut
520+
dF_drho_core = 1 - fcut;
521+
dF_dfcut = evdwl * dfcut - rho_core * dfcut;
522+
} else {
523+
basis_set->inner_cutoff(rho_core, rho_cut, drho_cut, fcut, dfcut);
524+
evdwl_cut = evdwl * fcut + rho_core;
525+
dF_drho_core = evdwl * dfcut + 1;
526+
}
494527
for (DENSITY_TYPE p = 0; p < ndensity; ++p)
495528
dF_drho(p) *= fcut;
496-
evdwl_cut = evdwl * fcut + rho_core;
497529
#ifdef DEBUG_ENERGY_CALCULATIONS
498530
printf("ACE_cut = %f\n",evdwl_cut);
499531
#endif
500-
// E0 shift
532+
// E0 shift
501533
evdwl_cut += basis_set->E0vals(mu_i);
502534
#ifdef DEBUG_ENERGY_CALCULATIONS
503535
printf("E_total(+E0) = %f\n",evdwl_cut);
@@ -519,7 +551,7 @@ ACECTildeEvaluator::compute_atom(int i, DOUBLE_TYPE **x, const SPECIES_TYPE *typ
519551
#ifdef COMPUTE_B_GRAD
520552
if (this->compute_b_grad) {
521553
//actually, it is always += 1, due to CG for r=1
522-
weights_rank1_dB(f_ind, func->mus[0], func->ns[0] - 1) += func->ctildes[0];
554+
weights_rank1_dB(f_ind, func->mus[0], func->ns[0] - 1) += func->ctildes[0];
523555
}
524556
#endif
525557
}
@@ -728,6 +760,14 @@ ACECTildeEvaluator::compute_atom(int i, DOUBLE_TYPE **x, const SPECIES_TYPE *typ
728760
f_ji[0] += dF_drho_core * DCR * r_hat[0];
729761
f_ji[1] += dF_drho_core * DCR * r_hat[1];
730762
f_ji[2] += dF_drho_core * DCR * r_hat[2];
763+
if (is_zbl) {
764+
if (jj == jj_min_actual) {
765+
// DCRU = 1.0
766+
f_ji[0] += dF_dfcut * r_hat[0];
767+
f_ji[1] += dF_dfcut * r_hat[1];
768+
f_ji[2] += dF_dfcut * r_hat[2];
769+
}
770+
}
731771
#ifdef PRINT_INTERMEDIATE_VALUES
732772
printf("with core-repulsion\n");
733773
printf("f_ji(jj=%d, i=%d)=(%f, %f, %f)\n", jj, i,

0 commit comments

Comments
 (0)