Skip to content
Snippets Groups Projects
Commit 3034e576 authored by Roman Belousov's avatar Roman Belousov
Browse files

Frozen and fixed beads

parent ca0a1ad2
No related branches found
No related tags found
No related merge requests found
......@@ -91,6 +91,8 @@ class State:
active_exponents (list[float]): Active exponents
surface_tension (list[float]): Surface tension between voxel types
modulation (list[float]): Modulation of spin interactions with distance
frozen (list[int]): Frozen voxel IDs (only MEDIUM and ECM types are accepted)
fixed (list[int]): Fixed voxel IDs (only MEDIUM and ECM types are accepted)
rng (dict|None): State of the random-number generator may be absent
"""
def __init__(self, **kwargs):
......@@ -115,8 +117,9 @@ class State:
active_exponents (list[float]): Active exponents
surface_tension (list[float]):
Required surface tension between voxel types
modulation (list[float]): Modulation of spin interactions with distance
(Optional)
modulation (list[float]): Modulation of spin interactions with distance (Optional)
frozen (list[int]): Frozen voxels (Optional)
fixed (list[int]): Fixed voxels (Optional)
rng (dict): Optional state of the random-number generator
"""
self.side = kwargs.pop('side')
......@@ -137,13 +140,15 @@ class State:
self.active_exponents = kwargs.pop('active_exponents', 8 * [0.0])
self.surface_tension = kwargs.pop('surface_tension')
self.modulation = kwargs.pop('modulation', [1.0, 1.0, 1.0])
self.frozen = kwargs.pop('frozen', [])
self.fixed = kwargs.pop('fixed', [])
if 'rng' in kwargs: self.rng = kwargs.pop('rng')
if len(kwargs) > 0:
raise TypeError(f'Unknown kwargs: {list(kwargs.keys())}')
def __getattr__(self, name):
if name == 'rng': return None
raise AttributeError()
raise AttributeError(f'State has no attribue `{name}`')
def to_json(self):
"""Return JSON-serializable data"""
......@@ -225,7 +230,7 @@ class State:
}
def ecm_coordinates(self):
"""Return center-of-mass coordinates of the ECM voxels"""
"""Return coordinates of the ECM voxels"""
return [self.voxel_coordinates(voxel) for voxel in self.ecm]
def volume(self, exclude_ecm = False):
......
......@@ -66,7 +66,7 @@ pub struct State {
/// Voxel ids of the ECM
#[serde(default)]
pub ecm: std::collections::HashSet<i64>,
pub ecm: std::collections::HashSet<VoxelId>,
/// The ecm production and degradation exponents
#[serde(default = "default_ecm_parameters")]
......@@ -119,6 +119,11 @@ pub struct State {
/// Spin interaction modulation
pub modulation: [f64; 3],
/// IDs of "frozen" voxels
pub frozen: std::collections::HashSet<VoxelId>,
/// IDs of "fixed" voxels
pub fixed: std::collections::HashSet<VoxelId>,
/// State of the random number generator
#[serde(default)]
pub rng: mt19937::MT19937
......@@ -205,6 +210,17 @@ impl State {
lattice[*voxel_id as usize] = ECM;
}
for frozen in self.frozen.iter() {
if lattice[*frozen as usize] > 0 {
panic!("Freezing a voxel (#{:?}) of a cell (#{:?}) not allowed", frozen, lattice[*frozen as usize])
}
}
for fixed in self.fixed.iter() {
if lattice[*fixed as usize] > 0 {
panic!("Freezing a voxel (#{:?}) of a cell (#{:?}) not allowed", fixed, lattice[*fixed as usize])
}
}
Ok(lattice)
}
......
......@@ -400,11 +400,15 @@ impl Kernel {
let mut target_values = Vec::<VoxelValue>::with_capacity(5);
target_values.push(voxel_value);
for triplet in &TARGET_NEIGHBORHOOD {
let neighbor_value = self.get_index_value(
let neighbor_index = [
voxel.index[0] + triplet[0],
voxel.index[1] + triplet[1],
voxel.index[2] + triplet[2]
);
];
let neighbor_id = self.index_to_id(neighbor_index[0], neighbor_index[1], neighbor_index[2]);
if self.state.frozen.contains(&neighbor_id) { continue }
let neighbor_value = self.get_index_value(neighbor_index[0], neighbor_index[1], neighbor_index[2]);
if neighbor_value != voxel_value && !target_values.contains(&neighbor_value) {
target_values.push(neighbor_value);
}
......@@ -746,6 +750,7 @@ impl Kernel {
/// Check if a voxel is active
fn is_active(&self, voxel: &Voxel) -> bool {
if self.state.frozen.contains(&voxel.id) || self.state.fixed.contains(&voxel.id) { return false }
let value = self.lattice[voxel.id as usize];
for triplet in &TARGET_NEIGHBORHOOD {
let neighbor_value = self.get_index_value(
......@@ -767,7 +772,8 @@ impl Kernel {
voxel.index[1] + triplet[1],
voxel.index[2] + triplet[2]
);
if 0 <= id && id < self.lattice.len() as i64 { self.front.insert(id); }
if !self.state.frozen.contains(&id) && !self.state.fixed.contains(&id)
&& 0 <= id && id < self.lattice.len() as i64 { self.front.insert(id); }
}
}
......
......@@ -42,7 +42,7 @@ fn active_exponents() {
action_probabilities: [0.001, 0.999, 0.999], death_probability: 0f64,
growth_rate: [0.5, 0.5], division_distribution: vec![10f64],
volume_elasticity: [1.0, 1.5], active_exponents: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0], frozen: hashset![], fixed: hashset![],
rng: mt19937::MT19937::default()
};
......@@ -137,7 +137,7 @@ fn kernel_layout() {
action_probabilities: [0.001, 0.999, 0.999], death_probability: 0f64,
growth_rate: [0.5, 0.5], division_distribution: vec![10f64],
volume_elasticity: [1.0, 1.5], active_exponents: [0f64; 8],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0], frozen: hashset![], fixed: hashset![],
rng: mt19937::MT19937::default()
};
assert_eq!(state.side, 3);
......@@ -306,7 +306,7 @@ fn cell_division() {
death_probability: 0f64,
growth_rate: [0.5, 0.5], division_distribution: vec![10f64],
volume_elasticity: [1.0, 1.5], active_exponents: [0f64; 8],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0], frozen: hashset![], fixed: hashset![],
rng: mt19937::MT19937::default()
});
assert_eq!(kernel.state.cells.len(), 1);
......@@ -348,7 +348,7 @@ fn cell_division() {
death_probability: 0f64,
growth_rate: [0.5, 0.5], division_distribution: vec![10f64],
volume_elasticity: [1.0, 1.5], active_exponents: [0f64; 8],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0], frozen: hashset![], fixed: hashset![],
rng: mt19937::MT19937::default()
});
assert_eq!(kernel.state.cells.len(), 1);
......@@ -371,7 +371,7 @@ fn cell_death() {
death_probability: 100f64,
growth_rate: [0.5, 0.5], division_distribution: vec![10f64],
volume_elasticity: [1.0, 1.5], active_exponents: [0f64; 8],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0], frozen: hashset![], fixed: hashset![],
rng: mt19937::MT19937::default()
});
assert_eq!(kernel.state.cells.len(), 1);
......@@ -396,7 +396,7 @@ fn tensor_gyration() {
death_probability: 0f64,
growth_rate: [0.5, 0.5], division_distribution: vec![10f64],
volume_elasticity: [1.0, 1.5], active_exponents: [0f64; 8],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0], frozen: hashset![], fixed: hashset![],
rng: mt19937::MT19937::default()
});
let cell = &kernel.state.cells[&2usize];
......@@ -456,7 +456,7 @@ fn connectivity_check() {
action_probabilities: [0.001, 0.999, 0.999],
death_probability: 0f64, growth_rate: [0.5, 0.5], division_distribution: vec![10f64],
volume_elasticity: [1.0, 1.5], active_exponents: [0f64; 8],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0], frozen: hashset![], fixed: hashset![],
rng: mt19937::MT19937::default()
});
......@@ -478,7 +478,7 @@ fn planar_index() {
death_probability: 0f64,
growth_rate: [0.5, 0.5], division_distribution: vec![10f64],
volume_elasticity: [1.0, 1.5], active_exponents: [0f64; 8],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0], frozen: hashset![], fixed: hashset![],
rng: mt19937::MT19937::default()
});
let voxel = kernel.get_voxel_by_id(13i64);
......@@ -574,7 +574,7 @@ fn kernel_getters() {
death_probability: 0f64,
growth_rate: [0.5, 0.5], division_distribution: vec![10f64],
volume_elasticity: [1.0, 1.5], active_exponents: [0f64; 8],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0],
surface_tension: [1.0, 2.0, 3.0, 4.0, 5.0], modulation: [1.0, 1.0, 1.0], frozen: hashset![], fixed: hashset![],
rng: mt19937::MT19937::default()
});
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment