forked from 1b-agent/fieldcraft-upstream
mesh.cells: sweep the cells of a body together, conforming with no seeds (#288)
hex_mesh_swept_cells lays out one cross-section for several cells: every cell's walls (its cut faces included) are imprinted together, every cell's levels are levels of all, one interval assignment and one set of layers, and each region of each level interval is filled by the cell it lies in. Cells meet node for node across every cut, T-junctions included. mesh.cells sweeps the cells of each design body together first and meshes cell by cell only what does not sweep together (saying why); the reply gives every cell's volume, scaled Jacobian and edge ratio. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
c3a1712069
commit
755576de8a
6 files changed
+580
-136
No files matched your search
@@ -228,22 +228,7 @@ pub(super) fn hex_blocks(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
// Replace the cells' meshes (replace.rs); other bodies and the definitions stay.
|
||||
let model = &mut s.model;
|
||||
let cleared = super::replace::clear(model, inputs.iter().map(|b| b.name.as_str()));
|
||||
let (first_node, first_element) = super::fresh_labels(model, m.nodes.len(), m.element_count())?;
|
||||
for (i, xyz) in m.nodes.iter().enumerate() {
|
||||
model.set_node(first_node + i as u32, *xyz)?;
|
||||
}
|
||||
let mut body_tags = Vec::with_capacity(inputs.len());
|
||||
for b in &inputs {
|
||||
body_tags.push(model.geometry_tag(&GeometryRef::body(b.name.as_str())?)?);
|
||||
}
|
||||
for e in 0..m.element_count() {
|
||||
let cell = cm.element_cell.get(e).map_or(0, |&c| c as usize);
|
||||
let nodes: Vec<u32> = m.element(e).unwrap_or(&[]).iter().map(|&i| first_node + i).collect();
|
||||
let l = first_element + e as u32;
|
||||
model.set_element(l, m.kind, nodes)?;
|
||||
model.tag_element(l, body_tags.get(cell).copied().ok_or_else(|| EngineError::Params("element without a cell".into()))?)?;
|
||||
}
|
||||
tag_faces(model, &inputs, |e| cm.element_cell.get(e as usize).map_or(0, |&c| c as usize), &m.boundary, first_element)?;
|
||||
add_cells(model, &inputs, &cm)?;
|
||||
let blocks: Vec<Value> =
|
||||
inputs.iter().zip(&cm.blocks).map(|(b, d)| json!({"body": b.name, "divisions": d, "elements": d.iter().product::<usize>()})).collect();
|
||||
let reply = json!({
|
||||
@@ -355,6 +340,29 @@ pub(super) fn hex_body(p: &Value, b: &Input, method: HexMethod, quadratic: bool,
|
||||
hex_mesh(&surface, &b.surfaces, &UniformSize(h), &options).map_err(|e| EngineError::of_body(&b.name, e))
|
||||
}
|
||||
|
||||
/// Add a mesh of several cells (`inputs[c]` is cell `c`) after the model's largest labels, its
|
||||
/// nodes shared between the cells, tagging each element with its cell's body and the boundary
|
||||
/// element faces with the cell's B-rep faces.
|
||||
pub(super) fn add_cells(model: &mut Model, inputs: &[Input], cm: &fieldcraft_mesh::hex::CellsMesh) -> Result<()> {
|
||||
let m = &cm.mesh;
|
||||
let (first_node, first_element) = super::fresh_labels(model, m.nodes.len(), m.element_count())?;
|
||||
for (i, xyz) in m.nodes.iter().enumerate() {
|
||||
model.set_node(first_node + i as u32, *xyz)?;
|
||||
}
|
||||
let mut body_tags = Vec::with_capacity(inputs.len());
|
||||
for b in inputs {
|
||||
body_tags.push(model.geometry_tag(&GeometryRef::body(b.name.as_str())?)?);
|
||||
}
|
||||
for e in 0..m.element_count() {
|
||||
let cell = cm.element_cell.get(e).map_or(0, |&c| c as usize);
|
||||
let nodes: Vec<u32> = m.element(e).unwrap_or(&[]).iter().map(|&i| first_node + i).collect();
|
||||
let l = first_element + e as u32;
|
||||
model.set_element(l, m.kind, nodes)?;
|
||||
model.tag_element(l, body_tags.get(cell).copied().ok_or_else(|| EngineError::Params("element without a cell".into()))?)?;
|
||||
}
|
||||
tag_faces(model, inputs, |e| cm.element_cell.get(e as usize).map_or(0, |&c| c as usize), &m.boundary, first_element)
|
||||
}
|
||||
|
||||
/// Add one body's hex mesh after the model's largest labels, tagging the elements with the body
|
||||
/// and the boundary element faces with its B-rep faces; returns the first node and element
|
||||
/// labels.
|
||||
|
||||
Reference in new issue
Block a user