Repository navigation
Conversation
…gument call OneLevelTransport builds a flux as numericalFluxType(vt, dirichlet, advective, diffusive) and appends the periodic conditions only when the p module sets them. RusanovNumericalFlux_Diagonal and ConvexOneSonicPointNumericalFlux required the periodic argument, so the ordinary call raised TypeError, and RusanovNumericalFlux called RusanovNumericalFlux_Diagonal.__init__ with four arguments, so it failed even when given five. Every deck using RusanovNumericalFlux stopped in its constructor (test/shallow_water/dambreak_1d at NumericalFlux.py:4726), since b8912a0 (2014) added the periodic argument. The periodic argument now defaults to None in all three and RusanovNumericalFlux forwards it; the Rusanov exterior flux already pairs periodic faces. Sweep of the 50 NF_base subclasses (test/test_numerical_flux_constructors.py, which imports the module and binds every constructor and every Base.__init__(self, ...) call): ordinary call refused: main 2 (ConvexOneSonicPoint, Rusanov_Diagonal) -> 0 base __init__ call unbound: main 1 (RusanovNumericalFlux:4726) -> 0 periodic argument dropped by a subclass that takes one: 0 on main 23 classes take no periodic argument at all; a periodic deck with one of them stops with TypeError. The test pins that set: most of them have no periodic face pairing, so accepting the argument would hide the gap, not close it. Seven more accept it and pair no faces (Diffusion_IIPG/SIPG_exterior, Stokes_*_IIPG/SIPG_exterior, NoFlux, StrongDirichlet, DoNothing): noted in the round handoff, not changed. dambreak_1d after this commit gets past the flux and stops in the DG limiter (ctimeIntegration, next commit). Tests: test_numerical_flux_constructors (3, all 3 fail on main), test_numerical_flux_arguments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 2019 Cython rewrite of the ctimeIntegration C module (proteustoolkit#879, f277124) gave seven wrappers new signatures: the sizes as leading arguments (nElements_global, nNodes_element, ...), the 1D limiter's flag first instead of last, and psiTCtteDT writing dt into a seventh argument instead of returning it. TimeIntegration.py kept the old calls, so 11 of its 16 calls into the module raised TypeError on first use: every 1D DG limiter (DGlimiterP1Lagrange1d and the classes built on it, the _withVacuumTol ones), the Durlofsky 2D/3D limiters and PsiTCtte's dt choice. The three Cockburn/shape-gradient wrappers already took the old arguments and are unchanged. The wrappers again infer the sizes from the array shapes, exactly as the C module did (nSpace from grad_v's last axis, nDOF from l2g), take the limiter flag last with its old default 1 (MUSCL), and psiTCtteDT returns dt. Nothing else calls these wrappers. TimeIntegration.py calls that do not bind: main 11 of 16 -> 0 P1 1D limiter, 4 elements: linear data kept, an extremum cell and its falling neighbour flattened to their means (flags 0/1/2; vacuum-tolerance variant the same); psiTCtteDT reads all 6 points of a (2,3) array and returns sqrt(tau/(max dy + 1e-8))*0.9 exactly. test/test_time_integration_wrappers.py: 3 tests, all 3 fail on main. test/shallow_water/dambreak_1d (RKDG P1, SSPRK2, Rusanov, P1 limiter) then runs to T=20 in 2.9 s, given the Cython 3 staticmethod wrapping of the class-stored limiter functions in TimeIntegration.py (#204, C47; without it Cython 3 passes self as an extra argument). Measured with #204's TimeIntegration.py hunks applied locally: mass 29/6 at all 101 outputs to 1.2e-14 (the P1 interpolation of the step), min h -5.0e-8 (3 outputs below 0, at the wall cell as the front arrives), and with an element partition (1 layer) serial = 2, 3 and 4 ranks to the last bit in h and hu at all 101 outputs. The deck test lands after #204. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…found
RANS2P_IB (RANS2P plus immersed Euler-Bernoulli beams, beamFEM) had no deck and could not have run one:
1. getJacobian read `elf.coefficients` (NameError on the first Newton iteration).
2. Coefficients passed RANS2P its default arguments instead of its own, so rho, nu, g, nd, LS_model, useMetrics, ...
were dropped: every RANS2P_IB run was 3D single-phase water (nu_0=1e-3, nd=2, LS_model=2 came out as 1.004e-6,
3, None). It now forwards them; the defaults it had (dragAlpha 0.01, eb_penalty_constant 10) are unchanged.
3. calculateBeams integrated the beam loads q1-q3, vel_avg and netBeamDrag over ghost elements too, then summed over
ranks, so elements shared by two ranks counted twice. They are now integrated over owned elements; every local
element still gets q_dragBeam*, the fluid's source. (C0's kernel territory, mprans/*.h.)
4. postStep printed the forces to stdout, so the history files RANS2P opens stayed empty, and wrote the deflection
row directly. It now queues RANS2P's rows (time, wetted area, forces, moments), the beam drag and the deflection
with deferWrite, so a retried step leaves no row. (RANS2P's postStep itself does not fit: this LevelModel is an
older copy without the lagged dV/active-element arrays, which its kernel does not read.)
Deck test/rans2p_ib/beam_channel: 0.4 x 0.69 x 0.2 channel from rest, inflow 0.1 m/s, no slip on the bottom and side
walls, one beam (radius 5 mm, height 0.1) at (0.2, 0.345); rigid (default) or flexible (beamRigid=False, EI=GJ=1e-4,
bends ~1 cm by t=0.04). P1, Backward Euler, dt 0.01 to 0.04, direct solves, Newton atol 1e-10.
Serial vs N ranks (node partition, no overlap, sums over owned nodes of p, u, v, w and squares, beam drag, q1-q3,
beam vertex coordinates), worst relative difference:
before 3. (1, 2 fixed) after
rigid, 2 ranks drag 1.12e-2 vs 7.99e-3 (+40%), q1 +41% 4e-16 (drag1, 4e-6 itself, 4e-14)
flexible, 2 ranks drag +42%, beam x-sum 1.0331 vs 1.0195, 4e-16
fluid u-sum 3.7e-8
rigid/flexible, 3 ranks 4e-16
(the fluid matched to 1e-15 before 3. for a rigid beam: the loads feed back only through a flexible beam's shape)
Retry (test_step_retry, two new cases): RANS2P_IB failing its 3rd solve, retried at half the step, against a
failure-free run on the same times: 0.0 in p, u, v, w, rigid and flexible; the deflection and time histories hold one
row per accepted step (before 4.: timeHistory.txt empty). NORESTORE gives 0.0 too on this single-model deck: postStep
runs only after an accepted step, so nothing of the beam's is ahead of the retry. In a multi-model deck a later
model's failure would leave a flexible beam moved (Beam_Solver Phi, xv/yv/zv, xq/yq/zq): RANS2P_IB needs a state()
for that, noted in the round handoff.
Tests: test/rans2p_ib/test_rans2p_ib.py (3; on main the deck stops at 1., and the coefficient test fails),
test_step_retry.py beam_channel cases (2).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The deck (RKDG P1 shallow water, Rusanov flux, P1 limiter, SSPRK2, a dry-bed dam break between two walls, 30 elements to T=20) stopped in RusanovNumericalFlux's constructor (7d95b91) and then in the 1D limiter wrappers (bb12679). Measured (macOS arm64, with #204's TimeIntegration.py, which Cython 3 needs for the limiter class attributes): mass 29/6 (the P1 interpolation of the step) at all 101 outputs to 1.2e-14; h below zero at 3 of 101 outputs, by at most 5.0e-8 (t=0.6, the wall cell as the front arrives: the P1 limiter does not preserve positivity); h in [0.3645, 0.4985] at T=20, settling to the rest depth 29/60; element partition, 1 layer, bjacobi/LU mass solve: serial = 2, 3 and 4 ranks to the last bit in h and hu at every output (2 ranks in the test). The test skips, saying why, until #204's staticmethod attributes are on the branch, and runs from then on. The p module's docstring is now raw (it held "\in", a SyntaxWarning). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tements to Transport) The floor was recorded on main ce43b73 (33f30b1): 522 of 685 statements, 76.2%. #199 (C0 round 5, 76f3e12) replaced NCLS3P's own scatterDOFArray (15 statements, all covered) by the one on OneLevelTransport, so main c09280c has 507 of 670, 75.67%: the same lines untested, a smaller file. Every pull request on c09280c without #204 (whose staticmethod lines add covered statements to the file) is below the floor: this one's coverage job and #212's both report NCLS3P 75.7%. Line by line, the NCLS3P lines hit in this branch's run and in #204's run (mapped through #204's edits) are the same set. The new floor is the measured value rounded down to a tenth. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cekees
added a commit
that referenced
this pull request
Nov 5, 2026
SO_base.modelStepTaken (Sequential_MinModelStep, default_so's default, 11 so files under test/; and Sequential_tnList) moves a model's t_model_last to the end of the system step as soon as that model's step is taken. When a later model of the same system step failed, restoreSystemStepState put the dofs and the lag state back but not t_model_last, so the retry, stepping to an earlier time, found the model already past it and skipped it; from then on it ran one step behind the others and never reached T. The controllers that override modelStepTaken (Sequential_MinAdaptiveModelStep, the TwoPhaseFlow decks, and the FLCBDF ones) do not move it there, which is why test_step_retry's cases never saw it. saveSystemStepState now keeps each model's t_model_last and restoreSystemStepState puts it back. The case: test/rans2p_ib/beam_channel_so.py, the beam channel with a dye (VOF, carried by RANS2P_IB's velocity) after RANS2P_IB; the dye's third solve is reported failed (step_retry_mpi.py FAILMODEL=dye FAILAT=3), the step 0.02 -> 0.03 is cut to 0.025, against a failure-free run on the same steps (REPLAY). Largest relative difference over each model's dofs, macOS arm64, serial, SuperLU: | | RANS2P_IB p, u, v, w | dye | |---|---|---| | main c09280c (rigid and flexible beam) | 4.8e-2, 8.0e-2, 5.2e-2, 9.2e-2 | 3.3e-4 | | this commit | 1.2e-6, 2.8e-6, 6.4e-6, 3.3e-6 | 2.7e-8 | Model solves of the forced run on main: beam_channel at 0.01, 0.02, 0.03 | retry: dye 0.025, beam_channel 0.02 (dt 0.005), dye 0.03, beam_channel 0.025, ... beam_channel last at 0.035. With the fix both models solve at 0.025, 0.03, 0.035, 0.04. What remains is RANS2P_IB's lagged beam drag, which the retry does not restore yet (next commit); the new test bounds it at 1e-5 until then. test_step_retry.py (all cases) passes unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RANS2P_IB's beam drag is lagged: after each model step its LevelModel's beamStep spreads the drag from the beams onto the mesh (Coefficients.q_dragBeam1-3, ebqe_dragBeam1-3, which the next step's residual reads) and integrates the beam loads (q1-q3); postStep then moves a flexible beam (xv..zq, each beamFEM solver's Phi and x, y, z) and numbers the beam file (tStep). Both run before the later models of the system step. Its Coefficients had no state() (RANS2P.Coefficients.state returns None for this older LevelModel copy), so when a later model failed, the retry restored the dofs and kept the failed attempt's drag and beam. Coefficients.state()/set_state() now carry them (vel_avg is set in attachModels so state() has it before the first beamStep). The same state is archived for a hot start (solver_state/<model>/coefficients). test/rans2p_ib: the dye after RANS2P_IB fails its third solve (beam_channel_so.py, previous commit), the retry against a failure-free run on the same steps. Largest relative difference over each model's dofs, macOS arm64, serial, SuperLU: | | RANS2P_IB p, u, v, w | dye | flexible beam deflection at the retried step | |---|---|---|---| | previous commit, rigid | 1.2e-6, 2.8e-6, 6.4e-6, 3.3e-6 | 2.7e-8 | | | previous commit, flexible | 1.3e-6, 3.2e-6, 6.4e-6, 3.8e-6 | 2.7e-8 | | | drag restored, beam not (flexible) | 8.8e-8, 1.3e-7, 6.6e-7, 1.8e-7 | 7.7e-10 | 8.2941e-3 vs 8.2956e-3 | | this commit, rigid and flexible | 0.0 | 0.0 | equal, no row from the failed attempt | The test's bound goes from 1e-5 to 1e-12, and the flexible case checks the deflection history. Ran: test/rans2p_ib (5, incl. serial = 2 ranks), test_step_retry beam_channel cases (2). Not checked: a hot start of the deck, which stops before reading any state (the restart reads regular_9x14x5_grid.node/.ele, which an in-memory box mesh never writes). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round 6's sweep found seven fluxes that accept the periodic argument and pair no periodic faces
(Diffusion_IIPG/SIPG_exterior, Stokes_Advection_DiagonalUpwind_Diffusion_IIPG/SIPG_exterior, NoFlux,
StrongDirichlet, DoNothing). All seven are boundary-only, so they serve C0 spaces, where the periodic DOF
map already joins the seam; whether skipping the pairing matters was measured, not assumed.
NF_base marks the face points of a periodic pair as DOF boundary with no value. The diffusion fluxes then
apply their weak-Dirichlet flux there with the trace equal to the interior value: the residual keeps a
one-sided -a grad(u).n on each side of the seam (it does not cancel, grad(u) jumps across) and the
Jacobian a penalty the residual lacks. The other three put nothing at the seam that depends on it.
C0 P1, -Laplace u = 5 pi^2 sin(2 pi x) sin(pi y) on the unit square, u = 0 at y = 0, 1, 8x8 cells, L2 error
and Newton iterations; "without" makes x = 0, 1 Dirichlet (the exact solution vanishes there too):
| flux | without the periodic pair | periodic in x |
|---|---|---|
| Diffusion_IIPG_exterior | 3.2e-2, 1 | 3.5e-1, not converged in 30 (10 retries) |
| Diffusion_SIPG_exterior | 4.3e-2, 1 | 4.4e-1, not converged |
| StrongDirichlet | 4.6e-2, 1 | 4.7e-2, 1 |
| NoFlux | 4.1 (imposes no Dirichlet) | 4.1, 1 |
| DoNothing | 1.5 (imposes no Dirichlet) | 1.5, 1 |
So the four diffusion fluxes (Stokes: the same diffusive flux at the same points, not run, no periodic
Stokes deck exists) now raise ValueError when built with periodic conditions, naming StrongDirichlet.
NF_base checks the exact class name (PERIODIC_SEAM_REFUSED); subclasses with their own exterior flux
(the HamiltonJacobi Lesaint-Raviart SIPG pair) are not covered. StrongDirichlet, DoNothing and NoFlux keep
accepting periodic conditions.
Who builds them with periodic conditions (Transport hook over test/periodic, TADR, LS_with_edgeBased_EV,
POD, test_adr_problem, test_pro_cli; plus a grep of every p/n module that sets periodicDirichletConditions):
StrongDirichlet: ADRProblem's StrongDirichletFactory (test_adr_problem's periodic Poisson, periodic
channel, periodic on 2-4 ranks);
DoNothing: test/periodic ls_consrv_n, redist_n; la_periodicGauss_n, hotstart_measure/rkev_gauss_n
(MCorr, RDLS);
the four refused classes: nobody. The Stokes ones are used without periodic conditions only
(solver_tests stokesDrivenCavity_2d_n, mesh_tests stokes_2d_n), unaffected.
Not changed, for the next round: Advection_DiagonalUpwind_Diffusion_IIPG_exterior pairs the periodic faces
and has the same seam defect on the same problem (1.06e-1 vs 3.2e-2, Newton not converged). The mprans
fluxes built on it (VOF, NCLS, CLSVOF, Kappa, Dissipation) run periodic decks in test/periodic; VOF and
NCLS have no diffusion there. Refusing it would break them; the fix is to drop the exterior diffusive flux
at C0 periodic face points.
Ran: test_numerical_flux_constructors (5), test_numerical_flux_arguments, test/periodic, test/TADR,
test/LS_with_edgeBased_EV, test/POD, test_adr_problem, solver_tests/test_stokesDC_TH_2D,
mesh_tests/test_quads: 127 passed, 6 skipped, 1 failed (test_ymfrun_knows_which_domains_fix_the_mesh:
the env's ymf has no discretizations.mesh_from_domain; fails the same without this commit).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
C0 round 6 (2.0-only). One commit per item, each with a test that fails without it. macOS arm64, MPICH,
FI_PROVIDER=tcp,-mat_partitioning_type current. Merge after or with #204 (C47): the dambreak_1d deck test skips,saying why, until #204's
staticmethodlimiter attributes are on the branch; nothing here touches TimeIntegration.py.RusanovNumericalFlux(and_Diagonal,ConvexOneSonicPoint) take the ordinary 4-argument call; sweep of all 50 NF_base subclasses__init__call does not bind; dambreak_1d TypeError at NumericalFlux.py:4726 (since 2014)ctimeIntegrationwrappers take TimeIntegration.py's arguments again (broken by the 2019 Cython rewrite, proteustoolkit#879)test/rans2p_ib/beam_channel, rigid or flexible beam) and four faults: JacobianelfNameError; Coefficients dropped every argument; beam loads integrated over ghost elements too; history rows to stdout / not deferredNCLS3P.py76.2 -> 75.6saveSystemStepState/restoreSystemStepStatekeep each model'st_model_last;SO_base.modelStepTaken, i.e. Sequential_MinModelStep, the default)beam_channel_so.py), dye fails: RANS2P_IB skipped in the retry, one step behind after, never reaches T; 9.2e-2 against the failure-free replayCoefficients.state(): the lagged beam drag (q/ebqe_dragBeam*, loads q1-q3) and the beams (xv..zq, each solver's Phi, x, y, z, file counter)Diffusion_IIPG/SIPG_exterior,Stokes_*_IIPG/SIPG_exteriorrefuse periodic conditions (ValueError naming StrongDirichlet); StrongDirichlet, DoNothing, NoFlux measured unaffected and keep themMeasured, not changed: RANS2P_IB's linear Newton rate is RANS2P's (its Jacobian freezes the stabilization tau; with
subgridError.lag=TrueRANS2P_IB converges quadratically), not the beam drag, which is a lagged constant source.Advection_DiagonalUpwind_Diffusion_IIPG_exteriorhas the same periodic-seam defect as the refused fluxes (1.06e-1 vs3.2e-2) but pairs faces and is the base of the mprans VOF/NCLS fluxes that run periodic decks; fix in a later round.
Not in this PR (in the round handoff): the RANS3PSed deck (none has ever existed in this repository; its 6-10-model
sediment chain is missing), the moving-mesh retry (Chrono state), and a measured proposal for node flags without
vertex markers (in-memory and
-Fdiffer, and-Fis partition-dependent; the fix belongs to C32/C7.1 files after adecision).
🤖 Generated with Claude Code