P6-b design 2: the Robin wall on the patch's Inner side — RobinWall { alpha, datum } with the wall velocity u_s + (t_f − datum)/α (explicit, damped by the wall's own viscous gain μ/(α d)) and the compliant-wall pressure term |S| p'/α implicit in the projection (the added-mass operator in the fluid's own response); Dirichlet bit for bit when off; MMS pin on the skewed annulus (orders 2.46/2.13 at α = 10 and 100 μ/h, the Dirichlet values; a 1e12 wall reproduces Dirichlet to 2e-6); OversetPisoSolver::patch_mut; harness knob RTX_FSI2O_ROBIN_ALPHA with the previous pass's tractions as the datum, printed in the header
CI / Build (ubuntu-latest) (push) Failing after 7s
CI / Format Check (push) Failing after 17s
Documentation / Build User Guide (push) Successful in 19s
Documentation / Build API Documentation (push) Failing after 1m51s
CI / Build CPU-Only (Explicit) (push) Failing after 1m58s
CI / Clippy Check (push) Failing after 2m13s
Performance Benchmarks / Run Benchmarks (push) Successful in 2m54s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Failing after 7s
CI / Format Check (push) Failing after 17s
Documentation / Build User Guide (push) Successful in 19s
Documentation / Build API Documentation (push) Failing after 1m51s
CI / Build CPU-Only (Explicit) (push) Failing after 1m58s
CI / Clippy Check (push) Failing after 2m13s
Performance Benchmarks / Run Benchmarks (push) Successful in 2m54s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01YJPeT6WA2e7YvAnS875AHL
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
c144a5f733
commit
c3dbd5040a
@@ -6,7 +6,7 @@
|
||||
use super::{CurvilinearPisoSolver, PatchField, PressureSystem, SideBc, StepGeometry};
|
||||
use crate::mesh::PatchSide;
|
||||
use crate::solvers::incompressible::sparse_bicgstab::{
|
||||
BicgstabResult, CsrMatrix, bicgstab_jacobi, project_mean,
|
||||
bicgstab_jacobi, project_mean, BicgstabResult, CsrMatrix,
|
||||
};
|
||||
|
||||
impl CurvilinearPisoSolver {
|
||||
@@ -116,7 +116,9 @@ impl CurvilinearPisoSolver {
|
||||
]
|
||||
.iter()
|
||||
.any(|&s| self.params.boundaries.get(s) == SideBc::Outlet);
|
||||
if has_outlet || self.acceptors.is_some() {
|
||||
// A Robin wall absorbs the net flux through its compliance (the
|
||||
// pressure system is then not pure Neumann).
|
||||
if has_outlet || self.acceptors.is_some() || self.robin.is_some() {
|
||||
return 0.0;
|
||||
}
|
||||
let (mut net, mut total_len) = (0.0, 0.0);
|
||||
@@ -158,6 +160,15 @@ impl CurvilinearPisoSolver {
|
||||
continue;
|
||||
}
|
||||
for (f, sign) in mesh.cell_faces(c) {
|
||||
if let Some(w) = &self.robin {
|
||||
if mesh.side(f) == Some(PatchSide::Inner) {
|
||||
// The compliant wall: outward flux `+|S| p'_c / alpha`.
|
||||
let sv = mesh.faces()[f].s;
|
||||
let len = (sv[0] * sv[0] + sv[1] * sv[1]).sqrt();
|
||||
tri.push((c, c, len / w.alpha));
|
||||
any_dirichlet = true;
|
||||
}
|
||||
}
|
||||
self.ops
|
||||
.face_gradient_coeffs(mesh, &self.params.boundaries, f, &mut coefs);
|
||||
if mesh.side(f).is_some() && !coefs.is_empty() {
|
||||
@@ -257,6 +268,16 @@ impl CurvilinearPisoSolver {
|
||||
for f in 0..mesh.faces().len() {
|
||||
field.flux[f] -= dt / rho * lp[f];
|
||||
}
|
||||
if let Some(w) = &self.robin {
|
||||
// The compliant wall's flux answer: `δu_b = −p' S / (alpha |S|)`,
|
||||
// `δF = δu_b · S = −p' |S| / alpha` in the face's own orientation.
|
||||
for &f in &self.robin_faces {
|
||||
let c = mesh.boundary_cell(f);
|
||||
let sv = mesh.faces()[f].s;
|
||||
let len = (sv[0] * sv[0] + sv[1] * sv[1]).sqrt();
|
||||
field.flux[f] -= pc[c] * len / w.alpha;
|
||||
}
|
||||
}
|
||||
for c in 0..mesh.cell_count() {
|
||||
if self.is_acceptor(c) {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user