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 "CircleCutUserObject.h" 11 : 12 : // MOOSE includes 13 : #include "MooseError.h" 14 : 15 : // XFEM includes 16 : #include "XFEMFuncs.h" 17 : 18 : registerMooseObject("XFEMApp", CircleCutUserObject); 19 : 20 : InputParameters 21 16 : CircleCutUserObject::validParams() 22 : { 23 : // Get input parameters from parent class 24 16 : InputParameters params = GeometricCut3DUserObject::validParams(); 25 : 26 : // Add required parameters 27 32 : params.addRequiredParam<std::vector<Real>>("cut_data", 28 : "Vector of Real values providing cut information"); 29 : // Class description 30 16 : params.addClassDescription("Creates a UserObject for circular cuts on 3D meshes for XFEM"); 31 : // Return the parameters 32 16 : return params; 33 0 : } 34 : 35 8 : CircleCutUserObject::CircleCutUserObject(const InputParameters & parameters) 36 24 : : GeometricCut3DUserObject(parameters), _cut_data(getParam<std::vector<Real>>("cut_data")) 37 : { 38 : // Set up constant parameters 39 : const int cut_data_len = 9; 40 : 41 : // Throw error if length of cut_data is incorrect 42 8 : if (_cut_data.size() != cut_data_len) 43 0 : mooseError("Length of CircleCutUserObject cut_data must be 9"); 44 : 45 : // Assign cut_data to vars used to construct cuts 46 8 : _center = Point(_cut_data[0], _cut_data[1], _cut_data[2]); 47 8 : _vertices.push_back(Point(_cut_data[3], _cut_data[4], _cut_data[5])); 48 8 : _vertices.push_back(Point(_cut_data[6], _cut_data[7], _cut_data[8])); 49 : 50 : std::pair<Point, Point> rays = std::make_pair(_vertices[0] - _center, _vertices[1] - _center); 51 : 52 8 : _normal = rays.first.cross(rays.second); 53 8 : Xfem::normalizePoint(_normal); 54 : 55 : std::pair<Real, Real> ray_radii = 56 8 : std::make_pair(std::sqrt(rays.first.norm_sq()), std::sqrt(rays.second.norm_sq())); 57 : 58 8 : if (std::abs(ray_radii.first - ray_radii.second) > 1e-10) 59 0 : mooseError("CircleCutUserObject only works for a circular cut"); 60 : 61 8 : _radius = 0.5 * (ray_radii.first + ray_radii.second); 62 8 : _angle = std::acos((rays.first * rays.second) / (ray_radii.first * ray_radii.second)); 63 8 : } 64 : 65 : bool 66 7840 : CircleCutUserObject::isInsideCutPlane(Point p) const 67 : { 68 : Point ray = p - _center; 69 7840 : if (std::abs(ray * _normal) < 1e-15 && std::sqrt(ray.norm_sq()) < _radius) 70 : return true; 71 : return false; 72 : } 73 : 74 : const std::vector<Point> 75 4 : CircleCutUserObject::getCrackFrontPoints(unsigned int number_crack_front_points) const 76 : { 77 4 : std::vector<Point> crack_front_points(number_crack_front_points); 78 : Point v1 = _vertices[0] - _center; 79 4 : Point v2 = _normal.cross(v1); 80 4 : v1 /= v1.norm(); 81 4 : v2 /= v2.norm(); 82 : // parametric circle in 3D: center + r * cos(theta) * v1 + r * sin(theta) * v2 83 44 : for (unsigned int i = 0; i < number_crack_front_points; ++i) 84 : { 85 40 : Real theta = 2.0 * libMesh::pi / number_crack_front_points * i; 86 40 : crack_front_points[i] = 87 40 : _center + _radius * std::cos(theta) * v1 + _radius * std::sin(theta) * v2; 88 : } 89 : 90 4 : return crack_front_points; 91 : } 92 : 93 : const std::vector<RealVectorValue> 94 0 : CircleCutUserObject::getCrackPlaneNormals(unsigned int /*num_crack_front_points*/) const 95 : { 96 0 : mooseError("getCrackPlaneNormals() is not implemented for this object."); 97 : }