parent
1ff5c11866
commit
cccb402d65
|
@ -119,7 +119,7 @@ def kinetic(velocity):
|
||||||
"""
|
"""
|
||||||
Computes the kenetic energy given a systems `velocity` state.
|
Computes the kenetic energy given a systems `velocity` state.
|
||||||
"""
|
"""
|
||||||
return (mass / 2.0) * jnp.linalg.norm(velocity, axis = 1).sum()
|
return (mass / 2.0) * (velocity**2).sum()
|
||||||
|
|
||||||
@jit
|
@jit
|
||||||
def step(position, velocity, acceleration, box_size, step_size):
|
def step(position, velocity, acceleration, box_size, step_size):
|
||||||
|
|
|
@ -99,15 +99,3 @@ if config.verbose:
|
||||||
print( "Final Mean Forces: {:.4e} {:.4e} {:.4e}".format(*final_mean_forces))
|
print( "Final Mean Forces: {:.4e} {:.4e} {:.4e}".format(*final_mean_forces))
|
||||||
print(f"Final Mean ||Forces||: {final_mean_fnorm:.4e}")
|
print(f"Final Mean ||Forces||: {final_mean_fnorm:.4e}")
|
||||||
print(f"Done: saved inital state to '{config.output}'")
|
print(f"Done: saved inital state to '{config.output}'")
|
||||||
|
|
||||||
# # if a plot path is provided
|
|
||||||
# if not config.plot is None:
|
|
||||||
# from mpl_toolkits import mplot3d
|
|
||||||
# import matplotlib.pyplot as plt
|
|
||||||
# # new plot with 3D axis
|
|
||||||
# plt.figure()
|
|
||||||
# ax = plt.axes(projection = "3d")
|
|
||||||
# # create 3D position scatter plot
|
|
||||||
# ax.scatter(position[:, 0], position[:, 1], position[:, 2])
|
|
||||||
# # and save to file
|
|
||||||
# plt.savefig(config.plot)
|
|
||||||
|
|
|
@ -10,6 +10,15 @@ arg_parser = OptionParser(usage = usage)
|
||||||
arg_parser.add_option("-i", "--input", action = "store", type = str,
|
arg_parser.add_option("-i", "--input", action = "store", type = str,
|
||||||
dest = "input", default = None,
|
dest = "input", default = None,
|
||||||
help = "input file path (required!)")
|
help = "input file path (required!)")
|
||||||
|
arg_parser.add_option("-A", "--outputA", action = "store", type = str,
|
||||||
|
dest = "outputA", default = "task04A.txt",
|
||||||
|
help = "first output file path (default: 'task04A.txt')")
|
||||||
|
arg_parser.add_option("-B", "--outputB", action = "store", type = str,
|
||||||
|
dest = "outputB", default = "task04B.txt",
|
||||||
|
help = "second output file path (default: 'task04B.txt')")
|
||||||
|
arg_parser.add_option("-s", "--cdf_sample_count", action = "store", type = int,
|
||||||
|
dest = "cdf_sample_count", default = 5,
|
||||||
|
help = "Radius interval sample count for CDF estimate (default: 5)")
|
||||||
arg_parser.add_option("-a", "--animate", action = "store_true",
|
arg_parser.add_option("-a", "--animate", action = "store_true",
|
||||||
dest = "animate", default = False,
|
dest = "animate", default = False,
|
||||||
help = "creates an trajectory animation of the states in the input file")
|
help = "creates an trajectory animation of the states in the input file")
|
||||||
|
@ -31,36 +40,109 @@ else:
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
### task 3 / trajectory generation ###
|
### task 4 / post processing ###
|
||||||
################################################################################
|
################################################################################
|
||||||
# note, load module _after_ processing script parameters (no need to load all
|
# note, load module _after_ processing script parameters (no need to load all
|
||||||
# of the heavy numeric modules if only usage or alike is needed)
|
# of the heavy numeric modules if only usage or alike is needed)
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
from mpl_toolkits import mplot3d
|
|
||||||
from molecular_dynamics import iter_load, energy, kinetic
|
from molecular_dynamics import iter_load, energy, kinetic
|
||||||
|
|
||||||
if config.animate:
|
|
||||||
# new plot with 3D axis
|
|
||||||
fig = plt.figure()
|
|
||||||
ax = fig.add_subplot(111, projection = "3d")
|
|
||||||
|
|
||||||
count = 0
|
# counte the number of states (system snapshots) in the input file
|
||||||
for (position, velocity), box_size in iter_load(config.input):
|
nr_states = 0
|
||||||
count += 1
|
# first output file and collect some info used in the next analysis!
|
||||||
|
with open(config.outputA, "w") as output:
|
||||||
|
# iterate over all state snapshots stored in the `config.input` file
|
||||||
|
for (position, velocity), box_size in iter_load(config.input):
|
||||||
|
nr_states += 1
|
||||||
|
# compute potneital and kinetic energy for current snapshot
|
||||||
e_pot = energy(position, box_size)
|
e_pot = energy(position, box_size)
|
||||||
e_kin = kinetic(velocity)
|
e_kin = kinetic(velocity)
|
||||||
print(f"{count: >3} - {e_pot:10.5e} {e_kin:10.5e} {(e_pot + e_kin):10.5e}")
|
# energy results
|
||||||
|
print(e_pot, e_kin, file = output)
|
||||||
|
# report file path
|
||||||
|
print(f"Saved energy change to '{config.outputA}'")
|
||||||
|
|
||||||
if config.animate:
|
# CDF radius sample points (`box_size` known from last loop)
|
||||||
ax.cla()
|
radii = np.linspace(0, box_size / 2.0, config.cdf_sample_count)[np.newaxis, :]
|
||||||
plt.title(f"time step {count}")
|
# radius Commulative Distribution Function estimate
|
||||||
plt.xlim([0, box_size])
|
CDF = np.zeros((config.cdf_sample_count, ))
|
||||||
plt.ylim([0, box_size])
|
|
||||||
ax.set_zlim([0, box_size])
|
# extract only one of two distance combinations of non-equal particles
|
||||||
# create 3D position scatter plot
|
lower_tri = np.tril_indices(position.shape[0], k = -1)
|
||||||
position = np.mod(position, box_size)
|
# maximum distance two particles (in folded space) can be apart
|
||||||
ax.scatter(position[:, 0], position[:, 1], position[:, 2])
|
max_dist = box_size / 2.0
|
||||||
# # and save to file
|
|
||||||
# plt.savefig(config.plot)
|
# second iteration to estimate pairwise distance CDF
|
||||||
plt.pause(0.01)
|
for i, ((position, velocity), box_size) in enumerate(iter_load(config.input)):
|
||||||
|
# ignore the first 25% (just keep it simple)
|
||||||
|
if 4 * i < nr_states:
|
||||||
|
continue
|
||||||
|
# magic for all particle pair distances
|
||||||
|
diff = position[:, np.newaxis, :] - position
|
||||||
|
diff = diff[lower_tri[0], lower_tri[1], :]
|
||||||
|
# fold space in all directions. The `max_dist` is the maximum distance
|
||||||
|
# in the folded space untill the distance through the folded space
|
||||||
|
# border is smaller than inside the box. 3-axis parallel fold
|
||||||
|
diff = np.mod(diff + max_dist, box_size) - max_dist
|
||||||
|
# count nr particles pairs with distance smaller than r
|
||||||
|
dist = np.linalg.norm(diff, axis = 1)
|
||||||
|
# accumulate per timepoint partial mean estimates of the CDF
|
||||||
|
CDF += np.mean(dist[:, np.newaxis] < radii, axis = 0)
|
||||||
|
# final division by timesteps as mean over pairs and time.
|
||||||
|
CDF /= nr_states
|
||||||
|
|
||||||
|
# store the CDF estimate to the second file
|
||||||
|
with open(config.outputB, "w") as output:
|
||||||
|
for r, cdf in zip(radii.ravel(), CDF.ravel()):
|
||||||
|
print(r, cdf, file = output)
|
||||||
|
# report file path
|
||||||
|
print(f"Saved radius CDF estimate to '{config.outputB}'")
|
||||||
|
|
||||||
|
|
||||||
|
# import matplotlib.pyplot as plt
|
||||||
|
# from mpl_toolkits import mplot3d
|
||||||
|
|
||||||
|
# if config.animate:
|
||||||
|
# # new plot with 3D axis
|
||||||
|
# count = 0
|
||||||
|
# fig = plt.figure()
|
||||||
|
# ax = fig.add_subplot(111, projection = "3d")
|
||||||
|
|
||||||
|
# for (position, velocity), box_size in iter_load(config.input):
|
||||||
|
# e_pot = energy(position, box_size)
|
||||||
|
# e_kin = kinetic(velocity)
|
||||||
|
# print(f"{e_pot:10.5e} {e_kin:10.5e} {(e_pot + e_kin):10.5e}")
|
||||||
|
|
||||||
|
# if config.animate:
|
||||||
|
# count += 1
|
||||||
|
# ax.cla()
|
||||||
|
# plt.title(f"time step {count}")
|
||||||
|
# plt.xlim([0, box_size])
|
||||||
|
# plt.ylim([0, box_size])
|
||||||
|
# ax.set_zlim([0, box_size])
|
||||||
|
# # create 3D position scatter plot
|
||||||
|
# position = np.mod(position, box_size)
|
||||||
|
# ax.scatter(position[:, 0], position[:, 1], position[:, 2])
|
||||||
|
# # # and save to file
|
||||||
|
# # plt.savefig(config.plot)
|
||||||
|
# plt.pause(0.01)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# import numpy as np
|
||||||
|
# import matplotlib.pyplot as plt
|
||||||
|
# from mpl_toolkits import mplot3d
|
||||||
|
# from molecular_dynamics import load, energy, kinetic
|
||||||
|
|
||||||
|
# (position, velocity), box_size = load("task02.xyz"):
|
||||||
|
|
||||||
|
# fig = plt.figure()
|
||||||
|
# ax = fig.add_subplot(111, projection = "3d")
|
||||||
|
# ax.cla()
|
||||||
|
# plt.xlim([0, box_size])
|
||||||
|
# plt.ylim([0, box_size])
|
||||||
|
# ax.set_zlim([0, box_size])
|
||||||
|
# # create 3D position scatter plot
|
||||||
|
# position = np.mod(position, box_size)
|
||||||
|
# ax.scatter(position[:, 0], position[:, 1], position[:, 2])
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue