Tools#
Data analysis#
- calorine.tools.analyze_data(data, max_lag=None)[source]#
Carries out an extensive analysis of the data series.
- Parameters:
data (
ndarray) – data series to compute autocorrelation function formax_lag (
int) – maximum lag between two data points, used for computing autocorrelation
- Returns:
calculated properties of the data including, mean, standard deviation, correlation length and a 95% error estimate.
- Return type:
dict
- calorine.tools.get_autocorrelation_function(data, max_lag=None)[source]#
Returns autocorrelation function.
The autocorrelation function is computed using pandas.Series.autocorr.
- calorine.tools.get_correlation_length(data)[source]#
Returns estimate of the correlation length of data.
The correlation length is taken as the first point where the autocorrelation functions is less than \(\exp(-2)\). If the correlation function never drops below \(\exp(-2)\)
np.nanis returned.If the correlation length cannot be computed since the auto-correlation function is unconverged the function returns
None.- Parameters:
data (
ndarray) – data series for which to the compute autocorrelation function- Return type:
Optional[int]- Returns:
correlation length
- calorine.tools.get_error_estimate(data, confidence=0.95)[source]#
Returns estimate of standard error \(\mathrm{error}\) with confidence interval.
\[\mathrm{error} = t_\mathrm{factor} * \mathrm{std}(\mathrm{data}) / \sqrt{N_s}\]where \(t_{factor}\) is the factor corresponding to the confidence interval and \(N_s\) is the number of independent measurements (with correlation taken into account).
If the correlation length cannot be computed since the auto-correlation function is unconverged the function returns
None.- Parameters:
data (
ndarray) – data series for which to estimate the error- Return type:
Optional[float]- Returns:
error estimate
Property calculation#
- calorine.tools.batch_predict_properties(structures, model, command=None, directory=None)[source]#
Evaluates NEP model properties for a list of structures in a single pass, using the
predictionmode of thenepexecutable (see here). This is substantially faster than evaluating structures one at a time withCPUNEPorGPUNEP, since all structures are transferred to the GPU in a single pass.- Parameters:
structures (
List[Atoms]) – Structures for which to evaluate properties.model (
Union[str,Model]) – Either a path to a NEP model innep.txtformat, or aModelobject.command (
Optional[str]) – Command used to invoke thenepexecutable. Default:nep, or the value of theCALORINE_NEP_COMMANDenvironment variable if set.directory (
Optional[str]) – Directory in which to runnep. IfNone, a temporary directory is created and removed once the calculation is finished. If specified, the directory is created if needed and is not deleted afterward, which is useful for debugging or for further analysis of the rawnepoutput files (e.g. viaread_structures).
- Returns:
A new list of
Atomsobjects, in the same order asstructures, each with aSinglePointCalculatorattached exposing the predicted properties in the standard way (energy,forces, andstress, pluschargesandborn_effective_chargesfor qNEP models, ordipole/polarizabilityfor TNEP models). The inputstructuresare not modified.- Return type:
List[Atoms]
- calorine.tools.get_elastic_stiffness_tensor(structure, clamped=False, epsilon=0.001, **kwargs)[source]#
Calculate and return the elastic stiffness tensor in units of GPa for the given structure in Voigt form.
- Parameters:
structure (
Atoms) – input structure; should be fully relaxedclamped (
bool) – ifFalse(default) return the relaxed elastic stiffness tensor; ifTruereturn the clamped ion elastic stiffness tensorepsilon (
float) – magnitude of the applied strainkwargs – keyword arguments forwarded to the
relax_structurefunction used for relaxing the structure when computing the relaxed stiffness tensor; it should not be necessary to change the default for the vast majority of use cases; use with care
- Return type:
- calorine.tools.get_entropy(descriptors, width, use_tqdm=True, device='cuda', block=1024, dtype=torch.float32, eps=1e-12)[source]#
Computes an estimate for the information entropy \(H(\mathbf{X})\) of a set of descriptors \(\mathbf{X}\). The estimate is described in [Nat. Comm. 16, 4014 (2025)](https://doi.org/10.1038/s41467-025-59232-0) and given by
\[\mathcal{H}(\{\mathbf{X}\}) = -\frac{1}{n} \sum_{i=1}^{n} p_i\]where
\[p_i = \log \left[ \frac{1}{n} \sum_{j=1}^{n} K_h(\mathbf{X}_i, \mathbf{X}_j) \right]\]with a Gaussian kernel
\[K_h(\mathbf{X}_i, \mathbf{X}_j) = \exp\!\left( -\frac{\lVert \mathbf{X}_i - \mathbf{X}_j \rVert^2}{2h^2}. \right)\]The calculation is done via torch if the library has been installed, and numpy otherwise. When using torch the calculation is run via CUDA. The latter behavior can be controlled using the
deviceargument.- Parameters:
descriptors (
ndarray|Tensor) – The set of descriptors \(\mathbf{X}\) for which to evaluate to the entropy. Typically each row corresponds to one atom and the columns correspond to the different descriptor components.width (
float) – Width \(h\) of the Gaussian kernel.use_tqdm (
bool) – Use tqdm to show a progress bar. Note that this requires tqdm to be installed.block (
int) – In order to limit the memory needs, the kernel density estimate matrix is handled in blocks. This parameter controls the size of each block. Smaller numbers imply a smaller memory footprint.eps (
float) – Smallest (absolute) permissible value.device (
str|device) – Device to use for calculation. The documentation of [torch.device](https://docs.pytorch.org/docs/stable/tensor_attributes.html#torch.device) provides more information. Only used when pytorch is available.dtype (
dtype) – Floating point precision used for the computation. The documentation of [torch.dtype](https://docs.pytorch.org/docs/stable/tensor_attributes.html) provides an overview. Only used when pytorch is available.
- Return type:
tuple[float,ndarray]- Returns:
A tuple comprising the total entropy \(H(\mathbf{X})\) and the entropy contributions
\(p_i\) from each row in the input descriptor matrix.
- calorine.tools.get_force_constants(structure, calculator, supercell_matrix, kwargs_phonopy={}, kwargs_generate_displacements={})[source]#
Calculates the force constants for a given structure using phonopy, which needs to be cited if this function is used for generating data for publication. The function returns a
Phonopyobject that can be used to calculate, e.g., the phonon dispersion, the phonon density of states as well as related quantities such as the thermal displacements and the free energy.- Parameters:
structure (
Atoms) – structure for which to compute the phonon dispersion; usually this is a primitive cellcalculator (
SinglePointCalculator) – ASE calculator to use for the calculation of forcessupercell_matrix (
ndarray) – specification of supercell size handed over to phonopy; should be a tuple of three values or a matrixkwargs_phonopy (
Dict[str,Any]) – Expert option: keyword arguments used when initializing thePhonopyobject; this includes, e.g., the tolerance used when determining the symmetry (symprec) and parameters for the non-analytical corrections (nac_params)kwargs_generate_displacements (
Dict[str,Any]) – Expert option: keyword arguments to be handed over to thegenerate_displacementsmethod; this includes in particular thedistancekeyword, which specifies the magnitude of the atomic displacement imposed when calculating the force constant matrix
- Return type:
Phonopy
Spectra#
- calorine.tools.apply_kramers_kronig(df, method='vectorized', max_memory_gb=4.0)[source]#
Apply the Kramers-Kronig relation to add the real part of the dielectric function.
Takes the output of
get_dielectric_function(), computes \(\epsilon_1(\omega)\) from \(\epsilon_2(\omega)\) via the Kramers-Kronig relation, and returns the DataFrame with newepsilon_real*columns appended.Each
epsilon_imag{suffix}column indfproduces a correspondingepsilon_real{suffix}column (e.g.epsilon_imag_xx→epsilon_real_xx).- Parameters:
df (
DataFrame) – DataFrame as returned byget_dielectric_function()orget_ir_spectrum(); must containangular_frequencyand at least one column whose name starts withepsilon_imag.method (
str) – Integration method.'vectorized'(default) uses an exact trapezoid rule over an \(n \times n\) matrix (\(\mathcal{O}(n^2)\) time and memory, where \(n\) is the number of rows ofdf);'fft'uses an \(\mathcal{O}(n \log n)\) Hilbert transform (\(\mathcal{O}(n)\) memory) and is faster for large arrays but approximates the principal-value integral. The two methods agree to within a few percent on typical grids.max_memory_gb (
float) – Whenmethodis'vectorized', the peak memory footprint is approximately \(3 \times 8n^2\) bytes (three \(n \times n\)float64buffers alive at once). If this estimate exceedsmax_memory_gb,ValueErroris raised before attempting the allocation, rather than letting the process hang or get OOM-killed. Passmethod='fft', a smaller frequency grid (e.g. a smallerwindow_sizeinget_dielectric_function()), or a largermax_memory_gbto proceed anyway. Set toNoneto disable the check. Ignored whenmethodis'fft'.
- Returns:
Input DataFrame with additional
epsilon_real*columns.- Return type:
DataFrame
- calorine.tools.apply_quantum_correction(df, temperature, column, order='first', force=False)[source]#
Apply a quantum correction to a classically computed spectrum.
Classical MD underestimates spectral intensities because it samples the classical Boltzmann distribution rather than the Bose-Einstein distribution. The correction factor depends on the scattering order and mode type [Cardona1982] [Rosander2025].
- Parameters:
df (
DataFrame) – DataFrame with anangular_frequencycolumn (THz) and the column to correct.temperature (
float) – Temperature in K.column (
str) – Name of the spectral column to correct (e.g.'raman_isotropic','ir_intensity','epsilon_imag').order (
str) –Correction type:
'first'First-order scattering (IR absorption and first-order Raman): \(f = \beta\hbar\omega / (1 - e^{-\beta\hbar\omega})\).
'overtone'Second-order overtone (same mode, \(\omega_1 = \omega/2\)): \(f = [y/(1 - e^{-y})]^2 (2 - e^{-y})\) with \(y = \beta\hbar\omega/2\).
'combination'Second-order combination band upper bound (\(\omega_1 = \omega_2 = \omega/2\)): \(f = [y/(1 - e^{-y})]^2\) with \(y = \beta\hbar\omega/2\).
force (
bool) – IfTrue, overwrite an existingcolumn + '_qm'column. DefaultFalseraisesValueErrorto prevent accidental double-correction.
- Returns:
Copy of
dfwith a new columncolumn + '_qm'containing the quantum-corrected intensities. The input is not mutated.- Return type:
DataFrame
References
[Cardona1982]M. Cardona, Resonance phenomena, in Topics in Applied Physics, Vol. 50, edited by M. Cardona and G. Güntherodt (Springer, Berlin, 1982).
[Rosander2025]Rosander et al., Phys. Rev. B 111, 064107 (2025), Supp. Eqs. S5, S7, S10.
- calorine.tools.get_absorption_coefficient(df)[source]#
Compute the absorption coefficient from the extinction coefficient.
\[\alpha(\omega) = \frac{2\kappa\omega}{c},\]where \(\kappa\) is the extinction coefficient (imaginary part of the complex index of refraction) and \(\omega\) is the angular frequency. With \(\omega\) in rad/s and \(c\) in m/s this gives \(\alpha\) in m-1; \(\alpha\) is returned here in cm-1 (matching the
wavenumber_invcmconvention used elsewhere in this module, though note that \(\alpha\) is a physically distinct quantity from the spectroscopic wavenumber \(\omega/2\pi c\)):\[\alpha\,[\mathrm{cm}^{-1}] = \frac{2\kappa\omega}{100\,c}.\]Each
refractive_index_imag{suffix}column indf(as returned byget_refractive_index()) produces a correspondingabsorption_coefficient{suffix}column. As a convenience, ifdflacksrefractive_index_imag{suffix}but contains a matchingepsilon_real{suffix}/epsilon_imag{suffix}pair, \(\kappa\) is derived internally using the same relation asget_refractive_index()(without adding the correspondingrefractive_index_real{suffix}/refractive_index_imag{suffix}columns to the output).- Parameters:
df (
DataFrame) – DataFrame containingangular_frequency(THz) and at least onerefractive_index_imag{suffix}column (as returned byget_refractive_index()), or, alternatively, a matchingepsilon_real{suffix}/epsilon_imag{suffix}column pair (as returned byget_dielectric_function()withreturn_real_part=True).- Returns:
Input DataFrame with additional
absorption_coefficient{suffix}columns (cm-1) appended.- Return type:
DataFrame- Raises:
ValueError – If
dflacksangular_frequency, or contains neitherrefractive_index_imag*columns nor a matchingepsilon_real*/epsilon_imag*column pair for a given component.
- calorine.tools.get_dielectric_function(signal, volume, temperature, column='dP', dt=None, t_sigma=None, window_size=None, return_real_part=True, kk_method='vectorized', kk_max_memory_gb=4.0)[source]#
Compute the dielectric function from a three-component polarization time series.
Computes all six unique Voigt components of \(\epsilon_2^{\alpha\beta}(\omega)\) (xx, yy, zz, yz, xz, xy) from the three-component time series written by GPUMD. The real part \(\epsilon_1^{\alpha\beta}(\omega)\) is obtained via the Kramers-Kronig relation when
return_real_partisTrue(the default).The imaginary part is related to the symmetrized cross-correlation via
\[\epsilon_2^{\alpha\beta}(\omega) = \frac{\beta}{\epsilon_0 \omega V} \,\mathrm{Re}\!\left[\int_0^\infty \langle \dot{P}_\alpha(0)\,\dot{P}_\beta(t) \rangle e^{-i\omega t}\,dt\right],\]where \(\beta = 1/(k_\mathrm{B}T)\) and \(V\) is the cell volume.
- Parameters:
signal (
DataFrame) –DataFrameas returned byread_dpdt()orread_dipole(). The columns to use are selected viacolumn.volume (
float) – Simulation cell volume in ų.temperature (
float) – Temperature in K.column (
str) –Selects which columns of
signalto use and implies whether the input is a time derivative:'dP'(default)Uses
dPx,dPy,dPzfromread_dpdt()(qNEP); input is \(\dot{\mathbf{P}}(t)\) in e·Å/fs.'P'Uses
Px,Py,Pzfromread_dpdt()(qNEP); input is the polarization \(\mathbf{P}(t)\) in e·Å.'mu'Uses
mu_x,mu_y,mu_zfromread_dipole()(TNEP); input is the dipole moment \(\boldsymbol{\mu}(t)\) in e·Å.
dt (
float) – Time between consecutive frames in ps. Auto-extracted from thetimecolumn when present (i.e. forread_dpdt()output). Must be supplied explicitly for step-indexed inputs such asread_dipole()output.t_sigma (
float) – Width of the Gaussian window applied to the ACF in ps.Noneuses no windowing.window_size (
float) – Length of the ACF to retain, in ps.None(default) uses \(5 \times\)t_sigmawhent_sigmais given, otherwise the full ACF (i.e. the full trajectory length). This directly sets the size of the frequency grid (\(n \approx\)window_size\(/\,dt\), or the number of frames insignalwhen unset) passed to the Kramers-Kronig step below; seekk_methodfor how the cost of that step depends on \(n\). A warning is issued ifwindow_sizeis less than \(3 \times\)t_sigma, since the Gaussian window is then truncated before it has meaningfully decayed. RaisesValueErrorifwindow_sizeexceeds the autocorrelation data available fromsignal.return_real_part (
bool) – WhenTrue(default), the real part \(\epsilon_1^{\alpha\beta}(\omega)\) is computed via the Kramers-Kronig relation and appended asepsilon_real_{xx,yy,zz,yz,xz,xy}columns.kk_method (
str) – Integration method passed toapply_kramers_kronig()whenreturn_real_partisTrue.'vectorized'(default) uses an exact trapezoid rule over an \(n \times n\) matrix (\(\mathcal{O}(n^2)\) time and memory, where \(n\) is the size of the frequency grid set bywindow_size);'fft'uses a faster (\(\mathcal{O}(n \log n)\) time, \(\mathcal{O}(n)\) memory) Hilbert transform approximation. Ignored whenreturn_real_partisFalse.kk_max_memory_gb (
float) – Memory limit (in GB) passed toapply_kramers_kronig()asmax_memory_gbwhenkk_methodis'vectorized'. If the estimated peak memory for the \(n \times n\) matrix would exceed this,ValueErroris raised before attempting the allocation, rather than letting the process hang or get OOM-killed; passkk_method='fft', a smallerwindow_size, or a largerkk_max_memory_gbinstead. Set toNoneto disable the check. Ignored whenreturn_real_partisFalseorkk_methodis'fft'.
- Returns:
Contains
angular_frequency(THz),wavenumber_invcm(\(\mathrm{cm}^{-1}\)),epsilon_imag_{xx,yy,zz,yz,xz,xy}(dimensionless, imaginary dielectric tensor components), andconductivity_{xx,yy,zz,yz,xz,xy}(S/m). Whenreturn_real_partisTrue,epsilon_real_{xx,yy,zz,yz,xz,xy}columns are appended.- Return type:
DataFrame
- calorine.tools.get_dielectric_function_from_refractive_index(df)[source]#
Compute the complex dielectric function from the complex index of refraction.
Given the complex index of refraction \(N = n + i\kappa\),
\[\epsilon_1 = n^2 - \kappa^2, \qquad \epsilon_2 = 2 n \kappa.\]This is the exact inverse of
get_refractive_index().Each
refractive_index_real{suffix}column (\(n\)) must be paired with either arefractive_index_imag{suffix}column (\(\kappa\), as returned byget_refractive_index()) or anabsorption_coefficient{suffix}column (\(\alpha\), in cm-1, as returned byget_absorption_coefficient()), from which \(\kappa\) is recovered via the inverse of \(\alpha = 2\kappa\omega/(100 c)\),\[\kappa = \frac{100\,c\,\alpha}{2\omega},\]which additionally requires the
angular_frequencycolumn. If both arefractive_index_imag{suffix}and anabsorption_coefficient{suffix}column are present for the same suffix, the former takes precedence.- Parameters:
df (
DataFrame) – DataFrame containing at least onerefractive_index_real{suffix}column together with a matchingrefractive_index_imag{suffix}orabsorption_coefficient{suffix}column (in the latter caseangular_frequencyin THz must also be present).- Returns:
Input DataFrame with additional
epsilon_real{suffix}andepsilon_imag{suffix}columns appended.- Return type:
DataFrame- Raises:
ValueError – If a
refractive_index_real{suffix}column has no matchingrefractive_index_imag{suffix}orabsorption_coefficient{suffix}column, or if the latter is used butangular_frequencyis missing.
- calorine.tools.get_ir_spectrum(signal, volume=None, temperature=None, column='dP', dt=None, polarization=None, t_sigma=None, window_size=None)[source]#
Compute the IR spectrum from a time series of dipole moments or polarizations.
- Parameters:
signal (
DataFrame) –DataFrameas returned byread_dpdt()orread_dipole(). The columns to use are selected viacolumn.volume (
float) – Simulation cell volume in ų. Required for extended systems; when provided the function returns the imaginary dielectric function and conductivity. PassNonefor molecules to obtain an unnormalized line shape in arbitrary units.temperature (
float) – Temperature in K. Required whenvolumeis notNone.column (
str) –Selects which columns of
signalto use and implies whether the input is a time derivative:'dP'(default)Uses
dPx,dPy,dPzfromread_dpdt()(qNEP); signal is \(\mathrm{d}P/\mathrm{d}t\) in e·Å/fs.'P'Uses
Px,Py,Pzfromread_dpdt()(qNEP); signal is the polarization \(P(t)\) in e·Å.'mu'Uses
mu_x,mu_y,mu_zfromread_dipole()(TNEP); signal is the dipole moment \(\mu(t)\) in e·Å.
dt (
float) – Time between consecutive frames in ps. Auto-extracted from thetimecolumn when present (i.e. forread_dpdt()output). Must be supplied explicitly for step-indexed inputs such asread_dipole()output.polarization (
ndarray) – Unit vector(3,)defining the electric-field polarization direction. When given, the spectrum is computed from the projected signal \(s(t) = \hat{n} \cdot \mathrm{signal}(t)\) instead of the isotropic average.t_sigma (
float) – Width of the Gaussian window applied to the ACF in ps.Noneuses no windowing.window_size (
float) – Length of the ACF to retain, in ps.None(default) uses \(5 \times\)t_sigmawhent_sigmais given, otherwise the full ACF. A warning is issued ifwindow_sizeis less than \(3 \times\)t_sigma, since the Gaussian window is then truncated before it has meaningfully decayed. RaisesValueErrorifwindow_sizeexceeds the autocorrelation data available fromsignal.
- Returns:
Always contains
angular_frequency(THz) andwavenumber_invcm(\(\mathrm{cm}^{-1}\)). Whenvolumeandtemperatureare given:epsilon_imag(dimensionless) andconductivity(S/m). WhenvolumeisNone:ir_intensity(arbitrary units, proportional to \(\mathrm{PSD}[\dot{\mu}]\)).- Return type:
DataFrame
- calorine.tools.get_raman_spectrum(dt, polarizability, polarization_in=None, polarization_out=None, t_sigma=None, window_size=None)[source]#
Compute the Raman spectrum from a time series of polarizability tensors.
- Parameters:
dt (
float) – Time between consecutive frames in ps.polarizability (
DataFrame) – DataFrame with columnsxx,yy,zz,xy,yz,xzcontaining the polarizability \(\alpha\) (molecules) or susceptibility \(\chi\) (extended systems), as returned byread_polarizability(). Units are those of the TNEP training data (typically bohr³).polarization_in (
ndarray) – Unit vector(3,)for the polarization of the incoming light. If bothpolarization_inandpolarization_outare given, the polarization-resolved intensity \(I(\omega) \propto \mathrm{FT}[\langle s(0)s(t)\rangle]\) with \(s(t) = \hat{n}^\mathrm{out} \cdot \alpha(t) \cdot \hat{n}^\mathrm{in}\) is added as the columnraman_polarized.polarization_out (
ndarray) – Unit vector(3,)for the polarization of the outgoing (scattered) light.t_sigma (
float) – Width of the Gaussian window applied to the ACF in ps.Noneuses no windowing.window_size (
float) – Length of the ACF to retain, in ps.None(default) uses \(5 \times\)t_sigmawhent_sigmais given, otherwise the full ACF. A warning is issued ifwindow_sizeis less than \(3 \times\)t_sigma, since the Gaussian window is then truncated before it has meaningfully decayed. RaisesValueErrorifwindow_sizeexceeds the autocorrelation data available frompolarizability.
- Returns:
Always contains
angular_frequency(THz),wavenumber_invcm(\(\mathrm{cm}^{-1}\)),raman_isotropic(proportional to \(\mathrm{FT}[\langle\gamma(0)\gamma(t)\rangle]\)), andraman_anisotropic(proportional to \(\mathrm{FT}[\langle\mathrm{Tr}[\beta(0)\beta(t)]\rangle]\)). If both polarization vectors are given, also containsraman_polarized.- Return type:
DataFrame
- calorine.tools.get_refractive_index(df)[source]#
Compute the complex index of refraction from the complex dielectric function.
Given the complex dielectric function \(\epsilon = \epsilon_1 + i\epsilon_2\), the complex index of refraction \(N = n + i\kappa\) is
\[n = \sqrt{\frac{|\epsilon| + \epsilon_1}{2}}, \qquad \kappa = \sqrt{\frac{|\epsilon| - \epsilon_1}{2}},\]where \(|\epsilon| = \sqrt{\epsilon_1^2 + \epsilon_2^2}\), taking the physical branch \(n \geq 0\) and giving \(\kappa\) the sign of \(\epsilon_2\) (since \(\epsilon_2 = 2n\kappa\) with \(n \geq 0\)). For a passive medium at positive frequency \(\epsilon_2 \geq 0\), so \(\kappa \geq 0\) as usual; a negative \(\epsilon_2\) (e.g. numerical noise near zero) carries through as a negative \(\kappa\) rather than being silently discarded. Both \(n\) and \(\kappa\) are dimensionless.
Each
epsilon_real{suffix}/epsilon_imag{suffix}column pair indf(e.g.epsilon_real_xx/epsilon_imag_xx, or the bareepsilon_real/epsilon_imag) produces a correspondingrefractive_index_real{suffix}/refractive_index_imag{suffix}column pair.- Parameters:
df (
DataFrame) – DataFrame as returned byget_dielectric_function()(withreturn_real_part=True) orapply_kramers_kronig(); must contain at least oneepsilon_real{suffix}/epsilon_imag{suffix}column pair sharing the same suffix.- Returns:
Input DataFrame with additional
refractive_index_real{suffix}(\(n\), dimensionless) andrefractive_index_imag{suffix}(\(\kappa\), dimensionless) columns appended.- Return type:
DataFrame- Raises:
ValueError – If
dfcontains noepsilon_imag*columns, or anepsilon_imag{suffix}column without a matchingepsilon_real{suffix}column (e.g. output ofget_dielectric_function()called withreturn_real_part=False).
Structure manipulation#
- calorine.tools.relax_structure(structure, fmax=0.001, steps=500, minimizer='bfgs', constant_cell=False, constant_volume=False, scalar_pressure=0.0, **kwargs)[source]#
Relaxes the given structure.
- Parameters:
structure (
Atoms) – Atomic configuration to relax.fmax (
float) – Stop relaxation if the absolute force for all atoms falls below this value.steps (
int) – Maximum number of relaxation steps the minimizer is allowed to take.minimizer (
str) – Minimizer to use; possible values: ‘bfgs’, ‘lbfgs’, ‘fire’, ‘gpmin’, ‘bfgs-scipy’.constant_cell (
bool) – If True do not relax the cell or the volume.constant_volume (
bool) – If True relax the cell shape but keep the volume constant.kwargs – Keyword arguments to be handed over to the minimizer; possible arguments can be found in the ASE documentation
scalar_pressure (
float) – External pressure in GPa.
- Return type:
None
Symmetry analysis#
- calorine.tools.get_primitive_structure(structure, no_idealize=True, to_primitive=True, symprec=1e-05)[source]#
Returns the primitive structure using spglib. This is a convenience interface to the
standardize_cell()function of spglib that works directly with ase Atoms objects.
- calorine.tools.get_spacegroup(structure, symprec=1e-05, angle_tolerance=-1.0, style='international')[source]#
Returns the space group of a structure using spglib. This is a convenience interface to the
get_spacegroup()function of spglib that works directly with ase Atoms objects.- Parameters:
structure (
Atoms) – Input atomic structure.symprec (
float) – Tolerance imposed when analyzing the symmetry.angle_tolerance (
float) – Tolerance imposed when analyzing angles.style (
str) – Space group notation to be used. Can be'international'for the interational tables of crystallography (ITC) style (Hermann-Mauguin and ITC number) or'Schoenflies'for the Schoenflies notation.
- Return type:
str
- calorine.tools.get_wyckoff_sites(structure, map_occupations=None, symprec=1e-05, include_representative_atom_index=False)[source]#
Returns the Wyckoff symbols of the input structure. The Wyckoff labels can be conveniently attached as an array to the structure object as demonstrated in the examples section below.
By default the occupation of the sites is part of the symmetry analysis. If a chemically disordered structure is provided this will usually reduce the symmetry substantially. If one is interested in the symmetry of the underlying structure one can control how occupations are handled. To this end, one can provide the
map_occupationskeyword argument. The latter must be a list, each entry of which is a list of species that should be treated as indistinguishable. As a shortcut, if all species should be treated as indistinguishable one can provide an empty list. Examples that illustrate the usage of the keyword are given below.- Parameters:
structure (
Atoms) – Input structure. Note that the occupation of the sites is included in the symmetry analysis.map_occupations (
List[List[str]]) – Each sublist in this list specifies a group of chemical species that shall be treated as indistinguishable for the purpose of the symmetry analysis.symprec (
float) – Tolerance imposed when analyzing the symmetry using spglib.include_representative_atom_index (
bool) – If True the index of the first atom in the structure that is representative of the Wyckoff site is included in the symbol. This is in particular useful in cases when there are multiple Wyckoff sites sites with the same Wyckoff letter.
- Return type:
List[str]
Examples
Wyckoff sites of a hexagonal-close packed structure:
>>> from ase.build import bulk >>> structure = bulk('Ti') >>> wyckoff_sites = get_wyckoff_sites(structure) >>> print(wyckoff_sites) ['2d', '2d']
The Wyckoff labels can also be attached as an array to the structure, in which case the information is also included when storing the Atoms object:
>>> from ase.io import write >>> structure.new_array('wyckoff_sites', wyckoff_sites, str) >>> write('structure.xyz', structure)
The function can also be applied to supercells:
>>> structure = bulk('GaAs', crystalstructure='zincblende', a=3.0).repeat(2) >>> wyckoff_sites = get_wyckoff_sites(structure) >>> print(wyckoff_sites) ['4a', '4c', '4a', '4c', '4a', '4c', '4a', '4c', '4a', '4c', '4a', '4c', '4a', '4c', '4a', '4c']
Now assume that one is given a supercell of a (Ga,Al)As alloy. Applying the function directly yields much lower symmetry since the symmetry of the original structure is broken:
>>> structure.set_chemical_symbols( ... ['Ga', 'As', 'Al', 'As', 'Ga', 'As', 'Al', 'As', ... 'Ga', 'As', 'Ga', 'As', 'Al', 'As', 'Ga', 'As']) >>> print(get_wyckoff_sites(structure)) ['8g', '8i', '4e', '8i', '8g', '8i', '2c', '8i', '2d', '8i', '8g', '8i', '4e', '8i', '8g', '8i']
Since Ga and Al occupy the same sublattice, they should, however, be treated as indistinguishable for the purpose of the symmetry analysis, which can be achieved via the
map_occupationskeyword:>>> print(get_wyckoff_sites(structure, map_occupations=[['Ga', 'Al'], ['As']])) ['4a', '4c', '4a', '4c', '4a', '4c', '4a', '4c', '4a', '4c', '4a', '4c', '4a', '4c', '4a', '4c']
If occupations are to ignored entirely, one can simply provide an empty list. In the present case, this turns the zincblende lattice into a diamond lattice, on which case there is only one Wyckoff site:
>>> print(get_wyckoff_sites(structure, map_occupations=[])) ['8a', '8a', '8a', '8a', '8a', '8a', '8a', '8a', '8a', '8a', '8a', '8a', '8a', '8a', '8a', '8a']