# EXPORT CONTROLLED — ITAR USML Category XX  (Ocean Guard M06A)
# Code_Aster STAT_NON_LINE hyperelastic O-ring/groove contact — AS568A-333 EPDM 90A.
# Auto-generated by oring_hyperelastic_comm.py. Do not hand-edit.
DEBUT(LANG='EN')

MESH = LIRE_MAILLAGE(FORMAT='MED', UNITE=20)

# D_PLAN (plane strain), not AXIS — see module docstring 2026-07-09 note
# (ELASHYPER_97: this Aster build forbids ELAS_HYPER+AXIS outright).
MODEL = AFFE_MODELE(
    MAILLAGE=MESH,
    AFFE=_F(TOUT='OUI', PHENOMENE='MECANIQUE', MODELISATION='D_PLAN'),
)

# EPDM 90A hyperelastic Mooney-Rivlin (dual-oring-sealing skill FEM baseline).
MAT = DEFI_MATERIAU(
    ELAS_HYPER=_F(C10=5.500000e+05, C01=1.400000e+05, C20=0.0, K=2.000000e+09),
)

FIELDMAT = AFFE_MATERIAU(MAILLAGE=MESH, AFFE=_F(TOUT='OUI', MATER=MAT))

# Groove floor fixed. Gland face ramps to the full squeeze displacement
# (0.9800 mm = 21.9% squeeze on CS=4.47mm).
LOAD_FIXED = AFFE_CHAR_MECA(
    MODELE=MODEL,
    DDL_IMPO=_F(GROUP_MA='GROOVE_FLOOR', DX=0.0, DY=0.0),
)

RAMP = DEFI_FONCTION(
    NOM_PARA='INST',
    VALE=(0.0, 0.0, 1.0, 1.0),
    PROL_DROITE='CONSTANT', PROL_GAUCHE='CONSTANT',
)

LOAD_SQUEEZE = AFFE_CHAR_MECA(
    MODELE=MODEL,
    DDL_IMPO=_F(GROUP_MA='GLAND_FACE', DY=9.800000e-04),
)

# NOTE (2026-07-03 fix, SUPERVIS_4): ZONE/ALGO_FROT is only an authorized
# keyword when FROTTEMENT='COULOMB' is also declared on the ZONE — Aster
# 17.4 rejects ALGO_FROT on a frictionless zone ("Unauthorized keyword:
# 'ALGO_FROT'"). Round-1 O-ring squeeze model is frictionless (no COULOMB
# law defined), so ALGO_FROT is simply dropped — ALGO_CONT='STANDARD'
# alone fully defines the normal-contact-only zone.
CONTACT = DEFI_CONTACT(
    MODELE=MODEL,
    FORMULATION='CONTINUE',
    ZONE=(
        _F(GROUP_MA_ESCL='O_RING_OUTER', GROUP_MA_MAIT='GLAND_FACE_MAIT',
           ALGO_CONT='STANDARD'),
    ),
)

LINST = DEFI_LIST_REEL(DEBUT=0.0, INTERVALLE=_F(JUSQU_A=1.0, NOMBRE=40))

DLIST = DEFI_LIST_INST(
    METHODE='AUTO',
    DEFI_LIST=_F(LIST_INST=LINST),
    ECHEC=_F(ACTION='DECOUPE', SUBD_METHODE='MANUEL', SUBD_PAS=4, SUBD_NIVEAU=6),
)

# STAT_NON_LINE — large displacement + hyperelastic (ELAS_HYPER) + contact.
# NOTE (2026-07-08 fix, COMPOR1_44): Code_Aster 17.4 rejects
# DEFORMATION='GROT_GDEP' combined with RELATION='ELAS_HYPER'
# ("<EXCEPTION> <COMPOR1_44> Le type de deformation choisi <GROT_GDEP> est
# incompatible avec le comportement <ELAS_HYPER>") — box-confirmed real
# run, first real STAT_NON_LINE attempt on this .comm. Same class of fix
# already applied in gate_codeaster_nonlinear.py's generate_comm_file()
# (that file's own 2026-07-03 COMPOR5_22 note): Aster's own exception text
# recommends GREEN_LAGRANGE as the large-strain-compatible alternative for
# hyperelastic materials on this mesh/element combination.
RESU = STAT_NON_LINE(
    MODELE=MODEL,
    CHAM_MATER=FIELDMAT,
    EXCIT=(
        _F(CHARGE=LOAD_FIXED),
        _F(CHARGE=LOAD_SQUEEZE, FONC_MULT=RAMP),
    ),
    CONTACT=CONTACT,
    COMPORTEMENT=_F(RELATION='ELAS_HYPER', DEFORMATION='GREEN_LAGRANGE', TOUT='OUI'),
    INCREMENT=_F(LIST_INST=DLIST),
    NEWTON=_F(MATRICE='TANGENTE', REAC_ITER=1),
    CONVERGENCE=_F(RESI_GLOB_RELA=1.0e-5, ITER_GLOB_MAXI=30),
)

RESU = CALC_CHAMP(reuse=RESU, RESULTAT=RESU, CONTRAINTE=('SIEF_NOEU',))

IMPR_RESU(FORMAT='RESULTAT', RESU=_F(RESULTAT=RESU, NOM_CHAM='DEPL'))

# Peak contact (Lagrange) pressure at the O-ring/gland contact surface.
TAB_CONTACT = POST_RELEVE_T(
    ACTION=_F(INTITULE='CONTACT_PRESSURE', GROUP_NO='O_RING_OUTER', RESULTAT=RESU,
              NOM_CHAM='CONT_NOEU', NOM_CMP='LAGR_C', OPERATION='EXTREMA'),
)

# Deterministic Python-level marker (round-1 coarse extraction — see module
# docstring). .comm files ARE Python; printing our own tagged marker avoids
# depending on Aster's table layout.
_max_contact_pa = 0.0
try:
    _arr = TAB_CONTACT.EXTR_TABLE().Array('NOEUD', 'LAGR_C')
    _max_contact_pa = max(abs(float(row[1])) for row in _arr) if len(_arr) else 0.0
except Exception:
    import re as _re
    _raw = str(TAB_CONTACT)
    _nums = _re.findall(r"[-+]?\d+\.\d+E[-+]\d+", _raw)
    _vals = [abs(float(n)) for n in _nums]
    _max_contact_pa = max(_vals) if _vals else 0.0

print("OG_CONTACT_PRESSURE_PA=%.6E" % _max_contact_pa)
print("OG_CONTACT_GATE_MPA=%.4f" % 30.0000)

FIN()
