Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions hoomd-blue/research/diblock-domain-fission/equi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

import sys
import time
import h5py
import shutil
import numpy as np

import hoomd
hoomd.context.initialize()
import hoomd.hdf5
import hoomd.md


def main(argv):
with hoomd.context.SimulationContext():
system = hoomd.init.read_gsd("start.gsd", time_step=0)

nl = hoomd.md.nlist.tree()
nl.reset_exclusions([])

qr = []
qr += ['temperature','potential_energy','kinetic_energy']
qr += ["pressure_xx","pressure_yy","pressure_zz","pressure_xy","pressure_xz","pressure_yz"]
qr += ["bond_harmonic_energy"]
qr += ["pair_dpd_energy",]

harmonic = hoomd.md.bond.harmonic()
harmonic.bond_coeff.set("backbone", k=16/3, r0=0)

seed = int(time.time())
dpd = hoomd.md.pair.dpd(r_cut=1.0, nlist=nl, seed=seed, kT=1.)
dpd.pair_coeff.set("A", "A", A=5., gamma=1.0)
dpd.pair_coeff.set("A", "B", A=7., gamma=1.0)
dpd.pair_coeff.set("B", "B", A=5., gamma=1.0)

hoomd.md.integrate.nve(group=hoomd.group.all())
hoomd.md.integrate.mode_standard(dt=1e-4)

# writes out trajectory every 1000 MD steps
gsd = hoomd.dump.gsd("equi_trajectory.gsd", group=hoomd.group.all(), period=1000, overwrite=True)

with hoomd.hdf5.File("equi_data.h5", "w") as h5file:
hoomd.hdf5.log(h5file, quantities=qr, period=1000)
hoomd.run(1e6, limit_multiple=10000)
final = hoomd.dump.gsd("equi_final.gsd", group=hoomd.group.all(), period=None, truncate=True, overwrite=True)

# Copy result of equi to preprocess for run.py
Nreplica = 14
for replica_num in range(Nreplica):
shutil.copy("equi_final.gsd",
f"final_{replica_num}.gsd")


if __name__ == "__main__":
main(sys.argv)
6 changes: 6 additions & 0 deletions hoomd-blue/research/diblock-domain-fission/execute.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/bash

python gen_gsd.py
python equi.py
python run.py
python plot_result.py
59 changes: 59 additions & 0 deletions hoomd-blue/research/diblock-domain-fission/gen_gsd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import sys
import numpy as np
import gsd
import gsd.hoomd

class System:

def __init__(self,n,N=256,b0=0.75):
self.L = np.asarray([10, 10, 10])
self.N = N
self.n = n
self.b0 = b0

def main(argv):
if len(argv) != 1:
print("Usage: ./gen_gsd.py")
return

n = 200
system = System(n)

snapshot = gsd.hoomd.Snapshot()

snapshot.configuration.box = np.concatenate((system.L,[0,0,0]))

snapshot.particles.N = system.n * system.N

snapshot.particles.types = ["A", "B"]
snapshot.particles.position = np.zeros( (snapshot.particles.N,3) )
snapshot.particles.velocity = np.random.standard_normal( (snapshot.particles.N,3) )
snapshot.particles.image = np.zeros( (snapshot.particles.N,3),dtype=np.int )
snapshot.particles.typeid = np.zeros( snapshot.particles.N, dtype = np.int )
snapshot.bonds.N = system.n * (system.N-1)
snapshot.bonds.types = ["backbone"]
snapshot.bonds.typeid = np.zeros( snapshot.bonds.N )
snapshot.bonds.group = []

for poly in range(system.n):
mono = 0
snapshot.particles.position[ poly * system.N + mono ] = [0,-system.L[1]/2,0] + np.random.standard_normal(3)*1e-3

for mono in range(1, system.N):
snapshot.particles.position[ poly * system.N +mono] = snapshot.particles.position[poly*system.N + mono-1] + np.random.standard_normal( 3 ) * system.b0/3

snapshot.bonds.group.append( [ poly*system.N+mono-1 , poly*system.N+mono])
if mono > 16:
snapshot.particles.typeid[poly * system.N +mono] = 1

snapshot.particles.image += np.rint(snapshot.particles.position/system.L).astype(np.int64)
snapshot.particles.position -= np.rint(snapshot.particles.position/system.L) * system.L

snapshot.particles.validate()

with gsd.hoomd.open( "start.gsd","wb") as f:
f.append(snapshot)


if __name__ == "__main__":
main(sys.argv)
91 changes: 91 additions & 0 deletions hoomd-blue/research/diblock-domain-fission/plot_result.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/usr/bin/env python
import sys
sys.path.append("..")
import numpy as np
import importlib

from droplet import *
import hoomd
import hoomd.md

import pysages
import pickle
import matplotlib.pyplot as plt

from gyana.plot_util import savefig, plot_data_to_str

def plot_energy(energies, centers, epsilons):
fig, ax = plt.subplots()

ax.set_xlabel(r"distance R $[\sigma]$")
ax.set_ylabel(r"free energy $[\epsilon]$")

# ax.set_ylim((0,850))
ax.set_xlim((0,6))

attachement_string = ""
for i in range(len(energies)):
center = centers[i]
free_energy = energies[i]
free_energy = free_energy
free_energy -= free_energy[0]
epsilon = epsilons[i]
ax.plot(center, free_energy, '.-', label=rf"$\Delta A = {epsilon}$")
attachement_string += plot_data_to_str((center, free_energy), r"$\Delta\epsilon = {epsilon-1}k_BT$")
ax.legend(loc="best")
savefig(fig, attachement_string, "energy.pdf")
plt.close(fig)

# def plot_hist(result, bins=50):
# fig, ax = plt.subplots(2, 2)

