Skip to content

Commit

Permalink
add some docs on some complicated low-level functions
Browse files Browse the repository at this point in the history
  • Loading branch information
kylebystrom committed Nov 26, 2024
1 parent 31bd9f3 commit 391850f
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 1 deletion.
20 changes: 20 additions & 0 deletions ciderpress/dft/lcao_interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,14 @@ def natm(self):
return self.atco.natm

def _set_num_ai(self, all_coords):
"""
This function computes the number of coordinates in
all_coords that fall in each spline "box" for the radial
interpolation grid on each atom. The result is then
used to create the _loc_ai member, which in turn
is used by the _compute_sline_ind_order function
to order grid coordinates by their spline box on a given atom.
"""
if all_coords is None:
assert self.is_num_ai_setup
return
Expand Down Expand Up @@ -425,6 +433,12 @@ def _set_num_ai(self, all_coords):
self.is_num_ai_setup = True

def _compute_spline_ind_order(self, a):
"""
Assuming _set_num_ai has been called previously, order
self.all_coords such that each coordinate is in increasing
order of spline index for the radial interpolation grid
on atom a.
"""
if not self.is_num_ai_setup:
raise RuntimeError
ngrids_tot = self.all_coords.shape[0]
Expand Down Expand Up @@ -452,6 +466,12 @@ def _compute_spline_ind_order(self, a):
return self._coords_ord, self._ind_ord_fwd

