Skip to content

Tutorial__GS__T02_GS_SE

Cristel Chandre edited this page Jul 11, 2024 · 4 revisions

Tutorial 2: Input parameters and output variables for ground-state Schrödinger equation calculations

In this tutorial, we discuss how users interface with the QMol-grid package, both to specify input parameters and to recover relevant data stored in the Schrödinger equation objects, e.g., after a ground-state calculation or time propagation (see also the next tutorial). We also discuss general features of Schrödinger equation objects that are common across the QMol-grid package.

Table of Contents

Schrödinger-equation class structure

Class properties

Class methods

Creating, accessing, and changing object parameters

Creating a Schrödinger-equation object

Changing properties in a Schrödinger-equation object

Accessing properties in a Schrödinger-equation object

Saving and loading a Schrödinger-equation object

Excited eigen-state calculation

Grid discretization and domain optimization

Notes

Schrödinger-equation class structure

In the QMol-grid package, Schrödinger-equation systems are modeled with the QMol_SE class, organized like in the following sketch:

Schrödinger-equation class structure

Below we give a brief overview of the main properties and methods in Schrödinger equation objects. We refer to the QMol_SE documentation page for a full description of the object functionalities.

Class properties

Schrödinger-equation objects arrange the model parameters between three member property objects:

  • The discretization (QMol_disc or QMol_disc_basis for basis-set model) property contains the simulation-domain grid discretization, as well as a suite of methods for data allocation, arithmetic, and various low-level computations that are used throughout the rest of the package. To facilitate user interface, only the grid discretization need to be specified with the property xspan, which is automatically converted into the relevant discretization object when the object is initialized. After a QMol_SE object is initialized xspan automatically returns the grid discretization contained in the discretization property.
  • The waveFunction property describes the Schrödinger equation wave function(s). It is not required to define a waveFunction when creating the object. numberWaveFunction specifies the number of wave functions in the Schrödinger equation model, all sharing the same potential (next).
  • The potential property defines the model atomic or molecular potential, as a QMol_SE_V object.

Class methods

Class methods for Schrödinger-equation objects can be sorted between 4 main groups:

  • The interface methods set, reset, and clear enable users to interact with the model and change the parameters. Those three methods are common to all classes in the QMol-grid package, all sharing the same signature and action on the object.
  • The initialization method initialize prepares the object for its use in various calculations. The main purpose of the initialization is to prepare the various internal components of the Schrödinger equation object and linking the different class-property objects. Ground-state and time-propagation features in the QMol-grid package automatically perform this initialization at the beginning of the calculation, allowing for un-initialized objects to be used as input. initialize is a common method for many classes, albeit with class-dependent signature.
  • The run-time documentation showDocumentation displays the input parameters and documentation for the specific implementation of the object. It requires the object to be initialized first -- see the previous tutorial. getMemoryProfile provides an estimate for the memory requirement for the Schrödinger-equation objects and all its properties without allocating the object (i.e., without initializing it). It can be used to benchmark simulations requirements before running anything.
  • The methods getEnergy and showEnergy calculate and display the energies of the wave functions or Schrödinger equation objects.

We give examples using these different methods in the various sections below.

Creating, accessing, and changing object parameters

Like for all classes in the QMol-grid package, visible member properties for the Schrödinger-equation class are defined with public GetAccess and private SetAccess attributes. Its means that the reading of data within objects can be done using the standard object-oriented dot notation (see previous tutorial) but changing class properties must be done via the set method.

Creating a Schrödinger-equation object

The previous tutorial presents a minimal example where only the required parameters are provided when creating the Schrödinger-equation object and all the other parameters are left to their default values. Optional parameters can be specified at creation using name-value pair assignment of the form QMol_SE('name1',value1,'name2',value2,___). Name-value pairs can be entered in arbitrary order and name# is case insensitive. For instance, repeating the example of the previous tutorial but requesting that two wave functions are included in the Schrödinger-equation object can be done with

% Create Schrödinger-equation object
H  = QMol_Va_softCoulomb('softeningParameter',sqrt(2));
SE = QMol_SE(                                           ...
         'xspan',               -15:.1:15,              ...
         'potential',           QMol_SE_V('atom',H),    ...
         'numberWaveFunction',  2);

% Check parameters
SE.initialize;
SE.showDocumentation;

yielding (only showing the relevant portion of the run-time documentation)

=== Discretization =======================================================
  * Domain discretization                                   Cartesian grid
    Grid = -15:0.1:15
    Size = 301 (7 x 43) points
    V-01.21.000 (06/17/2024)                                     F. Mauger

