Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://www.mooseframework.org 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 "BlockOrientationFromUserObject.h" 11 : #include "MooseMesh.h" 12 : #include "Assembly.h" 13 : #include "MooseVariable.h" 14 : #include "SystemBase.h" 15 : #include "libmesh/quadrature.h" 16 : #include "EulerAngles.h" 17 : 18 : registerMooseObject("SolidMechanicsApp", BlockOrientationFromUserObject); 19 : 20 : InputParameters 21 16 : BlockOrientationFromUserObject::validParams() 22 : { 23 16 : InputParameters params = GeneralVectorPostprocessor::validParams(); 24 : 25 32 : params.addRequiredParam<UserObjectName>( 26 : "block_orientation_uo", 27 : "Name of ComputeBlockOrientation user object for updated block orientation."); 28 : 29 32 : params.addParam<bool>( 30 : "degree_to_radian", 31 32 : false, 32 : "Whether to convert euler angles from degree to radian. The default is to use degrees."); 33 : 34 16 : params.addClassDescription( 35 : "Output the Euler angle for each block computed from average of quaternions."); 36 16 : return params; 37 0 : } 38 : 39 8 : BlockOrientationFromUserObject::BlockOrientationFromUserObject(const InputParameters & parameters) 40 : : GeneralVectorPostprocessor(parameters), 41 16 : _mesh(_subproblem.mesh()), 42 16 : _uo_name(getParam<UserObjectName>("block_orientation_uo")), 43 8 : _num_cols(4), // add one colum for the subdomain ID 44 16 : _num_rows(_mesh.meshSubdomains().size()) 45 : { 46 8 : _output_vector.resize(_num_cols); 47 : 48 40 : for (const auto j : make_range(_num_cols)) 49 : { 50 32 : if (j == 0) 51 8 : _output_vector[j] = &declareVector("subdomain_id"); 52 : else 53 48 : _output_vector[j] = &declareVector("euler_angle_" + std::to_string(j)); // can change 54 : } 55 : 56 8 : _uo = &getUserObjectByName<ComputeBlockOrientationBase>(_uo_name); 57 8 : } 58 : 59 : void 60 34 : BlockOrientationFromUserObject::initialize() 61 : { 62 170 : for (const auto j : make_range(_num_cols)) 63 : { 64 136 : _output_vector[j]->clear(); 65 136 : _output_vector[j]->resize(_num_rows, 0.0); 66 : } 67 34 : } 68 : 69 : void 70 34 : BlockOrientationFromUserObject::finalize() 71 : { 72 : // parallel communication 73 306 : for (const auto row : make_range(_num_rows)) 74 1360 : for (const auto col : make_range(_num_cols)) 75 1088 : _communicator.max((*_output_vector[col])[row]); 76 34 : } 77 : 78 : void 79 34 : BlockOrientationFromUserObject::execute() 80 : { 81 : int row = 0; 82 306 : for (const auto sid : _mesh.meshSubdomains()) 83 : { 84 : // get Euler angle for each subdomain 85 272 : EulerAngles ea = _uo->getBlockOrientation(sid); 86 : 87 : // convert EulerAngles to RealVectorValue 88 : RealVectorValue euler_angle = (RealVectorValue)ea; 89 : 90 544 : if (getParam<bool>("degree_to_radian")) 91 : euler_angle *= pi / 180.0; 92 : 93 1360 : for (const auto col : make_range(_num_cols)) 94 : { 95 1088 : if (col == 0) 96 272 : (*_output_vector[col])[row] = sid; 97 : else 98 816 : (*_output_vector[col])[row] = euler_angle(col - 1); 99 : } 100 272 : row++; 101 : } 102 34 : }