Skip to content

ExplicitBathe: optional local non-viscous damping (-lnvd) for pseudo-static analyses - #1832

Open
jaabell wants to merge 8 commits into
OpenSees:masterfrom
jaabell:feat/explicit-bathe-lnvd
Open

jaabell wants to merge 8 commits into
OpenSees:masterfrom
jaabell:feat/explicit-bathe-lnvd

Conversation

@jaabell

@jaabell jaabell commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

Branch: jaabell:feat/explicit-bathe-lnvd → OpenSees:master
Files: SRC/analysis/integrator/ExplicitBathe.{h,cpp} only

Documentation and examples

Documentation and examples are in a companion PR to OpenSees/OpenSeesDocumentation: OpenSees/OpenSeesDocumentation#202
It updates the ExplicitBathe page (syntax, the new -lnvd option, theory, limitations) and corrects the
existing page: the command is Tcl-only, and a broken substitution, a csv-table error and an unreferenced citation
are fixed. It also adds two verified, downloadable examples:

  • example_bathe_lnvd_sdof_decay.tcl: amplitude decay vs alpha;
  • example_bathe_lnvd_pseudostatic.tcl: converges to the exact static solution.

Summary

Adds an opt-in Cundall/FLAC local non-viscous damping to the explicit Bathe integrator, so that it can
be used for dynamic-relaxation (pseudo-static) analyses, as ExplicitDifferenceStatic already can (its damping was fixed in #1827):

integrator ExplicitBathe $p <$computeCriticalDt> <-lnvd $alpha>
  • -lnvd $alpha, with α in [0, 1), default 0 (off). With α = 0 the integrator is bit-identical to
    current master.
  • The damping is applied to the solved acceleration of each Bathe sub-step, with that sub-step's
    predicted velocity: a_d = a − α|a| sign(v). For the lumped mass an explicit scheme uses, this is the
    Cundall force form F_d = −α|F| sign(v) on F = P − R(u). Because the solved acceleration is fully
    assembled, it is consistent across processes for the parallel diagonal systems, and commands that
    re-form the unbalance (e.g. printB) do not affect the result.

Parser

The positional parser is replaced by an option loop. Old usages keep working:

  • integrator ExplicitBathe $p and integrator ExplicitBathe $p $flag behave as before. Any integer

    0 enables the critical-time-step report; on master a value of 2 silently skipped the computation.

  • -lnvd may appear before or after the flag.
  • An invalid -lnvd value or an unknown option prints a warning and is ignored; damping stays off. An
    invalid p still fails construction, as on master.
  • Numeric arguments coming from the Python interpreter are handled. The integrator remains Tcl-only,
    as on master.

Verification

  • α = 0: displacement, velocity and acceleration after 2000 steps are identical to master to the last
    digit, for both ExplicitBathe 0.54 and ExplicitBathe 0.54 -lnvd 0.0.
  • SDOF free vibration (k = 100, m = 1, u0 = 0.01, dt = 0.01, p = 0.54): max |u| over 3–4 s is
    1.0e-2 / 4.86e-4 / 4.80e-6 for α = 0 / 0.3 / 0.8. With p = 0.5 (no algorithmic dissipation) and
    α = 0.1, the decay ratio matches exp(−2α) within 0.04 %.
  • Pseudo-static hanging chain with -lnvd 0.8: converges to the exact static displacements
    (0.0000 % error).
  • Results are identical with and without printB after each step.
  • Built and tested standalone on current master (Linux, GCC, Conan 2).

Limitations

References

  • Cundall, P.A. (1987). Distinct element models of rock and soil structure. In Analytical and
    Computational Methods in Engineering Rock Mechanics
    , ch. 4.
  • Itasca Consulting Group. FLAC / FLAC3D manuals: local damping.

🤖 Generated with Claude Code

https://claude.ai/code/session_01K524skQQ24A6JCFWNnb7G1

jaabell and others added 8 commits October 1, 2026 19:04
…damping)

Explicit Bathe scheme with FLAC-style local non-viscous damping applied to
the nodal unbalance: Fd = -alpha * |F_unbal| * sign(v).

  integrator ExplicitBatheLNVD $p $alpha <$computeCriticalTimestep>

Extracted from merged-Explicit-ASDP-master (96feda4). Uses class tag 63,
since 62 is now taken upstream by ExplicitDifferenceStatic. The
experimental always-on damping that the same commit added to
ExplicitDifference is not included here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K524skQQ24A6JCFWNnb7G1
…atic runs

Replace the separate ExplicitBatheLNVD class (a fork of the old
ExplicitBathe) by an option of the current integrator:

  integrator ExplicitBathe $p <$computeCriticalDt> <-lnvd $alpha>

With alpha > 0, Cundall/FLAC local non-viscous damping
F_d = -alpha |F_unbal| sign(v) is added to the nodal unbalance at both
sub-steps, for dynamic-relaxation / pseudo-static analyses. alpha = 0
(the default) leaves ExplicitBathe unchanged. alpha is sent with
sendSelf/recvSelf. Removes ExplicitBatheLNVD and its class tag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K524skQQ24A6JCFWNnb7G1
DOF_Group::getUnbalance only holds applied nodal loads; element resisting
forces are assembled separately. Damping computed in formNodalUnbalance
therefore scaled with |P| instead of |P - R(u)| and vanished in free
vibration. Override formUnbalance instead: assemble the full unbalance,
then apply F_d = -alpha |B_i| sign(v_i) per equation using the predicted
velocity of the current sub-step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K524skQQ24A6JCFWNnb7G1
- Accept any integer for the critical-timestep flag again (> 0 enables
  it), as the original positional parser did, instead of only "0"/"1".
- Don't dereference a null OPS_GetString() result: Python returns null
  for numeric arguments; read them as the flag instead.
- Move the getVel() comment back above getVel(); full Cundall (1987)
  citation; note that the damped unbalance includes Rayleigh/modal forces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K524skQQ24A6JCFWNnb7G1
…l option errors

Review follow-ups:
- Apply the local damping to the solved acceleration of each sub-step
  (with that sub-step's predicted velocity) instead of to the assembled
  RHS. Equivalent for the lumped mass an explicit scheme uses, but the
  acceleration is fully assembled across processes for the parallel
  diagonal SOEs, and re-forming the unbalance (printB) no longer changes
  the result.
- Invalid -lnvd values and unknown options are reported and ignored
  instead of returning a null integrator (which could crash Tcl when an
  analysis already exists).

Results are bit-identical to before for alpha = 0 and to the previous
-lnvd formulation for alpha > 0 on lumped-mass models.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K524skQQ24A6JCFWNnb7G1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant