Finite Difference

This module sets up arbitrary order finite difference calculations for an arbitrary number of variables.

Finite difference is used to compute phonons and phonon interactions in PM, and this module isolates all the tasks associated with performing finite difference. Here we give some examples to illustrate the key features.

Let us consider a potential with three variables, labeled 0, 1, 2, and set up all derivatives to second order. Begin by instantiating the class:

>>> from principia_materia.finite_difference.finite_difference_np import FiniteDifferenceNP
>>> fd=FiniteDifferenceNP()

Set all the derivatives to be evaluated:

>>> fd.set_deriv(varset=[[0],[1],[2],[0,1],[0,2],[1,2]],
...              ordset=[[2],[2],[2],[1,1],[1,1],[1,1]])

Set the deltas to be the same for all variables and setup the finite difference amplitudes:

>>> fd.set_delta_global([0.01,0.02])
>>> fd.setup_amplitude()

We now have all the information we need to perform finite difference. For example, all amplitudes associated with a given set of variables is retrieved as:

>>> print (fd.get_var_amplitude([0,2]))
 
[[-0.02 -0.02]
 [-0.02  0.02]
 [-0.01 -0.01]
 [-0.01  0.01]
 [ 0.01 -0.01]
 [ 0.01  0.01]
 [ 0.02 -0.02]
 [ 0.02  0.02]]

In more complicated scenarios, the same amplitudes would appear multiple times, but this class accounts for that when making a final list of amplitudes. Take the following example containing second and fourth derivatives:

>>> fd.set_deriv(varset=[[0,1],[0,1]],
...              ordset=[[1,1],[2,2]])

Inspecting the list of amplitudes for variable [0,1], we see:

>>> print (fd.get_var_amplitude([0,1]))
 
[[-0.02 -0.02]
 [-0.02  0.02]
 [-0.01 -0.01]
 [-0.01  0.01]
 [ 0.01 -0.01]
 [ 0.01  0.01]
 [ 0.02 -0.02]
 [ 0.02  0.02]
 [-0.04 -0.04]
 [-0.04  0.04]
 [ 0.04 -0.04]
 [ 0.04  0.04]]

The same amplitudes are used for both the second and fourth derivatives, and the class is aware of this. Additionally, the fourth derivatives will need cases where one amplitude is zero, which do not appear. In this case, the class creates a new variable sets [0] and [1] that contain these amplitudes. For example,

>>> print (fd.get_var_amplitude([0]))

[[-0.04]
 [-0.02]
 [ 0.02]
 [ 0.04]]

Last modified September 21, 2023: added import statement. (e27c5c0)