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

            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/SolidMechanicsDriver.h"
      26              : #include "neml2/misc/assertions.h"
      27              : 
      28              : namespace neml2
      29              : {
      30              : OptionSet
      31            4 : SolidMechanicsDriver::expected_options()
      32              : {
      33            4 :   OptionSet options = TransientDriver::expected_options();
      34            4 :   options.doc() = "Driver for solid mechanics material model with optional thermal coupling.";
      35              : 
      36           16 :   EnumSelection control_selection({"STRAIN", "STRESS", "MIXED"}, "STRAIN");
      37            4 :   options.set<EnumSelection>("control") = control_selection;
      38            8 :   options.set("control").doc() =
      39           12 :       "External control of the material update. Options are " + control_selection.candidates_str();
      40              : 
      41           12 :   options.set<VariableName>("temperature") = VariableName(FORCES, "T");
      42            8 :   options.set("temperature").doc() = "Name of temperature";
      43            8 :   options.set<TensorName<Scalar>>("prescribed_temperature");
      44            8 :   options.set("prescribed_temperature").doc() =
      45            4 :       "Actual prescibed temperature values, when providing temperatures to the model";
      46              : 
      47           12 :   options.set<VariableName>("mixed_driving_force") = VariableName(FORCES, "fixed_values");
      48            8 :   options.set("mixed_driving_force").doc() = "Name of mixed driving force when using mixed control";
      49            8 :   options.set<TensorName<SR2>>("prescribed_mixed_driving_force");
      50            8 :   options.set("prescribed_mixed_driving_force").doc() =
      51              :       "The fixed, controlled values provided as user input for the mixed control case.  Where the "
      52              :       "control signal is 0 these are strain/deformation values, where it is 1 these are stress "
      53            4 :       "values";
      54              : 
      55           12 :   options.set<VariableName>("mixed_control_signal") = VariableName(FORCES, "control");
      56           12 :   options.set("mixed_control_signal").doc() =
      57            4 :       "The name of the control signal for mixed control on the input axis";
      58            8 :   options.set<TensorName<SR2>>("prescribed_mixed_control_signal");
      59            8 :   options.set("prescribed_mixed_control_signal").doc() =
      60              :       "The actual values of the control signal for mixed control. 0 implies strain/deformation "
      61            4 :       "control, 1 implies stress control";
      62              : 
      63            8 :   return options;
      64            4 : }
      65              : 
      66            7 : SolidMechanicsDriver::SolidMechanicsDriver(const OptionSet & options)
      67              :   : TransientDriver(options),
      68            7 :     _control(options.get<EnumSelection>("control")),
      69           28 :     _temperature_prescribed(options.get("prescribed_temperature").user_specified())
      70              : {
      71            7 : }
      72              : 
      73              : void
      74            7 : SolidMechanicsDriver::setup()
      75              : {
      76            7 :   TransientDriver::setup();
      77              : 
      78           14 :   if (_control == "STRAIN")
      79            5 :     init_strain_control(input_options());
      80            4 :   else if (_control == "STRESS")
      81            1 :     init_stress_control(input_options());
      82            2 :   else if (_control == "MIXED")
      83            1 :     init_mixed_control(input_options());
      84              :   else
      85              :     // LCOV_EXCL_START
      86              :     throw NEMLException("Unsupported control type.");
      87              :   // LCOV_EXCL_STOP
      88              : 
      89            7 :   if (_temperature_prescribed)
      90            1 :     init_temperature_control(input_options());
      91            7 : }
      92              : 
      93              : void
      94            1 : SolidMechanicsDriver::init_mixed_control(const OptionSet & options)
      95              : {
      96            1 :   _driving_force_name = options.get<VariableName>("mixed_driving_force");
      97            2 :   _driving_force = resolve_tensor<SR2>("prescribed_mixed_driving_force");
      98            1 :   _driving_force = _driving_force.to(_device);
      99              : 
     100            1 :   _mixed_control_name = options.get<VariableName>("mixed_control_signal");
     101            2 :   _mixed_control = resolve_tensor<SR2>("prescribed_mixed_control_signal");
     102            1 :   _mixed_control = _mixed_control.to(_device);
     103            1 : }
     104              : 
     105              : void
     106            1 : SolidMechanicsDriver::init_temperature_control(const OptionSet & options)
     107              : {
     108            1 :   _temperature_name = options.get<VariableName>("temperature");
     109            2 :   _temperature = resolve_tensor<Scalar>("prescribed_temperature");
     110            1 :   _temperature = _temperature.to(_device);
     111            1 : }
     112              : 
     113              : void
     114            7 : SolidMechanicsDriver::diagnose() const
     115              : {
     116            7 :   TransientDriver::diagnose();
     117              : 
     118            7 :   diagnostic_assert(_driving_force.batch_dim() >= 1,
     119              :                     "Input driving force (strain, stress, or mixed conditions) should have at "
     120              :                     "least one batch dimension for time steps but instead has batch dimension ",
     121            7 :                     _driving_force.batch_dim());
     122              : 
     123            7 :   diagnostic_assert(_time.batch_size(0) == _driving_force.batch_size(0),
     124              :                     "Input driving force (strain, stress, or mixed conditions) and time should "
     125              :                     "have the same number of time steps. The input time has ",
     126           14 :                     _time.batch_size(0),
     127              :                     " time steps, while the input driving force has ",
     128           14 :                     _driving_force.batch_size(0),
     129              :                     " time steps");
     130              : 
     131            7 :   if (_temperature_prescribed)
     132              :   {
     133            1 :     diagnostic_assert(_temperature.batch_dim() >= 1,
     134              :                       "Input temperature should have at least one batch dimension for time steps "
     135              :                       "but instead has batch dimension ",
     136            1 :                       _temperature.batch_dim());
     137              : 
     138            1 :     diagnostic_assert(
     139            1 :         _time.batch_size(0) == _temperature.batch_size(0),
     140              :         "Input temperature and time should have the same number of time steps. The input time has ",
     141            2 :         _time.batch_size(0),
     142              :         " time steps, while the input temperature has ",
     143            2 :         _temperature.batch_size(0),
     144              :         " time steps");
     145              :   }
     146              : 
     147           14 :   if (_control == "MIXED")
     148              :   {
     149            1 :     diagnostic_assert(_mixed_control.batch_dim() >= 1,
     150              :                       "Input control signal should have at least one batch dimension but instead "
     151              :                       "has batch dimension ",
     152            1 :                       _mixed_control.batch_dim());
     153            1 :     diagnostic_assert(
     154            1 :         _mixed_control.batch_size(0) == _time.batch_size(0),
     155              :         "Input control signal should have the same number of steps steps as time, but instead has ",
     156            2 :         _mixed_control.batch_size(0),
     157              :         " time steps");
     158              :   }
     159            7 : }
     160              : 
     161              : void
     162           70 : SolidMechanicsDriver::update_forces()
     163              : {
     164           70 :   TransientDriver::update_forces();
     165              : 
     166          140 :   _in[_driving_force_name] = _driving_force.batch_index({_step_count});
     167              : 
     168           70 :   if (_temperature_prescribed)
     169           20 :     _in[_temperature_name] = _temperature.batch_index({_step_count});
     170              : 
     171          140 :   if (_control == "MIXED")
     172           20 :     _in[_mixed_control_name] = _mixed_control.batch_index({_step_count});
     173          160 : }
     174              : }
        

Generated by: LCOV version 2.0-1