0

EOS5 / custom capillary-pressure modification: negative pressure and convergence issues when using nonzero entry pressure

Hello everyone,

I am working on a TOUGH3 EOS5 case for a Nuclear waste-cell / FORGE-type model with water + hydrogen and a rectilinear mesh.

I modified the capillary-pressure handling to use a custom negative capillary-pressure convention, and I am trying to keep a nonzero entry pressure (PE) in some materials. I would like help understanding whether the issue is in my constitutive formulation, my EOS modifications, or the way I am handling phase transitions.

What I am doing

I am using EOS5 (water + H2) and a custom PCAP function based on an SGM-type formulation.

In my model:

  • PCP(1) is negative

  • I am effectively using
    Pl = Pg + Pc

Some materials have a nonzero entry pressure, but Cledz clearly triggers the convergence problem.

  • Claym: PE = 2.0E+6

  • Bento: PE = 1.33E+6

  • Cledz: PE = 0.67E+6

  • Dredz: PE = 0.67E+6

The important point is that the issue appears specifically when Cledz uses PE = 0.67E+6.

If I keep Cledz = 0.67E+6, the model develops convergence problems.
If I set Cledz = 0, the model runs well.

So the problem seems to be specifically associated with activating PE = 0.67E+6 in Cledz.

Main symptom

At runtime, I get repeated timestep reductions and then errors like:

NO CONVERGENCE IN SUBROUTINE PP
+++++++++   CANNOT FIND PARAMETERS AT ELEMENT * 554*      XX(M) = -0.60568E+06  0.15715E-06  0.20000E+02

TOUGH ERROR: Error in the Time-dependent bc values.

So the liquid pressure becomes strongly negative because Pc is negative and large in magnitude.

My custom EOS behaviour

In the EOS, the primary variables are updated in the usual way:
 

XX(M)=X(NLOC+M)+XINCR

And I found that XX(1) can become negative during Newton iterations.
 

I tried temporarily protecting pressure with:

XX(1)=MAX(XX(1),1.0D0)

and this keeps the pressure stable enough to continue farther, but I know this is a numerical safeguard and may also affect the solution.

In the two-phase → liquid transition block, I also have logic like:
 

CALL PCAP(SATU,TX,PCP,NPH,NMAT,USRX,K)
pee = -PCP(1)
xx(1)=px-pee
DX(NLOC+1)=XX(1)-X(NLOC+1)

Since PCP(1) is negative, this is equivalent to resetting pressure with px + PCP(1).

My custom PCAP routine

My custom capillary-pressure routine uses a negative capillary-pressure convention. The relevant part is:
 

PC_0=-1.0D0/CP(3,NMAT)
PCE=-CP(6,NMAT)
...
PC=SE**(-1.0D0/AM)-1.0D0
PC=PC**(1.0D0-AM)
PC=PC_0*PC
IF(CP(4,NMAT).NE.0.0D0) PC=MAX(PC,-ABS(CP(4,NMAT)))
PCP(1)=PC

So CP(4) is acting as a soft cap on how negative Pc can become.

Parameter tests I tried

I tested several things:

  • setting PE = 0 → model runs well

  • keeping PE > 0 → convergence problems return

  • lowering CP(4) from 1.0E9 to 1.0E5 helped a bit

  • lowering CP(4) too much (for example 1.0E4) caused linear-solver issues

However, even after these changes, I still see PP failures and negative pressures during Newton iterations.

My question

I would appreciate advice on the following:

  1. Is this negative-Pc convention fundamentally problematic in EOS5, or can it be made robust?

  2. Is the main issue likely to be:

    • my PCAP formulation,

    • the EOS phase-transition reset logic,

    • Or the Newton update of pressure?

  3. For people who have implemented custom capillary-pressure laws in TOUGH3:

    • Is it better to limit DX for pressure?

    • protect XX(1),

    • or reformulate the phase-transition pressure reset?

  4. Has anyone used a similar nonzero PE formulation successfully with EOS5 / H2–water systems?

Summary

  • EOS: EOS5

  • Components: water + hydrogen

  • The problem appears only when a nonzero entry pressure is used

  • PE = 0 runs fine

  • Custom PCAP returns negative PCP(1)

  • Repeated failures occur in PP, with XX(1) becoming negative

  • Sometimes the run later stops with Time-dependent bc values or VISCOH2 range errors

Any suggestions on the best way to keep the physical nonzero PE while avoiding these EOS/convergence failures would be very helpful.

Thank you.

3 replies

