wavepacket 0.4.0__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wavepacket-0.4.0 → wavepacket-0.4.1}/CHANGELOG.rst +22 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/LICENSE +1 -1
- {wavepacket-0.4.0 → wavepacket-0.4.1}/PKG-INFO +1 -1
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/conf.py +1 -1
- {wavepacket-0.4.0 → wavepacket-0.4.1}/pyproject.toml +1 -1
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/__init__.py +1 -1
- wavepacket-0.4.1/src/wavepacket/logging.py +54 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/plot/plot_1d.py +1 -1
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/special/pulse_shapes.py +1 -1
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/state_utilities.py +3 -1
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/special/test_pulse_shapes.py +2 -2
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/test_state_utilities.py +8 -2
- wavepacket-0.4.1/test_acceptance/readme +7 -0
- wavepacket-0.4.1/test_acceptance/test_1d_absorbing_boundaries.txt +75 -0
- wavepacket-0.4.1/test_acceptance/test_2d_harmonic_oscillator.txt +65 -0
- wavepacket-0.4.1/test_acceptance/test_laser_pulse_with_density_operator.txt +161 -0
- wavepacket-0.4.1/test_acceptance/test_relaxation.txt +37 -0
- wavepacket-0.4.1/test_acceptance/test_tise.txt +49 -0
- wavepacket-0.4.0/src/wavepacket/logging.py +0 -39
- {wavepacket-0.4.0 → wavepacket-0.4.1}/README.rst +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/Makefile +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/advanced/ode_solvers.md +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/advanced/pendular_states.md +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/advanced/plane_wave_grid.md +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/advanced/polynomial_solvers.md +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/advanced/thermal_states.md +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/architecture.rst +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/index.rst +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/license.rst +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/license.txt +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/make.bat +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/representations.rst +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/requirements.txt +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/tutorials/chebychev_solvers.md +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/tutorials/eigenstates.md +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/tutorials/plotting.md +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/tutorials/relaxation.md +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/doc/tutorials/schroedinger_cat.md +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/builder/__init__.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/builder/density.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/builder/wave_function.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/exceptions.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/expression/__init__.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/expression/expressionbase.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/expression/liouvillian.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/expression/schroedingerequation.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/grid/__init__.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/grid/_utils.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/grid/dofbase.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/grid/grid.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/grid/planewavedof.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/grid/spherical_harmonics_dof.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/grid/state.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/operator/__init__.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/operator/_clipping.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/operator/fbroperators.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/operator/misc_operators.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/operator/operatorbase.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/operator/potentials.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/operator/time_dependent_operators.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/operator_utils.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/plot/__init__.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/plot/_utilities.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/plot/plot_2d.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/py.typed +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/solver/__init__.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/solver/chebychev.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/solver/odesolver.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/solver/solverbase.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/special/__init__.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/special/generators.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/testing/__init__.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/testing/assertions.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/testing/dummydof.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/testing/dummyoperator.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/testing/random.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/typing/__init__.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/src/wavepacket/typing/data_types.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/builder/test_density.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/builder/test_product_wave_function.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/builder/test_wave_function.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/conftest.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/expression/test_expression_sum.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/expression/test_liouvillian.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/expression/test_schroedingerequation.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/grid/test_dofbase.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/grid/test_grid.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/grid/test_planewavedof_basics.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/grid/test_planewavedof_transformations.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/grid/test_sphericalharmonicsdof_basics.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/grid/test_sphericalharmonicsdof_transformations.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/grid/test_state.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/operator/test_clipping.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/operator/test_fbroperators.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/operator/test_misc_operators.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/operator/test_operator_arithmetic.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/operator/test_operatorbase.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/operator/test_planewavefbroperator.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/operator/test_potential1d.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/operator/test_time_dependent_operators.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/solver/test_chebychev.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/solver/test_odesolver.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/solver/test_solverbase.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/special/test_generators.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/test_base_exports.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/test_logging.py +0 -0
- {wavepacket-0.4.0 → wavepacket-0.4.1}/test/test_operator_utilities.py +0 -0
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
ChangeLog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
0.4.1
|
|
6
|
+
-----
|
|
7
|
+
|
|
8
|
+
Minor changes:
|
|
9
|
+
|
|
10
|
+
- (#56) Added acceptance / regression tests, also for CI
|
|
11
|
+
|
|
12
|
+
Bug fixes:
|
|
13
|
+
|
|
14
|
+
- The SinSquare function had an incorrect implementation without the "square" part
|
|
15
|
+
|
|
16
|
+
- population() could return complex values for density operators.
|
|
17
|
+
The imaginary part was negligible, but the type was still wrong.
|
|
18
|
+
The return values are also no longer (negligible) negative values.
|
|
19
|
+
|
|
20
|
+
- log() calculated <x> only for the first degree of freedom,
|
|
21
|
+
and reported it for all other degrees of freedom as well.
|
|
22
|
+
Also, fixed a typo in the output.
|
|
23
|
+
|
|
24
|
+
- Stacked1DPlot threw an exception if you exceeded the number of plots.
|
|
25
|
+
It now overwrites the last plot as it is documented.
|
|
26
|
+
|
|
5
27
|
0.4
|
|
6
28
|
---
|
|
7
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wavepacket
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: A package for solving Schrödinger and Liouville von Neumann equations.
|
|
5
5
|
Keywords: wave packet,quantum simulation,quantum system,DVR,Schroedinger equation,Liouville von Neumann equation,open systems,wave function,density operator,Liouvillian
|
|
6
6
|
Author: Ulf Lorenz
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
project = "Wavepacket"
|
|
10
10
|
copyright = "2024-%Y, Ulf Lorenz"
|
|
11
11
|
author = "Ulf Lorenz"
|
|
12
|
-
release = "0.4"
|
|
12
|
+
release = "0.4.1"
|
|
13
13
|
|
|
14
14
|
# -- General configuration ---------------------------------------------------
|
|
15
15
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
|
@@ -98,7 +98,7 @@ env_list = ["py311", "py312", "py313", "py314", "py311-min", "py312-min", "py313
|
|
|
98
98
|
description = "Run unit tests under {python_base}; Standard environments like py313 implicitly inherit this."
|
|
99
99
|
set_env = { "PIP_ONLY_BINARY" = ":all:" }
|
|
100
100
|
dependency_groups = ["test"]
|
|
101
|
-
commands = [["pytest", "test"]]
|
|
101
|
+
commands = [["pytest", "test", "test_acceptance"]]
|
|
102
102
|
|
|
103
103
|
[tool.tox.env.py311-min]
|
|
104
104
|
dependency_groups = ["minimum_dependencies", "test"]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
import wavepacket as wp
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def _truncate(value: float, truncation: float | None) -> float:
|
|
7
|
+
if truncation is None or abs(value) >= truncation:
|
|
8
|
+
return value
|
|
9
|
+
else:
|
|
10
|
+
return 0.0
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def log(
|
|
14
|
+
t: float, state: wp.grid.State, precision: int = 6, truncate: float | None = None
|
|
15
|
+
) -> None:
|
|
16
|
+
"""
|
|
17
|
+
Prints some data about the state for inspection.
|
|
18
|
+
|
|
19
|
+
The idea is that you call this function during every solver step and get
|
|
20
|
+
a log with the most important values about the propagation, for example
|
|
21
|
+
the state trace (if it deviates from one, this may be caused by poor convergence).
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
t : float
|
|
26
|
+
The time at which you log.
|
|
27
|
+
state : wp.grid.State
|
|
28
|
+
The state to log.
|
|
29
|
+
precision : int, default=6
|
|
30
|
+
How many decimal places should be printed.
|
|
31
|
+
truncate: float | None, default=None
|
|
32
|
+
If set, set all calculated values smaller than this boundary to zero.
|
|
33
|
+
The main use case is for tests; values that are approximately zero can
|
|
34
|
+
differ in their actual value based on numpy version etc. This causes
|
|
35
|
+
regression tests to fail for uninteresting reasons.
|
|
36
|
+
"""
|
|
37
|
+
print(
|
|
38
|
+
f"\n-----------------------------------------------\n"
|
|
39
|
+
f"t = {float(t):.{precision}}, trace = {wp.trace(state):.{precision}}\n"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
normalized_state = wp.normalize(state)
|
|
43
|
+
for index, dof in enumerate(state.grid.dofs):
|
|
44
|
+
x = wp.operator.Potential1D(state.grid, index, lambda dvr_grid: dvr_grid)
|
|
45
|
+
|
|
46
|
+
x_val = wp.expectation_value(x, normalized_state).real
|
|
47
|
+
x2_val = wp.expectation_value(x * x, normalized_state).real
|
|
48
|
+
|
|
49
|
+
x_avg = _truncate(x_val, truncate)
|
|
50
|
+
dx = _truncate(math.sqrt(x2_val - x_avg**2), truncate)
|
|
51
|
+
|
|
52
|
+
# In exotic cases, the error dx**2 can become negative, so we trade
|
|
53
|
+
# correctness for robustness here by taking its absolute value.
|
|
54
|
+
print(f"<x_{index}> = {x_avg:.{precision}} +/- {dx:.{precision}}")
|
|
@@ -227,7 +227,7 @@ class StackedPlot1D(BasePlot1D):
|
|
|
227
227
|
|
|
228
228
|
def plot(self, t: float, state: wp.grid.State) -> plt.Axes:
|
|
229
229
|
axes: plt.Axes = self._axes.flat[self._index]
|
|
230
|
-
self._index = min(self._index + 1, self._axes.size)
|
|
230
|
+
self._index = min(self._index + 1, self._axes.size - 1)
|
|
231
231
|
|
|
232
232
|
super()._plot(axes, t, state)
|
|
233
233
|
|
|
@@ -324,6 +324,8 @@ def population(state: wp.grid.State, target: wp.grid.State) -> float:
|
|
|
324
324
|
matrix_form = np.reshape(state.data, [state.grid.size, state.grid.size])
|
|
325
325
|
flat_target = np.ravel(target.data)
|
|
326
326
|
left_summation = np.tensordot(np.conj(flat_target), matrix_form, axes=(0, 0))
|
|
327
|
-
return np.
|
|
327
|
+
return np.abs(
|
|
328
|
+
np.tensordot(left_summation, flat_target, axes=(0, 0)).sum() / target_trace
|
|
329
|
+
)
|
|
328
330
|
else:
|
|
329
331
|
raise wp.BadStateError("Input is not a valid state.")
|
|
@@ -18,9 +18,9 @@ def test_sin_square_values():
|
|
|
18
18
|
functor = wp.special.SinSquare(5.0, 2.0)
|
|
19
19
|
|
|
20
20
|
assert functor(2.9) == 0
|
|
21
|
-
assert_allclose(functor(4),
|
|
21
|
+
assert_allclose(functor(4), 0.5, rtol=0, atol=1e-12)
|
|
22
22
|
assert functor(5) == 1
|
|
23
|
-
assert_allclose(functor(6),
|
|
23
|
+
assert_allclose(functor(6), 0.5, rtol=0, atol=1e-12)
|
|
24
24
|
assert functor(7.1) == 0
|
|
25
25
|
|
|
26
26
|
|
|
@@ -52,6 +52,7 @@ def test_wave_function_dvr_density():
|
|
|
52
52
|
dx = 1 / 3.0 * 2 / 5.0
|
|
53
53
|
expected = np.abs(psi.data**2) / dx
|
|
54
54
|
assert_allclose(result, expected, atol=1e-14, rtol=0)
|
|
55
|
+
assert_allclose(np.imag(result), 0, atol=0, rtol=0)
|
|
55
56
|
|
|
56
57
|
|
|
57
58
|
def test_density_operator_dvr_density(grid_2d):
|
|
@@ -62,6 +63,7 @@ def test_density_operator_dvr_density(grid_2d):
|
|
|
62
63
|
density_from_rho = wp.dvr_density(rho)
|
|
63
64
|
|
|
64
65
|
assert_allclose(density_from_rho, density_from_psi, atol=1e-14, rtol=0)
|
|
66
|
+
assert_allclose(np.imag(density_from_rho), 0, atol=0, rtol=0)
|
|
65
67
|
|
|
66
68
|
|
|
67
69
|
def test_wave_function_fbr_density():
|
|
@@ -76,6 +78,7 @@ def test_wave_function_fbr_density():
|
|
|
76
78
|
expected = np.zeros(grid.shape)
|
|
77
79
|
expected[5 - 2, 7 - 5] = 4
|
|
78
80
|
assert_allclose(expected, density, rtol=0, atol=1e-12)
|
|
81
|
+
assert_allclose(0, np.imag(density), rtol=0, atol=0)
|
|
79
82
|
|
|
80
83
|
|
|
81
84
|
def test_density_operator_fbr_density(grid_2d):
|
|
@@ -86,6 +89,7 @@ def test_density_operator_fbr_density(grid_2d):
|
|
|
86
89
|
density_from_rho = wp.fbr_density(rho)
|
|
87
90
|
|
|
88
91
|
assert_allclose(density_from_psi, density_from_rho, rtol=0, atol=1e-12)
|
|
92
|
+
assert_allclose(0, np.imag(density_from_rho), rtol=0, atol=0)
|
|
89
93
|
|
|
90
94
|
|
|
91
95
|
def test_reduced_dvr_and_fbr_density(grid_2d):
|
|
@@ -136,6 +140,7 @@ def test_trace():
|
|
|
136
140
|
rho = wp.builder.pure_density(psi)
|
|
137
141
|
result_rho = wp.trace(rho)
|
|
138
142
|
assert_allclose(result_rho, result, atol=1e-12, rtol=0)
|
|
143
|
+
assert_allclose(result_rho.imag, 0, atol=0, rtol=0)
|
|
139
144
|
|
|
140
145
|
|
|
141
146
|
def test_normalize(grid_1d):
|
|
@@ -236,7 +241,7 @@ def test_population(grid_2d):
|
|
|
236
241
|
a, target = (states[0], states[1])
|
|
237
242
|
|
|
238
243
|
# create a state that triggers a complex scalar product to check for abs()
|
|
239
|
-
psi =
|
|
244
|
+
psi = 2j * a + 0.7 * target * np.sqrt(1j)
|
|
240
245
|
rho = wp.builder.pure_density(psi)
|
|
241
246
|
expected = 0.7**2
|
|
242
247
|
|
|
@@ -245,13 +250,14 @@ def test_population(grid_2d):
|
|
|
245
250
|
|
|
246
251
|
rho_projection = wp.population(rho, target)
|
|
247
252
|
assert_allclose(rho_projection, expected, rtol=0, atol=1e-12)
|
|
253
|
+
assert_allclose(rho_projection.imag, 0, rtol=0, atol=0)
|
|
248
254
|
|
|
249
255
|
|
|
250
256
|
def test_normalize_population_target(grid_2d):
|
|
251
257
|
target = wp.testing.random_state(grid_2d, 1)
|
|
252
258
|
target /= math.sqrt(wp.trace(target))
|
|
253
259
|
|
|
254
|
-
psi = 0.
|
|
260
|
+
psi = 0.7j * target * np.sqrt(1j)
|
|
255
261
|
rho = wp.builder.pure_density(psi)
|
|
256
262
|
expected = 0.7**2
|
|
257
263
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
The tests here verify the correctness on a higher level than the unit tests in test/.
|
|
2
|
+
Thy are meant to catch issues in code that is difficult to unit-test (e.g., logging output),
|
|
3
|
+
and to catch invalid unit tests.
|
|
4
|
+
Because the tests are full-fledged simulations and sometimes do unusual things,
|
|
5
|
+
they can also serve as additional examples, but that is not the primary focus here.
|
|
6
|
+
|
|
7
|
+
Because results are not meant to change at all, most if not all tests are regression tests.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
>>> import numpy as np
|
|
2
|
+
>>> import wavepacket as wp
|
|
3
|
+
>>>
|
|
4
|
+
>>> dof = wp.grid.PlaneWaveDof(-10, 20, 96)
|
|
5
|
+
>>> grid = wp.grid.Grid(dof)
|
|
6
|
+
>>>
|
|
7
|
+
>>> def absorbing_boundary(x):
|
|
8
|
+
... potential = -10j * (x - 12.0) ** 2 / (20 - 12.0) ** 2
|
|
9
|
+
... potential[x < 12] = 0
|
|
10
|
+
... return potential
|
|
11
|
+
>>>
|
|
12
|
+
>>> kinetic = wp.operator.CartesianKineticEnergy(grid, 0, mass=1)
|
|
13
|
+
>>> absorber = wp.operator.Potential1D(grid, 0, absorbing_boundary)
|
|
14
|
+
>>> equation = wp.expression.SchroedingerEquation(kinetic + absorber)
|
|
15
|
+
>>>
|
|
16
|
+
>>> psi0 = wp.builder.product_wave_function(grid, wp.special.Gaussian(-5, 2, rms=1))
|
|
17
|
+
>>> solver = wp.solver.OdeSolver(equation, 1)
|
|
18
|
+
>>>
|
|
19
|
+
>>> for t, psi in solver.propagate(psi0, 0.0, 10):
|
|
20
|
+
... wp.log(t, psi, precision=4, truncate=1e-10)
|
|
21
|
+
<BLANKLINE>
|
|
22
|
+
-----------------------------------------------
|
|
23
|
+
t = 0.0, trace = 1.0
|
|
24
|
+
<BLANKLINE>
|
|
25
|
+
<x_0> = -5.0 +/- 0.7071
|
|
26
|
+
<BLANKLINE>
|
|
27
|
+
-----------------------------------------------
|
|
28
|
+
t = 1.0, trace = 1.0
|
|
29
|
+
<BLANKLINE>
|
|
30
|
+
<x_0> = -3.0 +/- 1.0
|
|
31
|
+
<BLANKLINE>
|
|
32
|
+
-----------------------------------------------
|
|
33
|
+
t = 2.0, trace = 1.0
|
|
34
|
+
<BLANKLINE>
|
|
35
|
+
<x_0> = -1.0 +/- 1.581
|
|
36
|
+
<BLANKLINE>
|
|
37
|
+
-----------------------------------------------
|
|
38
|
+
t = 3.0, trace = 1.0
|
|
39
|
+
<BLANKLINE>
|
|
40
|
+
<x_0> = 1.0 +/- 2.236
|
|
41
|
+
<BLANKLINE>
|
|
42
|
+
-----------------------------------------------
|
|
43
|
+
t = 4.0, trace = 0.9999
|
|
44
|
+
<BLANKLINE>
|
|
45
|
+
<x_0> = 2.999 +/- 2.914
|
|
46
|
+
<BLANKLINE>
|
|
47
|
+
-----------------------------------------------
|
|
48
|
+
t = 5.0, trace = 0.996
|
|
49
|
+
<BLANKLINE>
|
|
50
|
+
<x_0> = 4.959 +/- 3.552
|
|
51
|
+
<BLANKLINE>
|
|
52
|
+
-----------------------------------------------
|
|
53
|
+
t = 6.0, trace = 0.9615
|
|
54
|
+
<BLANKLINE>
|
|
55
|
+
<x_0> = 6.637 +/- 3.959
|
|
56
|
+
<BLANKLINE>
|
|
57
|
+
-----------------------------------------------
|
|
58
|
+
t = 7.0, trace = 0.8678
|
|
59
|
+
<BLANKLINE>
|
|
60
|
+
<x_0> = 7.791 +/- 4.111
|
|
61
|
+
<BLANKLINE>
|
|
62
|
+
-----------------------------------------------
|
|
63
|
+
t = 8.0, trace = 0.7319
|
|
64
|
+
<BLANKLINE>
|
|
65
|
+
<x_0> = 8.47 +/- 4.154
|
|
66
|
+
<BLANKLINE>
|
|
67
|
+
-----------------------------------------------
|
|
68
|
+
t = 9.0, trace = 0.5905
|
|
69
|
+
<BLANKLINE>
|
|
70
|
+
<x_0> = 8.83 +/- 4.18
|
|
71
|
+
<BLANKLINE>
|
|
72
|
+
-----------------------------------------------
|
|
73
|
+
t = 10.0, trace = 0.4666
|
|
74
|
+
<BLANKLINE>
|
|
75
|
+
<x_0> = 8.994 +/- 4.221
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
>>> import math
|
|
2
|
+
>>> import wavepacket as wp
|
|
3
|
+
>>>
|
|
4
|
+
>>> dof = wp.grid.PlaneWaveDof(-10, 10, 96)
|
|
5
|
+
>>> grid = wp.grid.Grid([dof, dof])
|
|
6
|
+
>>>
|
|
7
|
+
>>> kin_args = {"mass": 1, "cutoff": 40}
|
|
8
|
+
>>> pot_args = {"generator": lambda x: 0.5 * x**2, "cutoff": 40}
|
|
9
|
+
>>> T_0 = wp.operator.CartesianKineticEnergy(grid, 0, **kin_args)
|
|
10
|
+
>>> T_1 = wp.operator.CartesianKineticEnergy(grid, 1, **kin_args)
|
|
11
|
+
>>> V_0 = wp.operator.Potential1D(grid, 0, **pot_args)
|
|
12
|
+
>>> V_1 = wp.operator.Potential1D(grid, 1, **pot_args)
|
|
13
|
+
>>> hamiltonian = T_0 + T_1 + V_0 + V_1
|
|
14
|
+
>>> equation = wp.expression.SchroedingerEquation(hamiltonian)
|
|
15
|
+
>>>
|
|
16
|
+
>>> psi0 = wp.builder.product_wave_function(
|
|
17
|
+
... grid, [wp.special.Gaussian(-5, 0, rms=1), wp.special.Gaussian(0, 5, rms=1)]
|
|
18
|
+
... )
|
|
19
|
+
>>> solver = wp.solver.ChebychevSolver(equation, math.pi / 3, (0, 160))
|
|
20
|
+
>>>
|
|
21
|
+
>>> for t, psi in solver.propagate(psi0, 0.0, 6):
|
|
22
|
+
... wp.log(t, psi, precision=4, truncate=1e-10)
|
|
23
|
+
<BLANKLINE>
|
|
24
|
+
-----------------------------------------------
|
|
25
|
+
t = 0.0, trace = 1.0
|
|
26
|
+
<BLANKLINE>
|
|
27
|
+
<x_0> = -5.0 +/- 0.7071
|
|
28
|
+
<x_1> = 0.0 +/- 0.7071
|
|
29
|
+
<BLANKLINE>
|
|
30
|
+
-----------------------------------------------
|
|
31
|
+
t = 1.047, trace = 1.0
|
|
32
|
+
<BLANKLINE>
|
|
33
|
+
<x_0> = -2.5 +/- 0.7071
|
|
34
|
+
<x_1> = 4.33 +/- 0.7071
|
|
35
|
+
<BLANKLINE>
|
|
36
|
+
-----------------------------------------------
|
|
37
|
+
t = 2.094, trace = 1.0
|
|
38
|
+
<BLANKLINE>
|
|
39
|
+
<x_0> = 2.5 +/- 0.7071
|
|
40
|
+
<x_1> = 4.33 +/- 0.7071
|
|
41
|
+
<BLANKLINE>
|
|
42
|
+
-----------------------------------------------
|
|
43
|
+
t = 3.142, trace = 1.0
|
|
44
|
+
<BLANKLINE>
|
|
45
|
+
<x_0> = 5.0 +/- 0.7071
|
|
46
|
+
<x_1> = 1.077e-07 +/- 0.7071
|
|
47
|
+
<BLANKLINE>
|
|
48
|
+
-----------------------------------------------
|
|
49
|
+
t = 4.189, trace = 1.0
|
|
50
|
+
<BLANKLINE>
|
|
51
|
+
<x_0> = 2.5 +/- 0.7071
|
|
52
|
+
<x_1> = -4.33 +/- 0.7071
|
|
53
|
+
<BLANKLINE>
|
|
54
|
+
-----------------------------------------------
|
|
55
|
+
t = 5.236, trace = 1.0
|
|
56
|
+
<BLANKLINE>
|
|
57
|
+
<x_0> = -2.5 +/- 0.7071
|
|
58
|
+
<x_1> = -4.33 +/- 0.7071
|
|
59
|
+
<BLANKLINE>
|
|
60
|
+
-----------------------------------------------
|
|
61
|
+
t = 6.283, trace = 1.0
|
|
62
|
+
<BLANKLINE>
|
|
63
|
+
<x_0> = -5.0 +/- 0.7071
|
|
64
|
+
<x_1> = -2.187e-07 +/- 0.7071
|
|
65
|
+
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Note:
|
|
2
|
+
|
|
3
|
+
* It is not required to use a density operator here; in fact, doing so
|
|
4
|
+
slows down the calculation by a factor of ~10; however, we have no
|
|
5
|
+
other complex test of density operators right now.
|
|
6
|
+
* For a proper calculation, the time evolution should have 20 steps,
|
|
7
|
+
which is the length of the laser pulse. We truncate because
|
|
8
|
+
using a density operator is rather expensive.
|
|
9
|
+
|
|
10
|
+
>>> import numpy as np
|
|
11
|
+
>>> import wavepacket as wp
|
|
12
|
+
>>>
|
|
13
|
+
>>> unit_amu = 1e-3 / 9.10938215E-31 / 6.0221408E23
|
|
14
|
+
>>> unit_angstroem = 1.88973
|
|
15
|
+
>>> unit_debye = 1e10 / 1.60217662E-19 * 1e-21 / 299792458
|
|
16
|
+
>>> unit_mv_per_cm = 0.000194469
|
|
17
|
+
>>> unit_fs = 41.3414
|
|
18
|
+
>>> unit_inv_cm = 4.55634e-06
|
|
19
|
+
>>>
|
|
20
|
+
>>> def morse_potential(x):
|
|
21
|
+
... return 0.1994 * (1 - np.exp(-1.189 * (x - 1.821))) ** 2
|
|
22
|
+
>>>
|
|
23
|
+
>>> def mecke_dipole(x):
|
|
24
|
+
... q0 = 7.85 * unit_debye
|
|
25
|
+
... r0 = 0.6 * unit_angstroem
|
|
26
|
+
... return q0 * x * np.exp(-x / r0)
|
|
27
|
+
>>>
|
|
28
|
+
>>> mass_H1 = 1.0078250 * unit_amu
|
|
29
|
+
>>> mass_O16 = 15.994915 * unit_amu
|
|
30
|
+
>>> mu = mass_H1 * mass_O16 / (mass_H1 + mass_O16)
|
|
31
|
+
>>>
|
|
32
|
+
>>> dof = wp.grid.PlaneWaveDof(0.7, 8, 64)
|
|
33
|
+
>>> grid = wp.grid.Grid(dof)
|
|
34
|
+
>>>
|
|
35
|
+
>>> kinetic = wp.operator.CartesianKineticEnergy(grid, 0, mass=mu, cutoff=0.3)
|
|
36
|
+
>>> potential = wp.operator.Potential1D(grid, 0, morse_potential, cutoff=0.3)
|
|
37
|
+
>>> dipole = wp.operator.Potential1D(grid, 0, mecke_dipole)
|
|
38
|
+
>>> laser = wp.operator.LaserField(grid,
|
|
39
|
+
... max_field=328.5 * unit_mv_per_cm,
|
|
40
|
+
... shape=wp.special.SinSquare(500 * unit_fs, 500 * unit_fs),
|
|
41
|
+
... omega=3424.19 * unit_inv_cm)
|
|
42
|
+
>>> equation = wp.expression.CommutatorLiouvillian(kinetic + potential - dipole * laser)
|
|
43
|
+
>>>
|
|
44
|
+
>>> bound_states = [state for energy, state in wp.diagonalize(kinetic + potential) if energy < 0.1994]
|
|
45
|
+
>>>
|
|
46
|
+
>>> psi_0 = wp.builder.product_wave_function(grid, lambda x: bound_states[0].data)
|
|
47
|
+
>>> rho_0 = wp.builder.pure_density(psi_0)
|
|
48
|
+
>>>
|
|
49
|
+
>>> solver = wp.solver.OdeSolver(equation, 50.0 * unit_fs)
|
|
50
|
+
>>> populations = np.zeros((9, 8))
|
|
51
|
+
>>> time_index = 0
|
|
52
|
+
>>> for t, rho in solver.propagate(rho_0, 0.0, 8):
|
|
53
|
+
... for state_index in range(8):
|
|
54
|
+
... populations[time_index, state_index] = wp.population(rho, bound_states[state_index])
|
|
55
|
+
... time_index += 1
|
|
56
|
+
>>>
|
|
57
|
+
>>> populations[np.abs(populations) < 1e-10] = 0
|
|
58
|
+
>>>
|
|
59
|
+
>>> for i in range(7):
|
|
60
|
+
... print(f"\n\nbound state {i}\n\n")
|
|
61
|
+
... for t in range(9):
|
|
62
|
+
... print(f"{t*50*41.341:.4}: {populations[t, i]:.4}")
|
|
63
|
+
<BLANKLINE>
|
|
64
|
+
<BLANKLINE>
|
|
65
|
+
bound state 0
|
|
66
|
+
<BLANKLINE>
|
|
67
|
+
<BLANKLINE>
|
|
68
|
+
0.0: 1.0
|
|
69
|
+
2.067e+03: 0.9999
|
|
70
|
+
4.134e+03: 0.9978
|
|
71
|
+
6.201e+03: 0.9894
|
|
72
|
+
8.268e+03: 0.9662
|
|
73
|
+
1.034e+04: 0.9366
|
|
74
|
+
1.24e+04: 0.8892
|
|
75
|
+
1.447e+04: 0.803
|
|
76
|
+
1.654e+04: 0.705
|
|
77
|
+
<BLANKLINE>
|
|
78
|
+
<BLANKLINE>
|
|
79
|
+
bound state 1
|
|
80
|
+
<BLANKLINE>
|
|
81
|
+
<BLANKLINE>
|
|
82
|
+
0.0: 0.0
|
|
83
|
+
2.067e+03: 0.0001345
|
|
84
|
+
4.134e+03: 0.002225
|
|
85
|
+
6.201e+03: 0.01055
|
|
86
|
+
8.268e+03: 0.03287
|
|
87
|
+
1.034e+04: 0.05944
|
|
88
|
+
1.24e+04: 0.09693
|
|
89
|
+
1.447e+04: 0.1512
|
|
90
|
+
1.654e+04: 0.1706
|
|
91
|
+
<BLANKLINE>
|
|
92
|
+
<BLANKLINE>
|
|
93
|
+
bound state 2
|
|
94
|
+
<BLANKLINE>
|
|
95
|
+
<BLANKLINE>
|
|
96
|
+
0.0: 0.0
|
|
97
|
+
2.067e+03: 3.286e-08
|
|
98
|
+
4.134e+03: 5.724e-06
|
|
99
|
+
6.201e+03: 9.384e-05
|
|
100
|
+
8.268e+03: 0.0009288
|
|
101
|
+
1.034e+04: 0.003546
|
|
102
|
+
1.24e+04: 0.01048
|
|
103
|
+
1.447e+04: 0.02547
|
|
104
|
+
1.654e+04: 0.03777
|
|
105
|
+
<BLANKLINE>
|
|
106
|
+
<BLANKLINE>
|
|
107
|
+
bound state 3
|
|
108
|
+
<BLANKLINE>
|
|
109
|
+
<BLANKLINE>
|
|
110
|
+
0.0: 0.0
|
|
111
|
+
2.067e+03: 0.0
|
|
112
|
+
4.134e+03: 2.451e-08
|
|
113
|
+
6.201e+03: 1.135e-06
|
|
114
|
+
8.268e+03: 4.049e-05
|
|
115
|
+
1.034e+04: 0.0003052
|
|
116
|
+
1.24e+04: 0.001663
|
|
117
|
+
1.447e+04: 0.006138
|
|
118
|
+
1.654e+04: 0.02057
|
|
119
|
+
<BLANKLINE>
|
|
120
|
+
<BLANKLINE>
|
|
121
|
+
bound state 4
|
|
122
|
+
<BLANKLINE>
|
|
123
|
+
<BLANKLINE>
|
|
124
|
+
0.0: 0.0
|
|
125
|
+
2.067e+03: 0.0
|
|
126
|
+
4.134e+03: 1.793e-10
|
|
127
|
+
6.201e+03: 3.112e-08
|
|
128
|
+
8.268e+03: 4.711e-06
|
|
129
|
+
1.034e+04: 4.706e-05
|
|
130
|
+
1.24e+04: 0.0007506
|
|
131
|
+
1.447e+04: 0.006458
|
|
132
|
+
1.654e+04: 0.03295
|
|
133
|
+
<BLANKLINE>
|
|
134
|
+
<BLANKLINE>
|
|
135
|
+
bound state 5
|
|
136
|
+
<BLANKLINE>
|
|
137
|
+
<BLANKLINE>
|
|
138
|
+
0.0: 0.0
|
|
139
|
+
2.067e+03: 0.0
|
|
140
|
+
4.134e+03: 0.0
|
|
141
|
+
6.201e+03: 2.164e-09
|
|
142
|
+
8.268e+03: 1.098e-06
|
|
143
|
+
1.034e+04: 4.586e-05
|
|
144
|
+
1.24e+04: 0.0005787
|
|
145
|
+
1.447e+04: 0.003726
|
|
146
|
+
1.654e+04: 0.01069
|
|
147
|
+
<BLANKLINE>
|
|
148
|
+
<BLANKLINE>
|
|
149
|
+
bound state 6
|
|
150
|
+
<BLANKLINE>
|
|
151
|
+
<BLANKLINE>
|
|
152
|
+
0.0: 0.0
|
|
153
|
+
2.067e+03: 0.0
|
|
154
|
+
4.134e+03: 0.0
|
|
155
|
+
6.201e+03: 0.0
|
|
156
|
+
8.268e+03: 7.184e-08
|
|
157
|
+
1.034e+04: 1.186e-05
|
|
158
|
+
1.24e+04: 0.0003607
|
|
159
|
+
1.447e+04: 0.003443
|
|
160
|
+
1.654e+04: 0.01842
|
|
161
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
>>> import numpy as np
|
|
2
|
+
>>> import wavepacket as wp
|
|
3
|
+
>>>
|
|
4
|
+
>>> dof = wp.grid.PlaneWaveDof(0.7, 8, 96)
|
|
5
|
+
>>> grid = wp.grid.Grid(dof)
|
|
6
|
+
>>>
|
|
7
|
+
>>> def morse_potential(x):
|
|
8
|
+
... return 0.1994 * (1 - np.exp(-1.189 * (x - 1.821))) ** 2
|
|
9
|
+
>>>
|
|
10
|
+
>>> kinetic = wp.operator.CartesianKineticEnergy(grid, 0, mass=1728.539, cutoff=0.3)
|
|
11
|
+
>>> potential = wp.operator.Potential1D(grid, 0, morse_potential, cutoff=0.3)
|
|
12
|
+
>>> hamiltonian = kinetic + potential
|
|
13
|
+
>>>
|
|
14
|
+
>>> bound_states = [state for energy, state in wp.diagonalize(kinetic + potential) if energy < 0.1994]
|
|
15
|
+
>>>
|
|
16
|
+
>>> solver = wp.solver.RelaxationSolver(hamiltonian, 20, (0, 0.6))
|
|
17
|
+
>>> psi0 = wp.builder.product_wave_function(grid, wp.special.Gaussian(2, 0, fwhm=0.5))
|
|
18
|
+
>>>
|
|
19
|
+
>>> relaxed_states = []
|
|
20
|
+
>>> for i in range(5):
|
|
21
|
+
... psi = psi0
|
|
22
|
+
... for step in range(20):
|
|
23
|
+
... psi = solver.step(psi, 0.0)
|
|
24
|
+
... # Trick: the last element is orthogonalized w.r.t. all other elements.
|
|
25
|
+
... # That way, we can orthonormalize psi against all already found states.
|
|
26
|
+
... psi = wp.orthonormalize(relaxed_states + [psi])[-1]
|
|
27
|
+
... relaxed_states.append(psi)
|
|
28
|
+
>>>
|
|
29
|
+
>>> for i in range(5):
|
|
30
|
+
... energy_bound = wp.expectation_value(hamiltonian, bound_states[i]).real
|
|
31
|
+
... energy_relaxed = wp.expectation_value(hamiltonian, relaxed_states[i]).real
|
|
32
|
+
... print(f"State {i}: E_bound = {energy_bound:.6} E_relax = {energy_relaxed:.6}")
|
|
33
|
+
State 0: E_bound = 0.00892781 E_relax = 0.00892781
|
|
34
|
+
State 1: E_bound = 0.02617 E_relax = 0.02617
|
|
35
|
+
State 2: E_bound = 0.0425944 E_relax = 0.0425944
|
|
36
|
+
State 3: E_bound = 0.0582008 E_relax = 0.0582009
|
|
37
|
+
State 4: E_bound = 0.0729895 E_relax = 0.0729896
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
>>> import numpy as np
|
|
2
|
+
>>> import wavepacket as wp
|
|
3
|
+
>>>
|
|
4
|
+
>>> dof = wp.grid.PlaneWaveDof(-7, 7, 96)
|
|
5
|
+
>>> grid = wp.grid.Grid(dof)
|
|
6
|
+
>>>
|
|
7
|
+
>>> def razavy_potential(x):
|
|
8
|
+
... cosh_val = np.cosh(x)
|
|
9
|
+
... return -0.7 * cosh_val + 0.01 * cosh_val ** 2
|
|
10
|
+
>>>
|
|
11
|
+
>>> kinetic = wp.operator.CartesianKineticEnergy(grid, 0, mass=0.5)
|
|
12
|
+
>>> potential = wp.operator.Potential1D(grid, 0, razavy_potential)
|
|
13
|
+
>>> hamiltonian = kinetic + potential
|
|
14
|
+
>>>
|
|
15
|
+
>>> states = [psi for _, psi in wp.diagonalize(hamiltonian)]
|
|
16
|
+
>>>
|
|
17
|
+
>>> for index, psi in enumerate(states[:30]):
|
|
18
|
+
... print(f"{index}: {wp.expectation_value(hamiltonian, psi).real:.4}")
|
|
19
|
+
0: -9.002
|
|
20
|
+
1: -9.002
|
|
21
|
+
2: -4.012
|
|
22
|
+
3: -4.011
|
|
23
|
+
4: -1.16
|
|
24
|
+
5: -0.9569
|
|
25
|
+
6: 0.2135
|
|
26
|
+
7: 1.374
|
|
27
|
+
8: 2.813
|
|
28
|
+
9: 4.463
|
|
29
|
+
10: 6.305
|
|
30
|
+
11: 8.324
|
|
31
|
+
12: 10.51
|
|
32
|
+
13: 12.86
|
|
33
|
+
14: 15.37
|
|
34
|
+
15: 18.03
|
|
35
|
+
16: 20.84
|
|
36
|
+
17: 23.79
|
|
37
|
+
18: 26.88
|
|
38
|
+
19: 30.11
|
|
39
|
+
20: 33.48
|
|
40
|
+
21: 36.99
|
|
41
|
+
22: 40.62
|
|
42
|
+
23: 44.39
|
|
43
|
+
24: 48.28
|
|
44
|
+
25: 52.3
|
|
45
|
+
26: 56.45
|
|
46
|
+
27: 60.72
|
|
47
|
+
28: 65.11
|
|
48
|
+
29: 69.62
|
|
49
|
+
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import math
|
|
2
|
-
|
|
3
|
-
import wavepacket as wp
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def log(t: float, state: wp.grid.State, precision: int = 6) -> None:
|
|
7
|
-
"""
|
|
8
|
-
Prints some data about the state for inspection.
|
|
9
|
-
|
|
10
|
-
The idea is that you call this function during every solver step and get
|
|
11
|
-
a log with the most important values about the propagation, for example
|
|
12
|
-
the state trace (if it deviates from one, this may be caused by poor convergence).
|
|
13
|
-
|
|
14
|
-
Parameters
|
|
15
|
-
----------
|
|
16
|
-
t : float
|
|
17
|
-
The time at which you log.
|
|
18
|
-
state : wp.grid.State
|
|
19
|
-
The state to log.
|
|
20
|
-
precision : int, default=6
|
|
21
|
-
How many decimal places should be printed.
|
|
22
|
-
"""
|
|
23
|
-
print(
|
|
24
|
-
f"\n-----------------------------------------------\n"
|
|
25
|
-
f"t = {float(t):.{precision}}, trace = {wp.trace(state):.{precision}}\n"
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
normalized_state = wp.normalize(state)
|
|
29
|
-
for index, dof in enumerate(state.grid.dofs):
|
|
30
|
-
x = wp.operator.Potential1D(state.grid, 0, lambda dvr_grid: dvr_grid)
|
|
31
|
-
|
|
32
|
-
x_avg = wp.expectation_value(x, normalized_state).real
|
|
33
|
-
x2_avg = wp.expectation_value(x * x, normalized_state).real
|
|
34
|
-
|
|
35
|
-
# In exotic cases, the error dx**2 can become negative, so we trade
|
|
36
|
-
# correctness for robustness here by taking its absolute value.
|
|
37
|
-
print(
|
|
38
|
-
f"<x_{index}> = {x_avg:.{precision}} =/- {math.sqrt(abs(x2_avg - x_avg ** 2)):.{precision}}"
|
|
39
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{wavepacket-0.4.0 → wavepacket-0.4.1}/test/grid/test_sphericalharmonicsdof_transformations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|