QMol_TDSE_sympSplitOp - fmauger1/QMol-grid GitHub Wiki
QMol_TDSE_sympSplitOp
Parent class for time-dependent Schrรถdinger-equation (TDSE) propagators using a symplectic split-operator scheme.
Description
QMol_TDSE_sympSplitOp
defines an abstract class for the time propagation of Schrodinger equation models using symplectic split-operator schemes, as discussed in [Mauger 2024]. It is designed to be agnostic of the model dimension and spin polarized or restricted configuration but requires a grid discretization. QMol_TDSE_sympSplitOp
overloads the QMol_TDSE
class. Here we only document the new or overloaded properties and methods specific to the QMol_TDSE_sympSplitOp
. We provide a quick overview of the handful of implementation-specific (for a given dimension) required to enable symplectic split-operator schemes in the QMol-grid package.
Table of Contents
โOther hidden class properties
โโChoice of gauge
โโExternal-field components used in simulations
โโOther initialization methods
Enabling implementation-specific symplectic split-operator schemes
Class properties
Time propagation
splitMotif
Splitting motif [ 'VTV' (default) | 'TVT' ]
- Whether the splitting starts with applying the potential (
'VTV'
) or kinetic ('TVT'
) part of the Schrodinger-equation Hamiltonian.
externalFieldGauge (EFG)
Gauge in which the external driving field is described [ [] (default) | 'none' | 'length' | 'velocity' ]
'none'
ignores any input external field and propagates the field-free TDSE dynamics
potentialVector (FA)
Potential vector of the external driving field [ [] (default) | function handle | griddedInterpolant ]
- For developers: When initializing the class, non-empty
potentialVector
is moved into theexternalField
property object (if needed creating the object first). During run time,FA
contains the value of the potential vector used in the propagation (where relevant).
electricField (FE)
Electric field of the external driving field [ [] (default) | function handle | griddedInterpolant ]
- For developers: When initializing the class, non-empty
electricField
is moved into theexternalField
property object (if needed creating the object first). During run time,FE
contains the value of the electric field used in the propagation (where relevant).
electricFieldDerivative (FDE)
Derivative of the electric field of the external driving field [ [] (default) | function handle | griddedInterpolant ]
- For developers: When initializing the class, non-empty
electricFieldDerivative
is moved into theexternalField
property object (if needed creating the object first). During run time,FDE
contains the value of the derivative of the electric field used in the propagation (where relevant).
diffDT
Time step for used for copmuting derivatives [ nonnegative scalar (default 1e-5) ]
Other hidden class properties
QMol_TDSE_sympSplitOp
defines a handful of additional hidden properties used for the time propagation. These properties cannot be edited with the set
method, nor by any function outisde of the object (SetAccess=protected
attribute).
isVTV
Selected splitting motif: true
uses the VTV splitMotif
and false
the TVT one
t_
Internal time variable, keeping track of the exact time within each propagation step
dt_
Current time step in propagator
FG
Field gauge: 0
ignores any field, 1
uses the length gauge, and 2
uses the velocity gauge
uA
Whether to use EF.potentialVector
to get the potential vector (true
) or compute it from the electric field (false
), where relevant
uE
Whether to use EF.electricField
to get the electric field (true
) or compute it from the potential vector (false
), where relevant
uDE
Whether to use EF.electricFieldDerivative
to get the derivative of the electric field (true
) or compute it from the electric field or potential vector (false
), where relevant
xi
Autonomized-Hamiltonian energy coordinate
c_
Keeping track of the current coefficients for the split kinetic (c_(1)
) and potential (c_(2)
) terms in the propagator
expT
Exponentiated kinetic-term propagator
expV
Exponentiated potential-term propagator
nWfcn
Number of wave functions.
dv
Grid-discretization symplex volume (SE.disc.dx
in 1D, SE.disc.dx*SE.disc.dy
in 2D, and SE.disc.dx*SE.disc.dy*SE.disc.dz
in 3D)
pWfcn
Holds memory when the projection of the wave functions is requested as an output
X
X-direction position operator
Y
Y-direction position operator (in 2D and 3D only)
Z
Z-direction position operator (in 3D only)
Class methods
Initializing the object
QMol_TDSE_sympSplitOp
is initialized via QMol_TDSE
's call to the initializeChildren
method, which sets the proper run-time variables. Notably, when starting a TDSE propagation from scratch (non restart mode), it
- Identifies the splitting motif,
- Moves any
potentialVector
,electricField
, orelectricFieldDerivative
into the external driving field objectexternalField
. - Identifies the gauge
- Determines which (if any) external-field components should be used in the propagation
Choice of gauge
If no specific gauge is specified with externalFieldGauge
, the selected gauge is
- Length gauge if
externalField.electricField
is a function handle, otherwise - Velocity gauge if
externalField.potentialVector
is a function handle, otherwise - Length gauge if
externalField.electricField
is agriddedInterpolant
, otherwise - Velocity gauge if
externalField.potentialVector
is agriddedInterpolant
, otherwise - Field free (ignore any input field)
External-field components used in simulations
Depending on the types of input, not all provided external-field may be used in the simulations. For the potential vector and electric field:
- If both are provided as function handles, then
externalField.electricField
andexternalField.potentialVector
are called whenever the values for the potential vector or electric field are required. Note that the TDSE propagator does not check whether the provided potential vector and electric field are consistent with each other ($E(t)=-\partial_t A(t)
$) and providing non-matching components will likely result in erroneous results. Otherwise, - If only one of them is provided as a function handle, then both the potential vector and electric field are computed from that same function handle (see below for details on how this is done). Otherwise,
- In the length gauge, if
externalField.electricField
is agriddedInterpolant
then it is used to compute both the electric field and potential vector, otherwiseexternalField.potentialVector
is used to compute them both. - In the velocity gauge, if
externalField.potentialVector
is agriddedInterpolant
then it is used to compute both the electric field and potential vector, otherwiseexternalField.electricField
is used to compute them both. - If none of the
externalField.electricField
andexternalField.potentialVector
are defined, the TDSE propagation is performed field free irrespective of the choice ofexternalFieldGauge
and even if anexternalField.electricFieldDerivative
is defined.
The choice of ignoring some (interpolated) input fields is to ensure the self-consistency of the TDSE dynamics, and associated observables, during the numerical propagation. To force using an interpolated field input, one can encapsulate it into a function handle @(t) interpolatedField(t)
.
For the electric-field derivative:
- If
externalField.electricFieldDerivative
is defined as a function handle, thenexternalField.electricFieldDerivative
is called when the derivative of the electric field is required. - Otherwise the electric-field derivative is numerically computed from
externalField.electricField
orexternalField.potentialVector
, depending on which field component(s) are being used in the TDSE propagation.
Numerical computation of missing or ignored field components:
- Where required, the potential vector is computed from the electric field using a Simpson's 1/3 quadrature rule.
- Where required, the electric field is computed from the potential vector using a second-order centered finite difference with
diffDT
time step. - Where required, the electric field derivative is computed from the electric field or the potential vector using a second-order centered finite difference with
diffDT
time step.
Other initialization methods
These methods are defined with a protected
attribute
initializeChildren
: Initializes the symplectic split-operator schemesetOutputExternalField
: Initializes and cleans up the external-field ioformation appended to the output external structures.setOutputWaveFunction
: Initializes and cleans up the output structure in which the saved wave functions and their projection are saved
Run-time documentation
These methods are defined with a protected
attribute
getMemoryProfileWaveFunction
: Estimates the memory footprint of saving the wave functionsgetMemoryProfilePropagator
: Estimates the memory footprint of the symplectic split-operator propagatorshowDoc
: Displays the part of the run-dime documentation describing the symplectic split-operator scheme
TDSE propagation
These methods are defined with a protected
attribute
addOutputExternalField
: Adds the external driving-field information to the named output structure.saveOutputWaveFunction
: Saves the wave functions and projection to their respective output structuressetExpT(obj,d)
: Sets the exponentiated kinetic-term propagatorexpT
and intermediate-step coefficientd
setExpV(obj,c)
: Sets the exponentiated potential-term propagatorexpV
and intermediate-step coefficientc
Enabling implementation-specific symplectic split-operator schemes
To enable symplectic split-operator schemes for a given implementation, one must implement a QMol_TDSE_SSO
class overloading QMol_TDSE_sympSplitOp
(classdef QMol_TDSE_SSO < QMol_TDSE_sympSplitOp
) with the following signature and methods
methods (Access=protected)
function saveOutputIonization(obj,K,t) %=====================================
%saveOutputIonization
% Compute ionization (if any)
% Add external field
if obj.sEF, obj.addOutputExternalField('oIon',K,t); end
% Update counter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
obj.oIon.n = obj.oIon.n + 1;
end
function saveOutputDipole(obj,K,t) %=======================================
%saveOutputDipole
% Dipole signal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if K == obj.oDip.ind(obj.oDip.n)
% Compute dipole (if any)
% Add external field
if obj.sEF, obj.addOutputExternalField('oDip',K,t); end
% Update counter
obj.oDip.n = obj.oDip.n + 1;
end
% Dipole velocity signal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if K == obj.oVel.ind(obj.oVel.n)
% Compute dipole velocity (if any)
% Add external field
if obj.sEF, obj.addOutputExternalField('oVel',K,t); end
% Update counter
obj.oVel.n = obj.oVel.n + 1;
end
% Dipole acceleration signal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if K == obj.oAcc.ind(obj.oAcc.n)
% Compute dipole acceleration
% Add external field
if obj.sEF, obj.addOutputExternalField('oAcc',K,t); end
% Update counter
obj.oAcc.n = obj.oAcc.n + 1;
end
end
function [E,DE] = getExternalFieldEnergy(obj,~)
%getExternalFieldEnergy
% Compute the external-field energy
% Autonomization
DE = obj.xi;
end
function applyExpT(obj) %==================================================
%applyExpT apply the Liouville operator for the kinetic term. Recall that
% obj.expT contains the exponentiated kinetic-term operator.
end
function applyExpV(obj) %==================================================
%applyExpV apply the Liouville operator for the potential term. Recall that
% obj.expV, obj.expVup, and obj.expVdw contain the exponentiated
% potential-term operators.
end
end
Test suite
For consistency with the rest of the QMol-grid package, QMol_TDSE_sympSplitOp
defines an associated test suite. Run the test suite for the class in normal or summary mode respectively with
QMol_test.test('TDSE_sympSplitOp');
QMol_test.test('-summary','TDSE_sympSplitOp');
See QMol_test
for details regarding how to create a test suite for new classes.
References
[Mauger 2024] F. Mauger, C. Chandre, M.B. Gaarde, K. Lopata, and K.J. Schafer, "Hamiltonian formulation and symplectic split-operator schemes for time-dependent density-functional-theory equations of electron dynamics in molecules," Communications in Nonlinear Science and Numerical Simulation 129, 107685 (2024).
Notes
QMol_TDSE_sympSplitOp
was introduced in version 01.20