@@ -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