QMol_disc - fmauger1/QMol-grid GitHub Wiki
QMol_disc
Cartesian-grid domain discretization.
Table of Contents
Comparing domain discretizations
Schrödinger-equation class methods
Description
QMol_disc defines the Cartesian-grid discretization of the domain for all grid-based simulations in the QMol-grid package. It also provides a suite of functionalities for data (object) allocation, arithmetic, and various low-level computations that are used throughout the rest of the package.
Class properties
Domain definition
Properties associated with the domain definition can be accessed using the regular dot operator but, outside of the QMol-grid package, can only be edited using the set method.
xspan (x)
Discretization grid of the simulation domain [ vector (default []) ]
xspanis assumed to be a Cartesian grid (all increasing, equally-spaced, vertices)QMol_discdoes not check whetherxspanis indeed a Cartesian grid. Using a non-Cartesian grid will almost certainly produce wrong results.
Differential operators
Differential-operator properties are dependent and hold meaningful values only after the QMol_disc object has been initialized. Access differential-operator properties using the regular dot operator. Differential-operator properties cannot be edited with the set method.
D
Discretization of the gradient operator $\nabla$ in Fourier space [ vector (default []) ]
- At initialization,
Dis defined as1i*fourierTool.fftGrid(obj.x).' Dis a column vector with the same number of element asxspan.- Compute the gradient of a function
f, defined overxspanand with with vanishing or periodic boundary conditions, withifft(obj.D.fft(f)).
T
Discretization of the Laplacian operator $-\frac{\Delta }{2}$ in Fourier space [ vector (default []) ]
- At initialization,
Tis defined as-0.5*D.^2 Tis a column vector with the same number of element asxspan.- Compute the Laplacian of a function
f, defined overxspanand with with vanishing or periodic boundary conditions, withifft(obj.T.fft(f)).
Tv
Discretization of the velocity-gauge Laplacian operator in Fourier space [ vector (default []) ]
Tvis independently initialized using thesetTvmethod. For a potential vectorA, Tv is defined as0.5*(-1i*D+A).^2.Tvis a column vector with the same number of element asxspan.- Compute the velocity-gauge Laplacian of a function
f, defined overxspanand with with vanishing or periodic boundary conditions, withifft(obj.Tv.fft(f)). - Empty
Tvindicates that the velocity-gauge laplacian has not been initialized using thesetTvmethod.
Initialization status
Internally, QMol_disc objects keep track as to whether they have been initialized after creation. Access the initialization status using the regular dot operator. The initialization status cannot be edited with the set method. All QMol_disc object, irrespective of prior initialization are guaranteed to define a meaningful initialization status.
isInitialized (isInit)
Initialization status of the QMol_disc object [ false (default) | true ]
isInitialized == falseindicates that the object is not (fully) initialized. This is the status after creation, and using any of theset, reset, orclearmethods of the class.isInitialized == trueindicates that the object is (fully) initialized. This is the status after running theinitializemethod.
Miscellaneous
Internally, QMol_disc objects keeps track of some properties that are necessary for some of its methods. Access miscellaneous properties using the regular dot operator. Miscellaneous properties cannot be edited with the set method, they are defined at initialization of the object.
dx
Discretization stencil [ scalar (default []) ]
- At initialization,
dxis defined asxspan(2)-xspan(1).
basisSize (nV)
Number of grid points in the domain discretization [ positive integer (default []) ]
- At initialization,
basisSizeis defined asnumel(obj.xspan). basisSizeis typically used for data preallocation (thus the name).
QM
Parent QMol-grid theory object [ handle-class object (default []) ]
- Knowledge of the parent QM object is required for running some of the
QMol_discmethods -- such methods are identified below. - For developers: For practical reasons,
QMis editable byQMol_DFTclasses.
isBasis
Flag indicating that QMol_disc objects are not a basis-set discretization [ false ]
- At run time,
isBasiscan be used to discriminateQMol_discobjects fromQMol_disc_basis(which overloads the class) - For class development purposes,
isBasisis technically a static method. Practically, though, it can virtually almost always be treated as a constant property.
Generic class methods
Creation
default constructor
Create a QMol_disc object with all properties set to their default values
obj = QMol_disc;
Create a QMol_disc object with name property set to the specified value. Several name-value paris can be consecutively. Suitable name is any of the domain definition properties and is case insensitive.
obj = QMol_disc(name,value);
obj = QMol_disc(name1,value1,name2,value2,___);
Changing class properties
After creation, the domain definition properties of a QMol_disc object can be edited.
set
Update the name property of a QMol_disc object to the specified value. Several name-value pairs can be specified consecutively. Suitable name are specified in the domain definition properties and are case insensitive.
obj.set(name1,value1);
obj.set(name1,value1,name2,value2,___);
- The
setmethod alsoresetthe class. - After running, the
setproperty updates theisInitializedflag to afalsevalue.
reset
Reset the object and update the isInitialized flag to a false.
obj.reset;
- The
resetmethod clears the dependent propertiesD,T,Tv,dx,basisSize, andQM. - After running, the
resetproperty updates theisInitializedflag to afalsevalue.
clear
Clear all the domain definition properties
obj.clear;
Clear a specific set of the domain definition properties. Suitable name are any of the domain definition properties and are case insensitive.
obj.clear(name1,name2,___);
- The
clearmethod alsoresetthe class. - The
clearmethod can be used to delete specific properties before saving a QMol_disc object.
Initializing QMol_disc objects
To set dependent class properties that are required for most of the class properties, QMol_disc objects must be initialized.
initialize
Initialize a QMol_disc object without attaching a QMol-grid theory object
obj.initialize;
obj.initialize([]);
- This initializes the dependent properties
D,T,dx, andbasisSize, and sets theisInitializedflag totrue. - The
QMproperty is left empty. - Methods requiring a QMol-grid theory object specified in
QMwill not work, most likely causing an error.
Initialize a QMol_disc object with attaching a QMol-grid theory object
obj.initialize(QM);
- This performs the same initialization as previously plus copying the input
QMobject into theQMproperty. - Methods requiring a QMol-grid theory object specified in
QMwill not work provided QM is of a compatible type. - Properties that require a QMol-grid theory object specified in
QMand the compatibility criteria are specified in each property description below.
setTv
After the QMol_disc object has been initialized, set the velocity-gauge Laplacian operator Tv with
obj.setTv(A);
- The input scalar
Aspecifies the value of the vector potential for the velocity-gauge laplacian.
Clear the velocity-gauge Laplacian operator Tv with either of
obj.setTv;
obj.setTv([]);
Run-time documentation
getMemoryProfile
Get an estimate of the memory held by a QMol_disc object with either
mem = obj.getMemoryProfile;
mem = obj.getMemoryProfile(false);
- The object must be properly initialized.
- The estimate only includes the discretization of member components over the domain grid and ignores other (small) properties.
- The output
memis the estimated size in bytes.
Additionally display the detail of the memory footprint with
mem = obj.getMemoryProfile(true);
Comparing domain discretizations
The class overloads the == and ~= operators to facilitate the comparison between QMol_disc objects
eq (==)
Test if two QMol_disc objects describe the same domain discretization
obj1 == obj2
- This is defined as
all(abs(obj1.xspan(:)-obj2.xspan(:)) <= eqTol,'all') eqTol = 1e-10is a tolerance parameter to account for possible roundoff mismatch between two domain-discretization objects.- Any mismatch in the size of the two domain grids returns a
falseresult. - The equality test ignores any QMol-grid theory object specified in
QM.
ne (~=)
Test if two QMol_disc objects describe different domain discretizations
obj1 ~= obj2
- This is equivalent to
~(obj1 == obj2).
DFT class methods
Component names (static)
To facilitate housekeeping of a specific domain discretization compared with overloading classes for a different flavors of discretization, QMol_disc defines static methods returning the names of the classes that describe one-body densities, and Kohn-Sham orbitals and potentials
DFT_classDensity (static)
Get the name of the class describing one-body densities
obj.DFT_classDensity;
- Returns
'QMol_DFT_density'
DFT_classOrbital (static)
Get the name of the class describing Kohn-Sham orbitals
obj.DFT_classOrbital;
- Returns
'QMol_DFT_orbital'
DFT_classPotential (static)
Get the name of the class describing Kohn-Sham potentials
obj.DFT_classPotential;
- Returns
'QMol_DFT_Vks'
DFT_classPotentialGradient (static)
Get the name of the class describing Kohn-Sham potential gradients
obj.DFT_classPotentialGradient;
- Returns
'QMol_DFT_Vks_grad'
Data allocation
Note: all DFT data/object allocation require the QMol_disc object to have been initialized with a DFT-theory object (QMol_DFT_spinRes or QMol_DFT_spinPol object).
DFT_allocateDensity
Allocate a new one-body density object with either
rho = obj.DFT_allocateDensity;
rho = obj.DFT_allocateDensity([]);
rho = obj.DFT_allocateDensity([],false);
- Only the density object is created and no memory is preallocated for the discretization of the one-body density itself.
- The allocation also initializes the
QMol_DFT_densityobject, i.e., theisInitializedflag of the outputrhois set totrue.
Allocate a new one-body density object and force the discretization of the one-body density to be preallocated with zero values
rho = obj.DFT_allocateDensity([],true);
Reallocate an existing one-body density object
obj.DFT_allocateDensity(rho);
obj.DFT_allocateDensity(rho,false);
obj.DFT_allocateDensity(rho,true);
- This will first arease all data in the input
QMol_DFT_densityobjectrhoand then perform the (re)allocation.
DFT_allocateOrbital
Allocate a new Kohn-Sham-orbital object with either
KSO = obj.DFT_allocateOrbital(N);
KSO = obj.DFT_allocateOrbital(N,[]);
- For spin restricted DFT models,
Nis a positive integer specifying the number of orbitals to be allocated. - For spin polarized DFT models, N is a two vector of positive integers specifying the number of orbitals to be allocated in the up- and down-spin channels, respectively.
- In all cases, the relevant properties in the output
QMol_DFT_orbitalobject are allocated to zero. - The allocation also initializes the
QMol_DFT_orbitalobject, i.e., theisInitializedflag of the outputKSOis set totrue.
Reallocate and existing Kohn-Sham-orbital object
obj.DFT_allocateOrbital(N,KSO);
- If the input
QMol_DFT_orbitalobject KSO has a different spin polarization than QM, or the size of the member orbital properties does not match the domain discretization, all content in KSO is wiped out and a new, zero-valued, orbital object is allocated. - Otherwise, the content of the orbital properties is resized to match the requested number of orbitals: The final orbitals are removed for smaller
Nor zero-value orbitals are added at the end for largerN. - Orbital resizing is typically used to restart (TD)DFT computations from a previous result instead of scratch.
- To force the reallocation of zero-valued orbitals irrespective of matching spin polarization of domain size, first clear the orbital object with
KSO.clearbeforeobj.DFT_allocateOrbital(N,KSO). - The allocation also initializes the
QMol_DFT_orbitalobject, i.e., theisInitializedflag of the inputKSOis set totrue.
Allocate with random values (instead of the default zeros) with
KSO = obj.DFT_allocateOrbital(N,[],randStr); % Allocate new orbitals
KSO = obj.DFT_allocateOrbital(N,[],randStr,false);
obj.DFT_allocateOrbital(N,KSO,randStr); % Reallocate existing ones
obj.DFT_allocateOrbital(N,KSO,randStr,false);
randStris a random number stream from which the random values are taken.- The (random) orbitals are complex valued and normalized (but not orthogonal).
Allocate with random real values with
KSO = obj.DFT_allocateOrbital(N,[],randStr,true); % Allocate new orbitals
obj.DFT_allocateOrbital(N,KSO,randStr,true); % Reallocate existing ones
DFT_allocatePotential
Allocate a new Kohn-Sham potential object with either
V = obj.DFT_allocatePotential;
V = obj.DFT_allocatePotential([]);
- Only the potential object is created and no memory is preallocated for the discretization of the Kohn-Sham potential itself.
- The allocation does not initialize the
QMol_DFT_Vksobject, i.e., theisInitializedflag of the outputVis left tofalse(unlike for the density and orbitals).
Reallocate an existing Kohn-Sham potential object
obj.DFT_allocatePotential(V);
- This will first arease all data in the input
QMol_DFT_VksobjectVand then perform the (re)allocation.
DFT_allocatePotentialGradient
Allocate a new Kohn-Sham potential gradient object with either
DV = obj.DFT_allocatePotentialGradient;
DV = obj.DFT_allocatePotentialGradient([]);
- Only the potential gradient object is created and no memory is preallocated for the discretization of the Kohn-Sham potential gradient itself.
- The allocation does not initialize the
QMol_DFT_Vks_gradobject, i.e., theisInitializedflag of the output DVis left tofalse(unlike for the density and orbitals).
Reallocate an existing Kohn-Sham potential gradient object
obj.DFT_allocatePotentialGradient(DV);
- This will first erase all data in the input
QMol_DFT_Vks_gradobjectDVand then perform the (re)allocation.
Miscellaneous
DFT_dist
Compute the distance between two one-body densities
d = obj.DFT_dist(rho1,rho2);
- For spin restricted DFT models, the output scalar
dcontains the numerical evaluation of $\sqrt{\int (\rho_1 (x)-\rho_2 (x))^2 ~dx}$ - For spin polarized DFT models, the output two vector
dcontains the numerical evaluation of $\sqrt{\int (\rho_1^{\uparrow } (x)-\rho_2^{\uparrow } (x))^2 ~dx}$ and $\sqrt{\int (\rho_1^{\downarrow } (x)-\rho_2^{\downarrow } (x))^2 ~dx}$ , respectively - Both one-body density objects must be allocated and initialized beforehand, and have matching spin polarized or restricted nature.
DFT_mix
Linearly mix pairs of spin-restricted one-body densities
rho = obj.DFT_mix(rho,alpha1,rho1,alpha2,rho2,___);
- Performs the linear mixing of densities $\rho =\alpha_1 \rho_1 +\alpha_2 \rho_2 +\cdots$
- Each of the
rhois a spin-restricted one-body density object and each of thealphais a scalar - Note that this is an in-place function and the content of the first input one-body density object is changed by
DFT_mix obj.DFT_mix(rho1,alpha1,rho1,alpha2,rho2,___), with the one-body density object repeated in the first mixing pair, formally performs in place mixing $\rho_1 \gets \alpha_1 \rho_1 +\alpha_2 \rho_2 +\cdots$
Linearly mix pairs of spin-polarized one-body densities
rho = obj.DFT_mix(rho,[a11 a12],rho1,[a21 a22],rho2,___);
- Performs the linear mixings of densities $
\rho^{\uparrow } =a_{11} \rho_1^{\uparrow } +a_{21} \rho_2^{\uparrow } +\cdots$ and $\rho^{\downarrow } =a_{21} \rho_1^{\downarrow } +a_{22} \rho_2^{\downarrow } +\cdots$ - Each of the
rhois a spin-polarized one-body density object and each of theais a scalar - Note that this is an in-place function and the content of the first input one-body density object is changed by
DFT_mix obj.DFT_mix(rho,[a11 a12],rho1,[a21 a22],rho2,___), with the one-body density object repeated in the first mixing pair, formally performs in place mixing
Linearly mix pairs of Kohn-Sham potentials
Vks = obj.DFT_mix(Vks,alpha1,Vks1,alpha2,Vks2,___);
- Performs the linear mixing of potentials $
{\mathcal{V}}_{{\mathrm{K}\mathrm{S}}} =\alpha_1 {\mathcal{V}}_{{\mathrm{K}\mathrm{S},1}} +\alpha_2 {\mathcal{V}}_{{\mathrm{K}\mathrm{S},2}} +\cdots$ - Each of the
Vksis a Kohn-Sham potential object - For spin-restricted DFT models, each of the
alphais a scalar - For spin-polarized DFT models, each of the alpha is a two vector indicating the mixing coefficients for the up- and down-spin channels
- In-place mixing can be performed by repeating the output Kohn-Sham potential object in the first mixing pair
obj.DFT_mix(Vks1,alpha1,Vks1,alpha2,Vks2,___) - Note that only the explicit part of the potential is mixed: any implicit components of input $
{\mathcal{V}}_{{\mathrm{K}\mathrm{S}}}$ are left unchanged in the output while all implicit components of ${\mathcal{V}}_{{\mathrm{K}\mathrm{S},1}} , {\mathcal{V}}_{{\mathrm{K}\mathrm{S},2}} , \cdots$ are ignored. - Note that this is an in-place function and the content of the first input Kohn-Sham potential object is changed by
DFT_mix
DFT_mix does not perform any density/potential allocation or initialization; all input objects must be created and initialized beforehand. DFT_mix is typically used by self-consistent-field solvers in ground-state DFT computations
DFT_normalizeOrbital
Normalize Kohn-Sham orbitals to
p = obj.DFT_normalizeOrbital(p);
- The input
pis a matrix whose columns contain the Kohn-Sham orbitals to be normalized - The normalization is such that $\int |\phi_k (x)|^2 ~dx=1$ for all the orbitals $\phi_k$ in
p - Note that this is an in-place function which avoids creating a copy of the matrix p when performing the normalization
DFT_randomOrbital
Generate a random Kohn-Sham orbital from random number stream
p = obj.DFT_randomOrbital(randStr);
- The input random number stream
randStrenables reproducibility across runs - The output vector
pis a single normalized Kohn-Sham orbital p = DFT_randomOrbital(randStr,0)is equivalent top = DFT_randomOrbital(randStr)and produces a random orbital with no specific symmetry
Generate a random symmetric Kohn-Sham orbital
p = obj.DFT_randomOrbital(randStr,1);
Generate a random antisymmetric Kohn-Sham orbital
p = obj.DFT_randomOrbital(randStr,-1);
Random orbitals with a specific symmetry are typically used as a seed for ground-state DFT computations with enforced symmetry for the solution.
DFT_SCF_AndersonMixCoeff
Compute the mixing coefficient for self-consistent-field computations with an Anderson mixing scheme from one-body densities
b = obj.DFT_SCF_AndersonMixCoeff(rho1i,rho2i,rho1o,rho2o);
- For spin restricted DFT models, the output scalar
bcontains the numerical evaluation of the mixing coefficient for the Anderson mixing scheme - For spin polarized DFT models, the output two vector contains the numerical evaluation of the mixing coefficient for the Anderson mixing scheme
- All one-body density objects must be allocated and initialized beforehand, and have matching spin polarized or restricted nature.
Compute the mixing coefficient for self-consistent-field computations with an Anderson mixing scheme from Kohn-Sham potentials
b = obj.DFT_SCF_AndersonMixCoeff(Vks1i,Vks2i,Vks1o,Vks2o);
- For spin restricted DFT models, the output scalar
bcontains the numerical evaluation of the mixing coefficient for the Anderson mixing scheme - For spin polarized DFT models, the output two vector contains the numerical evaluation of the mixing coefficient for the Anderson mixing scheme
- Note that only the explicit part of the potential is used to define the mixing coefficient and any implicit component is ignored.
- All Kohn-Sham potentials must be allocated and initialized beforehand, and have matching spin polarized or restricted nature.
DFT_SCF_AndersonMixCoeff is used in the QMol_DFT_SCF_Anderson class and is not expected to have any use for end users.
DFT_sizeOrbital
Get the size of a Kohn-Sham orbital
s = obj.DFT_sizeOrbital;
- This is defined as
s = [numel(obj.x) 1] - This is typically used for data preallocation
Operators and functionals
DFT_energyKinetic
Compute the DFT kinetic energy for specifies occupation coefficients and Kohn-Sham orbitals
E = obj.DFT_energyKinetic(occ,KSO);
- For spin-restricted models, the output positive real E corresponds to the numerical evaluations of the DFT kinetic energy defined as $E=\sum_k n_k \langle \phi_k |\hat{\mathcal{T}} |\phi_k \rangle$ . The population coefficients $n_k$ are specified in the input vector occ and the Kohn-Sham orbitals $|\phi_k \rangle$ in the
QMol_DFT_orbitalobjectKSO. - For spin-polarized models, the ouput positive vector [
Eup Edown]corresponds to the numerical evaluation of the DFT kinetic energy in the up- and down-spin channels, respectively. The population coefficients for each spin channel are grouped in a cellocc = {occUp,occDown}. DFT_energyKineticautomatically detect whether to use the length- or velocity-gauge kinetic operator $\hat{\mathcal{T}}$ to compute the energy.
DFT_energyOrbital
Compute the energy of Kohn-Sham orbitals for a specific potential
E = obj.DFT_energyOrbital(Vks,KSO);
- For an orbital $
\left|\phi \right\rangle$ , the orbital energy is defined as the real $E=\langle \phi |{\hat{\mathcal{H}} }_{{\mathrm{D}\mathrm{F}\mathrm{T}}} |\phi \rangle$ where ${\hat{\mathcal{H}} }_{{\mathrm{D}\mathrm{F}\mathrm{T}}}$ is the total DFT Hamiltonian operator. - For spin-restricted models,
Eis aN-by-1vector containing the energies of each of theNKohn-Sham orbitals in theQMol_DFT_orbitalobjectKSO. - For spin-polarized models,
Eis a cell containing aNup-by-1andNdown-by-1vectors respectively with energies of each of theNupandNdownKohn-Sham orbitals in the up- and down-spin channels of theQMol_DFT_orbitalobjectKSO. - The input
Vksis aQMol_DFT_Vksobject describing the Kohn-Sham potential to be used in the Hamiltonian operator
Additionally compute the errors for the Kohn-Sham orbitals
[E,DE] = obj.DFT_energyOrbital(Vks,KSO);
- For an orbital $
\left|\phi \right\rangle$ , the error is defined as the positive real $\left\|({\hat{\mathcal{H}} }_{{\mathrm{D}\mathrm{F}\mathrm{T}}} -E)|\phi \rangle \right\|$ with the orbital energy $E$ defined as above. - For spin-restricted or polarized models, the additional output
DEis a vector or cell of vectors with the errors matching each orbital energy.
DFT_operatorHamiltonian
For spin-restricted models, apply the total, kinetic plus potential, DFT Hamiltonian operator to a wave function with either
Hp = obj.DFT_operatorHamiltonian(Vks,p);
Hp = obj.DFT_operatorHamiltonian(Vks,p,0);
pandHpare bothnumel(xspan)-by-1vectors respectively containing the discretization of the orbital to which the potential should be applied and its result. Vks is aQMol_DFT_Vksobject describing the Kohn-Sham potential.DFT_operatorHamiltonianautomatically detect whether to use the length- or velocity-gauge kinetic operator.
For spin-polarized models, apply the total, kinetic plus potential, DFT Hamiltonian operator to a wave function respectively with
Hp = obj.DFT_operatorHamiltonian(Vks,p,true); % spin up
Hp = obj.DFT_operatorHamiltonian(Vks,p,true,0);
Hp = obj.DFT_operatorHamiltonian(Vks,p,false); % spin down
Hp = obj.DFT_operatorHamiltonian(Vks,p,false,0);
pandHpare bothnumel(xspan)-by-1vectors respectively containing the discretization of the orbital to which the potential should be applied and its result. Vks is aQMol_DFT_Vksobject describing the Kohn-Sham potential.DFT_operatorHamiltonianautomatically detect whether to use the length- or velocity-gauge kinetic operator.
Enforce symmetric or antisymmetric results respectively with
Hp = obj.DFT_operatorHamiltonian(___,1);
Hp = obj.DFT_operatorHamiltonian(___,-1);
- The symmetric constraint enforces that
Hpmatchesflip(Hp,1)within roundoff error - The antisymmetric constraint enforces that
Hpmatches -flip(Hp,1)within roundoff error - In both cases, the input wave function should match the same symmetry condition, but no check is performed for this (i.e., using symmetry enforced
DFT_operatorPotentialon a wave function that does not match the same symmetry condition will produce erroneous results) - This is typically used in ground-state DFT computations with enforced symmetry.
DFT_operatorKinetic
Apply the kinetic operator to a wave function with either
Hp = obj.DFT_operatorKinetic(p);
Hp = obj.DFT_operatorKinetic(p,0);
- In the velocity gauge, after setting the Laplacian with
setTv, numerically computes $\frac{(-i\nabla +A)^2 }{2}\left|\phi \right\rangle$ on the input wave functionp - In the length gauge, numerically computes $-\frac{\Delta }{2}\left|\phi \right\rangle$ on the input wave function
p pandHpare bothnumel(xspan)-by-1vectors respectively containing the discretization of the orbital to which the potential should be applied and its result.
Enforce symmetric or antisymmetric results respectively with
Hp = obj.DFT_operatorKinetic(p,1);
Hp = obj.DFT_operatorKinetic(p,-1);
- The symmetric constraint enforces that
Hpmatchesflip(Hp,1)within roundoff error - The antisymmetric constraint enforces that
Hpmatches -flip(Hp,1)within roundoff error - In both cases, the input wave function should match the same symmetry condition, but no check is performed for this (i.e., using symmetry enforced
DFT_operatorKineticon a wave function that does not match the same symmetry condition will produce erroneous results) - This is typically used in ground-state DFT computations with enforced symmetry.
DFT_operatorPotential
For spin-restricted models, apply the Kohn-Sham potential operator to a wave function with either
Hp = obj.DFT_operatorPotential(Vks,p);
Hp = obj.DFT_operatorPotential(Vks,p,0);
- This computes the action of the entire, including both explicit and implicit components, Kohn-Sham potential operator described by the
Vksobject on the input wave functionp. pandHpare bothnumel(xspan)-by-1vectors respectively containing the discretization of the orbital to which the potential should be applied and its result.Vksis aQMol_DFT_Vksobject- This method interface is provided to completeness, instead
Hp = Vks.applyPotential(p)is recommended
For spin-polarized models, apply the up- and down-spin Kohn-Sham potential operators to a wave function respectively with
Hp = obj.DFT_operatorPotential(Vks,p,true); % spin up
Hp = obj.DFT_operatorPotential(Vks,p,true,0);
Hp = obj.DFT_operatorPotential(Vks,p,false); % spin down
Hp = obj.DFT_operatorPotential(Vks,p,false,0);
- This computes the action of the entire -- including both explicit and implicit components -- Kohn-Sham potential operator described by the
Vksobject on the input wave functionp. pandHpare bothnumel(xspan)-by-1vectors respectively containing the discretization of the orbital to which the potential should be applied and its result. Vks is aQMol_DFT_Vksobject- This method interface is provided to completeness, instead
Hp = Vks.applyPotential(p,true)andHp = Vks.applyPotential(p,false)are recommended
Enforce symmetric or antisymmetric results respectively with
Hp = obj.DFT_operatorPotential(___,1);
Hp = obj.DFT_operatorPotential(___,-1);
- The symmetric constraint enforces that
Hpmatchesflip(Hp,1)within roundoff error - The antisymmetric constraint enforces that
Hpmatches -flip(Hp,1)within roundoff error - In both cases, the input wave function should match the same symmetry condition, but no check is performed for this (i.e., using symmetry enforced
DFT_operatorPotentialon a wave function that does not match the same symmetry condition will produce erroneous results) - This is typically used in ground-state DFT computations with enforced symmetry.
Schrödinger-equation class methods
Component names (static)
To facilitate housekeeping of a specific domain discretization compared with overloading classes for a different flavors of discretization, QMol_disc defines static methods returning the names of the classes that describe wave functions and potentials.
SE_classWaveFunction (static)
Get the name of the class describing wave functions
obj.SE_classWaveFunction;
- Returns
'QMol_SE_wfcn'
SE_classPotential (static)
Get the name of the class describing potentials
obj.DFT_classPotential;
- Returns
'QMol_SE_V'
Data allocation
Note: all Schrödinger-equation data/object allocation require the QMol_disc object to have been initialized with a Schrödinger-equation object (QMol_SE object).
SE_allocateWaveFunction
Allocate a new wave function object with either
wfcn = obj.SE_allocateWaveFunction(N);
wfcn = obj.SE_allocateWaveFunction(N,[]);
Nis a positive integer specifying the number of wave functions to be allocated.- The relevant properties in the output
QMol_SE_wfcnobject are allocated to zero. - The allocation also initializes the
QMol_SE_wfcnobject, i.e., theisInitializedflag of the outputwfcnis set totrue.
Reallocate and existing wave function object
wfcn = obj.SE_allocateWaveFunction(N,wfcn);
- If the size of the member wave functions property does not match the domain discretization, all content of the wave function in the input
QMol_SE_wfcnobjectwfcnis wiped out and a new, zero-valued, wave function object is allocated. - Otherwise, the content of the wave function property is resized to match the requested number of orbitals: The final wave functions are removed for smaller
Nor zero-value wave functions are added at the end for largerN. - Wave function resizing is typically used to restart (TD)SE computations from a previous result instead of from scratch.
- To force the reallocation of zero-valued wave functions irrespective of matching domain size, first clear the wave function object with
wfcn.clearbeforeobj.SE_allocateWaveFunction(N,wfcn). - The allocation also initializes the
QMol_SE_wfcnobject, i.e., theisInitializedflag of the inputwfcnis set totrue.
Allocate with random values (instead of the default zeros) with
wfcn = obj.SE_allocateWaveFunction(N,[],randStr); % Allocate new wave functions
wfcn = obj.SE_allocateWaveFunction(N,[],randStr,false);
obj.SE_allocateWaveFunction(N,wfcn,randStr); % Reallocate existing ones
obj.SE_allocateWaveFunction(N,wfcn,randStr,false);
randStris a random number stream from which the random values are taken.- The (random) wave functions are complex valued and normalized (but not orthogonal).
Allocate with random real values with
wfcn = obj.SE_allocateWaveFunction(N,[],randStr,true); % Allocate new wave functions
obj.SE_allocateWaveFunction(N,wfcn,randStr,true); % Reallocate existing ones
Miscellaneous
SE_normalizeWaveFunction
Normalize wave functions
p = obj.SE_normalizeWaveFunction(p);
- The input
pis a matrix whose columns contain the wave functions to be normalized - The normalization is such that $\int |\psi_k (x)|^2 ~dx=1$ for all the wave functions $\psi_k$ in
p - Note that this is an in-place function which avoids creating a copy of the matrix p when performing the normalization
SE_randomWaveFunction
Generate a random wave function from random number stream
p = obj.SE_randomWaveFunction(randStr);
- The input random number stream
randStrenables reproducibility across runs - The output vector
pis a single normalized wave function p = SE_randomWaveFunction(randStr,0)is equivalent top = SE_randomWaveFunction(randStr)and produces a random orbital with no specific symmetry
Generate a random symmetric wave function
p = obj.SE_randomWaveFunction(randStr,1);
Generate a random antisymmetric wave function
p = obj.SE_randomWaveFunction(randStr,-1);
Random wave functions with a specific symmetry are typically used as a seed for ground-state Schrödinger-equation computations with enforced symmetry for the solution.
SE_sizeWaveFunction
Get the size of a wave function
s = obj.SE_sizeWaveFunction;
- This is defined as
s = [numel(obj.x) 1] - This is typically used for data preallocation
Operators and functionals
SE_energyKinetic
Compute the Schrödinger-equation kinetic energy for the input wave functions
E = obj.SE_energyKinetic(occ,wfcn);
- The output positive real E corresponds to the numerical evaluations of the Schrödinger-equation kinetic energy, summed over all the wave functions, defined as $E=\sum_k \langle \psi_k |\hat{\mathcal{T}} |\psi_k \rangle$ .
SE_energyKineticautomatically detect whether to use the length- or velocity-gauge kinetic operator $\hat{\mathcal{T}}$ to compute the energy.
SE_energyWaveFunction
Compute the energy of wave functions for a specific potential
E = obj.SE_energyWaveFunction(V,wfcn);
- For a wave function $\left|\psi \right\rangle$ , the wave function energy is defined as the real $E=\langle \psi |\hat{\mathcal{H}} |\psi \rangle$ where $\hat{\mathcal{H}}$ is the total Schrödinger-equation Hamiltonian operator.
Eis aN-by-1vector containing the energies of each of theNwave functions orbitals in theQMol_SE_wfcnobjectwfcn.- The input V is a
QMol_SE_Vobject describing the potential to be used in the Hamiltonian operator
Additionally compute the errors for the wave functions
[E,DE] = obj.SE_energyWaveFunction(Vks,wfcn);
- For a wave function $\left|\psi \right\rangle$ , the error is defined as the positive real $
\left\| (\hat{\mathcal{H}} -E)|\psi \rangle \right\|$ with the wave function energy $E$ defined as above.
SE_operatorHamiltonian
Apply the total, kinetic plus potential, Schrödinger Hamiltonian operator to a wave function with either
Hp = obj.SE_operatorHamiltonian(Vks,p);
Hp = obj.SE_operatorHamiltonian(Vks,p,0);
pandHpare bothnumel(xspan)-by-1vectors respectively containing the discretization of the wave function to which the potential should be applied and its result. V is aQMol_SE_Vobject describing the potential.SE_operatorHamiltonianautomatically detect whether to use the length- or velocity-gauge kinetic operator.
Enforce symmetric or antisymmetric results respectively with
Hp = obj.SE_operatorHamiltonian(___,1);
Hp = obj.SE_operatorHamiltonian(___,-1);
- The symmetric constraint enforces that
Hpmatchesflip(Hp,1)within roundoff error - The antisymmetric constraint enforces that
Hpmatches-flip(Hp,1)within roundoff error - In both cases, the input wave function should match the same symmetry condition, but no check is performed for this (i.e., using symmetry enforced
SE_operatorHamiltonianon a wave function that does not match the same symmetry condition will produce erroneous results) - This is typically used in ground-state Schrödinger-equation computations with enforced symmetry.
SE_operatorKinetic
Apply the kinetic operator to a wave function with either
Hp = obj.SE_operatorKinetic(p);
Hp = obj.SE_operatorKinetic(p,0);
- In the velocity gauge, after setting the Laplacian with
setTv, numerically computes $\frac{(-i\nabla +A)^2 }{2}\left|\psi \right\rangle$ on the input wave functionp - In the length gauge, numerically computes $-\frac{\Delta }{2}\left|\psi \right\rangle$ on the input wave function
p pandHpare bothnumel(xspan)-by-1vectors respectively containing the discretization of the wave functions to which the potential should be applied and its result.
Enforce symmetric or antisymmetric results respectively with
Hp = obj.SE_operatorKinetic(p,1);
Hp = obj.SE_operatorKinetic(p,-1);
- The symmetric constraint enforces that
Hpmatchesflip(Hp,1)within roundoff error - The antisymmetric constraint enforces that
Hpmatches-flip(Hp,1)within roundoff error - In both cases, the input wave function should match the same symmetry condition, but no check is performed for this (i.e., using symmetry enforced
SE_operatorKineticon a wave function that does not match the same symmetry condition will produce erroneous results) - This is typically used in ground-state Schrödinger-equation computations with enforced symmetry.
SE_operatorPotential
Apply the potential operator to a wave function with either
Hp = obj.SE_operatorPotential(V,p);
Hp = obj.SE_operatorPotential(V,p,0);
- This computes the action of the potential operator described by the
Vobject on the input wave functionp. pandHpare bothnumel(xspan)-by-1vectors respectively containing the discretization of the wave function to which the potential should be applied and its result. V is aQMol_SE_Vobject
Enforce symmetric or antisymmetric results respectively with
Hp = obj.SE_operatorPotential(___,1);
Hp = obj.SE_operatorPotential(___,-1);
- The symmetric constraint enforces that
Hpmatchesflip(Hp,1)within roundoff error - The antisymmetric constraint enforces that
Hpmatches -flip(Hp,1)within roundoff error - In both cases, the input wave function should match the same symmetry condition, but no check is performed for this (i.e., using symmetry enforced
SE_operatorPotentialon a wave function that does not match the same symmetry condition will produce erroneous results) - This is typically used in ground-state Schrödinger-equation computations with enforced symmetry.
Examples
Create a discretization
disc = QMol_disc('x',-10:.1:15);
disc.initialize;
Display the estimated memory footprint for the object
disc.getMemoryProfile(true);
* Domain discretization
> domain 2.0 KB
> gradient 3.9 KB
> Laplacian 2.0 KB
> Laplacian (velocity gauge) 3.9 KB
Compute the gradient and Laplacian of a function
f = 3/sqrt(2*pi*3)*exp(-(disc.x(:)-3.5).^2/2/3);
df = ifft(disc.D.*fft(f));
ddf = ifft(disc.T.*fft(f));
Plot the three functions
figure; hold on
plot(disc.x,f,'-','LineWidth',2,'DisplayName','f')
plot(disc.x,df,'-','LineWidth',2','DisplayName','\nabla{f}')
plot(disc.x,ddf,'-','LineWidth',2','DisplayName','-\Delta{f}/2')
xlabel('position (a.u.)'); xlim(disc.x([1 end]));
ylabel('function/gradient/Laplacian')
legend show
Finally we can compare the numerical differentiations to closed-form formula.
% Analytical derivatives
Df = -(disc.x(:)-3.5)/3 .* f;
Ddf = (f/3 - (disc.x(:)-3.5).^2/9 .*f)/2;
% Plot differences
figure; hold on
plot(disc.x,Df-df,'-','LineWidth',2','DisplayName','\nabla{f}')
plot(disc.x,Ddf-ddf,'-','LineWidth',2','DisplayName','-\Delta{f}/2')
xlabel('position (a.u.)'); xlim(disc.x([1 end]));
ylabel('error')
legend show
and see that we have excellent agreement between the two (the error can be further driven down by increasing the box size).
Test suite
Run the test suite for the QMol_disc class in normal or summary mode respectively with
QMol_test.test('disc');
QMol_test.test('-summary','disc');
For developers
Class definition
QMol_disc defines a concrete handle class overloading QMol_suite.
QMol_disc is a cornerstone component to the QMol-grid package and, as such, contains many properties. For enhanced readability it implements most of it methods in separate files (inside the @QMol_disc folder). Its efficiency as compared to a regular definition of the class and all its methods in a single MATLAB file are untested. To make a single-file class, copy all the QMol_disc.m file class definition and move the file outside of @QMol_disc folder (and delete the folder).
Run-time documentation
After it has been initialized, display the run-time documentation associated with a specific QMol_disc object
obj.showDocumentation;
The run-time documentation is only accessible to the QMol_suite (and overloading) class.
Private methods
QMol_disc defines a handful of private methods (in the QMol_disc.m file itself).
DFT_applySymmetry
Apply the symmetrization operator to a Kohn-Sham orbital
p = obj.DFT_applySymmetry(1,p);
- The symmetrized orbital verifies
p = flip(p,1)within roundoff error
Apply the antisymmetrization operator to a Kohn-Sham orbital
p = obj.DFT_applySymmetry(-1,p);
- The antisymmetrized orbital verifies
p = -flip(p,1)within roundoff error
Note that DFT_applySymmetry is an in-place function. To provide a universal interface, p = obj.DFT_applySymmetry(0,p) is the identity operator, imposing no (anti)symmetrization to the orbital.
SE_applySymmetry
Apply the symmetrization operator to a wave function
p = obj.SE_applySymmetry(1,p);
- The symmetrized wave function verifies
p = flip(p,1)within roundoff error
Apply the antisymmetrization operator to a wave function
p = obj.SE_applySymmetry(-1,p);
- The antisymmetrized wave function verifies
p = -flip(p,1)within roundoff error
Note that SE_applySymmetry is an in-place function. To provide a universal interface, p = obj.SE_applySymmetry(0,p) is the identity operator, imposing no (anti)symmetrization to the orbital.
Notes
The results displayed in this documentation page were generated using version 01.21 of the QMol-grid package.
QMol_discwas introduced in version 01.00- Version 01.10 moved
DFT_getChargeandDFT_getDensitytoQMol_DFT_density - Version 01.10 changed the names of
DFT_orbitalEnergytoDFT_energyOrbitalandDFT_kineticEnergytoDFT_energyKinetic getMemoryProfilewas introduced in version 01.10- Schrödinger-equation methods were added in version 01.20