# # ax.set_xlabel("CV")
# # ax.set_ylabel("p(CV)")

# counter = 0
# hist_per = len(result["centers"]) // 4 + 1
# for x in range(2):
# for y in range(2):
# for i in range(hist_per):
# if counter + i < len(result["centers"]):
# center = np.asarray(result["centers"][counter + i])
# histo, edges = result["histograms"][counter + i].get_histograms(bins=bins)
# edges = np.asarray(edges)[0]
# edges = (edges[1:] + edges[:-1]) / 2
# ax[x, y].plot(edges, histo, label=f"center {center}")
# ax[x, y].legend(loc="best", fontsize="xx-small")
# ax[x, y].set_yscale("log")
# counter += hist_per
# while counter < len(result["centers"]):
# center = np.asarray(result["centers"][counter])
# histo, edges = result["histograms"][counter].get_histograms(bins=bins)
# edges = np.asarray(edges)[0]
# edges = (edges[1:] + edges[:-1]) / 2
# ax[1, 1].plot(edges, histo, label=f"center {center}")
# counter += 1

# attachement_string = str(result)
# savefig(fig, attachement_string, "hist.pdf")
# plt.close(fig)


def main(argv):
if len(argv) != 0:
print("Usage: ./plot_result.py")
return


deltaAs = [0.1, 0.2, 0.3, 0.4]
centers = []
energies = []
for delta in deltaAs:
with open(f"result_{delta}.pkl", "rb") as pkl_file:
result = pickle.load(pkl_file)
centers.append(np.asarray(result["centers"]))
energies.append(np.asarray(result["free_energy"]))

plot_energy(energies, centers, deltaAs)


if __name__ == "__main__":
main(sys.argv[1:])
116 changes: 116 additions & 0 deletions hoomd-blue/research/diblock-domain-fission/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import sys
import time
import datetime
import h5py
import numpy as np
import importlib

from droplet import *

import hoomd
import hoomd.md

import pysages
from pysages.colvars import Distance
from pysages.methods import UmbrellaIntegration, SerialExecutor

import gsd
import gsd.hoomd

import pickle

def generate_context(**kwargs):
# if kwargs.get("mpi", False):
# MPI = importlib.import_module("mpi4py.MPI")
# init_kwargs = {"mpi_comm": MPI.COMM_SELF}
# else:
# init_kwargs = {}
# hoomd.context.initialize("--single-mpi", **init_kwargs)
hoomd.context.initialize("--single-mpi")

context = hoomd.context.SimulationContext()
with context:
deltaA = kwargs.get("deltaA")
print(f"Operating replica {kwargs.get('replica_num')}: {deltaA}")
system = hoomd.init.read_gsd(f"final_{kwargs.get('replica_num')}.gsd", time_step=0)
box = system.box
nl = hoomd.md.nlist.tree()
nl.reset_exclusions([])

# Note that pysages energies from the bias potential can not be logged from hoomd
qr = []
qr += ['temperature','potential_energy','kinetic_energy']
qr += ["bond_harmonic_energy"]
qr += ["pair_dpd_energy",]

harmonic = hoomd.md.bond.harmonic()
harmonic.bond_coeff.set("backbone", k=16/3, r0=0)

seed = int(time.time()) ^ kwargs.get("replica_num")
dpd = hoomd.md.pair.dpd(r_cut=1.0, nlist=nl, seed=seed, kT=1.)
dpd.pair_coeff.set("A", "A", A=5., gamma=1.0)
dpd.pair_coeff.set("A", "B", A=5.+deltaA, gamma=1.0)
dpd.pair_coeff.set("B", "B", A=5., gamma=1.0)

hoomd.md.integrate.nve(group=hoomd.group.all())
hoomd.md.integrate.mode_standard(dt=1e-3)

hoomd.analyze.log(f"data_{kwargs.get('replica_num')}_{deltaA}.dat", qr, period=10000, overwrite=True)
return context

def post_run_action(**kwargs):
hoomd.util.quiet_status()
deltaA = kwargs.get("deltaA")
hoomd.dump.gsd(
filename=f"final_{kwargs.get('replica_num'):03d}_{deltaA}.gsd",
overwrite=True,
period=None,
group=hoomd.group.all(),
)
hoomd.util.unquiet_status()

def get_executor(mpi):
if mpi:
futures = importlib.import_module("mpi4py.futures")
return futures.MPIPoolExecutor()
return SerialExecutor()


def main(argv):

# Find indeces of the droplet forming polymer part
with gsd.hoomd.open("../start.gsd", "rb") as start_file:
frame = start_file[0]
idx = np.where(frame.particles.typeid == frame.particles.types.index("A"))[0].astype("int")
box = frame.configuration.box[:3]

Nidx = len(idx)
idxA = list(idx)[:Nidx//2]
idxB = list(idx)[Nidx//2:]

start = datetime.datetime.now()

for deltaA in [0.0, 0.1, 0.2, 0.3, 0.4]:
cvs = [Distance((idxA, idxB))]
centers = list(np.linspace(0, 6, 14))
method = UmbrellaIntegration(cvs, 1000., centers, 100, int(1e6))

context_args = {"mpi": True}
context_args["deltaA"] = deltaA

executor = get_executor(context_args["mpi"])

raw_result = pysages.run(method, generate_context, 2e6,
context_args=context_args,
post_run_action=post_run_action,
executor=executor)
result = pysages.analyze(raw_result)
print("end", time.asctime())
end = datetime.datetime.now()
diff = end - start
with open(f"result_{deltaA}.pkl", "wb") as file_handle:
pickle.dump(result, file_handle)


if __name__ == "__main__":
main(sys.argv)