Skip to content

Commit 27b983b

Browse files
committed
Implemented improved force-stalling extrusion protocol
1 parent 4358b9b commit 27b983b

File tree

4 files changed

+651
-659
lines changed

4 files changed

+651
-659
lines changed

examples/tutorial_stall.ipynb

Lines changed: 606 additions & 0 deletions
Large diffs are not rendered by default.

examples/tutorial_stretch.ipynb

Lines changed: 0 additions & 619 deletions
This file was deleted.

polychrom_hoomd/extrude.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
cuda_module = xp.RawModule(code=cuda_code, options=('--use_fast_math',))
1414

1515
_single_leg_search = cuda_module.get_function('_single_leg_search')
16-
_harmonic_boltzmann_filter = cuda_module.get_function('_harmonic_boltzmann_filter')
16+
_harmonic_distance_filter = cuda_module.get_function('_harmonic_distance_filter')
1717

1818
except ImportError:
1919
import numpy as xp
@@ -59,12 +59,17 @@ def update_topology(system, bond_list, local=True, thermalize=False):
5959
system.state.thermalize_particle_momenta(filter=hoomd.filter.All(), kT=1.0)
6060

6161

62-
def boltzmann_criterion(system, current_bond_list, trial_bond_list, step_dist=0.4, rest_dist=0.5, threads_per_block=256):
63-
"""Apply (3D) Boltzmann criterion to list of attempted (1D) extruder moves, based on harmonic bond potential"""
62+
def stall_criterion(system, current_bond_list, trial_bond_list, bonded_force_dict, threads_per_block=256):
63+
"""Apply (3D) tension-based stall criterion to list of attempted (1D) extruder moves, based on harmonic bond potential"""
6464

65-
mu = xp.float64(rest_dist)
66-
sigma2 = xp.float64(step_dist**2) * 2.
65+
assert bonded_force_dict["Backbone"]["Type"] == 'Harmonic'
6766

67+
rest_length = bonded_force_dict["Backbone"]["Rest length"]
68+
wiggle_dist = bonded_force_dict["Backbone"]["Wiggle distance"]
69+
70+
rest_length = xp.float64(rest_length)
71+
k_stretch = xp.float64(1./wiggle_dist**2)
72+
6873
hbox = xp.asarray(system.state.box.L, dtype=xp.float64) / 2.
6974

7075
old_bond_array = xp.asarray(current_bond_list, dtype=xp.int32)
@@ -76,17 +81,17 @@ def boltzmann_criterion(system, current_bond_list, trial_bond_list, step_dist=0.
7681
with system.state.gpu_local_snapshot as local_snap:
7782
N = int(new_bond_array.shape[0])
7883
rng = xp.random.random(N).astype(xp.float64)
79-
84+
8085
rtags = local_snap.particles.rtag._coerce_to_ndarray()
8186
positions = local_snap.particles.position._coerce_to_ndarray()
8287
positions = positions.astype(xp.float64)
8388

8489
num_blocks = (N+threads_per_block-1) // threads_per_block
8590

86-
_harmonic_boltzmann_filter(
91+
_harmonic_distance_filter(
8792
(num_blocks,),
8893
(threads_per_block,),
89-
(N, mu, sigma2,
94+
(N, k_stretch, rest_length,
9095
rng, hbox, positions, rtags,
9196
old_bond_array, new_bond_array)
9297
)

polychrom_hoomd/kernels/lef_spatial_utils.cuh

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
extern "C" {
2-
__global__ void _harmonic_boltzmann_filter(
2+
__global__ void _harmonic_distance_filter(
33
const unsigned int N,
4-
const double mu,
5-
const double sigma2,
4+
const double k_stretch,
5+
const double rest_length,
66
const double* rng,
77
const double* hdims,
88
const double* positions,
@@ -21,45 +21,45 @@ __global__ void _harmonic_boltzmann_filter(
2121
if ( (old_bond[i].x == -1) || (old_bond[i].y == -1) )
2222
return;
2323

24-
if ( (new_bond[i].x == -1) || (new_bond[i].y == -1) )
25-
return;
24+
if ( (new_bond[i].x == -1) || (new_bond[i].y == -1) )
25+
return;
2626

2727
double3* hdim = (double3*) hdims;
2828
double3* position = (double3*) positions;
2929

3030
bool has_moved_left = (old_bond[i].x != new_bond[i].x);
3131
bool has_moved_right = (old_bond[i].y != new_bond[i].y);
32+
33+
auto harmonic_work = [=](unsigned int& i, unsigned int& j) {
34+
35+
double dx = position[j].x - position[i].x;
36+
double dy = position[j].y - position[i].y;
37+
double dz = position[j].z - position[i].z;
38+
39+
dx -= (copysign(hdim->x, dx-hdim->x) + copysign(hdim->x, dx+hdim->x));
40+
dy -= (copysign(hdim->y, dy-hdim->y) + copysign(hdim->y, dy+hdim->y));
41+
dz -= (copysign(hdim->z, dz-hdim->z) + copysign(hdim->z, dz+hdim->z));
42+
43+
double step_size = sqrt(dx*dx + dy*dy + dz*dz);
44+
double harmonic_force = k_stretch * (step_size - rest_length);
45+
46+
return harmonic_force * step_size;
47+
};
3248

33-
if ( has_moved_left || has_moved_right ) {
34-
double delta_r2 = 0.;
49+
if ( has_moved_left ) {
50+
unsigned int rtag1 = rtags[old_bond[i].x];
51+
unsigned int rtag2 = rtags[new_bond[i].x];
3552

36-
for ( unsigned int j = 0; j < 2; ++j ) {
37-
int2 tags = ((j==0) ? old_bond[i] : new_bond[i]);
53+
if ( rng[i] > exp(-harmonic_work(rtag1, rtag2)) )
54+
new_bond[i].x = old_bond[i].x;
55+
}
3856

39-
unsigned int rtag1 = rtags[tags.x];
40-
unsigned int rtag2 = rtags[tags.y];
41-
42-
double dx = position[rtag2].x - position[rtag1].x;
43-
double dy = position[rtag2].y - position[rtag1].y;
44-
double dz = position[rtag2].z - position[rtag1].z;
45-
46-
dx -= (copysign(hdim->x, dx-hdim->x) + copysign(hdim->x, dx+hdim->x));
47-
dy -= (copysign(hdim->y, dy-hdim->y) + copysign(hdim->y, dy+hdim->y));
48-
dz -= (copysign(hdim->z, dz-hdim->z) + copysign(hdim->z, dz+hdim->z));
49-
50-
double delta_r = sqrt(dx*dx + dy*dy + dz*dz) - mu;
51-
delta_r2 += ((j==0) ? delta_r*delta_r : -delta_r*delta_r);
52-
}
57+
if ( has_moved_right ) {
58+
unsigned int rtag1 = rtags[old_bond[i].y];
59+
unsigned int rtag2 = rtags[new_bond[i].y];
5360

54-
double boltzmann_weight = exp(delta_r2/sigma2);
55-
56-
if ( rng[i] > boltzmann_weight ) {
57-
if ( has_moved_left )
58-
new_bond[i].x = old_bond[i].x;
59-
60-
if ( has_moved_right )
61-
new_bond[i].y = old_bond[i].y;
62-
}
61+
if ( rng[i] > exp(-harmonic_work(rtag1, rtag2)) )
62+
new_bond[i].y = old_bond[i].y;
6363
}
6464
}
6565

0 commit comments

Comments
 (0)