LCOV - code coverage report
Current view: top level - src/meshgenerators - SymmetryTransformGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 38 44 86.4 %
Date: 2025-07-17 01:28:37 Functions: 3 3 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 "SymmetryTransformGenerator.h"
      11             : #include "CastUniquePointer.h"
      12             : #include "MooseUtils.h"
      13             : #include "libmesh/mesh_modification.h"
      14             : 
      15             : registerMooseObject("MooseApp", SymmetryTransformGenerator);
      16             : 
      17             : InputParameters
      18       14285 : SymmetryTransformGenerator::validParams()
      19             : {
      20       14285 :   InputParameters params = MeshGenerator::validParams();
      21             : 
      22       14285 :   params.addClassDescription("Applies a symmetry transformation to the entire mesh.");
      23       14285 :   params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
      24       14285 :   params.addRequiredParam<RealEigenVector>(
      25             :       "mirror_point",
      26             :       "Any point on the plane/line over which the reflection operation will be done");
      27       14285 :   params.addRequiredParam<RealEigenVector>(
      28             :       "mirror_normal_vector",
      29             :       "A vector normal to (perpendicular/orthogonal to) the plane/line over which the "
      30             :       "reflection operation will be done");
      31             : 
      32       14285 :   return params;
      33           0 : }
      34             : 
      35          10 : SymmetryTransformGenerator::SymmetryTransformGenerator(const InputParameters & parameters)
      36             :   : MeshGenerator(parameters),
      37          10 :     _input(getMesh("input")),
      38          10 :     _mirror_point_vector(getParam<RealEigenVector>("mirror_point")),
      39          20 :     _mirror_normal_vector(getParam<RealEigenVector>("mirror_normal_vector"))
      40             : {
      41             :   // enforce 3D coordinates
      42          10 :   if (_mirror_point_vector.size() != 3)
      43           0 :     paramError("mirror_point",
      44             :                "mirror_point should be a 3d vector, but only ",
      45           0 :                _mirror_point_vector.size(),
      46             :                "components were specified.");
      47             : 
      48          10 :   if (_mirror_normal_vector.size() != 3)
      49           0 :     paramError("mirror_point",
      50             :                " mirror_normal_vector should be a 3d vector, but only ",
      51           0 :                _mirror_normal_vector.size(),
      52             :                "components were specified.");
      53             : 
      54             :   // convert normal vector into a unit normal vector
      55          10 :   const auto norm = _mirror_normal_vector.norm();
      56          10 :   if (!MooseUtils::absoluteFuzzyEqual(norm, 1))
      57           0 :     mooseInfo("Input normal plane vector was not normalized, normalization was performed");
      58          10 :   _mirror_normal_vector = _mirror_normal_vector / norm;
      59          10 : }
      60             : 
      61             : std::unique_ptr<MeshBase>
      62          10 : SymmetryTransformGenerator::generate()
      63             : {
      64          10 :   std::unique_ptr<MeshBase> mesh = std::move(_input);
      65             : 
      66             :   // https://en.wikipedia.org/wiki/Transformation_matrix#Reflection_2
      67             :   // variables renamed for readability and verification
      68          10 :   const auto a = _mirror_normal_vector[0], b = _mirror_normal_vector[1],
      69          10 :              c = _mirror_normal_vector[2],
      70          10 :              d = ((RealEigenVector)(-1 * _mirror_point_vector.transpose() * _mirror_normal_vector))(
      71          10 :                  0);
      72             : 
      73          10 :   RealEigenMatrix mirror_transformation(4, 4);
      74          10 :   mirror_transformation << (1 - 2 * a * a), (-2 * a * b), (-2 * a * c), (-2 * a * d), (-2 * a * b),
      75          10 :       (1 - 2 * b * b), (-2 * b * c), (-2 * b * d), (-2 * a * c), (-2 * b * c), (1 - 2 * c * c),
      76          10 :       (-2 * c * d), (0), (0), (0), (1);
      77             : 
      78         250 :   for (auto & node : mesh->node_ptr_range())
      79             :   {
      80         120 :     RealEigenVector location_vec(4);
      81         120 :     location_vec << (*node)(0), (*node)(1), (*node)(2), 1;
      82         120 :     location_vec = mirror_transformation * location_vec;
      83             : 
      84         120 :     (*node)(0) = location_vec(0);
      85         120 :     (*node)(1) = location_vec(1);
      86         120 :     (*node)(2) = location_vec(2);
      87         130 :   }
      88             : 
      89             :   // Fix flipped orientation from the symmetry
      90          10 :   MeshTools::Modification::orient_elements(*mesh);
      91             : 
      92          20 :   return mesh;
      93          10 : }

Generated by: LCOV version 1.14