Tasks#

Tasks are functions that carry out the elementary operations of an algorithm by modifying a State object and optionally a Parameters object, which are both dictionaries. Built-in tasks can be found in the qclab.tasks module and are documented on this page.

A generic tasks has the form:

def my_task(sim, state, parameters, **kwargs):
    # Get any keyword arguments, with default values if not provided.
    kwarg1 = kwargs.get('kwarg1', default_value1)
    # Carry out the task by modifying state and parameters
    return state, parameters

where sim is an instance of the Simulation class (see Simulations), and **kwargs are any additional keyword arguments that customize the task to the context in which it is used. Generally, keyword arguments specify which elements of the state and parameters objects are to be used and/or modified by the task (e.g., the name of the wavefunction or Hamiltonian attributes).

If a task is used with keyword arguments, they must be provided when the task is included in the algorithm’s recipe by using the partial function from the functools module, as in:

from functools import partial
# Specifying keyword arguments when including a task in a recipe.
algorithm.initialization_recipe = [partial(my_task, kwarg1=value1), ...]
# Including a task without keyword arguments.
algorithm.initialization_recipe = [another_task, ...]

Vectorization#

In QC Lab, attributes of the state and parameters objects are vectorized by default, meaning that they have an additional leading dimension that indexes multiple trajectories. For example, the diabatic wavefunction attribute wf_db of the state object has shape (sim.settings.batch_size, sim.model.constants.num_quantum_states), where sim.settings.batch_size is the number of trajectories in the batch and sim.model.constants.num_quantum_states is the number of quantum states in the model.

Initialization, Update, and Collect Tasks#

Tasks are organized into three categories: initialization tasks, update tasks, and collect tasks. Initialization tasks create objects in the state and parameters objects that are needed for the simulation, update tasks propagate the attributes of the state and parameters objects forward in time, and collect tasks gather and process the results of the simulation into the output dictionary.

Examples of these tasks are:

def my_initialization_task(sim, state, parameters, **kwargs):
    # Create an attribute in the State object.
    shape = (sim.settings.num_trajs, sim.model.constants.num_quantum_states)
    state["new_attribute"] = np.zeros(shape, dtype=complex)
    return state, parameters

def my_update_task(sim, state, parameters, **kwargs):
    # Update an attribute in the State object.
    shape = (sim.settings.num_trajs, sim.model.constants.num_quantum_states)
    state["new_attribute"] = state["new_attribute"] + 1j*np.ones(shape, dtype=complex)
    return state, parameters

def my_collect_task(sim, state, parameters, **kwargs):
    # Collect results into the output dictionary.
    state["output_dict"]["new_attribute"] = state.new_attribute
    return state, parameters

These tasks can then be included in the appropriate recipe of an Algorithm object. Notice that none of these tasks have keyword arguments and so can be included directly in recipes without using partial.

Built-in Tasks#

Built-in tasks can be found in the qclab.tasks module and are documented below.

Note

All tasks assume that the Model object has a minimal set of constants including num_quantum_states (the number of quantum states), num_classical_coordinates (the number of classical coordinates), classical_coordinate_mass (the mass of the classical coordinates), and classical_coordinate_weight (the weight of the classical coordinates). These constants are discussed in Models. For brevity we exclude explicit mention of these constants in the task documentation.

Initialization Tasks#

This module contains the tasks that initialize quantities in the state and parameters objects.

These are typically used in the initialization recipe of the Algorithm object.

qclab.tasks.initialization_tasks.initialize_variable_objects(sim, state, parameters)#

Populates the State object with non-private variables in sim.initial_state, and an empty dictionary for storing output quantities.

For any non-private (i.e., not beginning with “_”) ndarray in sim.initial_state, a new array is created in state with shape (batch_size, *original_shape) where original_shape is the shape of the array in sim.initial_state. The new array is initialized by copying the original array into each slice along the first axis.

Reads:

sim.initial_state[name] (ndarray of shape original_shape with dtype=original_dtype) – Any ndarray in initial_state that does not have a key beginning with “_”.

Writes:
  • state[name] (ndarray of shape (B, *original_shape) and dtype=original_dtype) – Corresponding ndarray with a shape expanded over a new trajecgtory index.

  • state[“output_dict”] (dict) – Dictionary to store output quantities during a simulation.

Notes

  • B = sim.settings.batch_size

qclab.tasks.initialization_tasks.initialize_norm_factor(sim, state, parameters, norm_factor_name='norm_factor')#

Assigns the normalization factor to the State object.

When collected values are summed in the Data object the normalization factor is used to normalize the sum to a trajectory average. In all algorithms in QC Lab this is equivalent to the batch size.

Optional Keyword Arguments:

norm_factor_name – Name of the normalization factor in the State object.

Writes:

state[norm_factor_name] – Normalization factor for trajectory averages.

qclab.tasks.initialization_tasks.initialize_branch_seeds(sim, state, parameters, seed_name='seed', branch_ind_name='branch_ind')#

Distributes random seeds over branches for deterministic surface hopping.

This is done by first assuming that the number of branches is equal to the number of quantum states. Then, a branch index is created which gives the branch index of each seed in the batch. Then a new set of seeds is created by floor dividing the original seeds by the number of branches so that the seeds corresponding to different branches within the same trajectory are the same.

Notably, this leads to the number of unique classical initial conditions being equal to the number of trajectories divided by the number of branches in deterministic surface hopping.

Optional Keyword Arguments:
  • seed_name – Name of seed array in State object.

  • branch_ind_name – Name of the branch index array in state.

Reads:

state[seed_name] (ndarray of shape (B,), dtype=int) – Seed for each trajectory.

Writes:
  • state[seed_name] – Seed for each trajectory remapped for the number of branches.

  • state[branch_ind_name] – Branch index for each trajectory.

Notes

  • B = sim.settings.batch_size

qclab.tasks.initialization_tasks.initialize_z_mcmc(sim, state, parameters, seed_name='seed', z_name='z')#

Initializes complex classical coordinates according to Boltzmann statistics using Markov Chain Monte Carlo with a Metropolis-Hastings algorithm.

The algorithm has two modes, separable and non-separable. In the separable mode, each classical coordinate is evolved as an independent random walker. In the non-separable mode, the full classical coordinate vector is evolved as a single random walker. The separable mode converges much faster but assumes that the classical Hamiltonian can be written as a sum of independent terms depending on each classical coordinate.

Optional Keyword Arguments:
  • seed_name – Name of seed array in State object.

  • z_name – Name of destination attribute in state.

Constants and Settings:
  • sim.model.constants.mcmc_burn_in_size (int, default: 1000) – Burn-in step count.

  • sim.model.constants.mcmc_sample_size (int, default: 10000) – Number of retained samples.

  • sim.model.constants.mcmc_std (float, default: 1.0) – Sampling standard deviation.

  • sim.model.constants.mcmc_init_z (ndarray, default: random sample generated by functions.gen_sample_gaussian) – Initial value of the coordinate at the outset of sampling.

  • sim.model.constants.kBT (float) – Thermal energy.

Ingredients:

h_c – Classical Hamiltonian.

Reads:

state[seed_name] (ndarray of shape (B,), dtype=int) – Seed for each trajectory.

Writes:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Classical coordinate in each trajectory.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.initialization_tasks.initialize_z(sim, state, parameters, seed_name='seed', z_name='z')#

Initializes the classical coordinate by using the init_classical function from the Model object.

Optional Keyword Arguments:
  • seed_name – Name of seed array in State object.

  • z_name – Name of classical coordinate in State object.

Ingredients:

init_classical – Classical coordinate initialization.

Reads:

state[seed_name] (ndarray of shape (B,), dtype=int) – Seed in each trajectory.

Writes:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Initialized classical coordinates.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.initialization_tasks.copy_in_state(sim, state, parameters, orig_name, copy_name)#

