QMol_DFT_density - fmauger1/QMol-grid GitHub Wiki

QMol_DFT_density

One-body-density object

Description

Use QMol_DFT_density to store the one-body density for (TD)DFT simulations. QMol_DFT_density is a handle class.

Class properties

One-body density

The QMol_DFT_density class defines the following public get-access properties; each can be changed using the set method:

density (rho)

Discretization of the one-body density [ vector (default []) ]

  • For spin restricted DFT model; irrelevant for spin restricted ones
  • Properly allocated density is a numel(disc.xspan)-by-1 vector matching the domain discretization of the associated (TD)DFT model

densityUp (rhoUp)

Discretization of the up-spin channel one-body density [ vector (default []) ]

  • For spin polarized DFT model; irrelevant for spin restricted ones
  • Properly allocated densityUp is a numel(disc.xspan)-by-1 vector matching the domain discretization of the associated (TD)DFT model

densityDown (rhoDw)

Discretization of the down-spin channel one-body density [ vector (default []) ]

  • For spin polarized DFT model; irrelevant for spin restricted ones
  • Properly allocated densityDown is a numel(disc.xspan)-by-1 vector matching the domain discretization of the associated (TD)DFT model

isSpinPol

Whether the one-body density is spin polarized (true) or spin restricted (false). isSpinPol is used by other classes to determine whether they should use the density or densityUp and densityDown properties in their calculations.

One-body density gradient

If necessary, the QMol_DFT_density class also provides support for the gradient of the one-body density. Gradient properties can be accessed like the one-body density ones above but cannot be assigned a value with the set property or cleared; use specific gradient properties instead.

D_rho

For spin-restricted models, gradient of the one-body density property.

D_rhoUp

For spin-polarized models, gradient of the up-spin one-body density property.

D_rhoDw

For spin-polarized models, gradient of the down-spin one-body density property.

Other properties

These properties cannot be edited with the set method.

isInitialized (isInit)

Whether the density object is properly initialized. This is used throughout the QMol-grid package to check that the density object holds meaningful information and is ready for use. Changing its isSpinPol may cause simulations to fail or produce erroneous results.

Class methods

Creation

constructor

Create a one-body density object with empty class properties.

obj = QMol_DFT_density;

Create a one-body density object with the name properties set to the specified value. Several name-value pairs can be specified consecutively. Suitable name is any of the one-body density properties and is case insensitive.

obj = QMol_DFT_density(name1,value1);
obj = QMol_DFT_density(name1,value1,name2,value2,___);

Most often, one-body density objects are created through domain-discretization or DFT objects.

obj = disc.DFT_allocateDensity;
obj = DFT.getDensity;

Changing class properties

set

Update the name properties of a one-body density object to the specified value. Several name-value pairs can be specified consecutively. Suitable name is any of the one-body density properties and is case insensitive.

obj.set(name1,value1);
obj.set(name1,value1,name2,value2,___);

This is the common name-value pair assignment method used throughout the QMol-grid package. The set method also reset the class. After running, the set property updates the isInitialized flag to a false value.

reset

Reset the object by deleting/re-initializing all run-time properties of the class and updating the isInitialized flag to false.

obj.reset;

This is the common reset method available to all classes throughout the QMol-grid package.

clear

Clear all class properties

obj.clear;

Clear a specific set of the class properties. Suitable name is any of the one-body density properties and is case insensitive.

obj.clear(name1,name2,___);

This is the common clear method available to all classes throughout the QMol-grid package. The clear method also reset the class. The clear method can be used to delete specific properties before saving an instance of the QMol_DFT_density class.

Initializing the object

initialize

For computations that do not require computation of the density gradient, initialize the one-body density objects and set the isInitialized flag to true.

obj.initialize;
  • To avoid any mismatch in internal properties, initialize first reset the object before performing the initialization

For computations that may require computation of the density gradient, also specify the associated domain-discretization object

obj.initialize(disc);

Run-time documentation

getMemoryProfile

Get an estimate of the memory held by a QMol_DFT_density object with either

mem = obj.getMemoryProfile;
mem = obj.getMemoryProfile(false);
  • The object must be properly initialized with a domain discretization.
  • The estimate only includes the discretization of the one-body density on the domain grid and ignores other (small) properties.
  • The output mem is the estimated size in bytes.

Additionally display the detail of the memory footprint with

mem = obj.getMemoryProfile(true);

Comparing densities

The class overloads the == and ~= operators to facilitate the comparison between density objects

eq (==)

Test if two one-body density objects describe the same density

obj1 == obj2
  • For spin-restricted objects, it is defined as all(abs(obj1.density-obj2.density) <= eqTol,'all')
  • For spin polarized objects, it is defined as all(abs(obj1.densityUp-obj2.densityUp) <= eqTol,'all') && all(abs(obj1.densityDown-obj2.densityDown) <= eqTol,'all')
  • eqTol = 1e-10 is a tolerance parameter to account for possible roundoff mismatch between two density objects.
  • Any mismatch in the size of the two objects density components or spin-polarized/restricted returns a false result.
  • If both one-body density objects have been initialized with a domain-discretization object. The equality operator also checks that the to density objects have the same domain discretization obj1.disc == obj2.disc.

ne (~=)

Test if two one-body density objects describe different densities

obj1 ~= obj2

It is equivalent to ~(obj1 == obj2) .

Density gradient

To avoid multiple computations of the same one-body density gradient, the QMol_DFT_density class stores the density gradient the first time it is requested and keeps track as to when it should be recomputed. For end users, the D_rho, D_rhoUp, and D_rhoDw gradient-holding properties can be accessed like regular class properties with the guaranty that (i) they match the one-body density currently held in the object, and (ii) the gradient is computed only when it is needed -- e.g., if only the one-body density is required for computations, the gradient is never computed.