=== Potential ============================================================
  * Potential
    V-01.21.000 (06/17/2024)                                     F. Mauger
  * Atom-like center(s)
    > ???, parameterized as                                 (soft Coulomb)
      Z =  1.00 | a =  1.41 | X0 =   0.00
  * Soft-Coulomb potential [Javanainen 1988]                (soft Coulomb)
    Parameterized as V(x) = -Z ./ sqrt( (x-X0).^2 + a^2 ). 
    V-01.21.000 (06/17/2024)                                     F. Mauger

=== System model =========================================================
  * Electronic structure                                    wave functions
    2 wave function(s)

Note how we combined the creation of the Schrödinger-equation object SE with the definition of the dicretization domain (xspan property) and model potential.

In the example above, the various parameter names provide an unambiguous denomination for each parameter but lead to somewhat long lines of code. Instead, one can use their short-hand equivalent (indicated between parentheses in the QMol_SE documentation page, and again case insensitive) with

% Create Schrödinger-equation object
H  = QMol_Va_softCoulomb('a',sqrt(2));
SE = QMol_SE(                                       ...
         'x',   -15:.1:15,                          ...
         'V',   QMol_SE_V('atom',H),   ...
         'N',   2);

% Check parameters
SE.initialize;
SE.showDocumentation;

as expected yielding the same result

=== Discretization =======================================================
  * Domain discretization                                   Cartesian grid
    Grid = -15:0.1:15
    Size = 301 (7 x 43) points
    V-01.21.000 (06/17/2024)                                     F. Mauger

=== Potential ============================================================
  * Potential
    V-01.21.000 (06/17/2024)                                     F. Mauger
  * Atom-like center(s)
    > ???, parameterized as                                 (soft Coulomb)
      Z =  1.00 | a =  1.41 | X0 =   0.00
  * Soft-Coulomb potential [Javanainen 1988]                (soft Coulomb)
    Parameterized as V(x) = -Z ./ sqrt( (x-X0).^2 + a^2 ). 
    V-01.21.000 (06/17/2024)                                     F. Mauger

=== System model =========================================================
  * Electronic structure                                    wave functions
    2 wave function(s)

Note that long- and short-name parameter definition can be mixed in the object creation. For instance, in the example above, replacing 'x' with 'xspan' yields the same SE object.

Both the name-value parameter definition at creation and availability of long- and short-name parameter definition are general features available in all classes of the QMol-grid package (e.g., in the example above we specified the softening parameter in QMol_Va_softCoulomb with 'a' instead of 'softeningParameter').

Changing properties in a Schrödinger-equation object

All the property parameters in QMol_SE objects are defined with private SetAccess attributes. This means that trying to change a parameter using the dot notation, e.g., with SE.xspan = -15:.1:20, produces an error. Instead, to edit one or several properties, one must use the set method with

SE.set('xspan',-15:.1:20);

The set method has the same signature as the constructor, with new parameters indicated as name-value pairs (in arbitrary order and case insensitive), and supporting both long- and short-name parameter definition.

Note that the set method de-initialize the object, such that to print out the updated run-time documentation on must use

SE.initialize;
SE.showDocumentation;

yielding (only showing the portion of the run-time documentation that has changed)

(...)
=== Discretization =======================================================
  * Domain discretization                                   Cartesian grid
    Grid = -15:0.1:20
    Size = 351 (3 x 3 x 3 x 13) points
    V-01.21.000 (06/17/2024)                                     F. Mauger
(...)

The set method is a general feature of all classes in the QMol-grid package and can be used to update property-object within a class. For instance, to shift the location of the model-potential minimum, one can use

% Change potential
H.set('position',3);

% Check parameters
SE.initialize;
SE.showDocumentation;

yielding (again, only showing the portion of the run-time documentation that has changed)

(...)
=== Potential ============================================================
  * Potential
    V-01.21.000 (06/17/2024)                                     F. Mauger
  * Atom-like center(s)
    > ???, parameterized as                                 (soft Coulomb)
      Z =  1.00 | a =  1.41 | X0 =   3.00
  * Soft-Coulomb potential [Javanainen 1988]                (soft Coulomb)
    Parameterized as V(x) = -Z ./ sqrt( (x-X0).^2 + a^2 ). 
    V-01.21.000 (06/17/2024)                                     F. Mauger
(...)

Note that, in the example above, we did not explicitly changed the SE object but instead the atomic pseudopotential object H used to define the model potential. This is because QMol_Va_softCoulomb, like all other classes in the QMol-grid package, is defined as a handle class and changing its properties is globally reflected in all objects that use H.

Alternatively, nested property-objects can be updates using the set method on the property itself. For instance, to update the displayed name for the H pseudopotential, one may use

% Update potential name
SE.potential.atom{1}.set('name','H');

% Check parameters
SE.initialize;
SE.showDocumentation;

