LCOV - code coverage report
Current view: top level - user_tensors - Orientation.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.1 % 47 40
Test Date: 2025-06-29 01:25:44 Functions: 100.0 % 4 4

            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/user_tensors/Orientation.h"
      26              : 
      27              : #include "neml2/tensors/Quaternion.h"
      28              : #include "neml2/tensors/Rot.h"
      29              : #include "neml2/tensors/Vec.h"
      30              : #include "neml2/tensors/functions/where.h"
      31              : 
      32              : namespace neml2
      33              : {
      34              : register_NEML2_object(Orientation);
      35              : 
      36              : OptionSet
      37            2 : Orientation::expected_options()
      38              : {
      39            2 :   OptionSet options = UserTensorBase::expected_options();
      40              : 
      41            2 :   options.doc() = "An orientation, internally defined as a set of Modified Rodrigues parameters "
      42              :                   "given by \\f$ r = n \\tan{\\frac{\\theta}{4}} \\f$ with \\f$ n \\f$ the axis of "
      43              :                   "rotation and \\f$ \\theta \\f$ the rotation angle about that axis.  However, "
      44              :                   "this class provides a variety of ways to define the orientation in terms of "
      45            2 :                   "other, more common representations.";
      46              : 
      47            4 :   options.set<std::string>("input_type") = "euler_angles";
      48            6 :   options.set("input_type").doc() =
      49            2 :       "The method used to define the angles, 'euler_angles' or 'random'";
      50              : 
      51            4 :   options.set<std::string>("angle_convention") = "kocks";
      52            4 :   options.set("angle_convention").doc() = "Euler angle convention, 'Kocks', 'Roe', or 'Bunge'";
      53              : 
      54            4 :   options.set<std::string>("angle_type") = "degrees";
      55            2 :   options.set("angle_type").doc() = "Type of angles, either 'degrees' or 'radians'";
      56              : 
      57            6 :   options.set<std::vector<double>>("values") = {};
      58            4 :   options.set("values").doc() = "Input Euler angles, as a flattened n-by-3 matrix";
      59              : 
      60            4 :   options.set<bool>("normalize") = false;
      61            6 :   options.set("normalize").doc() =
      62              :       "If true do a shadow parameter replacement of the underlying MRP representation to move the "
      63            2 :       "inputs farther away from the singularity";
      64              : 
      65            4 :   options.set<unsigned int>("quantity") = 1;
      66            2 :   options.set("quantity").doc() = "Number (batch size) of random orientations";
      67              : 
      68            2 :   return options;
      69            0 : }
      70              : 
      71            6 : Orientation::Orientation(const OptionSet & options)
      72              :   : Rot(fill(options)),
      73            6 :     UserTensorBase(options)
      74              : {
      75            6 : }
      76              : 
      77              : Rot
      78            6 : Orientation::fill(const OptionSet & options) const
      79              : {
      80            6 :   std::string input_type = options.get<std::string>("input_type");
      81              : 
      82            6 :   Rot R;
      83            6 :   if (input_type == "euler_angles")
      84              :   {
      85            6 :     auto vals = options.get<std::vector<double>>("values");
      86            6 :     auto t = neml2::Tensor::create(vals);
      87            6 :     auto v = Vec(t.reshape({-1, 3}));
      88           18 :     R = expand_as_needed(Rot::fill_euler_angles(v,
      89           12 :                                                 options.get<std::string>("angle_convention"),
      90           18 :                                                 options.get<std::string>("angle_type")),
      91            6 :                          options.get<unsigned int>("quantity"));
      92            6 :   }
      93            0 :   else if (input_type == "random")
      94              :   {
      95            0 :     R = Rot::fill_random(options.get<unsigned int>("quantity"));
      96              :   }
      97              :   else
      98            0 :     throw NEMLException("Unknown Orientation input_type " + input_type);
      99              : 
     100           12 :   if (options.get<bool>("normalize"))
     101            0 :     return neml2::where((R.norm_sq() < 1.0).unsqueeze(-1), R, R.shadow());
     102              : 
     103            6 :   return R;
     104            6 : }
     105              : 
     106              : Rot
     107            6 : Orientation::expand_as_needed(const Rot & input, unsigned int inp_size) const
     108              : {
     109            6 :   if (inp_size > 1)
     110            0 :     return input.batch_expand({inp_size});
     111              : 
     112            6 :   return input;
     113            0 : }
     114              : 
     115              : } // namespace neml2
        

Generated by: LCOV version 2.0-1