Creates a copy of a variable in the State object with a new name.

Optional Keyword Arguments:
  • orig_name – Name of the original in the State object.

  • copy_name – Name of the copy in the State object.

Reads:

state[orig_name] – Object to be copied.

Writes:

state[copy_name] – Copy of object.

qclab.tasks.initialization_tasks.copy_in_parameters(sim, state, parameters, orig_name, copy_name)#

Creates a copy of a variable in the Parameters object with a new name.

Optional Keyword Arguments:
  • orig_name – Name of the original in the Parameters object.

  • copy_name – Name of the copy in the Parameters object.

Reads:

parameters[orig_name] – Object to be copied.

Writes:

parameters[copy_name] – Copy of object.

qclab.tasks.initialization_tasks.copy_to_parameters(sim, state, parameters, state_name, parameters_name)#

Copies an object from the State object to the Parameters object.

Optional Keyword Arguments:
  • state_name – Name of the object in the State object.

  • parameters_name – Name of the object in the Parameters object.

Reads:

state[state_name] – Object to be copied.

Writes:

parameters[parameters_name] – Copy of object.

qclab.tasks.initialization_tasks.initialize_active_surface(sim, state, parameters, act_surf_ind_0_name='act_surf_ind_0', act_surf_ind_name='act_surf_ind', act_surf_name='act_surf', init_act_surf_rand_vals_name='init_act_surf_rand_vals', wf_adb_name='wf_adb')#

Initializes the active surface, active surface index, and initial active surface index for FSSH.

If fssh_deterministic=True it will set the initial active surface index to be the same as the branch index and assert that the number of branches is equal to the number of quantum states.

If fssh_deterministic=False it will stochastically sample the active surface from the density corresponding to the initial quantum wavefunction in the adiabatic basis.

Optional Keyword Arguments:
  • act_surf_ind_0_name – Name of the initial active surface index in the State object.

  • act_surf_ind_name – Name of the active surface index in the State object.

  • act_surf_name – Name of the active surface in the State object.

  • init_act_surf_rand_vals_name (str, default:) – Name of the random numbers for active surface initialization in FSSH.

  • wf_adb_name (str, default:) – Name of the adiabatic wavefunction in the State object.

Constants and Settings:

sim.algorithm.settings.fssh_deterministic (Bool) – Boolean indicating if the FSSH simulation is deterministic.

Reads:

