LCOV - code coverage report
Current view: top level - models/solid_mechanics - TwoStageThermalAnnealing.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 44 44
Test Date: 2025-06-29 01:25:44 Functions: 100.0 % 6 6

            Line data    Source code
       1              : // Copyright 2024, UChicago Argonne, LLC
       2              : // All Rights Reserved
       3              : // Software Name: NEML2 -- the New Engineering material Model Library, version 2
       4              : // By: Argonne National Laboratory
       5              : // OPEN SOURCE LICENSE (MIT)
       6              : //
       7              : // Permission is hereby granted, free of charge, to any person obtaining a copy
       8              : // of this software and associated documentation files (the "Software"), to deal
       9              : // in the Software without restriction, including without limitation the rights
      10              : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      11              : // copies of the Software, and to permit persons to whom the Software is
      12              : // furnished to do so, subject to the following conditions:
      13              : //
      14              : // The above copyright notice and this permission notice shall be included in
      15              : // all copies or substantial portions of the Software.
      16              : //
      17              : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      18              : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      19              : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      20              : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      21              : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      22              : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      23              : // THE SOFTWARE.
      24              : 
      25              : #include "neml2/models/solid_mechanics/TwoStageThermalAnnealing.h"
      26              : #include "neml2/tensors/Scalar.h"
      27              : #include "neml2/tensors/SR2.h"
      28              : #include "neml2/tensors/SSR4.h"
      29              : #include "neml2/misc/string_utils.h"
      30              : #include "neml2/tensors/functions/where.h"
      31              : 
      32              : namespace neml2
      33              : {
      34              : #define REGISTER(T)                                                                                \
      35              :   using T##TwoStageThermalAnnealing = TwoStageThermalAnnealing<T>;                                 \
      36              :   register_NEML2_object(T##TwoStageThermalAnnealing);                                              \
      37              :   template class TwoStageThermalAnnealing<T>
      38              : REGISTER(Scalar);
      39              : REGISTER(SR2);
      40              : 
      41              : template <typename T>
      42              : OptionSet
      43            4 : TwoStageThermalAnnealing<T>::expected_options()
      44              : {
      45              :   // This is the only way of getting tensor type in a static method like this...
      46              :   // Trim 6 chars to remove 'neml2::'
      47            4 :   auto tensor_type = utils::demangle(typeid(T).name()).substr(7);
      48              : 
      49            4 :   OptionSet options = Model::expected_options();
      50            4 :   options.doc() =
      51              :       "Thermal annealing recovery for a hardening variable of type " + tensor_type +
      52              :       "."
      53              :       "For temperatures below \\f$ T_1 \\f$ the model keeps the base model hardenign rate."
      54              :       "For temperatures above \\f$T_1\\f$ but below \\f$T_2 \\f$ the model zeros the hardening "
      55              :       "rate."
      56              :       "For temperatures above \\f$T_2\\f$ the model replaces the hardening rate with "
      57              :       "\\f$ \\dot{h} = \\frac{-h}{\\tau} \\f$ where \\f$ \\tau \\f$ is the rate of recovery.";
      58              : 
      59            8 :   options.set_input("base_rate");
      60            8 :   options.set("base_rate").doc() = "Base hardening rate";
      61              : 
      62            8 :   options.set_input("base");
      63            8 :   options.set("base").doc() = "Underlying base hardening variable";
      64              : 
      65            8 :   options.set_output("modified_rate");
      66            4 :   options.set("modified_rate").doc() = "Output for the modified hardening rate.";
      67              : 
      68           12 :   options.set_input("temperature") = VariableName(FORCES, "T");
      69            8 :   options.set("temperature").doc() = "Temperature";
      70              : 
      71            8 :   options.set_parameter<TensorName<Scalar>>("T1");
      72            8 :   options.set("T1").doc() = "First stage annealing temperature";
      73              : 
      74            8 :   options.set_parameter<TensorName<Scalar>>("T2");
      75            8 :   options.set("T2").doc() = "Second stage annealing temperature";
      76              : 
      77            8 :   options.set_parameter<TensorName<Scalar>>("tau");
      78            4 :   options.set("tau").doc() = "Recovery rate for second stage annealing.";
      79              : 
      80            8 :   return options;
      81            4 : }
      82              : 
      83              : template <typename T>
      84            2 : TwoStageThermalAnnealing<T>::TwoStageThermalAnnealing(const OptionSet & options)
      85              :   : Model(options),
      86            2 :     _base_rate(declare_input_variable<T>("base_rate")),
      87            2 :     _base_h(declare_input_variable<T>("base")),
      88            2 :     _modified_rate(declare_output_variable<T>("modified_rate")),
      89            2 :     _T(declare_input_variable<Scalar>("temperature")),
      90            8 :     _T1(declare_parameter<Scalar>("T1", "T1")),
      91            8 :     _T2(declare_parameter<Scalar>("T2", "T2")),
      92           10 :     _tau(declare_parameter<Scalar>("tau", "tau"))
      93              : {
      94            2 : }
      95              : 
      96              : template <typename T>
      97              : void
      98            4 : TwoStageThermalAnnealing<T>::set_value(bool out, bool dout_din, bool /*d2out_din2*/)
      99              : {
     100            4 :   auto one = Scalar::ones_like(_T);
     101            4 :   auto zero = Scalar::zeros_like(_T);
     102            4 :   auto base_region = where(_T < _T1, one, zero);
     103            4 :   auto recover_region = where(_T >= _T2, one, zero);
     104              : 
     105            4 :   if (out)
     106            2 :     _modified_rate = base_region * _base_rate + recover_region * -_base_h / _tau;
     107              : 
     108            4 :   if (dout_din)
     109              :   {
     110            2 :     auto I = T::identity_map(_T.options());
     111              : 
     112            2 :     if (_base_rate.is_dependent())
     113            2 :       _modified_rate.d(_base_rate) = base_region * I;
     114              : 
     115            2 :     if (_base_h.is_dependent())
     116            2 :       _modified_rate.d(_base_h) = -recover_region * I / _tau;
     117            2 :   }
     118            4 : }
     119              : } // namespace neml2
        

Generated by: LCOV version 2.0-1