def _eval_spline_bas_single(self, a):
"""
Note that _set_num_ai must have been called previously, because
it is required for _compute_spline_ind_order to work, which
is called by this function. TODO might be better to have a cleaner
solution for this algorithm.
"""
self._compute_spline_ind_order(a)
ngrids = self._coords_ord.shape[0]
if self.onsite_direct:
Expand Down
24 changes: 24 additions & 0 deletions ciderpress/dft/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ def _get_fl_ueg(s):
def get_cider_exponent(
rho, sigma, tau, a0=1.0, grad_mul=0.0, tau_mul=0.03125, rhocut=1e-10, nspin=1
):
"""
Evaluate an NLDF length-scale exponent at the MGGA level.
"""
if nspin > 2:
raise ValueError
if isinstance(rho, np.ndarray):
Expand Down Expand Up @@ -113,6 +116,9 @@ def get_cider_exponent(


def get_cider_exponent_gga(rho, sigma, a0=1.0, grad_mul=0.03125, rhocut=1e-10, nspin=1):
"""
Evaluate an NLDF length-scale exponent at the GGA level.
"""
if nspin > 2:
raise ValueError
if isinstance(rho, np.ndarray):
Expand Down Expand Up @@ -161,6 +167,13 @@ def _get_ueg_expnt(aval, tval, rho):


class BaseSettings(ABC):
"""
This is a base class for storing the settings for different
types of density/density matrix feature in CiderPress.
Settings objects indicate which features must be evaluated,
and with which hyperparameters, to use as input to an ML functional.
"""

@property
@abstractmethod
def nfeat(self):
Expand All @@ -171,6 +184,9 @@ def nfeat(self):

@property
def is_empty(self):
"""
Return true of this settings object specifies zero features.
"""
return self.nfeat == 0

@abstractmethod
Expand Down Expand Up @@ -201,6 +217,14 @@ def get_reasonable_normalizer(self):


class EmptySettings(BaseSettings):
"""
The EmptySettings class is a representation of a feature set containing
zero features. It is used when a certain type of feature is not
present in a model. (For example, if a model does not use SDMX
features, that model's FeatureSettings.sdmx_settings will be
an EmptySettings instance.)
"""

@property
def nfeat(self):
return 0
Expand Down
2 changes: 1 addition & 1 deletion ciderpress/gpaw/calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class is returned to evaluate the semilocal functional.
raise NotImplementedError(
"Currently only version j NLDF features are implemented in GPAW. "
"Other versions are planned for future development. The version "
"of your functional's features is: {}".format(
"of this functional's NLDF features is: {}".format(
mlfunc.settings.nldf_settings.version
)
)
Expand Down
3 changes: 3 additions & 0 deletions ciderpress/gpaw/descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ def get_descriptors(
use_paw (bool, True): Whether to use PAW corrections.
screen_dens (bool, True): Whether to remove low-density
grids from the return feature vectors.
kwargs: Any additional arguments to be passed to the
Cider functional object (like qmax, lambd, etc.)
to compute the functional.
Returns:
if p_i is None:
Expand Down
44 changes: 44 additions & 0 deletions ciderpress/lib/mod_cider/conv_interpolation.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,25 @@ void compute_num_spline_contribs_multi(spline_locator *spline_locs,
}
}

/**
* Compute the number of coordinates (coords) that fall within each
* radial spline block. The result (num_ai) can then be used
* in compute_spline_ind_order_new
* to order the grids by their distance from the atom at atm_coord.
* num_ai: The result, num_ai[ia * nrad + ir] contains the number of
* grid points that fall in spline index ir of atom with index ia.
* coords: coords + 3 * g is the real-space coordinate of grid g.
* atm_coords: atm_coords + 3 * ia is the real-space coordinate of atom ia.
* aparam, dparam: The radial grid with index ir is
* aparam * (exp(dparam * ir) - 1)
* natm: Number of atoms
* ngrids: Number of 3D real-space grids
* nrad: Number of grids for the radial spline on each atom.
* iatom_g: coords + 3 * g is part of the atomic grid belonging
* to the atom with index iatom_g[g]. If iatom_g is NULL,
* it is ignored. If it is not NULL, it is used to ignore
* on-site grids when constructing num_ai.
*/
void compute_num_spline_contribs_new(int *num_ai, double *coords,
double *atm_coords, double aparam,
double dparam, int natm, int ngrids,
Expand Down Expand Up @@ -432,6 +451,31 @@ void compute_spline_ind_order(int *loc_i, double *coords, double *atm_coord,
free(num_i_tmp);
}

/**
* TODO this function should be modified to run in parallel.
* This function sorts the grid coordinates (coords) in order of their
* distance from the atomic coordinate (atm_coord).
* loc_i: For each radial index ir, loc_i[ir] says where each batch
* corresponding to index ir of the radial spline is located
* in the coords_ord array. It is constructed in the
* _set_num_ai function of ciderpress.dft.lcao_interpolation.
* coords: 3-D grid coordinations
* atm_coord: Atomic coordinate
* coords_ord: OUTPUT. The ordered coordinates are saved to this array.
* ind_ord_fwd, ind_ord_bwd: OUTPUT. After execution, for x in 0, 1, 2,
* the following relationships hold:
* coords_ord[3 * g + x] == coords[3 * ind_ord_fwd[g] + x]
* coords_ord[3 * ind_ord_bwd[g] + x] == coords[3 * g + x]
* aparam, dparam: The radial grid with index ir is
* aparam * (exp(dparam * ir) - 1)
* ngrids: Number of 3D real-space grids
* nrad: Number of grids for the radial spline on each atom.
* iatom_g: coords + 3 * g is part of the atomic grid belonging
* to the atom with index iatom_g[g]. If iatom_g is NULL,
* it is ignored. If it is not NULL, it is used to ignore
* on-site grids when constructing num_ai.
* iatom: Index of the atom of for which the grids are being ordered.
*/
void compute_spline_ind_order_new(int *loc_i, double *coords, double *atm_coord,
double *coords_ord, int *ind_ord_fwd,
int *ind_ord_bwd, double aparam,
Expand Down
11 changes: 11 additions & 0 deletions ciderpress/pyscf/sdmx.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,21 @@ def _get_ylm_atom_loc(mol):


def _get_nrf(mol):
"""
Get the number of unique radial functions associated with a basis
"""
return np.sum(mol._bas[:, NCTR_OF])


def _get_rf_loc(mol):
"""
Get an integer numpy array with that gives the location of the
unique radial functions corresponding to each shell.
So rf_loc[shl : shl + 1] is the range of radial functions contained
in the shell. This is similar to ao_loc, except that it does not
include spherical harmonics, so each shell has a factor of 2l+1
more functions in ao_loc than rf_loc.
"""
rf_loc = mol._bas[:, NCTR_OF]
rf_loc = np.append([0], np.cumsum(rf_loc)).astype(np.int32)
return rf_loc
Expand Down

0 comments on commit 391850f

Please sign in to comment.