setGradient

Force the computation and storage of the one-body density gradient with either

obj.setGradient;
obj.setGradient(1);

This feature is mostly relevant for QMol-grid internal routines and, most of the time, can be ignored by end users.

resetGradient

Force the object to consider the gradient properties as not matching its one-body density. A soft gradient reset with either

obj.resetGradient;
obj.resetGradient(false);

simply changes the internal run-time flags that keeps track as to whether the gradient properties match the one-body density. A hard reset with

obj.resetGradient(true);

also releases the memory held by the one-body density gradient.

getGradient

Uniform interface for accessing the gradient of the on-body density.

D_rho = obj.getGradient(1)

For spin-restricted density objects, returns the spatial derivative of the one-body density contained in the density property. The input argument 1 is for consistency with implementation of the density object in higher dimensions and should always be provided -- otherwise it will cause an error. D_rho = obj.getGradient(1) is equivalent to, but less efficient than, directly accessing the D_rho property with obj.D_rho.

D_rho = obj.getGradient(1,true)
D_rho = obj.getGradient(1,false)

For spin-polarized density objects, returns the spatial derivative of the one-body density contained in the densityUp and densityDown properties, respectively. The input argument 1 is for consistency with implementation of the density object in higher dimensions and should always be provided -- otherwise it will cause an error. D_rho = obj.getGradient(1,true) and D_rho = obj.getGradient(1,false) are equivalent to, but less efficient than, directly accessing the D_rhoUp and D_rhoDw properties with obj.D_rhoUp and obj.D_rhoDw, respectively.

Examples

Create a discretization domain

disc = QMol_disc('x',-10:.1:15);
disc.initialize;

Create a spin-restricted one-body density object on that domain

rho = QMol_DFT_density('isSpinPol',false,'density',3/sqrt(2*pi*3)*exp(-(disc.x(:)-3.5).^2/2/3));
rho.initialize(disc);

Display the estimated memory footprint for the object

rho.getMemoryProfile(true);
  * One-body density                                             
    > density                                                       2.0 KB
    > gradient                                                      2.0 KB

Note that we initialized the one-body density object with providing the discretization object. This will be required to compute the gradient (next). Plot the one-body density and its gradient

figure; hold on
plot(disc.x,rho.density,'-','LineWidth',2,'DisplayName','\rho')
plot(disc.x,rho.D_rho,'-','LineWidth',2','DisplayName','\nabla\rho')
xlabel('position (a.u.)'); xlim(disc.x([1 end]));
ylabel('density/gradient')
legend show

Test suite

Run the test suite for the class in normal or summary mode respectively with

QMol_test.test('DFT_density');
QMol_test.test('-summary','DFT_density');

For developers

QMol_DFT_density implements a streamlined version of the clear all method, since it might be called frequently in DFT and TDDFT computations. If adding properties to the class, the streamlined clear all must be updated accordingly; likewise QMol-grid package methods may need update.

After initialization, the domain discretization is stored in the transient property disc for later use, e.g., in computing the density gradient(s). Future version of the QMol-grid package might remove the transient nature of disc.

For computation-speed considerations, the gradient of the one-body density is stored in the transient properties D_rho, D_rhoUp, and D_rhoDw. This avoids computing the same derivative multiple times. Internally, the class keeps track as to whether the values in these indeed corresponds to the one-body density in rho, rhoUp, and rhoDw using the isGrad property (true if they match, false otherwise).

Within the QMol-grid package, the different methods that edit the one-body density will update the isGrad flag accordingly; but this is not an automatic feature. If directly editing the content of any of the D_rho, D_rhoUp, and D_rhoDw, one should also perform a derivative soft-reset with obj.resetGradient(false).

QMol_DFT_density overloads QMol_suite.

QMol-grid package methods

QMol_DFT_density defines additional methods restricted to the QMol-grid package (classes overloading QMol_suite).

getCharge

Compute the charge held a one-body density object

N = obj.getCharge;
  • For spin-restricted models, the output N is a scalar containing the numerical evaluation of $\int \rho (x)~dx$
  • For spin-polarized models, the output N is a two vector containing the numerical evaluations of $\int \rho^{\uparrow } (x)~dx$ and $\int \rho^{\downarrow } (x)~dx$ , respectively. Get the overall charge with sum(obj.getCharge)
  • In all cases, getCharge requires the density object to have been initialized with a domain discretization object.

getDensity

Build the one-body density associated with a set of Kohn-Sham orbitals and occupation coefficients

obj.getDensity(occ,KSO);
  • Updates the one-body density properties to match the input Kohn-Sham orbitals and occupation coefficients
  • Input KSO is a properly initialized Kohn-Sham orbital (QMol_DFT_orbital or QMol_DFT_orbital_basis) object
  • For spin restricted models, input N is a vector containing the orbitals' occupations coefficients.
  • For spin polarized models, input N = {Nup,Ndown} is a cell containing two vectors with the up- and down-spin orbitals' occupation coefficients, respectively
  • In all cases, the number of elements in the occupation coefficients is assumed to match the number of orbitals in KSO.
  • At the end getDensity initializes the density object with the domain discretization from input orbital (KSO.disc) to ensure consistency between the two objects.

Notes

The results displayed in this documentation page were generated using version 01.21 of the QMol-grid package.

  • QMol_DFT_density was introduced in version 01.00
  • Version 01.10 integrated support for the density spatial derivative (gradient) to it
  • Version 01.10 repatriated getCharge and getDensity from QMol_disc (and overloading classes)
  • getMemoryProfile was introduced in version 01.10