LCOV - code coverage report
Current view: top level - drivers/solid_mechanics - LDISolidMechanicsDriver.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.5 % 80 74
Test Date: 2025-06-29 01:25:44 Functions: 88.9 % 9 8

            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/drivers/solid_mechanics/LDISolidMechanicsDriver.h"
      26              : #include "neml2/misc/assertions.h"
      27              : #include "neml2/base/LabeledAxis.h"
      28              : #include "neml2/models/Model.h"
      29              : 
      30              : namespace neml2
      31              : {
      32              : register_NEML2_object(LDISolidMechanicsDriver);
      33              : 
      34              : OptionSet
      35            2 : LDISolidMechanicsDriver::expected_options()
      36              : {
      37            2 :   OptionSet options = SolidMechanicsDriver::expected_options();
      38            2 :   options.doc() +=
      39            2 :       " This driver is specialized for large deformation models using the incremental formulation.";
      40              : 
      41            6 :   options.set<VariableName>("deformation_rate") = VariableName(FORCES, "deformation_rate");
      42            4 :   options.set("deformation_rate").doc() = "Deformation rate";
      43            4 :   options.set<TensorName<SR2>>("prescribed_deformation_rate");
      44            4 :   options.set("prescribed_deformation_rate").doc() =
      45            2 :       "Prescribed deformation rate (when control = STRAIN)";
      46              : 
      47            6 :   options.set<VariableName>("cauchy_stress_rate") = VariableName(FORCES, "cauchy_stress_rate");
      48            4 :   options.set("cauchy_stress_rate").doc() = "Cauchy stress rate";
      49            4 :   options.set<TensorName<SR2>>("prescribed_cauchy_stress_rate");
      50            4 :   options.set("prescribed_cauchy_stress_rate").doc() =
      51            2 :       "Prescribed cauchy stress rate (when control = STRESS)";
      52              : 
      53            6 :   options.set<VariableName>("vorticity") = VariableName(FORCES, "vorticity");
      54            4 :   options.set("vorticity").doc() = "Vorticity";
      55            4 :   options.set<TensorName<WR2>>("prescribed_vorticity");
      56            4 :   options.set("prescribed_vorticity").doc() = "Prescribed vorticity";
      57              : 
      58            4 :   options.set<bool>("cp_warmup") = false;
      59            6 :   options.set("cp_warmup").doc() =
      60              :       "Whether to perform a warm-up step for crystal plasticity models. The warm-up step uses a "
      61            2 :       "relaxed/damped elastic predictor for the very first time step.";
      62            4 :   options.set<double>("cp_warmup_elastic_scale") = 1.0;
      63            4 :   options.set("cp_warmup_elastic_scale").doc() =
      64            2 :       "Elastic step scale factor used for the crystal plasticity warm-up step";
      65            6 :   options.set<VariableName>("cp_warmup_elastic_strain") = VariableName(STATE, "elastic_strain");
      66            4 :   options.set("cp_warmup_elastic_strain").doc() =
      67            2 :       "Elastic strain name used for the CP warm-up step";
      68              : 
      69            2 :   return options;
      70            0 : }
      71              : 
      72            1 : LDISolidMechanicsDriver::LDISolidMechanicsDriver(const OptionSet & options)
      73              :   : SolidMechanicsDriver(options),
      74            1 :     _vorticity_prescribed(options.get("prescribed_vorticity").user_specified()),
      75            2 :     _cp_warmup(options.get<bool>("cp_warmup")),
      76            2 :     _cp_warmup_elastic_scale(options.get<double>("cp_warmup_elastic_scale")),
      77            3 :     _cp_warmup_elastic_strain(options.get<VariableName>("cp_warmup_elastic_strain"))
      78              : {
      79            1 : }
      80              : 
      81              : void
      82            1 : LDISolidMechanicsDriver::setup()
      83              : {
      84            1 :   SolidMechanicsDriver::setup();
      85            1 :   init_vorticity_control(input_options());
      86            1 : }
      87              : 
      88              : void
      89            1 : LDISolidMechanicsDriver::init_strain_control(const OptionSet & options)
      90              : {
      91            1 :   _driving_force_name = options.get<VariableName>("deformation_rate");
      92            2 :   _driving_force = resolve_tensor<SR2>("prescribed_deformation_rate");
      93            1 :   _driving_force = _driving_force.to(_device);
      94            1 : }
      95              : 
      96              : void
      97            0 : LDISolidMechanicsDriver::init_stress_control(const OptionSet & options)
      98              : {
      99            0 :   _driving_force_name = options.get<VariableName>("cauchy_stress_rate");
     100            0 :   _driving_force = resolve_tensor<SR2>("prescribed_cauchy_stress_rate");
     101            0 :   _driving_force = _driving_force.to(_device);
     102            0 : }
     103              : 
     104              : void
     105            1 : LDISolidMechanicsDriver::init_vorticity_control(const OptionSet & options)
     106              : {
     107            1 :   _vorticity_name = options.get<VariableName>("vorticity");
     108            2 :   _vorticity = resolve_tensor<WR2>("prescribed_vorticity");
     109            1 :   _vorticity = _vorticity.to(_device);
     110            1 : }
     111              : 
     112              : void
     113            1 : LDISolidMechanicsDriver::diagnose() const
     114              : {
     115            1 :   SolidMechanicsDriver::diagnose();
     116              : 
     117            1 :   if (_vorticity_prescribed)
     118              :   {
     119            1 :     diagnostic_assert(_vorticity.batch_dim() >= 1,
     120              :                       "Input vorticity should have at least one batch dimension but instead "
     121              :                       "has batch dimension ",
     122            1 :                       _vorticity.batch_dim());
     123            1 :     diagnostic_assert(
     124              : 
     125            1 :         _vorticity.batch_size(0) == _time.batch_size(0),
     126              :         "Input vorticity should have the same number of steps steps as time, but instead has ",
     127            2 :         _vorticity.batch_size(0),
     128              :         " time steps");
     129              :   }
     130              : 
     131            1 :   if (_cp_warmup)
     132              :   {
     133            1 :     diagnostic_assert(_control == "STRAIN", "CP warm-up step is only supported for STRAIN control");
     134            1 :     diagnostic_assert(_model->input_axis().has_variable(_cp_warmup_elastic_strain),
     135              :                       "Model's input axis should have variable ",
     136            1 :                       _cp_warmup_elastic_strain,
     137              :                       " for the CP warm-up step but it does not");
     138              :   }
     139            1 : }
     140              : 
     141              : void
     142           10 : LDISolidMechanicsDriver::update_forces()
     143              : {
     144           10 :   SolidMechanicsDriver::update_forces();
     145           20 :   _in[_vorticity_name] = _vorticity.batch_index({_step_count});
     146           20 : }
     147              : 
     148              : void
     149            9 : LDISolidMechanicsDriver::apply_predictor()
     150              : {
     151            9 :   SolidMechanicsDriver::apply_predictor();
     152              : 
     153            9 :   if (_cp_warmup && (_step_count == 1))
     154              :   {
     155            1 :     const auto D = SR2(_in[_driving_force_name]);
     156            1 :     const auto t = Scalar(_in[_time_name]);
     157            1 :     const auto t_n = Scalar(_result_in[_step_count - 1][_time_name]);
     158            1 :     _in[_cp_warmup_elastic_strain] = D * (t - t_n) * _cp_warmup_elastic_scale;
     159            1 :   }
     160            9 : }
     161              : 
     162              : } // namespace neml2
        

Generated by: LCOV version 2.0-1