Skip to content

Feature neo hookean - #4

Open
SreejithNREL wants to merge 12 commits into
mainfrom
Feature_Neo_Hookean
Open

Feature neo hookean#4
SreejithNREL wants to merge 12 commits into
mainfrom
Feature_Neo_Hookean

Conversation

@SreejithNREL

Copy link
Copy Markdown
Owner

Neo Hookean constitutive model

SreejithNREL and others added 10 commits August 11, 2026 20:48
…cs where considered in the same code block. a clear bug. corrected it. added constants to make bc type more clear and coder-friendly
…onduction_Convection and Adiabatic are running into bugs. I need to take a look at it. Commiting this dirty version
…cs where considered in the same code block. a clear bug. corrected it. added constants to make bc type more clear and coder-friendly (NatLabRockies#19)

Co-authored-by: SreejithNREL <sreejith.nadakkalappukuttan@nlr.gov>
* corrected bug about temperature bcs. Earlier periodic and adiabatic bcs where considered in the same code block. a clear bug. corrected it. added constants to make bc type more clear and coder-friendly

* corrected a bug where in splines were using a wrong stencil for periodic bcs

---------

Co-authored-by: SreejithNREL <sreejith.nadakkalappukuttan@nlr.gov>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a Neo-Hookean constitutive model into the MPM solver while also updating several preprocessing scripts/configs (notably adding configurable particle density and standardizing some test preprocessing behaviors), and refining temperature boundary-condition handling.

Changes:

  • Add Neo-Hookean solid support (constitutive model ID 2) in particle stress update and particle-file parsing.
  • Update temperature BC handling and convective BC formulation to use node conductivity-derived Biot number.
  • Update multiple test preprocessors/configs (density parameter, HDF5 defaults, auto-tag behavior, cleanup/removal of unused helper functions).

Reviewed changes

Copilot reviewed 26 out of 27 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
Tests/Elastic_disk_collision/PreProcess/Generate_MPs_Inputfile_Generic.py Thread density from config into particle generation; remove unused legacy generation/plotting helpers.
Tests/Elastic_disk_collision/PreProcess/config.json Add density field; update output_tag/build_system metadata.
Tests/Dam_Break/PreProcess/Generate_MPs_Inputfile_Generic.py Thread density from config into particle generation; remove unused legacy generation/plotting helpers.
Tests/Dam_Break/PreProcess/config.json Add density field; update output_tag/build_system metadata.
Tests/Dam_Break_With_Obstacles/PreProcess/Generate_MPs_Inputfile_Generic.py Thread density from config into particle generation; remove unused legacy generation/plotting helpers; adjust EB-related inputs.
Tests/2D_Heat_Conduction/PreProcess/Generate_MPs_Inputfile_Generic.py Thread density from config into particle generation; remove unused legacy generation/plotting helpers.
Tests/2D_Heat_Conduction/PreProcess/config.json Add density; switch preprocessing output to HDF5 and enable HDF5 build.
Tests/2D_Heat_Conduction_Cylinder_Dirichlet/PreProcess/Generate_MPs_Inputfile_Generic.py Thread density from config into particle generation; remove unused legacy generation/plotting helpers.
Tests/2D_Heat_Conduction_Cylinder_Dirichlet/PreProcess/config.json Add density field.
Tests/1D_Heat_Conduction/PreProcess/Generate_MPs_Inputfile_Generic.py Thread density from config into particle generation; remove unused legacy generation/plotting helpers.
Tests/1D_Heat_Conduction/PreProcess/config.json Add density; switch preprocessing output to HDF5 and enable HDF5 build.
Tests/1D_Heat_Conduction_HeatFlux/PreProcess/Generate_MPs_Inputfile_Generic.py Thread density from config into particle generation; remove unused legacy generation/plotting helpers.
Tests/1D_Heat_Conduction_HeatFlux/PreProcess/config.json Add density; update build_system/output_tag metadata.
Tests/1D_Heat_Conduction_Convective/PreProcess/Generate_MPs_Inputfile_Generic.py Thread density from config into particle generation; remove unused legacy generation/plotting helpers.
Tests/1D_Heat_Conduction_Convective/PreProcess/config.json Add density; adjust ppc/boundary_conditions; update build_system/output_tag metadata.
Tests/1D_Heat_Conduction_Convective/Generate_MPs_and_InputFiles.sh Update how the preprocessing script is invoked.
Tests/1D_Axial_Bar_Vibration/PreProcess/Generate_MPs_Inputfile_Generic.py Thread density from config into particle generation; remove unused legacy generation/plotting helpers.
Tests/1D_Axial_Bar_Vibration/PreProcess/config.json Add density; switch preprocessing output to HDF5 and enable HDF5 build.
Source/utilities.cpp Simplify Apply_Nodal_BCs_Temperature flow and pass through dirichlet_only to EB temperature BCs.
Source/nodal_data_ops.cpp Use node conductivity-derived Biot number for convective temperature BCs.
Source/mpm_specs.H Map temperature BC strings to named BC constants instead of hard-coded integers.
Source/mpm_particle_timestep.cpp Include constitutive model ID 2 in timestep wave-speed logic.
Source/mpm_particle_container.cpp Add Neo-Hookean constitutive model branch using deformation gradient.
Source/mpm_init.cpp Parse constitutive model ID 2 from particle files and read E/nu for it.
Source/constitutive_models.H Update plane-strain components; add Neo-Hookean stress implementation and supporting tensor helper.
Developer_Tools/Run_All_Tests.py Include density in generated configs; adjust parameter sweep spaces and enable additional sweeps.
.gitignore Ignore Python __pycache__ and sweep output file.
Suppressed comments (1)

Source/mpm_particle_timestep.cpp:63

  • Calculate_time_step() treats constitutive_model==2 (neo-Hookean) like a fluid and computes Cs from Bulk_modulus, but particles with constitutive_model==2 are initialized with Bulk_modulus = 0.0 (see mpm_init.cpp:1072). This makes Cs=0 and can produce an overly large timestep.
                if (p.idata(intData::constitutive_model) == 1 or
                    p.idata(intData::constitutive_model) == 2)
                {
                    Cs = std::sqrt(p.rdata(realData::Bulk_modulus) /
                                   p.rdata(realData::density));
                }

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

0.0,
0.0
],
"density": 1.0,
left_cauchy_green(const amrex::Real F[NCOMP_FULLTENSOR],
amrex::Real b[NCOMP_TENSOR])
{
constexpr int d = AMREX_SPACEDIM; // stride into F, NOT 3
#if (AMREX_SPACEDIM == 1)
detF = F[0];
#elif (AMREX_SPACEDIM == 2)
detF = F[0] * F[3] - F[1] * F[2];
Comment on lines +189 to +193
*
* Implements compressible neo-hookean elasticity in 1D, 2D, or 3D depending on
* AMREX_SPACEDIM. Uses Young’s modulus (E) and Poisson’s ratio (v) to form
* the constitutive matrix and multiplies it by the strain tensor eps[].
*
Comment thread Source/utilities.cpp
Comment on lines +228 to +235
nodal_bcs_temperature(
geom, nodaldata, specs.bclo_temp.data(), specs.bchi_temp.data(),
specs.bc_temp_T_wall_lo.data(), specs.bc_temp_T_wall_hi.data(),
specs.bc_temp_flux_lo.data(), specs.bc_temp_flux_hi.data(),
specs.bc_temp_h_lo.data(), specs.bc_temp_h_hi.data(),
specs.bc_temp_Tinf_lo.data(), specs.bc_temp_Tinf_hi.data());
compute_udf_temp_at_nodes(geom, specs, t);
apply_udf_nodal_bcs_temperature(geom, nodaldata, specs);
@@ -1 +1 @@
python3 ./PreProcess/Generate_MPs_Inputfile_Generic.py --config ./PreProcess/config.json
python ./PreProcess/Generate_MPs_Inputfile_Generic.py --config ./PreProcess/config.json

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 27 changed files in this pull request and generated 4 comments.

Suppressed comments (5)

Tests/Elastic_disk_collision/PreProcess/config.json:97

  • This duplicates the top-level density key already set to 997.0 on line 73. Python's json.load silently keeps this later value, so manual preprocessing generates the elastic disks at density 1.0 instead of the intended 997.0. Remove this duplicate entry.
  "density": 1.0,

Tests/1D_Heat_Conduction_Convective/Generate_MPs_and_InputFiles.sh:1

  • Use python3 here, as the other generator scripts do (for example Tests/1D_Heat_Conduction/Generate_MPs_and_InputFiles.sh:1). Many supported environments provide python3 without a python alias, so the changed command can fail before preprocessing starts.
python ./PreProcess/Generate_MPs_Inputfile_Generic.py --config ./PreProcess/config.json

Source/utilities.cpp:232

  • dirichlet_only no longer affects configured domain boundaries. On MUSL's first thermal pass (main.cpp:103-104), this now applies heat-flux and convection conditions even though that pass is explicitly Dirichlet-only, before applying the full conditions again on the second pass. Restore the filtered boundary-type arrays when this flag is true.
    nodal_bcs_temperature(
        geom, nodaldata, specs.bclo_temp.data(), specs.bchi_temp.data(),
        specs.bc_temp_T_wall_lo.data(), specs.bc_temp_T_wall_hi.data(),
        specs.bc_temp_flux_lo.data(), specs.bc_temp_flux_hi.data(),
        specs.bc_temp_h_lo.data(), specs.bc_temp_h_hi.data(),

Source/constitutive_models.H:139

  • This out-of-plane component mixes a 3D deviatoric correction (trace/3) with the in-plane components above, which use the 2D correction (trace/2). Consequently the viscous deviatoric stress is not trace-free, contrary to the documented 2μ ε̇_dev model. Use one consistent 2D convention, or switch all three plane-strain components to the 3D trace correction.
    sigma[ZZ] = 2 * dyn_visc * (epsdot[ZZ] - trace_epsdot / 3.0) - pressure;

Source/constitutive_models.H:204

  • The new constitutive model has no automated case that selects constitutive-model ID 2 or verifies its stress response; the existing test configurations cover only elastic and fluid models. Add a finite-deformation regression that exercises initialization, CFL calculation, and Neo-Hookean stress in a supported dimension/output format.
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void
neo_hookean(amrex::Real sigma[NCOMP_TENSOR],
            const amrex::Real F[NCOMP_FULLTENSOR],
            amrex::Real E,
            amrex::Real v)

Comment thread Source/mpm_particle_timestep.cpp Outdated
Comment on lines 58 to 62
if (p.idata(intData::constitutive_model) == 1 or
p.idata(intData::constitutive_model) == 2)
{
Cs = std::sqrt(p.rdata(realData::Bulk_modulus) /
p.rdata(realData::density));
Comment thread Source/mpm_init.cpp
Comment on lines +1068 to +1072
else if (p.idata(intData::constitutive_model) == 2)
{
safe_read(ifs, p.rdata(realData::E), "Error reading E");
safe_read(ifs, p.rdata(realData::nu), "Error reading nu");
p.rdata(realData::Bulk_modulus) = 0.0;
matpt_filename = cfg["materialpoint_filename"]
plot_to_check = cfg["plot_to_check"]
CFL = cfg["CFL"]
density = cfg["density"]
Comment on lines +126 to +130
else if (p.idata(intData::constitutive_model) == 2)
{
// Neo-Hookean solid
neo_hookean(stress, deformation_gradient,
p.rdata(realData::E),

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 27 changed files in this pull request and generated no new comments.

Suppressed comments (15)

Source/utilities.cpp:229

  • When dirichlet_only is true (the first MUSL thermal pass), this now passes the full BC arrays, so heat-flux and convection conditions are applied during the predictor pass and then again during the second pass. Preserve the filtering for domain BCs just as nodal_levelset_bcs_temperature does.
        geom, nodaldata, specs.bclo_temp.data(), specs.bchi_temp.data(),

Tests/Elastic_disk_collision/PreProcess/config.json:97

  • This file now contains two root-level density keys (997.0 at line 73 and 1.0 here). Python's JSON loader silently keeps the latter, so the elastic-disk particles are generated at density 1.0 instead of the intended 997.0.
  "density": 1.0,

Tests/Dam_Break_With_Obstacles/PreProcess/Generate_MPs_Inputfile_Generic.py:1210

  • All three obstacle configurations omit density, so this required lookup raises KeyError before particle generation. Add density to every obstacle config or retain the previous 997.0 default here.
    density = cfg["density"]

Tests/1D_Heat_Conduction_Convective/Generate_MPs_and_InputFiles.sh:1

  • The other test launchers consistently use python3; changing this one to python breaks generation on systems where no unversioned Python executable is installed.
python ./PreProcess/Generate_MPs_Inputfile_Generic.py --config ./PreProcess/config.json

Source/constitutive_models.H:139

  • This out-of-plane term uses a 3D trace/3 correction while the in-plane terms above still use the 2D trace/2 correction. The resulting viscous deviator is not traceless. Keep sigma[ZZ] zero for the existing 2D formulation, or consistently convert all three normal components to a plane-strain 3D formulation.
    sigma[ZZ] = 2 * dyn_visc * (epsdot[ZZ] - trace_epsdot / 3.0) - pressure;

Source/constitutive_models.H:204

  • The new Neo-Hookean path has no integration or unit test: repository test configurations still select only elastic or fluid. Add a case that loads model ID 2 and verifies zero stress at identity plus a known finite deformation, so the preprocessing, HDF5/ASCII loading, and constitutive formula are exercised.
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void
neo_hookean(amrex::Real sigma[NCOMP_TENSOR],
            const amrex::Real F[NCOMP_FULLTENSOR],
            amrex::Real E,
            amrex::Real v)

Tests/Elastic_disk_collision/PreProcess/Generate_MPs_Inputfile_Generic.py:1205

  • Blank output tags now call make_auto_tag_from_cfg, but that helper indexes root-level constitutive_model and temperature keys while this script's configs store both under bodies. A blank tag therefore raises KeyError instead of being generated.
    if(output_tag==""):
        output_tag = make_auto_tag_from_cfg(cfg)

Tests/Dam_Break/PreProcess/Generate_MPs_Inputfile_Generic.py:1205

  • Blank output tags now call make_auto_tag_from_cfg, but that helper indexes root-level constitutive_model and temperature keys while this script's configs store both under bodies. A blank tag therefore raises KeyError instead of being generated.
    if(output_tag==""):
        output_tag = make_auto_tag_from_cfg(cfg)

Tests/Dam_Break_With_Obstacles/PreProcess/Generate_MPs_Inputfile_Generic.py:1205

  • Blank output tags now call make_auto_tag_from_cfg, but that helper indexes root-level constitutive_model and temperature keys while this script's configs store both under bodies. A blank tag therefore raises KeyError instead of being generated.
    if(output_tag==""):
        output_tag = make_auto_tag_from_cfg(cfg)

Tests/2D_Heat_Conduction/PreProcess/Generate_MPs_Inputfile_Generic.py:1205

  • Blank output tags now call make_auto_tag_from_cfg, but that helper indexes root-level constitutive_model and temperature keys while this script's configs store both under bodies. A blank tag therefore raises KeyError instead of being generated.
    if(output_tag==""):
        output_tag = make_auto_tag_from_cfg(cfg)

Tests/2D_Heat_Conduction_Cylinder_Dirichlet/PreProcess/Generate_MPs_Inputfile_Generic.py:1205

  • Blank output tags now call make_auto_tag_from_cfg, but that helper indexes root-level constitutive_model and temperature keys while this script's configs store both under bodies. A blank tag therefore raises KeyError instead of being generated.
    if(output_tag==""):
        output_tag = make_auto_tag_from_cfg(cfg)

Tests/1D_Heat_Conduction/PreProcess/Generate_MPs_Inputfile_Generic.py:1205

  • Blank output tags now call make_auto_tag_from_cfg, but that helper indexes root-level constitutive_model and temperature keys while this script's configs store both under bodies. A blank tag therefore raises KeyError instead of being generated.
    if(output_tag==""):
        output_tag = make_auto_tag_from_cfg(cfg)

Tests/1D_Heat_Conduction_HeatFlux/PreProcess/Generate_MPs_Inputfile_Generic.py:1205

  • Blank output tags now call make_auto_tag_from_cfg, but that helper indexes root-level constitutive_model and temperature keys while this script's configs store both under bodies. A blank tag therefore raises KeyError instead of being generated.
    if(output_tag==""):
        output_tag = make_auto_tag_from_cfg(cfg)

Tests/1D_Heat_Conduction_Convective/PreProcess/Generate_MPs_Inputfile_Generic.py:1205

  • Blank output tags now call make_auto_tag_from_cfg, but that helper indexes root-level constitutive_model and temperature keys while this script's configs store both under bodies. A blank tag therefore raises KeyError instead of being generated.
    if(output_tag==""):
        output_tag = make_auto_tag_from_cfg(cfg)

Tests/1D_Axial_Bar_Vibration/PreProcess/Generate_MPs_Inputfile_Generic.py:1205

  • Blank output tags now call make_auto_tag_from_cfg, but that helper indexes root-level constitutive_model and temperature keys while this script's configs store both under bodies. A blank tag therefore raises KeyError instead of being generated.
    if(output_tag==""):
        output_tag = make_auto_tag_from_cfg(cfg)

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.

3 participants