Exercise 6
Part of the course Computational Chemistry.
When implementing classical molecular dynamics, computational efficiency is key. We will implement two common tricks to allow for cheaper potentials: the discretization of a function and introducing a cutoff for large distances. Note that real-world implementations are more sophisticated, but work similarly.
Task 6.1: Discretize
Write a class Surface
which can store values for a one-dimensional potential energy surface in arbitrary order. Feed some points into a class instance e.g. by evaluating the Morse potential. Make sure the discretized potential can be queried at arbitrary locations x
where the class should calculate the linear interpolation between the closest two points on either side of x
.
Example:
pes = Surface()
pes.add_point(x=0, y=2)
pes.add_point(x=1, y=1)
pes.add_point(x=4, y=4)
pes.query(x=2) == 2.0
Task 6.2: Interpolate
Write a class SurfaceSwitching
where two surfaces can be combined by interpolating the two linearly within the interval \((A,B)\) where for \(x<A\) only the first surface will be returned and for \(x>B\) only the second surface will be returned.
Example:
switch = SurfaceSwitching(pes1, pes2)
switch.set_region(A, B)
switch.query(A - 1) == pes1.query(A - 1)
switch.query(B + 1) == pes2.query(B + 1)
midpoint = (A + B)/2
switch.query(midpoint) == (pes1.query(midpoint) + pes2.query(midpoint)) / 2
Optional: Can you reduce the interpolation to the same problem as in the first task and re-use the implementation?
Task 6.3: Reduce
Write a function to convert any SurfaceSwitching
instance into a Surface
instance - but without any loss of accuracy! Extend both classes such that you can be sure to not loose any information.