yielding (again, only showing the portion of the run-time documentation that has changed)

(...)
=== Potential ============================================================
  * Potential
    V-01.21.000 (06/17/2024)                                     F. Mauger
  * Atom-like center(s)
    > H, parameterized as                                   (soft Coulomb)
      Z =  1.00 | a =  1.41 | X0 =   3.00
  * Soft-Coulomb potential [Javanainen 1988]                (soft Coulomb)
    Parameterized as V(x) = -Z ./ sqrt( (x-X0).^2 + a^2 ). 
    V-01.21.000 (06/17/2024)                                     F. Mauger
(...)

The somewhat intricate path to change the atom name stems from the fact that SE.potential corresponds to the general interface to define atomic and molecular potentials, listed in the SE.potential.atom cell. Note that this changes the H object (H.atom now is equal to 'H'), again because it corresponds to a handle class.

Workaround SetAccess restrictions

For advanced calculations and experienced users, there may be cases where one wants to be able to change class properties without using the set method (and without de-initializing the object). This can be done by creating a new class that derives from QMol_suite and defining the editing function as a member method for that class. This is a common workaround in the QMol-grid package where classes generally grant SetAccess privileges to QMol_suite objects.

This workaround is to be used with caution and at user's risks, as it removes all side-effect protections associated with changing the class properties.

Accessing properties in a Schrödinger-equation object

All properties listed in the documentation are defined with public GetAccess attributes, meaning that they can simply be accessed using the standard object-oriented dot notation. Both long- and short-property name can be used, but are case sensitive. For instance, the domain discretization can be retrieved using both SE.xspan and SE.x. This is what we used in the previous tutorial to plot the calculated ground-state wave function.

Saving and loading a Schrödinger-equation object

When saving a Schrödinger-equation object, all the listed class properties in the documentation page are saved with the object except for xspan (which is contained in the discretization property). For instance

% Create Schrödinger-equation object
H  = QMol_Va_softCoulomb('softeningParameter',sqrt(2));
SE = QMol_SE(                                           ...
         'xspan',               -15:.1:15,              ...
         'potential',           QMol_SE_V('atom',H),    ...
         'numberWaveFunction',  1);

% Calculate ground
GSS = QMol_SE_eigs;
GSS.computeGroundState(SE);

% Save the Schrödinger-equation object
save('SE_object.mat','SE');

Save the SE object containing the result of the ground-state calculation with it in the MATLAB file SE_object.mat. To load the object back into MATLAB workspace one can use

clear SE H
load('SE_object.mat');

Note that the loaded object is un-initialized but can be reinitialized with

% Re-initialize loaded object
SE.initialize;

% Check loaded ground
SE.showEnergy('wave function');

yielding

(...)
  Wave fcn      Energy (-eV)         Error(a.u.)
  --------     ------------          -----------
      1           13.606              3.213e-13
  ----------------------------------------------
(...)

Excited eigen-state calculation

The QMol_SE_eigs class can be used to calculate not only the ground but also excited eigen-states of Schrödinger-equation objects. Specifically, for a Schrödinger-equation object with $n$ numberWaveFunction, QMol_SE_eigs calculates the $n$ lowest-energy eigen-states, i.e., the ground state plus the $n-1$ first excited states. For instance

% Create Schrödinger-equation object
H  = QMol_Va_softCoulomb('softeningParameter',sqrt(2));
SE = QMol_SE(                                       ...
         'x',   -15:.1:15,                          ...
         'V',   QMol_SE_V('atom',H),   ...
         'N',   4);

% Calculate ground and first 3 excited states
GSS = QMol_SE_eigs;
GSS.computeGroundState(SE);

yields (only showing the eigen-state calculation results)

(...)
=== Wave-function energies ===============================================
  Wave fcn      Energy (-eV)         Error(a.u.)
  --------     ------------          -----------
      1           13.606              4.226e-13
      2            6.338              3.625e-13
      3            3.649              4.019e-13
      4            2.181              5.008e-13
  ----------------------------------------------

=== Schrodinger-equation-component energies ==============================
  Component      Energy (a.u.)      Energy (eV)
  -----------    -------------     -------------
  Kinetic             0.351              9.557
  Potential          -1.298            -35.330
  -----------    -------------     -------------
  Total              -0.947            -25.774
  ----------------------------------------------

The wave function 1 corresponds to the same ground state as above, followed by the first three excited states (with decreasing energies). We can check that the calculated eigen-states form an orthonormal family (of real-valued wave functions) with

% Recover grid spacing
dx = SE.xspan(2)-SE.xspan(1);