null
    • kenny
    • 22 hrs ago
    • Reported - view

    Great problem statement — this is very likely a sign-consistency issue plus Newton overshoot, not just a single bad parameter.

     

    From your description, the key risk is that EOS5 internals are generally written around the convention

    Pc = Pg - Pl (nonnegative),

    while your custom path uses negative Pc and then applies transformations in multiple places (PCAP, phase-transition reset, BC checks). If even one branch still assumes the native sign, PP/BC lookups can receive unphysical pressure states (as you see with XX(1) < 0).

     

    What I would do (in order):

     

    1) Keep one internal convention everywhere (recommended: native EOS sign)

    - Return PCP(1) as nonnegative capillary pressure inside EOS routines.

    - If you want negative Pc for reporting, apply the sign only at I/O boundaries (plots/output), not in state updates.

     

    2) Recheck the two-phase -> liquid reset formula

    - With native convention: Pl = Pg - Pc.

    - Your current reset xx(1)=px+PCP(1) is only correct if PCP is negative everywhere and all downstream code also expects that. Any mixed usage causes exactly this failure mode.

     

    3) Use step limiting on DX(pressure), not hard clipping XX(1)

    - Hard clamp XX(1)=MAX(XX(1),...) can hide inconsistency and hurt Newton convergence.

    - Better: damp the pressure increment (trust-region style), then recompute residual/Jacobian.

     

    4) Smooth entry-pressure activation

    - Nonzero PE introduces a kink if implemented as hard max/min. Ensure Pc(Sl) and dPc/dSl are continuous around the entry transition (small smoothing interval).

     

    5) Run a minimal 1-element/1D debug case with identical constitutive law

    - Log per Newton iteration: Pg, Pl, PCP, Sg, dPc/dS, and the exact branch taken in phase-transition reset.

    - First target: prove all branches preserve the same identity (Pc = Pg - Pl).

     

    Quick diagnostic for your current run:

    - For the failing element/time step, print both

      A = Pg - Pl

      B = PCP(1)

      and their sign.

    If A and B differ by sign or magnitude after a branch switch, that is the root cause.

     

    So to your direct question: yes, a negative-Pc convention can be made to work, but only if every EOS/transition/BC path is transformed consistently. In practice, it is much more robust to keep native sign internally and only map sign at output.

     

    If useful, I can sketch a branch-by-branch checklist for EOS5 transition points (single-phase liquid, two-phase, boundary-condition update) to verify consistency quickly.

      • Abdelrazik_Elfar
      • 20 hrs ago
      • Reported - view

       

      Thank you for your prompt reply.

      Yes, if you could sketch the branch-by-branch checklist, that would be very helpful. I agree with your point that this is likely a sign-consistency issue together with Newton overshoot, rather than simply a bad parameter choice.

      • kenny
      • 17 hrs ago
      • Reported - view

       

      Great—here is a compact branch-by-branch checklist you can run in EOS5.

      1. One internal sign convention (global)
      • Decide one internal identity and enforce it everywhere (recommended: Pc = Pg - Pl >= 0).
      • In each routine that touches pressure/capillary terms, log once at startup which convention it assumes.
      1. PCAP return contract
      • Verify PCAP always returns the same sign/units for all materials (including Cledz).
      • Log per call (debug mode): material, Sg/Sl, PCP(1), dPc/dS, clamp trigger.
      • Confirm continuity near entry-pressure activation (no derivative jump spike).
      1. Primary-variable update stage (Newton)
      • After XX update, log XX(1), DX pressure component, and damping factor.
      • Add pressure-increment limiter (DX) before residual recomputation; avoid hard XX clamp unless emergency.
      1. Phase-transition branch reset (2-phase <-> liquid)
      • At each transition branch, log pre/post values of Pg, Pl, Pc, and branch ID.
      • Immediately check invariant: A = Pg - Pl, B = Pc_internal.
      • If |A-B| exceeds tolerance right after branch switch, that branch is the bug source.
      1. BC/source-sink interface checks
      • Before PP/BC lookup, print the same invariant (A vs B) plus effective phase state.
      • This catches sign mismatch crossing from EOS state update into BC routines.
      1. Material-isolated reproduction
      • Run minimal case with only Cledz constitutive settings first.
      • Then add one neighboring material at a time.
      • Compare first timestep/element where invariant fails.
      1. Convergence decision rule
      • If invariant holds but Newton still diverges -> tune numerics (DX damping, timestep control).
      • If invariant breaks at branch boundary -> fix branch algebra/sign mapping first (do not tune parameters yet).

Content aside

  • 17 hrs agoLast active
  • 3Replies
  • 12Views
  • 2 Following