LCOV - code coverage report
Current view: top level - src/meshgenerators - TransformGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 67 69 97.1 %
Date: 2026-05-29 20:35:17 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "TransformGenerator.h"
      11             : #include "libmesh/mesh_modification.h"
      12             : #include "CastUniquePointer.h"
      13             : 
      14             : #include "libmesh/mesh_tools.h"
      15             : 
      16             : registerMooseObject("MooseApp", TransformGenerator);
      17             : 
      18             : InputParameters
      19        6245 : TransformGenerator::validParams()
      20             : {
      21             :   MooseEnum transforms("TRANSLATE=1 TRANSLATE_CENTER_ORIGIN=2 TRANSLATE_MIN_ORIGIN=3 ROTATE=4 "
      22       18735 :                        "SCALE=5 ROTATE_WITH_MATRIX=6 ROTATE_EXT=7");
      23             : 
      24        6245 :   InputParameters params = MeshGenerator::validParams();
      25             : 
      26       24980 :   params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
      27       12490 :   params.addClassDescription("Applies a linear transform to the entire mesh.");
      28       24980 :   params.addRequiredParam<MooseEnum>(
      29             :       "transform",
      30             :       transforms,
      31             :       "The type of transformation to perform (TRANSLATE, TRANSLATE_CENTER_ORIGIN, "
      32             :       "TRANSLATE_MIN_ORIGIN, ROTATE, SCALE, ROTATE_WITH_MATRIX, ROTATE_EXT)");
      33       24980 :   params.addParam<RealVectorValue>(
      34             :       "vector_value",
      35             :       "The value to use for the transformation. When using TRANSLATE or SCALE, the "
      36             :       "xyz coordinates are applied in each direction respectively. When using "
      37             :       "ROTATE, the values are interpreted as the Euler angles phi, theta and psi "
      38             :       "given in degrees. For ROTATE_EXT, an extrinsic rotation is carried out using prescribed "
      39             :       "Euler angles alpha, beta, and gamma in degrees.");
      40       18735 :   params.addParam<RealTensorValue>(
      41             :       "rotation_matrix",
      42             :       "Precomputed extrinsic rotation matrix to be applied to mesh (ROTATE_WITH_MATRIX option).");
      43             : 
      44       12490 :   return params;
      45        6245 : }
      46             : 
      47        1573 : TransformGenerator::TransformGenerator(const InputParameters & parameters)
      48             :   : MeshGenerator(parameters),
      49        1573 :     _input(getMesh("input")),
      50        4719 :     _transform(getParam<MooseEnum>("transform"))
      51             : {
      52        1563 :   if ((_transform != "TRANSLATE_CENTER_ORIGIN" && _transform != "TRANSLATE_MIN_ORIGIN" &&
      53        4311 :        _transform != "ROTATE_WITH_MATRIX") &&
      54        5098 :       !isParamValid("vector_value"))
      55           0 :     paramError("transform",
      56             :                "The parameter 'vector_value' must be supplied with 'transform' = ",
      57           0 :                _transform);
      58        1573 : }
      59             : 
      60             : std::unique_ptr<MeshBase>
      61        1506 : TransformGenerator::generate()
      62             : {
      63        1506 :   std::unique_ptr<MeshBase> mesh = std::move(_input);
      64             : 
      65        1506 :   RealVectorValue vector_value;
      66        1506 :   RealTensorValue rotation_matrix;
      67        1506 :   if (_transform == 2 || _transform == 3)
      68             :   {
      69          20 :     const auto bbox = MeshTools::create_bounding_box(*mesh);
      70          20 :     if (_transform == 2)
      71          10 :       vector_value = -0.5 * (bbox.max() + bbox.min());
      72             :     else
      73          10 :       vector_value = -bbox.min();
      74             :   }
      75        1486 :   else if (_transform == 6)
      76        1104 :     rotation_matrix = getParam<RealTensorValue>("rotation_matrix");
      77             :   else
      78        3354 :     vector_value = getParam<RealVectorValue>("vector_value");
      79             : 
      80             :   // Any non-identity transform is going to invalidate any existing
      81             :   // point locator
      82        1506 :   mesh->clear_point_locator();
      83             : 
      84        1506 :   switch (_transform)
      85             :   {
      86         714 :     case 1:
      87             :     case 2:
      88             :     case 3:
      89         714 :       MeshTools::Modification::translate(*mesh, vector_value(0), vector_value(1), vector_value(2));
      90             :       // libMesh translate() fails to properly mark the spatial
      91             :       // dimension as unprepared in cases where we've displaced a 1D
      92             :       // mesh in y or z or a 2D mesh in z.  Until that's fixed we work
      93             :       // around the bug.
      94         714 :       mesh->unset_has_cached_elem_data();
      95         714 :       break;
      96         264 :     case 4:
      97         264 :       MeshTools::Modification::rotate(*mesh, vector_value(0), vector_value(1), vector_value(2));
      98             :       // libMesh rotate() tries to set the spatial dimension properly,
      99             :       // and probably does for all realistic use cases, but there are
     100             :       // at least hypothetical cases where it could be wrong.
     101             :       //
     102             :       // Until that's fixed we work around it.
     103         264 :       mesh->unset_has_cached_elem_data();
     104         264 :       break;
     105          54 :     case 5:
     106          54 :       MeshTools::Modification::scale(*mesh, vector_value(0), vector_value(1), vector_value(2));
     107             :       // Is anybody using scale() to just squash a manifold's spatial
     108             :       // dimension down to its mesh dimension?  Let's be safe until
     109             :       // libMesh is handling that case.
     110          54 :       mesh->unset_has_cached_elem_data();
     111          54 :       break;
     112         368 :     case 6:
     113         368 :       TransformGenerator::rotateWithMatrix(*mesh, rotation_matrix);
     114         368 :       break;
     115         106 :     case 7:
     116         106 :       TransformGenerator::rotateExtrinsic(*mesh, vector_value(0), vector_value(1), vector_value(2));
     117         106 :       break;
     118             :   }
     119             : 
     120        1506 :   mesh->unset_is_prepared();
     121        3012 :   return dynamic_pointer_cast<MeshBase>(mesh);
     122        1506 : }
     123             : 
     124             : void
     125         106 : TransformGenerator::rotateExtrinsic(MeshBase & mesh,
     126             :                                     const Real alpha,
     127             :                                     const Real beta,
     128             :                                     const Real gamma)
     129             : {
     130             : #if LIBMESH_DIM == 3
     131             :   const auto R = RealTensorValue::extrinsic_rotation_matrix(
     132         106 :       alpha, beta, gamma); // this line is the only difference from rotate...
     133             : 
     134             :   // Let's not try to guess what this did to our spatial dimension (it
     135             :   // could have reduced it, depending on the input mesh!), let's just
     136             :   // mark that it needs to be recomputed.
     137         106 :   mesh.unset_has_cached_elem_data();
     138             : 
     139        7748 :   for (auto & node : mesh.node_ptr_range())
     140             :   {
     141        7642 :     Point & pt = *node;
     142        7642 :     pt = R * pt;
     143         106 :   }
     144             : #else
     145             :   libmesh_ignore(mesh, alpha, beta, gamma);
     146             :   libmesh_error_msg(
     147             :       "MeshTools::Modification::rotate() requires libMesh to be compiled with LIBMESH_DIM==3");
     148             : #endif
     149         106 : }
     150             : 
     151             : void
     152         368 : TransformGenerator::rotateWithMatrix(MeshBase & mesh,
     153             :                                      const GenericRealTensorValue<false> & rotation_matrix)
     154             : {
     155             : #if LIBMESH_DIM == 3
     156             :   // Let's not try to guess what this did to our spatial dimension,
     157             :   // let's just mark that it needs to be recomputed.
     158         368 :   mesh.unset_has_cached_elem_data();
     159             : 
     160       28932 :   for (auto & node : mesh.node_ptr_range())
     161             :   {
     162       28564 :     Point & pt = *node;
     163       28564 :     pt = rotation_matrix * pt;
     164         368 :   }
     165             : 
     166             : #else
     167             :   libmesh_ignore(mesh, phi, theta, psi);
     168             :   libmesh_error_msg(
     169             :       "MeshTools::Modification::rotate() requires libMesh to be compiled with LIBMESH_DIM==3");
     170             : #endif
     171         368 : }

Generated by: LCOV version 1.14