Repository navigation
experimental/adrh: boundary kinds (prescribed inflow flux, weak Dirichlet IIPG/NIPG/SIPG) against Proteus - #96
Merged
Merged
Conversation
…t IIPG/NIPG/SIPG) against Proteus
boundary.h has one exterior-face kernel, exteriorFaceKernel, and a BC functor that returns a
kind per component and quadrature point: Strong (nothing on the face), Flux (prescribed
diffusive flux; advective flux prescribed where given, else the interior f(u).n on outflow and
zero on inflow, as StrongDirichlet's 'outFlow' does) and WeakDirichlet (upwinded advective
flux against f(g), -a grad phi.n + (C/h^p)(u - g) with h the face's longest edge, and the
adjoint -sigma (u - g)(a^T n).grad w), each the engine's version of a Proteus exterior
numerical-flux treatment. WeakDirichletParams carries C, p, sigma (2/1/0 IIPG, 10/1/-1 NIPG,
100/1/+1 SIPG, Proteus's class defaults). The header's comment maps every term to the
Proteus routine it follows and names the two deliberate differences (the adjoint's tensor
contraction, da/du in the Jacobian), neither visible with an isotropic constant a.
ad_regression.py gets AD_BC=strong|mixed|inflow|iipg|nipg|sipg, with the Proteus side in
ad_sine_p.py/ad_sine_n.py (StrongDirichletFactory with flux boundary conditions, or
Advection_DiagonalUpwind_Diffusion_{IIPG,NIPG,SIPG}_exterior). Engine and Proteus nodal
solutions agree to 7e-15 or better in every mode at nn = 5, 9, 17; L2 rates 1.85-1.97.
Boundary faces are picked plane by plane: a face whose nodes lie on different planes is
interior.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…sion in 2D and 3D
exteriorFaceKernel is now generic in Coefficients::nSpace (2 or 3): a face is the nS nodes
other than the opposite one, the normal is the edge's perpendicular in 2D and the cross
product in 3D, the penalty's h is the longest face edge (the edge itself in 2D), and the
reference quadrature has nS - 1 coordinates. The Flux kind takes a diffusive flux affine in
the trace, gdiff + dgdiff u, which is what RobinFactory's alpha u + beta q.n = g amounts to
(q.n = g/beta - (alpha/beta) u, Jacobian -alpha/beta). AdvectionDiffusionSine and SineBC are
templates on the dimension; the module's advection_diffusion_sine and
advection_diffusion_sine_faces take nd first.
ad_regression.py: AD_ND=2|3, and a seventh mode AD_BC=robin (face x = 1 carries
alpha u + beta q.n = g with alpha, beta = 1, 2, against RobinFactory over
StrongDirichletFactory({0: 'outFlow'})). Engine and Proteus nodal solutions agree in all
seven modes: 3D (nn 5/9/17) to 7.1e-15, 2D (nn 9/17/33/65) to 4.6e-14; L2 rates 2.00 in 2D,
1.90-1.97 in 3D. Boundary faces are picked plane by plane with the plane count following nd.
Co-Authored-By: Claude Fable 5.1 <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.
Stacked on #91 (base
adrh-engine); the design note's section 14 listed these as the next boundary kinds. Nothing outsideexperimental/adrh/changes.boundary.h: one exterior-face kernel,exteriorFaceKernel, with a BC functor returning a kind per component and boundary quadrature point:Strong(nothing on the face),Flux(prescribed diffusive flux; advective flux prescribed where given, else the interiorf(u).non outflow and zero on inflow, which is whatStrongDirichlet's'outFlow'does),WeakDirichlet(upwinded advective flux againstf(g),-a grad phi.n + (C/h^p)(u - g)withhthe face's longest edge, adjoint-sigma (u - g)(a^T n).grad w).WeakDirichletParams=C, p, sigma: 2/1/0 IIPG, 10/1/-1 NIPG, 100/1/+1 SIPG, Proteus's class defaults. The header comment maps each term to the Proteus routine it follows (calculateExteriorNumericalAdvectiveFlux,calculateExteriorNumericalDiffusiveFlux,updateExteriorElementBoundaryDiffusionAdjoint,computeGeometricInfo_tetrahedronforh) and names two deliberate differences: Proteus's adjoint contracts the tensor by its column sums (equal to(a^T n).grad wonly for diagonala), and its adjoint Jacobian ignoresda/du. Neither shows with an isotropic constanta.ad_regression.py:AD_BC=strong|mixed|inflow|iipg|nipg|sipgselects the treatment on both sides (ad_sine_p.py/ad_sine_n.py:StrongDirichletFactorywith flux boundary conditions, orAdvection_DiagonalUpwind_Diffusion_{IIPG,NIPG,SIPG}_exterior). Boundary faces are picked plane by plane, since a face with nodes on different planes is interior.Engine vs Proteus nodal solutions on the same mesh, nn = 5 / 9 / 17 (max abs difference), and L2 rates:
compare_with_python.pyandcompare_masks.pyare unchanged and still pass (7e-16 / 6e-16; chain nc=5 masked 6.8 us vs 172 us per element). Design note:ADRH_ENGINE_DESIGN.mdsection 15 (beside the campaign notes, not in this repo).Second commit (400144d): 2D segments and Robin fluxes.
exteriorFaceKernelis generic inCoefficients::nSpace(2 or 3): segments of triangles with the edge's perpendicular as normal and the edge length as the penalty'sh, triangles of tetrahedra as before. TheFluxkind's diffusive flux may be affine in the trace (gdiff + dgdiff u), which is whatRobinFactory'salpha u + beta q.n = gamounts to, so Robin needed no new kind.ad_regression.pytakesAD_ND=2|3and a seventh modeAD_BC=robin(againstRobinFactory(base=StrongDirichletFactory({0: 'outFlow'})), alpha, beta = 1, 2).Engine vs Proteus, max nodal difference, all seven modes: 3D (nn 5/9/17) <= 7.1e-15; 2D (nn 9/17/33/65) <= 4.6e-14, growing with system size as the direct solves' round-off does. L2 rates 2.00 in 2D, 1.90-1.97 in 3D. Design note section 16.
🤖 Generated with Claude Code