-
Notifications
You must be signed in to change notification settings - Fork 1
TDDFT
The QMol-grid package uses the Kohn-Sham formulation of time-dependent density-functional theory (TDDFT) [Kohn 1965, Runge 1984], where the evolution of the Kohn-Sham orbitals, in atomic units, is described by the nonlinear system of partial differential equations
where the index
For clarity and streamlined future development of TDDFT capabilities in the QMol-grid package, we sort TDDFT component (classes) into different topical groups. Each component is equally compatible with both spin-polarized and -restricted TDDFT models
External driving fields provide the explicit time dependence in the Hamiltonian operator
-
QMol_extField_dipole
is a container class for external driving fields in the dipole approximation
Absorbing boundaries emulate the exit from the simulation domain of outgoing wave packets near the edges of the simulation domain, therefore avoiding (reducing) reflections on the boundaries
-
QMol_TDDFT_abs_CAP
enables absorbing boundaries using a complex absorbing potential (CAP) at the edges of the domain -
QMol_TDDFT_abs_mask
enables absorbing boundaries using a mask function at the edges of the domain
The choice of the DFT model together with the set of observables to save, and how often, during the TDDFT propagation can greatly affect the memory resources required to carry out simulation
-
QMol_DFT_profiler
provides estimates of the memory requirements for a given TDDFT simulation
See the DFT documentation for tips and examples as to how to optimize simulations.
The QMol-grid package supports various types of TDDFT propagators
General-purpose propagators are the most versatile schemes with few, if any, restrictions on the DFT model but require more resources
- No general-purpose propagators have been implemented yet
For DFT models that use a basis-set discretization scheme
- No basis-set propagators have been implemented yet
For DFT models discretized on a grid and with local exchange-correlation potentials (LDA and GGA type).
-
QMol_TDDFT_SSO_2S
implements the 2nd order Strang splitting (a.k.a. Verlet) scheme -
QMol_TDDFT_SSO_4BM
implements the 4th order Blanes and Moan optimized scheme -
QMol_TDDFT_SSO_4FR
implements the 4th order Forest-Ruth symplectic scheme -
QMol_TDDFT_SSO_6BM
implements the 6th order Blanes and Moan optimized scheme
Symplectic split-operator TDDFT propagators are build from the Hamiltonian description of the dynamics and discussed in [Mauger 2024] (including a comparison of the performance of the schemes).
All TDDFT propagators in the QMol-Grid package take a spin-polarized or -restricted DFT model object as input and evolve it over the user-specified time interval and action of external driving field(s). During the propagation, they also support on-the-fly computation and storage of the following observables:
- Dipole, dipole velocity, and dipole acceleration: Each can individually be enabled and define its own sampling time and may provide the signal contribution from individual Kohn-Sham orbitals in addition to the total result. The dipole velocity and acceleration are self-consistently computed using analytical formula (i.e., not from taking the time derivative of the dipole).
-
DFT and Kohn-Sham orbital energies: Tracking the DFT energy can be used a a proxy for evaluating the accuracy of the numerical simulations (since the energy should be conserved). In addition to the total total energy, activating the DFT-energy feature keeps track of the variations in the kinetic, external, Hartree, exchange-correlation, external-field, and autonomization [Mauger 2024] components. The instantaneous Kohn-Sham orbital energy is defined as
$\left\langle \phi (t)\left|{\hat{\mathcal{H}} } _{{\mathrm{DFT}}} [\lbrace \phi _k \rbrace_k ;t]\right|\phi (t)\right\rangle$ . Both the DFT and orbital energies are directly computed from the DFT-objectgetEnergy
method -- see the corresponding documentation page for details. - Ionization signal: Keep track of how much density is absorbed on the boundaries, optionally resolved by individual Kohn-Sham orbital channels.
- Kohn-Sham orbitals, projection of the orbitals, and one-body density: Each can individually be enabled and define its own sampling time. Saving the Kohn-Sham orbitals or one-body density is generally discouraged as they generally lead to very large memory requirements; saving the DFT object into separate MATLAB files or using the installable output functions are recommended, where possible -- see below. Alternatively, saving the projection of the Kohn-Sham orbitals onto a specific basis generally uses less memory, at the cost of possibly losing some details of the orbitals and the time to compute the projections.
Additionally, one can
- Add the external-field information to each of the requested output results structures.
- Save the intermediate-time DF-model object into a separate MATLAB file. This is the best option if the intermediate Kohn-Sham orbitals are required for post-processing.
- Save the results of installable output functions: Installable output functions enable on-the-fly custom analysis and saving of the TDDFT dynamics. Two types of output functions are supported (i) a function of the one-body density, where a density object is passed to the function at the requested output times, and (ii) a function of the Kohn-Sham orbitals, where a copy of the orbital object is passed to the function at the queried times. Each output function can be individually enabled and defined its own sampling time. Enabled output functions must each return a scalar, vector, or array of arbitrary size and shape but must be consistent throughout the propagation (each output function can return an output with a different size or shape). The output results from each function are appended in an array with one extra dimension compared to the output and the last index label the output time.
- Generate a restart file from which the propagation can be restarted in case it gets stopped before the end of the propagation.
All output can individually be enabled and define their own sampling times, which need not be uniformly distributed in time. The respective results are stored in output structure properties in the TDDFT-propagator object; each of these structures keep a record of the precise time at which the results have been sampled (as these may be slightly different from the requested input -- see the respective propagator documentation pages for details).
TDDFT propagators provides general support for on-the-fly computation and storage of various commonly used observables and output results. We give sample scripts for some of these.
We compare the high-order harmonic generation (HHG) spectrum computed from the dipole, dipole-velocity, and dipole-acceleration signals. First, we define the DFT model and the ground-state configuration
% Molecular model
Va_1 = QMol_Va_softCoulomb('atom','A','charge',3,'position',-1.5);
Va_2 = QMol_Va_softCoulomb('atom','A','charge',3,'position', 1.5);
% DFT model
Vext = QMol_DFT_Vext('atom',{Va_1,Va_2});
Vh = QMol_DFT_Vh_conv;
Vxc = {QMol_DFT_Vx_LDA_soft,QMol_DFT_Vc_LDA_soft};
DFT = QMol_DFT_spinRes( ...
'xspan', -50:.1:50, ... small prime factors
'occupation', [2 2 2], ...
'externalPotential', Vext, ...
'HartreePotential', Vh, ...
'exchangeCorrelationPotential', Vxc, ...
'selfInteractionCOrrection', 'ADSIC' );
% DFT ground state
SCF = QMol_DFT_SCF_Anderson;
SCF.solveSCF(DFT);
Then, we define the external field -- ramped up for 2 laser cycles followed by a constant-amplitude plateau -- and TDDFT propagator using the Forest-Ruth symplectic split-operator scheme
% External field
E0 = convertLaser.intensity2amplitude(2e13);
w = convertLaser.wavelength2frequency(2000e-9);
T = 2*2*pi/w;
EField = @(t) E0*sin(w*t).*sin(.5*pi*min(t,T)/T).^2;
t = 0:2*pi/w:T+5*2*pi/w;
% Absorbing boundaries
ABC = QMol_TDDFT_abs_CAP('shape','sin^1/8','length',10,'amplitude',.5);
% Propagator
dt = 5e-2; % Propagation time step
TDDFT = QMol_TDDFT_SSO_4FR( ...
'time', t, ...
'timeStep', dt, ...
'electricField', EField, ...
'saveExternalField', true, ...
'saveDipole', true, ...
'saveDipoleTime', -floor(.5/dt), ... equally-spaced time sampling close to 0.5 a.u.
'saveDipoleOrbitalIndex', 'all', ...
'saveDipoleVelocity', true, ...
'saveDipoleVelocityTime', 'dipole', ... same sampling as for the dipole signal
'saveDipoleVelocityOrbitalIndex', 'all', ...
'saveDipoleAcceleration', true, ...
'saveDipoleAccelerationTime', 'dipole', ... same sampling as for the dipole signal
'saveDipoleAccelerationOrbitalIndex', 'all', ...
'absorbingBoundary', ABC );
TDDFT.propagate(DFT);
Finally, we plot the HHG spectra computed from the dipole, dipole-velocity, and dipole-acceleration signals, and the contributions from the various Kohn-Sham orbitals
% Spectral analysis
W = zeros(size(TDDFT.outDipole.time));
ind = TDDFT.outDipole.time > T;
W(ind) = sin(pi*(0:sum(ind)-1)/(sum(ind)-1)).^2; % Hann window
% Total signal
F = fourierTool.fftGrid(TDDFT.outDipole.time);
D = fft(W.*TDDFT.outDipole.total).*F.^2;
V = fft(W.*TDDFT.outDipoleVelocity.total).*F;
A = fft(W.*TDDFT.outDipoleAcceleration.total);
% Orbital-resolved signals
O = NaN(size(TDDFT.outDipoleAcceleration.orbital_x));
for k = 1:numel(DFT.occupation)
O(k,:) = fft(TDDFT.outDipoleAcceleration.orbital_x(k,:).*W);
end
% Plot results
ind = F > 0; % Positive frequencies
F = F(ind)/w;
D = abs(D(ind)).^2;
V = abs(V(ind)).^2;
A = abs(A(ind)).^2;
O = abs(O(:,ind)).^2;
figure
subplot(2,1,1), set(gca,'yscale','log'), hold on
plot(F,D,'-' ,'LineWidth',3,'DisplayName','dipole')
plot(F,V,'--','LineWidth',2,'DisplayName','velocity')
plot(F,A,':' ,'LineWidth',2,'DisplayName','acceleration')
hold off
%xlim(TDDFT.outEnergyDFT.time([1 end]))
xlim([0 120]), xlabel('harmonic order')
ylim([1e-6 1]), ylabel('intensity (arb. units)')
title('total harmonic signal')
legend show
subplot(2,1,2), set(gca,'yscale','log'), hold on
plot(F,O(3,:),'-' ,'LineWidth',3,'DisplayName','KSO #3')
plot(F,O(2,:),'--','LineWidth',2,'DisplayName','KSO #2')
plot(F,O(1,:),':' ,'LineWidth',2,'DisplayName','KSO #1')
hold off
%xlim(TDDFT.outEnergyDFT.time([1 end]))
xlim([0 120]), xlabel('harmonic order')
ylim([1e-6 1]), ylabel('intensity (arb. units)')
title('orbital-resolved harmonic signal')
legend show
Here we check the conservation of the DFT energy in a spin-polarized molecular model where an electron is suddenly removed form a localized-core orbital and subjected to an external driving field in the dipole approximation and length gauge. First, we define the DFT model and compute the (neutral) ground-state configuration
% Molecular model
Va_1 = QMol_Va_softCoulomb('atom','X','charge',4,'position',-4);
Va_2 = QMol_Va_softCoulomb('atom','A','charge',2,'position', 0);
Va_3 = QMol_Va_softCoulomb('atom','A','charge',2,'position', 3);
% DFT model
Vext = QMol_DFT_Vext('atom',{Va_1,Va_2,Va_3});
Vh = QMol_DFT_Vh_conv;
Vxc = {QMol_DFT_Vx_LDA_soft,QMol_DFT_Vc_LDA_soft};
DFT = QMol_DFT_spinPol( ...
'xspan', -50:.1:50, ... small prime factors
'occupation', {[1 1 1 1],[1 1 1 1]}, ...
'externalPotential', Vext, ...
'HartreePotential', Vh, ...
'exchangeCorrelationPotential', Vxc, ...
'selfInteractionCOrrection', 'ADSIC' );
% DFT ground state
SCF = QMol_DFT_SCF_Anderson;
SCF.solveSCF(DFT);
Next, we remove the core orbital from the down-spin channel and define the external driving field
% Remove core orbital
DFT.orbital.set('orbitalDown',DFT.KSO.orbitalDown(:,2:end));
DFT.set('occupation',{[1 1 1 1],[1 1 1]});
% External potential-vector field
E0 = convertLaser.intensity2amplitude(1e13);
w = convertLaser.wavelength2frequency(800e-9);
EField = @(t) E0*sin(w*t);
Finally we propagate the TDDFT dynamics using the Forest-Ruth symplectic split-operator scheme
% TDDFT propagator
TDDFT = QMol_TDDFT_SSO_4FR( ...
'time', 0:10:100, ...
'timeStep', 2e-2, ...
'electricField', EField, ...
'externalFieldGauge', 'length', ...
'saveExternalField', true, ...
'saveEnergyDFT', true, ...
'saveEnergyDFTtime', 1, ... save DFT energy every 1 a.u.
'absorbingBoundary', QMol_TDDFT_abs_CAP);
TDDFT.propagate(DFT);
With this, we can plot the variation of the total DFT energy and its various components.
% Plot results
figure
subplot(2,1,1), hold on
plot(TDDFT.outEnergyDFT.time,TDDFT.outEnergyDFT.total-TDDFT.outEnergyDFT.total(1),...
'-','LineWidth',2,'DisplayName','total');
hold off
xlim(TDDFT.outEnergyDFT.time([1 end]))
xlabel('time (a.u.)')
ylabel('error (a.u.)')
title('total DFT energy')
subplot(2,1,2), hold on
plot(TDDFT.outEnergyDFT.time,sum(TDDFT.outEnergyDFT.kinetic,1)-sum(TDDFT.outEnergyDFT.kinetic(:,1)),...
'-','LineWidth',2,'DisplayName','kinetic')
plot(TDDFT.outEnergyDFT.time,sum(TDDFT.outEnergyDFT.external,1)-sum(TDDFT.outEnergyDFT.external(:,1)),...
'-','LineWidth',2,'DisplayName','external')
plot(TDDFT.outEnergyDFT.time,sum(TDDFT.outEnergyDFT.externalField,1)-sum(TDDFT.outEnergyDFT.externalField(:,1)),...
'-','LineWidth',2,'DisplayName','external field')
plot(TDDFT.outEnergyDFT.time,TDDFT.outEnergyDFT.Hartree-TDDFT.outEnergyDFT.Hartree(1),...
'-','LineWidth',2,'DisplayName','Hartree')
plot(TDDFT.outEnergyDFT.time,TDDFT.outEnergyDFT.exchangeCorrelation-TDDFT.outEnergyDFT.exchangeCorrelation(1),...
'-','LineWidth',2,'DisplayName','exchange correlation')
plot(TDDFT.outEnergyDFT.time,TDDFT.outEnergyDFT.autonomization-TDDFT.outEnergyDFT.autonomization(1),...
'-','LineWidth',2,'DisplayName','autonomization')
hold off
xlim(TDDFT.outEnergyDFT.time([1 end]))
xlabel('time (a.u.)')
ylabel('variation (a.u.)')
title('DFT energy components')
legend show
The sudden change in the DFT energy error is caused by small portions of the wave function being absorbed on the edges of the simulation domain.
Here we track the ionization signal of a spin-restricted molecular model driven by an external field in the dipole approximation and velocity gauge. First, we define the DFT model and compute the (neutral) ground-state configuration
% Molecular model
Va_1 = QMol_Va_softCoulomb('atom','X','charge',4,'position',-4);
Va_2 = QMol_Va_softCoulomb('atom','A','charge',2,'position', 0);
Va_3 = QMol_Va_softCoulomb('atom','A','charge',2,'position', 3);
% DFT model
Vext = QMol_DFT_Vext('atom',{Va_1,Va_2,Va_3});
Vh = QMol_DFT_Vh_conv;
Vxc = {QMol_DFT_Vx_LDA_soft,QMol_DFT_Vc_LDA_soft};
DFT = QMol_DFT_spinRes( ...
'xspan', -50:.1:50, ... small prime factors
'occupation', [2 2 2 2], ...
'externalPotential', Vext, ...
'HartreePotential', Vh, ...
'exchangeCorrelationPotential', Vxc, ...
'selfInteractionCOrrection', 'ADSIC' );
% DFT ground state
SCF = QMol_DFT_SCF_Anderson;
SCF.solveSCF(DFT);
Next, we define the external potential-vector field and propagate the TDDFT dynamics using the Forest-Ruth symplectic split-operator scheme
% External potential-vector field
E0 = convertLaser.intensity2amplitude(1e14);
w = convertLaser.wavelength2frequency(800e-9);
T = 5*2*pi/w;
AField = @(t) E0/w*sin(w*t).*cos(.5*pi*t/T).^2;
% TDDFT propagator
ABC = QMol_TDDFT_abs_CAP('length',40);
TDDFT = QMol_TDDFT_SSO_4FR( ...
'time', -T:2*pi/w:T, ...
'timeStep', 5e-2, ...
'potentialVector', AField, ...
'externalFieldGauge', 'velocity', ...
'saveExternalField', true, ...
'saveIonization', true, ...
'saveIonizationOrbitalIndex', 'all', ...
'saveIonizationTime', 2, ... save ionization yield every 2 a.u.
'absorbingBoundary', ABC);
TDDFT.propagate(DFT);
Finally, we plot the total and Kohn-Sham-orbital resolved ionization rates
% Plot results
T = .5*(TDDFT.outIonization.time(2:end)+TDDFT.outIonization.time(1:end-1));
figure
subplot(2,1,1), hold on
plot(TDDFT.outIonization.time,TDDFT.outIonization.potentialVector,...
'-','LineWidth',2,'DisplayName','A field');
hold off
xlim(TDDFT.outIonization.time([1 end]))
xlabel('time (a.u.)')
ylabel('field (a.u.)')
title('potential vector')
subplot(2,1,2), hold on
plot(T,(TDDFT.outIonization.total(2:end)-TDDFT.outIonization.total(1:end-1))/(T(2)-T(1)),...
'-','LineWidth',2,'DisplayName','total')
plot(T,(TDDFT.outIonization.orbital(1,2:end)-TDDFT.outIonization.orbital(1,1:end-1))/(T(2)-T(1)),...
':','LineWidth',2,'DisplayName','KSO #1')
plot(T,(TDDFT.outIonization.orbital(2,2:end)-TDDFT.outIonization.orbital(2,1:end-1))/(T(2)-T(1)),...
':','LineWidth',2,'DisplayName','KSO #2')
plot(T,(TDDFT.outIonization.orbital(3,2:end)-TDDFT.outIonization.orbital(3,1:end-1))/(T(2)-T(1)),...
':','LineWidth',2,'DisplayName','KSO #3')
plot(T,(TDDFT.outIonization.orbital(4,2:end)-TDDFT.outIonization.orbital(4,1:end-1))/(T(2)-T(1)),...
':','LineWidth',2,'DisplayName','KSO #4')
hold off
xlim(TDDFT.outIonization.time([1 end]))
xlabel('time (a.u.)')
ylabel('variation (a.u.)')
title('Ionization rate')
legend show
We use an installable output function of the one-body density to store the spin density, down-sampled and over a reduced domain, to illustrate how this feature can be used as an alternative to storing the entire one-body density. We also use an installable output function of the Kohn-Sham orbitals to follow the current density in the TDDFT dynamics. Here we consider a spin-polarized molecular model in which we introduce a localized ionization. First, we define the DFT model and compute the (neutral) ground-state configuration
% Molecular model
Va_1 = QMol_Va_softCoulomb('atom','X','charge',2,'position',-3);
Va_2 = QMol_Va_softCoulomb('atom','A','charge',2,'position', 0);
Va_3 = QMol_Va_softCoulomb('atom','A','charge',2,'position', 3);
% DFT model
Vext = QMol_DFT_Vext('atom',{Va_1,Va_2,Va_3});
Vh = QMol_DFT_Vh_conv;
Vxc = {QMol_DFT_Vx_LDA_soft,QMol_DFT_Vc_LDA_soft};
DFT = QMol_DFT_spinPol( ...
'xspan', -50:.1:50, ... small prime factors
'occupation', {[1 1 1],[1 1 1]}, ...
'externalPotential', Vext, ...
'HartreePotential', Vh, ...
'exchangeCorrelationPotential', Vxc, ...
'selfInteractionCOrrection', 'ADSIC' );
% DFT ground state
SCF = QMol_DFT_SCF_Anderson;
SCF.solveSCF(DFT);
Next, we alter the electronic structure to emulate the localized ionization (by mixing the highest two orbitals in the down-spin channel), define the output function handles and propagate the TDDFT dynamics using the Forest-Ruth symplectic split-operator scheme
% Remove core orbital
DFT.orbital.set('orbitalDown',[DFT.KSO.KSOdw(:,1) (DFT.KSO.KSOdw(:,2)+DFT.KSO.KSOdw(:,3))/sqrt(2)]);
DFT.set('occupation',{[1 1 1],[1 1]});
% Installable output functions
ind = DFT.disc.x >= -15 & DFT.disc.x <= 15 & mod(1:numel(DFT.disc.x),2) == 1; % 1/2 grid points between -15 and 15
funRho = @(rho,t) rho.densityUp(ind) - rho.densityDown(ind);
funKSO = @(KSO,t) real(-1i*conj(KSO.KSOup(:,1)).*ifft(DFT.disc.D.*fft(KSO.KSOup(:,1)))) * DFT.occ{1}(1) + ...
real(-1i*conj(KSO.KSOup(:,2)).*ifft(DFT.disc.D.*fft(KSO.KSOup(:,2)))) * DFT.occ{1}(2) + ...
real(-1i*conj(KSO.KSOup(:,3)).*ifft(DFT.disc.D.*fft(KSO.KSOup(:,3)))) * DFT.occ{1}(3) + ...
real(-1i*conj(KSO.KSOdw(:,1)).*ifft(DFT.disc.D.*fft(KSO.KSOdw(:,1)))) * DFT.occ{2}(1) + ...
real(-1i*conj(KSO.KSOdw(:,2)).*ifft(DFT.disc.D.*fft(KSO.KSOdw(:,2)))) * DFT.occ{2}(2);
% TDDFT propagator
ABC = QMol_TDDFT_abs_CAP('length',20);
TDDFT = QMol_TDDFT_SSO_4FR( ...
'time', 0:10:100, ...
'timeStep', 2e-2, ...
'saveOutputFunctionDensity', funRho, ...
'saveOutputFunctionDensityTime', 1, ... save spin density every 1 a.u.
'saveOutputFunctionOrbital', funKSO, ...
'saveOutputFunctionOrbitalTime', 1, ... save current every 2 a.u.
'absorbingBoundary', ABC);
TDDFT.propagate(DFT);
With this, we can plot the results of the installable output functions
% Plot results
figure
subplot(2,1,1), hold on
imagesc(TDDFT.outOutputFunctionDensity.time,DFT.x(ind),TDDFT.outOutputFunctionDensity.result)
hold off
xlim(TDDFT.outOutputFunctionDensity.time([1 end]))
ylim([-10 10])
xlabel('time (a.u.)')
ylabel('position (a.u.)')
title('spin density')
colorbar vert
subplot(2,1,2), hold on
imagesc(TDDFT.outOutputFunctionOrbital.time,DFT.x,TDDFT.outOutputFunctionOrbital.result)
hold off
xlim(TDDFT.outOutputFunctionOrbital.time([1 end]))
ylim([-10 10])
xlabel('time (a.u.)')
ylabel('position (a.u.)')
title('current density')
colorbar vert
The QMol_TDDFT
abstract class defines the common interface and run-time documentation for TDDFT propagators -- see its documentation page for details on how to implement new TDDFT propagators.
[Kohn 1965] W. Kohn and L.J. Sham, "Self-Consistent Equations Including Exchange and Correlation Effects," Physical Review 140, A1133 (1965).
[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).
[Runge 1984] E. Runge and E.K.U. Gross, "Density-functional theory for time-dependent systems," Physical Review Letters 52, 997 (1984).
The results displayed in this documentation page were generated using version 01.21 of the QMol-grid package.
This wiki is a copy of the documentation provided with the QMol-grid package (accessible in MATLAB documentation, via the "Supplemental Software" section).
Copyright © 2024, Francois Mauger, all right reserved.
Density-functional theory (DFT)
QMol_DFT_density
QMol_DFT_eigs
QMol_DFT_eig_basis
QMol_DFT_orbital
QMol_DFT_orbital_basis
QMol_DFT_profiler
QMol_DFT_SCF_Anderson
QMol_DFT_spinPol
QMol_DFT_spinRes
QMol_DFT_Vc_LDA_soft
QMol_DFT_Vext
QMol_DFT_Vh_conv
QMol_DFT_Vh_fft
QMol_DFT_Vks
QMol_DFT_Vks_basis
QMol_DFT_Vks_grad
QMol_DFT_Vx_LDA_exp
QMol_DFT_Vx_LDA_soft
QMol_DFT_Vx_XX_conv
QMol_DFT_Vx_XX_fft
Tutorials
- Tutorial 1: Schrödinger-equation ground state
- Tutorial 2: Schrödinger-equation input and output
- Tutorial 3: Time-dependent Schrödinger equation
- Tutorial 4: Time-dependent Schrödinger-equation input and output
- Tutorial 5: Density-functional theory ground state
- Tutorial 6: Time-dependent density-functional theory
- Tutorial 7: Time-dependent density-functional theory input and output