% Check orthonormality
for k = 1:SE.numberWaveFunction, for l = k:SE.numberWaveFunction
    s = sum(SE.waveFunction.waveFunction(:,k).*SE.waveFunction.waveFunction(:,l))*dx;
    fprintf('< psi_%u | psi_%u >',k,l)
    if k == l, fprintf('-1 = '); else, fprintf('   = '); end
    fprintf('%#10.3e\n',s - (k==l));
end, end

yielding (actual numbers may vary from machine to machine but should systematically be on the same small order as below)

< psi_1 | psi_1 >-1 =  2.220e-16
< psi_1 | psi_2 >   = -3.183e-16
< psi_1 | psi_3 >   = -6.660e-16
< psi_1 | psi_4 >   =  1.597e-17
< psi_2 | psi_2 >-1 =  2.220e-16
< psi_2 | psi_3 >   =  2.558e-16
< psi_2 | psi_4 >   = -8.616e-17
< psi_3 | psi_3 >-1 = -3.331e-16
< psi_3 | psi_4 >   =  4.466e-17
< psi_4 | psi_4 >-1 =  0.000e+00

See the QMol_SE_eigs documentation for a description of additional parameters/features available in eigen-state calculations.

Grid discretization and domain optimization

The QMol-grid package uses an underlying Cartesian-grid discretization for all its calculations, including for claculations using a basis set approach (the basis-set elements are themselves discretized on the underlying Cartesian grid). This is what the "grid" part of "QMol-grid" stands for.

Throughout the QMol-grid package, spatial derivatives are calculated using fast-Fourier transforms. As a consequence, simulations can be optimized by choosing a discretization domain with small prime-number factors (MATLAB fft documentation indicates that "Transform lengths that have only small prime factors (not greater than 7) result in significantly faster execution time than those that are prime or have large prime factors"). The prime-factor decomposition is indicated in the Discretization/Domain discretization part of the run-time documentation. For instance

% Create Schrödinger-equation object
H  = QMol_Va_softCoulomb('softeningParameter',sqrt(2));
SE = QMol_SE(                                           ...
         'xspan',               -15:.1:15,              ...
         'potential',           QMol_SE_V('atom',H),    ...
         'numberWaveFunction',  2);

% Check parameters
SE.initialize;
SE.showDocumentation;

gives

(...)
=== Discretization =======================================================
  * Domain discretization                                   Cartesian grid
    Grid = -15:0.1:15
    Size = 301 (7 x 43) points
    V-01.21.000 (06/17/2024)                                     F. Mauger
(...)

indicating that the discretization domain has 301 grid points, corresponding to the prime-factor decomposition 7 times 43. Aside from the most demanding simulations, e.g., running hundreds of ground/eigen-state calculations or propagation over very long time, experience is that the small-prime-factor decomposition is not really of practical concern.

System- and simulation-model-specific optimization can be performed using the QMol_SE_profiler class (make sure that no other resource-competing process is running on the computer for an accurate estimate of execution times).

QMol_SE_profiler(SE);

yielding (as usual, only showing the relevant part of the output; note that the average execution times will vary greatly from system to system)

=== Memory footprint =====================================================
  Components                                                    -- Size --
  * Domain discretization                                        
    > domain                                                        2.4 KB
    > gradient                                                      4.7 KB
    > Laplacian                                                     2.4 KB
    > Laplacian (velocity gauge)                                    4.7 KB
  * Wave function(s)                                                9.4 KB
  * Potential                                                    
    > potential                                                     2.4 KB
    > potential gradient                                            2.4 KB
                                                                ----------
                                                        TOTAL =    28.2 KB

=== Execution time =======================================================
  Operator components                                           -- Time --
  * Hamiltonian                                  2 x 3.96e-05 = 7.93e-05 s

  * Kinetic                                      2 x 3.34e-05 = 6.68e-05 s
  * Potential                                    2 x 1.42e-05 = 2.84e-05 s
                                                                ----------
                                                        TOTAL = 9.52e-05 s

  (average times over 500 iterations)

The first section "Memory footprint" is an estimate of the memory footprint for the Schrödinger-equation object -- see the QMol_SE_profiler documentation for details. The second section indicates the average execution time (over 500 iterations) for each of the Hamiltonian, Kinetic, and Potential operators. The "2 x" indicates that, since the Schrödinger-equation object contains two wave functions (with SE.numberWaveFunction set to 2), each operator must be applied twice, followed by the average run time for one calculation and finally the resulting average total execution time on the whole Schrödinger-equation object.

Notes

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

Density-functional theory (DFT)

$~~$ Hartree-Fock theory (HF)

Schrödinger equation (SE)
Time-dependent density-functional theory (TDDFT)
Time-dependent Schrödinger equation (TDSE)
Discretization
Pseudopotentials
External field
External components
Tutorials

$~~$ Documentation

$~~$ Test suite

For developers
Clone this wiki locally