forked from 1b-agent/fieldcraft-upstream
ui: fluid boundary face and obstacle faces as typed fields
The boundary's 'at' is a box face or an obstacle body and face (NameOr); the domain's obstacle faces are rows of a face and its wall condition (#449). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
98e96921e6
commit
9b705f5334
1 file changed
+35
-7
@@ -584,6 +584,24 @@ const FACE_CONDITION: &[Variant] = &[
|
|||||||
variant("periodic", "Periodic", &[]),
|
variant("periodic", "Periodic", &[]),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const BOX_FACE: Field =
|
||||||
|
choice("", "Box face", &[("x_min", "X min"), ("x_max", "X max"), ("y_min", "Y min"), ("y_max", "Y max"), ("z_min", "Z min"), ("z_max", "Z max")])
|
||||||
|
.help("A face of the domain's box, at the smallest or largest X, Y or Z.")
|
||||||
|
.req();
|
||||||
|
const OBSTACLE_FACE_FIELDS: &[Field] = &[
|
||||||
|
reference("body", "Body", C::Body).help("An obstacle body of the design.").req(),
|
||||||
|
text("face", "Face").help("A persistent face name of the body (e.g. F3); it also selects the face's split pieces.").req(),
|
||||||
|
];
|
||||||
|
const OBSTACLE_FACE: Field = group("face", "Face", OBSTACLE_FACE_FIELDS).help("The obstacle face.").req();
|
||||||
|
const SURFACE_CONDITION: &[Variant] = &[
|
||||||
|
variant("wall", "Wall at rest", &[]),
|
||||||
|
variant(
|
||||||
|
"moving_wall",
|
||||||
|
"Moving wall",
|
||||||
|
&[xyz("velocity", "Velocity", D::Velocity).help("The wall's tangential velocity; the body itself does not move.").req()],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
const fn face(key: &'static str, label: &'static str) -> Field {
|
const fn face(key: &'static str, label: &'static str) -> Field {
|
||||||
variants(key, label, FACE_CONDITION).hint("wall")
|
variants(key, label, FACE_CONDITION).hint("wall")
|
||||||
}
|
}
|
||||||
@@ -610,9 +628,16 @@ pub const FLUID_DOMAIN: &[Field] = &[
|
|||||||
)
|
)
|
||||||
.help("The condition on each face of the box."),
|
.help("The condition on each face of the box."),
|
||||||
references("obstacles", "Obstacles", C::Body).help("Bodies of the design the flow goes around."),
|
references("obstacles", "Obstacles", C::Body).help("Bodies of the design the flow goes around."),
|
||||||
json("surfaces", "Obstacle faces")
|
rows(
|
||||||
.help("Conditions on single obstacle faces, as JSON; walls by default.")
|
"surfaces",
|
||||||
.hint("[{\"face\", \"condition\"}]; walls by default"),
|
"Obstacle faces",
|
||||||
|
&[
|
||||||
|
OBSTACLE_FACE,
|
||||||
|
variants("condition", "Condition", SURFACE_CONDITION).help("The flow condition on that face.").req().def(r#"{"type": "wall"}"#),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.help("Conditions on single obstacle faces; every other obstacle face is a wall at rest.")
|
||||||
|
.hint("walls by default"),
|
||||||
xyz("initial_velocity", "Initial velocity", D::Velocity).help("The fluid's velocity at the start."),
|
xyz("initial_velocity", "Initial velocity", D::Velocity).help("The fluid's velocity at the start."),
|
||||||
xyz("acceleration", "Acceleration", D::Acceleration).help("A body acceleration on the fluid, such as gravity."),
|
xyz("acceleration", "Acceleration", D::Acceleration).help("A body acceleration on the fluid, such as gravity."),
|
||||||
positive("tolerance", "Obstacle tolerance", D::Length)
|
positive("tolerance", "Obstacle tolerance", D::Length)
|
||||||
@@ -622,11 +647,10 @@ pub const FLUID_DOMAIN: &[Field] = &[
|
|||||||
|
|
||||||
pub const FLUID_BOUNDARY: &[Field] = &[
|
pub const FLUID_BOUNDARY: &[Field] = &[
|
||||||
reference("domain", "Domain", C::FluidDomain).help("The fluid domain to change.").req(),
|
reference("domain", "Domain", C::FluidDomain).help("The fluid domain to change.").req(),
|
||||||
json("at", "Boundary")
|
name_or("at", "Boundary", &BOX_FACE, "Obstacle face", OBSTACLE_FACE_FIELDS)
|
||||||
.help("A box face (x_min … z_max) or an obstacle face, as JSON.")
|
.help("A face of the domain's box, or a named face of an obstacle body.")
|
||||||
.req()
|
.req()
|
||||||
.def("\"x_min\"")
|
.def("\"x_min\""),
|
||||||
.hint("\"x_min\" … \"z_max\", or {\"body\", \"face\"}"),
|
|
||||||
variants("condition", "Condition", FACE_CONDITION).help("The flow condition on that boundary.").req().def(r#"{"type": "velocity"}"#),
|
variants("condition", "Condition", FACE_CONDITION).help("The flow condition on that boundary.").req().def(r#"{"type": "velocity"}"#),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -2074,6 +2098,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
match f.kind {
|
match f.kind {
|
||||||
Kind::Group(g) | Kind::Rows { fields: g, .. } | Kind::Either(g) => walk(id, g, missing),
|
Kind::Group(g) | Kind::Rows { fields: g, .. } | Kind::Either(g) => walk(id, g, missing),
|
||||||
|
Kind::NameOr { name, fields, .. } => {
|
||||||
|
walk(id, std::slice::from_ref(name), missing);
|
||||||
|
walk(id, fields, missing);
|
||||||
|
}
|
||||||
Kind::Variants { variants, .. } => variants.iter().for_each(|v| walk(id, v.fields, missing)),
|
Kind::Variants { variants, .. } => variants.iter().for_each(|v| walk(id, v.fields, missing)),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user