Guide: Mesh Adaptation in Non-Linear Analysis with MACR_ADAP_MAIL
In complex mechanical simulations, maintaining an accurate mesh throughout a non-linear evolution is critical. This guide explores how to implement automatic mesh adaptation using the MACR_ADAP_MAIL macro in code_aster, specifically for cases involving the STAT_NON_LINE solver.
1. Overview of the Adaptation Strategy
The goal is to iteratively refine or derefine the mesh based on an error indicator (Zienkiewicz-Zhu type) to capture localized phenomena like plasticity or high stress gradients.
Key Steps in the Loop:
- Solve: Run
STAT_NON_LINEfor the current time step. - Estimate Error: Calculate the error field (e.g.,
ERZ1_ELEM). - Adapt: Use
MACR_ADAP_MAILto generate a new mesh based on that error. - Project: Transfer internal variables (stresses, hardening) from the old mesh to the new one.
- Equilibrate: Re-solve the current step on the new mesh to ensure a valid starting point for the next increment.
2. Implementing the Adaptation Macro
The MACR_ADAP_MAIL command acts as the brain of the adaptation process. In the provided example, it is configured for “Raffinement/Deraffinement” (RAFF_DERA).
Python
MACR_ADAP_MAIL(
MAILLAGE_N=MA[iNumPas], # Current mesh
MAILLAGE_NP1=MA[iNumPas + 1], # Resulting adapted mesh
ADAPTATION='RAFF_DERA',
RESULTAT_N=RESUNL, # Solution on the old mesh
NOM_CHAM='ERZ1_ELEM', # The error indicator field
NOM_CMP='ERREST',
CRIT_RAFF_PE=0.04, # Refinement threshold
CRIT_DERA_PE=0.4, # Derefinement threshold
NIVE_MAX=4, # Max levels of refinement
MAILLAGE_FRONTIERE=FRONT, # Keeps boundaries intact
MAJ_CHAM=( # Projects displacement to new mesh
_F(CHAM_MAJ=CO('DEPL2'), TYPE_CHAM='NOEU_DEPL_R',
RESULTAT=RESUNL, NOM_CHAM='DEPL', NUME_ORDRE=1),
),
)
Critical Parameters:
CRIT_RAFF_PE: A lower value leads to more aggressive refinement.MAILLAGE_FRONTIERE: Essential to ensure the geometry doesn’t “drift” during the remeshing of the interior.MAJ_CHAM: Updates the displacement field (DEPL) so it can be used as an initial state for the next step.
3. The State Projection (PROJ_CHAMP)
When the mesh changes, the history-dependent variables (plastic strain, internal variables) must be “mapped” from the old Gauss points to the new ones.
Python
# Extract internal variables and stresses from the old model
VARI1 = CREA_CHAMP(OPERATION='EXTR', TYPE_CHAM='ELGA_VARI_R', NOM_CHAM='VARI_ELGA', ...) [cite: 25]
SIGM1 = CREA_CHAMP(OPERATION='EXTR', TYPE_CHAM='ELGA_SIEF_R', NOM_CHAM='SIEF_ELGA', ...) [cite: 29]
# Project onto the NEW model (MO[iNumPas + 1])
VARI2 = PROJ_CHAMP(CHAM_GD=VARI1, MODELE_1=MO[iNumPas], MODELE_2=MO[iNumPas+1], METHODE='ECLA_PG') [cite: 29]
SIGM2 = PROJ_CHAMP(CHAM_GD=SIGM1, MODELE_1=MO[iNumPas], MODELE_2=MO[iNumPas+1], METHODE='ECLA_PG') [cite: 29]
4. Re-Equilibration
Because projection isn’t mathematically perfect, the stresses (SIGM2) might not be in perfect equilibrium on the new mesh. You must run a STAT_NON_LINE step using ETAT_INIT to “settle” the solution before moving to the next time increment.
Python
EQUILIB = STAT_NON_LINE(
MODELE=MO[iNumPas + 1],
CHAM_MATER=CM,
EXCIT=(_F(CHARGE=CH1, FONC_MULT=F_DEPL),),
COMPORTEMENT=_F(RELATION="VMIS_ISOT_TRAC"),
ETAT_INIT=_F(DEPL=DEPL2, SIGM=SIGM2, VARI=VARI2), # Using projected fields
INCREMENT=_F(LIST_INST=L_INST, INST_INIT=iNumPas * DT, INST_FIN=(iNumPas + 1) * DT),
...
)
CloudHPC is a HPC provider to run engineering simulations on the cloud. CloudHPC provides from 1 to 224 vCPUs for each process in several configuration of HPC infrastructure - both multi-thread and multi-core. Current software ranges includes several CAE, CFD, FEA, FEM software among which OpenFOAM, FDS, Blender and several others.
New users benefit of a FREE trial of 300 vCPU/Hours to be used on the platform in order to test the platform, all each features and verify if it is suitable for their needs