Skip to content

Commit

Permalink
Scalar trial stress update (#173)
Browse files Browse the repository at this point in the history
* Scalar trial stress update (#173)
* Modify the input file slightly so that the gold file can be reused
* Add unit tests for the two new objects

---------

Co-authored-by: Gary Hu <[email protected]>
  • Loading branch information
dschwen and hugary1995 authored Dec 5, 2024
1 parent 4b342de commit 53b7035
Show file tree
Hide file tree
Showing 9 changed files with 452 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@

namespace neml2
{
/// The plastic flow direction assuming J2 flow.
class J2FlowDirection : public Model
/// The plastic flow direction assuming an associative J2 flow.
class AssociativeJ2FlowDirection : public Model
{
public:
static OptionSet expected_options();

J2FlowDirection(const OptionSet & options);
AssociativeJ2FlowDirection(const OptionSet & options);

protected:
virtual void set_value(bool, bool, bool) override;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2024, UChicago Argonne, LLC
// All Rights Reserved
// Software Name: NEML2 -- the New Engineering material Model Library, version 2
// By: Argonne National Laboratory
// OPEN SOURCE LICENSE (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#pragma once

#include "neml2/models/Model.h"

namespace neml2
{
/**
* @brief Update the trial stress under the assumptions of J2 plasticity and isotropic linear
* elasticity
*
* This allows the construction of fully scalar return mapping models for
* isotropic materials.
*/
class LinearIsotropicElasticJ2TrialStressUpdate : public Model
{
public:
static OptionSet expected_options();

LinearIsotropicElasticJ2TrialStressUpdate(const OptionSet & options);

protected:
/// compute updated trial stress
virtual void set_value(bool out, bool dout_din, bool d2out_din2) override;

/// input trial stress (i.e., assuming a purely elastic step)
const Variable<Scalar> & _elastic_trial_stress;

/// input inelastic strain
const Variable<Scalar> & _inelastic_strain;

/// input old inelastic strain
const Variable<Scalar> & _inelastic_strain_old;

/// output (updated) trial stress
Variable<Scalar> & _updated_trial_stress;

/// Young's modulus
const Scalar & _E;

/// Poisson's ratio
const Scalar & _nu;
};
} // namespace neml2
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,37 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "J2FlowDirection.h"
#include "neml2/models/solid_mechanics/AssociativeJ2FlowDirection.h"
#include "neml2/tensors/SSR4.h"

namespace neml2
{
register_NEML2_object(J2FlowDirection);
register_NEML2_object(AssociativeJ2FlowDirection);

OptionSet
J2FlowDirection::expected_options()
AssociativeJ2FlowDirection::expected_options()
{
auto options = Model::expected_options();
options.doc() = "The plastic flow direction assuming an associative J2 flow.";

options.set<VariableName>("mandel_stress") = VariableName("state", "M");
options.set("mandel_stress").doc() = "Mandel stress";

options.set<VariableName>("flow_direction") = VariableName("state", "NM");
options.set("flow_direction").doc() = "Flow direction";

return options;
}

J2FlowDirection::J2FlowDirection(const OptionSet & options)
AssociativeJ2FlowDirection::AssociativeJ2FlowDirection(const OptionSet & options)
: Model(options),
_M(declare_input_variable<SR2>("mandel_stress")),
_N(declare_output_variable<SR2>("flow_direction"))
{
}

void
J2FlowDirection::set_value(bool out, bool dout_din, bool d2out_din2)
AssociativeJ2FlowDirection::set_value(bool out, bool dout_din, bool d2out_din2)
{
neml_assert_dbg(!d2out_din2, "Second derivatives not implemented");

Expand All @@ -60,10 +66,12 @@ J2FlowDirection::set_value(bool out, bool dout_din, bool d2out_din2)
}

if (dout_din)
{
auto I = SSR4::identity_sym(options());
auto J = SSR4::identity_dev(options());
_N.d(_M) = 3.0 / 2.0 * (I - 2.0 / 3.0 * dvm_dM.outer(dvm_dM)) * J / vm;
}
if (_M.is_dependent())
{
auto I = SSR4::identity_sym(options());
auto J = SSR4::identity_dev(options());

_N.d(_M) = 3.0 / 2.0 * (I - 2.0 / 3.0 * dvm_dM.outer(dvm_dM)) * J / vm;
}
}
} // namespace neml2
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2024, UChicago Argonne, LLC
// All Rights Reserved
// Software Name: NEML2 -- the New Engineering material Model Library, version 2
// By: Argonne National Laboratory
// OPEN SOURCE LICENSE (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "neml2/models/solid_mechanics/LinearIsotropicElasticJ2TrialStressUpdate.h"

namespace neml2
{
register_NEML2_object(LinearIsotropicElasticJ2TrialStressUpdate);

OptionSet
LinearIsotropicElasticJ2TrialStressUpdate::expected_options()
{
OptionSet options = Model::expected_options();

options.doc() = "Update the trial stress under the assumptions of J2 plasticity and isotropic "
"linear elasticity";

options.set_input("elastic_trial_stress") = VariableName("forces", "s");
options.set("elastic_trial_stress").doc() = "Initial trial stress assuming a purely elastic step";

options.set_input("equivalent_plastic_strain") = VariableName("state", "ep");
options.set("equivalent_plastic_strain").doc() =
"Current guess for the equivalent plastic strain";

options.set_output("updated_trial_stress") = VariableName("state", "s");
options.set("updated_trial_stress").doc() =
"Trial stress corrected for the current increment of plastic deformation";

options.set_parameter<CrossRef<Scalar>>("youngs_modulus");
options.set("youngs_modulus").doc() = "Young's modulus";

options.set_parameter<CrossRef<Scalar>>("poisson_ratio");
options.set("poisson_ratio").doc() = "Poisson's ratio";

return options;
}

LinearIsotropicElasticJ2TrialStressUpdate::LinearIsotropicElasticJ2TrialStressUpdate(
const OptionSet & options)
: Model(options),
_elastic_trial_stress(declare_input_variable<Scalar>("elastic_trial_stress")),
_inelastic_strain(declare_input_variable<Scalar>("equivalent_plastic_strain")),
_inelastic_strain_old(declare_input_variable<Scalar>(_inelastic_strain.name().old())),
_updated_trial_stress(declare_output_variable<Scalar>("updated_trial_stress")),
_E(declare_parameter<Scalar>("E", "youngs_modulus", /*allow_nonlinear=*/false)),
_nu(declare_parameter<Scalar>("nu", "poisson_ratio", /*allow_nonlinear=*/false))
{
}

void
LinearIsotropicElasticJ2TrialStressUpdate::set_value(bool out, bool dout_din, bool d2out_din2)
{
const auto three_shear = 3.0 * _E / (2.0 * (1.0 + _nu));

if (out)
_updated_trial_stress =
_elastic_trial_stress - three_shear * (_inelastic_strain - _inelastic_strain_old);

if (dout_din)
{
if (_elastic_trial_stress.is_dependent())
_updated_trial_stress.d(_elastic_trial_stress) = Scalar::identity_map(options());

if (_inelastic_strain.is_dependent())
_updated_trial_stress.d(_inelastic_strain) = -three_shear;

if (_inelastic_strain_old.is_dependent())
_updated_trial_stress.d(_inelastic_strain_old) = three_shear;
}

if (d2out_din2)
{
// zero
}
}
} // namespace neml2
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
stress = 'forces/S'
[]
[trial_flow_direction]
type = J2FlowDirection
type = AssociativeJ2FlowDirection
mandel_stress = 'forces/S'
flow_direction = 'forces/N'
[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ nbatch = 20
stress = 'forces/S'
[]
[trial_flow_direction]
type = J2FlowDirection
type = AssociativeJ2FlowDirection
mandel_stress = 'forces/S'
flow_direction = 'forces/N'
[]
Expand Down
Loading

0 comments on commit 53b7035

Please sign in to comment.