state[wf_adb_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the adiabatic basis.

Writes:
  • state[act_surf_ind_0_name] (ndarray of shape (B,), dtype=int) – Active surface index at the start of the simulation.

  • state[act_surf_ind_name] (ndarray of shape (B,), dtype=int) – Active surface index.

  • state[act_surf_name] (ndarray of shape (B, N), dtype=int) – Active surface vector in adiabatic basis: 1 if active 0 if not.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.initialization_tasks.initialize_random_values_fssh(sim, state, parameters, hop_prob_rand_vals_name='hop_prob_rand_vals', init_act_surf_rand_vals_name='init_act_surf_rand_vals', seed_name='seed')#

Initializes a set of random numbers using the trajectory seeds for FSSH.

Required Constants

None

Optional Keyword Arguments:
  • hop_prob_rand_vals_name – Name of the random numbers for hop decisions in the State object.

  • init_act_surf_rand_vals_name – Name of the random numbers for active surface initialization in FSSH.

  • seed_name – Name of seed array in State object.

Constants and Settings:

sim.algorithm.settings.fssh_deterministic (Bool) – Boolean indicating if the FSSH simulation is deterministic.

Reads:

state[seed_name]

Writes:
  • state[hop_prob_rand_vals_name] (ndarray of shape (B//b, t), dtype=float64) – Random numbers for hop decisions.

  • state[init_act_surf_rand_vals_name] – Random numbers for active surface selection in stochastic FSSH.

Notes

  • B = sim.settings.batch_size

  • b = sim.model.constants.num_quantum_states if fssh_deterministic == True, b = 1 otherwise.

  • t is the number of update timesteps.

qclab.tasks.initialization_tasks.initialize_dm_adb_0_fssh(sim, state, parameters, dm_adb_0_name='dm_adb_0', wf_adb_name='wf_adb')#

Initializes the initial adiabatic density matrix for FSSH.

Optional Keyword Arguments:
  • dm_adb_0_name – Name of the initial adiabatic density matrix in the State object.

  • wf_adb_name – Name of the adiabatic wavefunction in the State object.

Reads:

state[wf_adb_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the adiabatic basis.

Writes:

state[dm_adb_0_name] (ndarray of shape (B, N, N), dtype=complex128) – Initial density matrix in the adiabatic basis.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

Update Tasks#

This module contains tasks that update the state and parameters objects during propagation.

qclab.tasks.update_tasks.update_t(sim, state, parameters, t_name='t')#

Updates the time in the State object with the time index in each trajectory multiplied by the update timestep.

Optional Keyword Arguments:

t_name – Name of the time variable in the State object.

Writes:

state[t_name] (ndarray of shape (B,) dtype=float64) – Time variable in each trajectory.

Notes

  • B = sim.settings.batch_size

qclab.tasks.update_tasks.update_dh_c_dzc_finite_differences(sim, state, parameters, z_name='z', dh_c_dzc_name='dh_c_dzc')#

Updates the gradient of the classical Hamiltonian using finite differences.

Optional Keyword Arguments:
  • z_name – Name of the classical coordinates in the State object.

  • dh_c_dzc_name – Name under which to store the finite-difference gradient in the State object.

Constants and Settings:

sim.model.constants.dh_c_dzc_finite_difference_delta (float, default: numerical_constants.FINITE_DIFFERENCE_DELTA) – Finite-difference step size.

Ingredients:

h_c – Classical Hamiltonian.

Reads:

state[z_name] (ndarray, (batch_size, num_classical_coordinates), complex) – Classical coordinates.

Writes:

state[dh_c_dzc_name] (ndarray, (batch_size, num_classical_coordinates), complex) – Gradient of the classical Hamiltonian.

qclab.tasks.update_tasks.update_classical_force(sim, state, parameters, z_name='z', classical_force_name='classical_force')#

Updates the gradient of the classical Hamiltonian w.r.t. the conjugate classical coordinate.

Optional Keyword Arguments:
  • z_name (str, default:) – Name of the classical coordinates in the State object.

  • classical_force_name – Name under which to store the classical force in the State object.

Ingredients:

dh_c_dzc – Gradient of the classical Hamiltonian with respect to the conjugate classical coordinate.

Reads:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinate.

Writes:

state[classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Force arising from the classical Hamiltonian.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_dh_qc_dzc_finite_differences(sim, state, parameters, z_name='z', dh_qc_dzc_name='dh_qc_dzc')#

Updates the gradient of the quantum-classical Hamiltonian using finite differences.

Required Constants

dh_qc_dzc_finite_difference_deltafloat, defaultnumerical_constants.FINITE_DIFFERENCE_DELTA

Finite-difference step size.

Optional Keyword Arguments:
  • z_name – Name of classical coordinates in the State object.

  • dh_qc_dzc_name – Name under which to store the gradient of the quantum-classical Hamiltonian in the State object.

  • Constants and Settings

  • sim.model.constants.dh_qc_dzc_finite_difference_delta (float, default: numerical_constants.FINITE_DIFFERENCE_DELTA) – Finite-difference step size.

Ingredients:

h_qc – Quantum-classical Hamiltonian.

Reads:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

Writes:

state[dh_qc_dzc_name] (tuple) – Gradient of the quantum-classical Hamiltonian in sparse matrix format.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_dh_qc_dzc(sim, state, parameters, z_name='z', dh_qc_dzc_name='dh_qc_dzc')#

Updates the gradient of the quantum-classical Hamiltonian w.r.t. the conjugate classical coordinate.

Optional Keyword Arguments:
  • z_name – Name of classical coordinates in State object.

  • dh_qc_dzc_name – Name under which to store the gradient of the quantum-classical Hamiltonian in the State object.

Ingredients:

dh_qc_dzc – Gradient of the quantum-classical Hamiltonian.

Reads:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

Writes:

state[dh_qc_dzc_name] (tuple) – Gradient of the quantum-classical Hamiltonian in spare format.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_derivative_coupling_dzc(sim, state, parameters, z_name='z', derivative_coupling_dzc_name='derivative_coupling_dzc')#

Updates the derivative coupling matrix.

\[d^{i}_{\alpha,\beta} = \langle\alpha(z)\vert\partial_{z_{i}^{*}}\vert\beta(z)\rangle\]

Raises

Optional Keyword Arguments:

z_name – Name of the classical coordinates in the State object.

Constants and Settings:
  • sim.model.update_dh_qc_dzc (Bool, default: False) – Model flag indicating if the quantum-classical Hamiltonian is to be updated at each timestep.

  • sim.algorithm.settings.use_gauge_field_force (Bool, default: False) – Boolean indicating if a gauge field force is to be added to the quantum-classical force.

Ingredients:

derivative_coupling_dzc – Derivative coupling tensor.

Reads:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

Writes:

state[derivative_coupling_dzc_name] (ndarray of shape (B, C, N, N), dtype=complex128) – Quantum-classical force.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_quantum_classical_force(sim, state, parameters, z_name='z', wf_db_name='wf_db', dh_qc_dzc_name='dh_qc_dzc', quantum_classical_force_name='quantum_classical_force', state_ind_name='act_surf_ind', wf_changed=True, h_q_tot_name='h_q_tot', derivative_coupling_dzc_name='derivative_coupling_dzc', update_dh_qc_dzc_flag=True)#

Updates the quantum-classical force w.r.t. the wavefunction defined by wf_db.

If the model has a gauge_field_force ingredient, this term will be added to the quantum-classical force.

If the model has a derivative_coupling_dzc ingredient, this contribution will be added to the quantum-classical force.

Optional Keyword Arguments:
  • z_name – Name of classical coordinates in the State object.

  • wf_db_name – Name of the wavefunction (in the diabatic basis) in the State object.

  • dh_qc_dzc_name – Name of the gradient of the quantum-classical Hamiltonian in the State object.

  • quantum_classical_force_name – Name under which to store the quantum-classical force in the State object.

  • state_ind_name – Name in the State object of the state index for which to obtain the gauge field force. Required if algorithm.settings.use_gauge_field_force is True.

  • wf_changed – If True, the wavefunction has changed since the last time the force were calculated.

  • h_q_tot_name – Name under which to store the total Hamiltonian in the State object.

  • derivative_coupling_dzc_name – Name of the derivative coupling tensor in the State object.

Constants and Settings:
  • sim.model.update_dh_qc_dzc (Bool, default: False) – Model flag indicating if the quantum-classical Hamiltonian is to be updated at each timestep.

  • sim.algorithm.settings.use_gauge_field_force (Bool, default: False) – Boolean indicating if a gauge field force is to be added to the quantum-classical force.

Ingredients:

derivative_coupling_dzc – Derivative coupling tensor.

Reads:
  • state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

  • state[wf_db_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the diabatic basis.

  • state[dh_qc_dzc_name] (tuple) – Gradient of the quantum-classical Hamiltonian in sparse format.

  • state[h_qc_tot_name] (ndarray of shape (B, N, N), dtype=complex128) – Total quantum Hamiltonian.

  • state[derivative_coupling_dzc_name] (ndarray of shape (B, C, N, N), dtype=complex128 (optional)) – The derivative coupling tensor.

Writes:

state[quantum_classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Quantum-classical force.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.add_gauge_field_force(sim, state, parameters, z_name='z', adb_state_ind_name='act_surf_ind', quantum_classical_force_name='quantum_classical_force')#

Adds the quantum-classical force with the gauge field force if the model has a gauge_field_force ingredient.

Optional Keyword Arguments:
  • z_name – Name of classical coordinates in State object.

  • adb_state_ind_name – Name of the adiabatic state index for which to obtain the gauge field force.

  • quantum_classical_force_name – Name of the quantum-classical force in the State object.

Ingredients:

gauge_field_force – Forse originating from the gauge field.

Reads:
  • state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

  • state[adb_state_ind_name] (ndarray of shape (B,), dtype=int) – Index of the adiabatic state from which the gauge field originates.

Writes:

state[quantum_classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Quantum-classical force.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.diagonalize_matrix(sim, state, parameters, matrix_name, eigvals_name, eigvecs_name)#

Diagonalizes a given matrix from the State object and stores the eigenvalues and eigenvectors in the State object.

Optional Keyword Arguments:
  • matrix_name – Name of the matrix to diagonalize in the State object.

  • eigvals_name – Name of the eigenvalues in the State object.

  • eigvecs_name – Name of the eigenvectors in the State object.

Reads:

state[matrix_name] (ndarray) – A Hermitian matrix.

Writes:
  • state[eigvals_name] (ndarray) – Eigenvalues.

  • state[eigvecs_name] (ndarray) – Eigenvectors.

qclab.tasks.update_tasks.update_eigvecs_gauge(sim, state, parameters, eigvals_name='eigvals', eigvecs_name='eigvecs', eigvecs_previous_name='eigvecs_previous', output_eigvecs_name='eigvecs_name', z_name='z', gauge_fixing=None, dh_qc_dzc_name='dh_qc_dzc')#

Updates the gauge of the eigenvectors as specified by the gauge_fixing parameter.

if gauge_fixing == “sign_overlap”:

The sign of the eigenvector is changed so the real part of its overlap with the previous eigenvector is positive.

if gauge_fixing == “phase_overlap”:

The phase of the eigenvector is determined from its overlap with the previous eigenvector and used to maximize the real part of the overlap. The sign is then changed so the real part of the overlap is positive.

if gauge_fixing == “phase_der_couple”:

The phase of the eigenvector is determined by calculating the derivative couplings and changed so that all the derivative couplings are real-valued.

Optional Keyword Arguments:
  • eigvals_name – Name of the eigenvalues in the State object.

  • eigvecs_name – Name of the eigenvectors in the State object.

  • eigvecs_previous_name – Name of the previous eigenvectors in the State object.

  • output_eigvecs_name – Name of the output gauge-fixed eigenvectors in the State object.

  • z_name – Name of classical coordinates in the State object.

  • gauge_fixing (default: sim.algorithm.settings.gauge_fixing) – Gauge-fixing method to use.

  • dh_qc_dzc_name – Name of the gradient of the quantum-classical Hamiltonian in the State object.

Constants and Settings:

sim.algorithm.settings.gauge_fixing (str) – Gauge fixing method to use.

Reads:
  • state[eigvals_name] (ndarray of shape (B, N), dtype=float64) – Eigenvalues of the total quantum Hamiltonian.

  • state[eigvecs_name] (ndarray of shape (B, N, N), dtype=complex128) – Eigenvectors of the total quantum Hamiltonian.

  • state[eigvecs_previous_name] (ndarray of shape (B, N, N), dtype=complex128) – Eigenvectors of the total quantum Hamiltonian at the prior timestep.

  • state[dh_qc_dzc] (tuple)

Writes:

state[output_eigvecs_name] (ndarray of shape (B, N, N), dtype=complex128) – Gauge-fixed eigenvectors of the total quantum Hamiltonian.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_vector_basis(sim, state, parameters, input_vec_name, basis_name, output_vec_name, adb_to_db=False)#

Transforms a vector to a new basis.

Optional Keyword Arguments:
  • input_vec_name – Name of the vector to transform in the State object.

  • basis_name – Name of the basis to transform to in the State object. Assumed to be column vectors corresponding to adiabatic states.

  • output_vec_name – Name of the output vector in the State object.

  • adb_to_db – If True, transforms from adiabatic to diabatic. If False, transforms from adiabatic to diabatic.

Reads:
  • state[input_vec_name] (ndarray) – Vector to be transformed

  • state[basis_name] (ndarray) – Column vectors that form the new basis.

Writes:

state[output_vec_name] (ndarray) – Vector expressed in the new basis.

qclab.tasks.update_tasks.update_act_surf_wf(sim, state, parameters, act_surf_wf_name='act_surf_wf', act_surf_ind_name='act_surf_ind', eigvecs_name='eigvecs')#

Updates the wavefunction corresponding to the active surface.

Optional Keyword Arguments:
  • act_surf_wf_name – Name of the active surface wavefunction in the State object.

  • act_surf_ind_name – Name of the active surface index in the State object.

  • eigvecs_name – Name of the eigenvectors in the State object.

Reads:
  • state[eigvecs_name] (ndarray of shape (B, N), dtype=complex128) – Eigenvectors of the total quantum Hamiltonian.

  • state[act_surf_ind_name] (ndarray of shape (B,), dtype=int) – Active surface index in each trajectory.

Writes:

state[act_surf_wf_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction of the active surface in each trajectory.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_wf_db_propagator(sim, state, parameters, wf_db_name='wf_db', eigvals_name='eigvals', eigvecs_name='eigvecs')#

Updates the diabatic wavefunction by calculating and applying the propagator.

Optional Keyword Arguments:
  • wf_db_name – Name of the diabatic wavefunction in the State object.

  • eigvals_name – Name of the eigenvalues in the State object.

  • eigvecs_name – Name of the eigenvectors in the State object.

Reads:
  • state[wf_db_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the diabatic basis.

  • state[eigvals_name] (ndarray of shape (B, N), dtype=float64) – Eigenvalues of the total quantum Hamiltonian.

  • state[eigvecs_name] (ndarray of shape (B, N, N), dtype=complex128) – Eigenvectors of the total quantum Hamiltonian.

Writes:

state[wf_db_name] (ndarray of shape (B, N), dtype=complex128) – Propagated wavefunction coefficients in the diabatic basis.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_wf_db_rk4(sim, state, parameters, wf_db_name='wf_db', h_q_tot_name='h_q_tot')#

Updates the wavefunction using the 4th-order Runge-Kutta method.

Optional Keyword Arguments:
  • wf_db_name – Name of the diabatic wavefunction in the State object.

  • h_q_tot_name – Name of the quantum Hamiltonian in the State object.

Reads:
  • state[wf_db_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the diabatic basis.

  • state[h_q_tot_name] (ndarray of shape (B, N, N), dtype=complex128) – Total quantum Hamiltonian.

Writes:

state[wf_db_name] (ndarray of shape (B, N), dtype=complex128) – Updated wavefunction coefficients.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_hop_prob_fssh(sim, state, parameters, act_surf_ind_name='act_surf_ind', wf_adb_name='wf_adb', eigvecs_name='eigvecs', eigvecs_previous_name='eigvecs_previous', hop_prob_name='hop_prob', adb_connection_name='adb_connection')#

Calculates the hopping probabilities according to the FSSH algorithm.

\(P_{a \rightarrow b} = -2 \Re \left( (C_{b}/C_{a}) \langle a(t) | b(t-dt) \rangle \right)\)

Optional Keyword Arguments:
  • act_surf_ind_name – Name of the active surface index in the State object.

  • wf_adb_name – Name of the adiabatic wavefunction in the State object.

  • eigvecs_name – Name of the eigenvectors in the State object.

  • eigvecs_previous_name – Name of the previous eigenvectors in the State object.

  • hop_prob_name – Name under which to store the hopping probabilities in the State object.

  • adb_connection_name – Name of the adiabatic connection in the State object.

Constants and Settings:

sim.algorithm.settings.fssh_deterministic (Bool) – Boolean indicating if the FSSH simulation is deterministic.

Reads:
  • state[act_surf_ind_name] (ndarray of shape (B,), dtype=int) – Active surface index in each trajectory.

  • state[wf_adb_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the adiabatic basis.

  • state[eigvecs_name] (ndarray of shape (B, N, N), dtype=complex128) – Eigenvectors of the total quantum Hamiltonian.

  • state[eigvecs_previous_name] (ndarray of shape (B, N, N), dtype=complex128) – Eigenvectors of the total quantum Hamiltonian at the previous timestep.

  • state[adb_connection_name] (ndarray of shape (B, C, N, N), dtype=complex128)

Writes:

state[hop_prob_name] (ndarray of shape (B, N), dtype=float64) – Hopping probabilities between the active surface and all other surfaces.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_hop_inds_fssh(sim, state, parameters, act_surf_ind_name='act_surf_ind', hop_prob_name='hop_prob', hop_prob_rand_vals_name='hop_prob_rand_vals', hop_ind_name='hop_ind', hop_dest_name='hop_dest', hop_bool_name='hop_bool', hop_pairs_name='hop_pairs')#

Updates indices of trajectories that hop according to their probabilities (but may later be frustrated) and their destination state indices.

Optional Keyword Arguments:
  • act_surf_ind_name – Name of the active surface in the State object.

  • hop_prob_name – Name of the hopping probabilities in the State object.

  • hop_prob_rand_vals_name – Name of the random values for hopping probabilities in the State object.

  • hop_ind_name – Name under which to store the indices of the hopping trajectories in the State object.

  • hop_dest_name – Name under which to store the destination indices of the hopping trajectories in the State object.

  • hop_pairs_name – Name under which to store the pairs of initial and final indices of hopping trajectories in the State object.

Constants and Settings:

sim.algorithm.settings.fssh_deterministic (Bool) – Boolean indicating if the FSSH simulation is deterministic.

Reads:
  • state[act_surf_ind_name] (ndarray of shape (B,) dtype=int) – Active surface indices.

  • state[hop_prob_name] (ndarray of shape (B, N), dtype=float64) – Hopping probabilities between the active surface and all other surfaces.

  • state[hop_prob_rand_vals_name] (ndarray of shape (B//b, t), dtype=float64) – Random numbers for hop decisions.

Writes:
  • state[hop_ind_name] (ndarray of shape (H,), dtype=int) – Indices of trajectories that hop.

  • state[hop_dest_name] (ndarray of shape (H,), dtype=int) – Destination surface for each hop.

  • state[hop_bool_name] (ndarray of shape (B,), dtype=bool) – Boolean indicating if the trajectory hops.

  • state[hop_paris_name] (ndarray of shape (B, 2), dtype=int) – Indices of initial/final states of hops. Zero for trajectories that don’t hop.

Notes

  • H = The number of trajectories that hop.

  • B = sim.settings.batch_size

  • b = sim.model.constants.num_quantum_states if fssh_deterministic == True, b = 1 otherwise.

  • t = The number of update timesteps.

qclab.tasks.update_tasks.update_z_shift_fssh(sim, state, parameters, z_traj_name='z_traj', resc_dir_z_traj_name='resc_dir_z_traj', eigval_diff_traj_name='eigval_diff_traj', hop_successful_traj_name='hop_successful_traj', z_shift_traj_name='z_shift_traj')#

Determines if a hop occurs and calculates the shift in the classical coordinate at the single trajectory level.

Optional Keyword Arguments:
  • z_traj_name – Name of the classical coordinates for this trajectory in the State object.

  • resc_dir_z_traj_name – Name of the rescaling direction for this trajectory in the State object.

  • eigval_diff_traj_name – Name of the difference in eigenvalues between the initial and final states (e_final - e_initial) for this trajectory in the State object.

  • hop_successful_traj_name – Name under which to store whether the hop was successful for this trajectory in the State object.

  • z_shift_traj_name – Name under which to store the shift in classical coordinates for this trajectory in the State object.

Ingredients:

hop (optional, default: functions.numerical_fssh_hop) – Hopping ingredient that determines the energy conservation criterion for a given classical Hamiltonian.

Reads:

state[z_traj_name] (ndarray of shape (C,), dtype=complex128) – Complex-valued classical coordinates in a single trajectory.

Writes:
  • state[hop_successful_traj_name] (Bool) – Boolean value indicating if the hop was successful.

  • state[z_shift_traj_name] (ndarray of shape (C,), dtype=complex128) – Shift of the classical coordinate required to conserve energy.

Notes

  • C = sim.settings.batch_size

qclab.tasks.update_tasks.update_hop_vals_fssh(sim, state, parameters, z_shift_name='z_shift', hop_successful_name='hop_successful', hop_ind_name='hop_ind', hop_dest_name='hop_dest', eigvals_name='eigvals', eigvecs_name='eigvecs', z_name='z', act_surf_ind_name='act_surf_ind', dh_qc_dzc_name='dh_qc_dzc', z_traj_name='z_traj', resc_dir_z_traj_name='resc_dir_z_traj', eigval_diff_traj_name='eigval_diff_traj', hop_successful_traj_name='hop_successful_traj', z_shift_traj_name='z_shift_traj', derivative_coupling_dzc_name=None)#

Updates trajectory hopping information for FSSH.

Executes the hopping function for the hopping trajectories and stores the rescaled coordinates in state.z_rescaled and a Boolean registering if the hop was successful in state.hop_successful.

If the model has a rescaling_direction_fssh ingredient, it will be used to determine the direction in which to rescale the coordinates. Otherwise, the direction will be calculated with functions.calc_resc_dir_z_fssh.

Required Constants

None

Optional Keyword Arguments:
  • z_shift_name – Name under which to store the shift in coordinates for each hopping trajectory in the State object.

  • hop_successful_name – Name under which to store flags indicating if each hop was successful in the State object.

  • hop_ind_name – Name of the indices of the trajectories that are attempting to hop in the State object.

  • hop_dest_name – Name of the destination states of the trajectories that are attempting to hop in the State object.

  • eigvals_name – Name of the eigenvalues in the State object.

  • eigvecs_name – Name of the eigenvectors in the State object.

  • z_name – Name of classical coordinates in the State object.

  • act_surf_ind_name – Name of the active surface index in the State object.

  • dh_qc_dzc_name – Name of the gradient of the quantum-classical Hamiltonian in the State object.

  • z_traj_name – Name of the classical coordinates for the intermediate hopping trajectory in the State object.

  • resc_dir_z_traj_name – Name of the rescaling direction for the intermediate hopping trajectory in the State object.

  • eigval_diff_traj_name – Name of the difference in eigenvalues between the initial and final states (e_final - e_initial) for the intermediate hopping trajectory in the State object.

  • hop_successful_traj_name – Name under which to store whether the hop was successful for the intermediate hopping trajectory in the State object.

  • z_shift_traj_name – Name under which to store the shift in classical coordinates for the intermediate hopping trajectory in the State object.

  • derivative_coupling_dzc_name – Name of the derivative coupling in the State object.

Ingredients:

rescaling_direction_fssh (optional, default: derivative coupling) – Rescaling direction for FSSH.

Reads:
  • state[hop_ind_name] (ndarray of shape (h,), dtype=int) – Trajectory indices of trajectories that could hop.

  • state[hop_dest_name] (ndarray of shape (h,), dtype=int) – Destination states of trajectories that hop.

  • state[eigvals_name] (ndarray of shape (B, N), dtype=float64) – Eigenvalues of the total quantum Hamiltonian.

  • state[eigvecs_name] (ndarray of shape (B, N, N), dtype=complex128) – Eigenvectors of the total quantum Hamiltonian.

  • state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinate.

  • state[act_surf_ind_name] (ndarray of shape (B,), dtype=int) – Active surface index in each trajectory.

  • state[derivative_couplign_dzc_name] (ndarray of shape (B, C, N, N), dtype=complex128) – Derivative coupling tensor.

Writes:
  • state[hop_successful_name] (ndarray of shape (h,), dtype=Bool) – Boolean indicating if the hop was successful or frustrated in the trajectories that could hop.

  • state[z_shift_name] (ndarray of shape (h,C), dtype=complex128) – Shift in classical coordinates in trajectories that could hop. 0 for frustrated hops, nonzero otherwise.

Notes

  • h is the number of trajectories that could hop as determined by the hopping probabilities

    and random number, which are now being evaluated for energy conservation.

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_z_hop(sim, state, parameters, z_shift_name='z_shift', hop_ind_name='hop_ind', z_name='z')#

Updates the classical coordinates in trajectories that have hopped.

Optional Keyword Arguments:
  • z_shift_name – Name of the shift in coordinates for each hopping trajectory in the State object.

  • hop_ind_name – Name of the indices of the trajectories that are attempting to hop in the State object.

  • z_name (ndarray of shape (B, C), dtype=complex128) – Name of classical coordinates in the State object.

Reads:
  • state[z_shift_name] (ndarray of shape (h, C), dtype=complex128) – Shift in classical coordinates for trajectories that could hop. Zero for frustrated hops, nonzero otherwise.

  • state[hop_ind_name] (ndarray of shape (h,), dtype=int) – Trajectory indices of trajectories that could hop.

Writes:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

Notes

  • h is the number of trajectories that could hop as determined by the hopping probabilities

    and random number, which are now being evaluated for energy conservation.

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_act_surf_hop(sim, state, parameters, hop_ind_name='hop_ind', hop_dest_name='hop_dest', hop_successful_name='hop_successful', act_surf_name='act_surf', act_surf_ind_name='act_surf_ind')#

Updates the active surface, active surface index, and active surface wavefunction following a hop.

Optional Keyword Arguments:
  • hop_ind_name – Name of the indices of the trajectories that are attempting to hop in the State object.

  • hop_dest_name – Name of the destination states of the trajectories that are attempting to hop in the State object.

  • hop_successful_name – Name of the flags indicating if each hop was successful in the State object.

  • act_surf_name – Name of the active surface wavefunction in the State object.

  • act_surf_ind_name – Name of the active surface index in the State object.

Reads:
  • state[hop_successful_name] (ndarray of shape (h,), dtype=Bool) – Boolean indicating if the hop was successful or frustrated in the trajectories that could hop.

  • state[hop_ind_name] (ndarray of shape (h,), dtype=int) – Trajectory indices of trajectories that could hop.

  • state[hop_dest_name] (ndarray of shape (h,), dtype=int) – Destination states of trajectories that hop.

Writes:
  • state[act_surf_name] (ndarray of shape (B, N), dtype=int) – Active surface vector in adiabatic basis: 1 if active 0 if not.

  • state[act_surf_ind_name] (ndarray of shape (B,), dtype=int) – Active surface index.

Notes

  • h is the number of trajectories that could hop as determined by the hopping probabilities

    and random number, which are now being evaluated for energy conservation.

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_h_q_tot(sim, state, parameters, z_name='z', h_q_name='h_q', h_qc_name='h_qc', h_q_tot_name='h_q_tot')#

Updates the Hamiltonian matrix of the quantum subsystem.

Optional Keyword Arguments:
  • z_name – Name of classical coordinates in State object.

  • h_q_name – Name of the quantum Hamiltonian in the State object.

  • h_qc_name – Name of the quantum-classical coupling Hamiltonian in the State object.

  • h_q_tot_name – Name of the total Hamiltonian of the quantum subsystem in the State object. (h_q + h_qc)

Constants and Settings:

sim.model.update_h_q (Bool) – Flag used to determine if the quantum Hamiltonian should be updated at each timestep.

Ingredients:
  • h_q – Quantum Hamiltonian.

  • h_qc – Quantum-classical Hamiltonian.

Reads:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinate.

Writes:
  • state[h_q_name] (ndarray of shape (B, N, N), dtype=complex128) – Quantum Hamiltonian.

  • state[h_qc_name] (ndarray of shape (B, N, N), dtype=complex128) – Quantum-classical Hamiltonian.

  • state[h_q_tot_name] (ndarray of shape (B, N, N), dtype=complex128) – Total quantum Hamiltonian (quantum plus quantum-classical).

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_z_rk4_k123(sim, state, parameters, z_name='z', z_k_name='z_1', k_name='z_rk4_k1', classical_force_name='classical_force', quantum_classical_force_name='quantum_classical_force', dt_factor=0.5)#

Computes the first three RK4 intermediates for evolving the classical coordinates.

Optional Keyword Arguments:
  • z_name – Name of input coordinates in State object.

  • z_k_name – Name of the output coordinates in the State object.

  • k_name – Name of the k-th RK4 slope in the State object.

  • classical_force_name – Name of the classical force in the State object.

  • quantum_classical_force_name – Name of the quantum-classical force in the State object.

  • dt_factor – Factor to multiply the time step by. Typical values are 0.5 (for k1 and k2) and 1.0 (for k3).

Reads:
  • state[classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Force on the classical coordinates arising from the classical Hamiltonian.

  • state[quantum_classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Force on the classical coordinates arising from the quantum-classical Hamiltonian.

  • state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

Writes:
  • state[z_k_name] (ndarray of shape (B, C), dtype=complex128) – Intermediate classical coordinate after the k-th step of the RK4 algorithm.

  • state[k_name] (ndarray of shape (B, C), dtype=complex128) – Slope of the k-th step of the RK4 algorithm.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_z_rk4_k4(sim, state, parameters, z_name='z', k1_name='z_rk4_k1', k2_name='z_rk4_k2', k3_name='z_rk4_k3', classical_force_name='classical_force', quantum_classical_force_name='quantum_classical_force')#

Computes the final RK4 update for evolving the classical coordinates.

Optional Keyword Arguments:
  • z_name – Name of input coordinates in State object.

  • k1_name – Name of the first RK4 slope in the State object.

  • k2_name – Name of the second RK4 slope in the State object.

  • k3_name – Name of the third RK4 slope in the State object.

  • classical_force_name – Name of the classical force in the State object.

  • quantum_classical_force_name – Name of the quantum-classical force in the State object.

Reads:
  • state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

  • state[k1_name] (ndarray of shape (B, C), dtype=complex128) – First RK4 slope.

  • state[k2_name] (ndarray of shape (B, C), dtype=complex128) – Second RK4 slope.

  • state[k3_name] (ndarray of shape (B, C), dtype=complex128) – Third RK4 slope.

  • state[classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Force on the classical coordinates arising from the classical Hamiltonian.

  • state[quantum_classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Force on the classical coordinates arising from the quantum-classical Hamiltonian.

Writes:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Updated complex-valued classical coordinates.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_dm_db_wf(sim, state, parameters, wf_db_name='wf_db', dm_db_name='dm_db')#

Updates the diabatic density matrix based on the wavefunction.

Optional Keyword Arguments:
  • wf_db_name – Name of the diabatic wavefunction in the State object.

  • dm_db_name – Name of the diabatic density matrix in the State object.

Reads:

state[wf_db_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the diabatic basis.

Writes:

state[dm_db_name] (ndarray of shape (B, N, N), dtype=complex128) – Density matrix elements in the diabatic basis.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_classical_energy(sim, state, parameters, z_name='z', classical_energy_name='classical_energy')#

Updates the classical energy.

Optional Keyword Arguments:
  • z_name – Name of the classical coordinates in the State object.

  • classical_energy_name – Name under which to store the classical energy in the State object.

Ingredients:

h_c – Classical Hamiltonian.

Reads:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

Writes:

state[classical_energy_name] (ndarray of shape (B,), dtype=float64) – Classical energy in each trajectory.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_classical_energy_fssh(sim, state, parameters, z_name='z', classical_energy_name='classical_energy', dm_adb_0_name='dm_adb_0', branch_ind_name='branch_ind')#

Updates the classical energy for FSSH simulations.

If deterministic, the energy in each branch is summed together with weights determined by the initial adiabatic populations. If not deterministic (and so there is only one branch), the energy is computed for the single branch.

Optional Keyword Arguments:
  • z_name – Name of classical coordinates in State object.

  • dm_adb_0_name – Name of the initial adiabatic density matrix in the State object.

  • branch_ind_name – Name of the branch indices in the State object.

  • classical_energy_name – Name under which to store the classical energy in the State object.

Constants and Settings:

sim.algorithm.settings.fssh_deterministic (Bool) – Boolean indicating if the FSSH simulation is deterministic.

Ingredients:

h_c – Classical Hamiltonian.

Reads:
  • state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

  • state[dm_adb_0_name] (ndarray of shape (B, N, N), dtype=complex128) – Initial adiabatic density matrix.

  • state[branch_ind_name] (ndarray of shape (B,), dtype=int) – Branch index.

  • Writes

  • state[classical_energy_name] (ndarray of shape (B,), dtype=float64) – Classical energy in each trajectory.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_quantum_energy_wf(sim, state, parameters, wf_db_name='wf_db', h_q_tot_name='h_q_tot', quantum_energy_name='quantum_energy')#

Updates the quantum energy w.r.t. the wavefunction.

Optional Keyword Arguments:
  • wf_db_name – Name of the wavefunction in the State object.

  • h_q_tot_name – Name of the total Hamiltonian of the quantum subsystem in the State object. (h_q + h_qc)

  • quantum_energy_name – Name under which to store the quantum energy in the State object.

Reads:
  • state[wf_db_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the diabatic basis.

  • state[h_q_tot_name] (ndarray of shape (B, N, N), dtype=complex128) – Total quantum Hamiltonian.

Writes:

state[quantum_energy_name] (ndarray of shape (B,) dtype=float64) – Quantum energy in each trajectory.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_quantum_energy_act_surf(sim, state, parameters, wf_db_name='act_surf_wf', h_q_tot_name='h_q_tot', quantum_energy_name='quantum_energy', dm_adb_0_name='dm_adb_0')#

Updates the quantum energy using the active surface wavefunction.

Accounts for both stochastic and deterministic FSSH modes.

Optional Keyword Arguments:
  • wf_db_name – Name of the wavefunction in the State object.

  • h_q_tot_name – Name of the total Hamiltonian of the quantum subsystem in the State object. (h_q + h_qc)

  • quantum_energy_name – Name under which to store the quantum energy in the State object.

  • dm_adb_0_name – Name of the initial adiabatic density matrix in the State object.

Constants and Settings:

sim.algorithm.settings.fssh_deterministic (Bool) – Boolean indicating if the FSSH simulation is deterministic.

Reads:
  • state[h_q_tot_name] (ndarray of shape (B, N, N), dtype=complex128) – Total quantum Hamiltonian.

  • state[wf_db_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the diabatic basis.

  • state[dm_adb_0_name] (ndarray of shape (B, N, N), dtype=complex128) – Initial density matrix in the adiabatic basis.

Writes:

state[quantum_energy_name] (ndarray of shape (B,), dtype=float64) – Quantum energy in each trajectory.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_dm_db_fssh(sim, state, parameters, wf_adb_name='wf_adb', dm_adb_0_name='dm_adb_0', act_surf_name='act_surf', dm_db_name='dm_db', dm_adb_name='dm_adb', eigvecs_name='eigvecs')#

Updates the diabatic density matrix for FSSH.

Accounts for both stochastic and deterministic FSSH modes.

Optional Keyword Arguments:
  • wf_adb_name – Name of the adiabatic wavefunction in the State object.

  • dm_adb_0_name – Name of the initial adiabatic density matrix in the State object.

  • act_surf_name – Name of the active surface wavefunction in the State object.

  • dm_db_name – Name of the diabatic density matrix in the State object.

  • dm_adb_name – Name of the adiabatic density matrix in the State object.

  • eigvecs_name – Name of the eigenvectors in the State object.

Constants and Settings:

sim.algorithm.settings.fssh_deterministic (Bool) – Boolean indicating if the FSSH simulation is deterministic.

Reads:
  • state[wf_adb_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the adiabatic basis.

  • state[dm_adb_0_name] (ndarray of shape (B, N, N), dtype=complex128) – Initial density matrix in the adiabatic basis.

  • state[act_surf_name] (ndarray of shape (B, N), dtype=complex128) – Active surface.

  • state[eigvecs_name] (ndarray of shape (B, N, N), dtype=complex128) – Eigenvectors of the total quantum Hamiltonian.

Writes:
  • state[dm_adb_name] (ndarray of shape (B, N, N), dtype=complex128) – Density matrix in the adiabatic basis.

  • state[dm_db_name] (ndarray of shape (B, N, N), dtype=complex128) – Density matrix in the diabatic basis.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_adb_connection(sim, state, parameters, z_name='z', adb_connection_name='adb_connection', classical_force_name='classical_force', quantum_classical_force_name='quantum_classical_force', derivative_coupling_dzc_name='derivative_coupling_dzc', wf_overlaps_name='aip_wf_overlaps', update_derivative_coupling=False)#

Updates the adiabatic connection matrix.

This matrix describes the coupling between different adiabatic states.

\[A = U^{\dagger}\partial_{t}U = B - B^{\dagger}\]

where

\[B = \dot{z}^{*}\cdot U^{\dagger}\partial_{z^{*}} U\]

and \(U\) is a matrix of adiabatic states (column vectors).

Updates the derivative coupling if needed.

Optional Keyword Arguments:
  • z_name – Name of classical coordinates in the State object.

  • adb_connection_name – Name under which to store the adiabatic connection in the State object.

  • classical_force_name – Name of the classical force in the State object.

  • quantum_classical_force_name – Name of the quantum-classical force in the State object.

  • derivative_coupling_dzc_name – Name of the derivative coupling tensor in the State object.

  • use_wf_overlaps – Boolean indicating if the wavefunction overlaps should be used to construct the adiabatic connection.

  • wf_overlaps_name – Name of the wavefunction overlaps in the State object.

Constants and Settings:

sim.algorithm.settings.use_wf_overlaps_for_adb_connection (bool, default: False) – If True, uses a finite difference formula to construct the adiabatic connection from wavefunction overlaps. If False, uses the derivative coupling.

Ingredients:
  • adb_connection – Adiabatic connection matrix.

  • derivative_coupling_dzc – Derivative coupling matrix.

Reads:
  • state[z_name] (ndarray of shape (B, C), dtype=complex128) – Complex-valued classical coordinates.

  • state[wf_overlaps_name] (ndarray of shape (B, N, N), dtype=float64) – Wavefunction overlaps.

Writes:

state[adb_connection_name] (ndarray of shape (B, N, N), dtype=complex128) – Adiabatic connection.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_wf_adb_rk4(sim, state, parameters, wf_adb_name='wf_adb', h_q_tot_name='h_q_tot', adb_connection_name='adb_connection')#

Updates the adiabatic wavefunction using the 4th-order Runge-Kutta method.

Optional Keyword Arguments:
  • wf_adb_name – Name of the diabatic wavefunction in the State object.

  • h_q_tot_name – Name of the quantum Hamiltonian in the State object.

  • adb_connection_name – Name of the adiabatic connection in the State object.

Reads:
  • state[wf_adb_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the adiabatic basis.

  • state[h_q_tot_name] (ndarray of shape (B, N, N), dtype=complex128) – Total quantum Hamiltonian in the adiabatic basis.

  • state[adb_connection_name] (ndarray of shape (B, N, N), dtype=complex128) – Adiabatic connection matrix.

Writes:

state[wf_adb_name] (ndarray of shape (B, N), dtype=complex128) – Updated wavefunction coefficients in the adiabatic basis.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_wf_adb_hop_prob(sim, state, parameters, h_q_tot_name='h_q_tot', adb_connection_name='adb_connection', h_q_tot_previous_name='h_q_tot_previous', adb_connection_previous_name='adb_connection_previous', wf_adb_name='wf_adb', update_hopping_probabilities=False, hop_prob_name='hop_prob')#

Updates the adiabatic wavefunction by diagonalizing the Hamiltonian.

Optionally integrates the hopping probability over the time interval.

Hopping probability formula is taken from:

Hammes‐Schiffer, S.; Tully, J. C. Proton Transfer in Solution: Molecular Dynamics with Quantum Transitions. J. Chem. Phys. 1994, 101 (6), 4657–4667. https://doi.org/10.1063/1.467455.

\[g_{k->j} = ( \int_{t}^{t+\Delta} b_{jk}(t') dt' ) / (c^{*}_{k}(t)c_{k}(t))\]
\[b_{jk}(t) = -2\Re(c_{j}^{*}(t)c_{k}(t) A_{jk}(t))\]
\[A_{jk}(t) = \dot{q}(t) \cdot d_{jk}(t)\]

Note that this is consistent with Eq. 19-21 for real and complex \(d_{jk}\).

Eq. 30 (follwoing) is equivalent to the above expression for \(b_{jk}\) when \(d_{jk}\) is real-valued:

\[b_{jk}(t) = -2\Re(c_{j}(t)c_{k}^{*}(t) A_{jk}(t))\]
Optional Keyword Arguments:
  • h_q_tot_name – Name of the quantum Hamiltonian in the State object.

  • adb_connection_name – Name of the adiabatic connection in the State object.

  • h_q_tot_previous_name – Name of the quantum Hamiltonian from the previous time step in the State object.

  • adb_connection_previous_name – Name of the adiabatic connection from the previous time step in the State object.

  • wf_adb_name – Name of the adiabatic wavefunction in the State object.

  • update_hopping_probabilities – Boolean indicating if to update the hopping probabilities.

  • hop_prob_name – Name of the hopping probabilities in the State object.

Constants and Settings:

sim.algorithm.settings.update_wf_adb_eig_num_substeps (int, default: 1) – Number of substeps to use when updating the adiabatic wavefunction.

Reads:
  • state[wf_adb_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the adiabatic basis.

  • state[h_q_tot_name] (ndarray of shape (B, N, N), dtype=complex128) – Total quantum Hamiltonian in the adiabatic basis.

  • state[adb_connection_name] (ndarray of shape (B, N, N), dtype=complex128) – Adiabatic connection matrix.

  • state[h_q_tot_previous_name] (ndarray of shape (B, N, N), dtype=complex128) – Total quantum Hamiltonian in the adiabatic basis at the previous timestep.

  • state[adb_connection_previous_name] (ndarray of shape (B, N, N), dtype=complex128) – Adiabatic connection matrix at the previous timestep.

Writes:
  • state[wf_adb_name] (ndarray of shape (B, N), dtype=complex128) – Wavefunction coefficients in the adiabatic basis.

  • state[hop_prob_name] (ndarray of shape (B, N), dtype=float64) – Hopping probabilities.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_q_velocity_verlet(sim, state, parameters, z_name='z', classical_force_name='classical_force', quantum_classical_force_name='quantum_classical_force')#

Updates the position component of the classical coordinates using velocity Verlet.

Optional Keyword Arguments:
  • z_name – Name of classical coordinates in the State object.

  • classical_force_name – Name of the classical force in the State object.

  • quantum_classical_force_name – Name of the quantum-classical force in the State object.

Reads:
  • state[z_name] (ndarray of shape (B, C), dtype=complex128) – Updated classical coordinates.

  • state[classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Force arising from the classical Hamiltonian.

  • state[quantum_classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Force arising from the quantum-classical Hamiltonian.

Writes:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Updated complex-valued classical coordinates.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_p_velocity_verlet(sim, state, parameters, z_name='z', classical_force_name='classical_force', classical_force_previous_name='classical_force_previous', quantum_classical_force_name='quantum_classical_force', quantum_classical_force_previous_name='quantum_classical_force_previous')#

Updates the momentum component of the classical coordinates using velocity Verlet.

Optional Keyword Arguments:
  • z_name – Name of classical coordinates in the State object.

  • classical_force_name – Name of the classical force in the State object.

  • quantum_classical_force_name – Name of the quantum-classical force in the State object.

  • quantum_classical_force_previous_name – Name of the quantum-classical force from the previous time step in the State object.

Reads:
  • state[z_name] (ndarray of shape (B, C), dtype=complex128) – Updated classical coordinates.

  • state[classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Force arising from the classical Hamiltonian.

  • state[classical_force_previous_name] (ndarray of shape (B, C), dtype=complex128) – Force arising from the classical Hamiltonian at the previous timestep.

  • state[quantum_classical_force_name] (ndarray of shape (B, C), dtype=complex128) – Force arising from the quantum-classical Hamiltonian.

  • state[quantum_classical_force_previous_name] (ndarray of shape (B, C), dtype=complex128) – Force arising from the quantum-classical Hamiltonian at the previous timestep.

Writes:

state[z_name] (ndarray of shape (B, C), dtype=complex128) – Updated complex-valued classical coordinates.

Notes

  • B = sim.settings.batch_size

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_derivative_coupling_dzc_gauge(sim, state, parameters, wf_overlaps_name='aip_wf_overlaps', derivative_coupling_dzc_name='derivative_coupling_dzc')#

Updates the gauge of the derivative coupling tensor using the wavefunction overlaps. Assumes real-valued wavefunction overlaps.

Optional Keyword Arguments:
  • wf_overlaps_name – Name of the wavefunction overlaps in the State object.

  • derivative_coupling_dzc_name – Name of the derivative coupling tensor in the State object.

Reads:
  • state[wf_overlaps_name] (ndarray of shape (B, N), dtype=float64) – Wavefunction overlaps.

  • state[derivative_coupling_dzc_name] (ndarray of shape (B, C, N, N), dtype=float64) – Derivative coupling tensor.

Writes:

state[derivative_coupling_dzc_name] (ndarray of shape (B, C, N, N), dtype=float64) – Derivative coupling tensor in the updated gauge.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

  • C = sim.model.constants.num_classical_coordinates

qclab.tasks.update_tasks.update_wf_overlaps_gauge(sim, state, parameters, wf_overlaps_name='aip_wf_overlaps')#

Updates the gauge of the overlap matrix. Assumes real-valued overlaps.

Optional Keyword Arguments:

wf_overlaps_name – The name of the wavefunction overlaps in the State object.

Reads:

state[wf_overlaps_name] (ndarray of shape (B, N), dtype=float64) – Wavefunction overlaps.

Writes:

state[wf_overlaps_name] (ndarray of shape (B, N), dtype=float64) – Wavefunction overlaps in the updated gauge.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.update_tasks.update_ab_initio_property(sim, state, parameters, ab_initio_property_name='ab_initio_property', property_dict={'derivative_coupling': {'state_inds_derivative_coupling': None, 'z': 'z'}, 'energy': {'excited_amplitudes': True, 'z': 'z'}, 'gradient': {'state_inds_gradient': None, 'z': 'z'}, 'wf_overlaps': {'z': 'z', 'z_previous': 'z_previous'}})#

Calculates ab initio properties using the ab initio property calculator ingredient.

Stores the properties as a list of dictionaries in the Parameters object, a dictionary in the State object containing vectorized properties, and as new variables in the State object with the same name in property_dict appended with “aip_” where aip stands for “ab initio property”.

Optional Keyword Arguments:
  • ab_initio_property_name – The name under which to store the ab initio properties in the State and Parameters objects.

  • property_dict – A dictionary of properties and associated argument dictionaries, i.e. {property_name:{arg1:arg1_name,…}}. The argument dictionaries contain names of objects in the State object, Booleans, or None.

Ingredients:

ab_initio_property_calculator – Ab initio property calculator.

Writes:
  • parameters[ab_initio_property_name] (List) – A List of dictionaries containing the ab initio properties calculated for each trajectory.

  • state[ab_initio_property_name] (Dict) – A dictionary containing the calculated ab initio properties restructured into a ndarray where the first index corresponds to the trajectory index.

  • state[“aip_” + property] (ndarray of shape (B, shape(property)), dtype=type(property)) – A new variable in the State object giving the result of the calculation of property.

Notes

  • B = sim.settings.batch_size

Collect Tasks#

This module contains tasks that are used to collect data from the state or parameters objects into the output dictionary of the State object.

qclab.tasks.collect_tasks.collect_t(sim, state, parameters, t_name='t', t_output_name='t')#

Collects the time from the State object and stores it in the output dictionary.

Optional Keyword Arguments:
  • t_name – Name of the time in the State object.

  • t_output_name – Name of the time in the output dictionary.

Reads:

state[t_name] (ndarray of shape (B,), dtype=float64) – Time in each trajectory.

Writes:

state[“output_dict”][t_output_name] (ndarray of shape (B,), dtype=float64) – Time in each trajectory.

Notes

  • B = sim.settings.batch_size

qclab.tasks.collect_tasks.collect_dm_db(sim, state, parameters, dm_db_name='dm_db', dm_db_output_name='dm_db')#

Collects the diabatic density matrix from the State object and stores it in the output dictionary.

Optional Keyword Arguments:
  • dm_db_name – Name of the diabatic density matrix in the State object.

  • dm_db_output_name – Name of the diabatic density matrix in the output dictionary.

Reads:

state[dm_db_name] (ndarray of shape (B, N, N), dtype=complex128) – Density matrix in the diabatic basis.

Writes:

state[“output_dict”][dm_db_output_name] (ndarray of shape (B, N, N), dtype=complex128) – Density matrix in the diabatic basis.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.collect_tasks.collect_classical_energy(sim, state, parameters, classical_energy_name='classical_energy', classical_energy_output_name='classical_energy')#

Collects the classical energy from the State object and stores it in the output dictionary.

Optional Keyword Arguments:
  • classical_energy_name – Name of the classical energy in the State object.

  • classical_energy_output_name – Name of the classical energy in the output dictionary.

Reads:

state[classical_energy_name] (ndarray of shape (B,), dtype=float64) – Classical energy of each trajectory.

Writes:

state[“output_dict”][classical_energy_output_name] (ndarray of shape (B,), dtype=float64) – Classical energy of each trajectory.

Notes

  • B = sim.settings.batch_size

  • N = sim.model.constants.num_quantum_states

qclab.tasks.collect_tasks.collect_quantum_energy(sim, state, parameters, quantum_energy_name='quantum_energy', quantum_energy_output_name='quantum_energy')#

Collects the quantum energy from the State object and stores it in the output dictionary.

Optional Keyword Arguments:
  • quantum_energy_name – Name of the quantum energy in the State object.

  • quantum_energy_output_name – Name of the quantum energy in the output dictionary.

Reads:

state[quantum_energy_name] (ndarray of shape (B,) with dtype=float64) – Quantum energy in each trajectory.

Writes:

state[“output_dict”][quantum_energy_output_name] (ndarray of shape (B,) with dtype=float64) – Quantum energy in each trajectory.

Notes

  • B = sim.settings.batch_size