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 : // MOOSE includes
11 : #include "NodalNormalsPreprocessor.h"
12 :
13 : #include "Assembly.h"
14 : #include "AuxiliarySystem.h"
15 : #include "MooseMesh.h"
16 : #include "MooseVariableFE.h"
17 :
18 : #include "libmesh/numeric_vector.h"
19 : #include "libmesh/quadrature.h"
20 :
21 : std::mutex NodalNormalsPreprocessor::_nodal_normals_mutex;
22 :
23 : registerMooseObject("MooseApp", NodalNormalsPreprocessor);
24 :
25 : InputParameters
26 14640 : NodalNormalsPreprocessor::validParams()
27 : {
28 14640 : InputParameters params = ElementUserObject::validParams();
29 14640 : params.addClassDescription(
30 : "An object that prepares MOOSE for computing nodal normal vectors. This object is "
31 : "automatically created via the \\[NodalNormals\\] input block.");
32 14640 : params.addRequiredParam<std::vector<BoundaryName>>(
33 : "surface_boundary", "The list of boundary IDs where nodal normals are computed");
34 14640 : params.addParam<BoundaryName>("corner_boundary",
35 : "Node set ID which contains the nodes that are in 'corners'.");
36 14640 : params.addPrivateParam<FEFamily>("fe_family", LAGRANGE);
37 14640 : params.addPrivateParam<Order>("fe_order", FIRST);
38 :
39 14640 : return params;
40 0 : }
41 :
42 : /**
43 : * Local function to check to see if any intersection occurs between two vectors. Neither can be
44 : * assumed to be sorted but both are generally very short (just 1 or 2 entries) so doing an explicit
45 : * double loop is probably the easiest.
46 : */
47 : bool
48 277664 : hasBoundary(const std::vector<BoundaryID> & boundary_ids1,
49 : const std::vector<BoundaryID> & boundary_ids2)
50 : {
51 565324 : for (auto id1 : boundary_ids1)
52 : {
53 377580 : if (id1 == Moose::ANY_BOUNDARY_ID)
54 89920 : return true;
55 :
56 665496 : for (auto id2 : boundary_ids2)
57 377836 : if (id1 == id2 || id2 == Moose::ANY_BOUNDARY_ID)
58 89920 : return true;
59 : }
60 187744 : return false;
61 : }
62 :
63 195 : NodalNormalsPreprocessor::NodalNormalsPreprocessor(const InputParameters & parameters)
64 : : ElementUserObject(parameters),
65 390 : _aux(_fe_problem.getAuxiliarySystem()),
66 195 : _fe_type(getParam<Order>("fe_order"), getParam<FEFamily>("fe_family")),
67 195 : _has_corners(isParamValid("corner_boundary")),
68 195 : _boundaries(_mesh.getBoundaryIDs(getParam<std::vector<BoundaryName>>("surface_boundary"))),
69 390 : _corner_boundary_id(_has_corners
70 195 : ? _mesh.getBoundaryID(getParam<BoundaryName>("corner_boundary"))
71 : : static_cast<BoundaryID>(-1)),
72 390 : _grad_phi(_assembly.feGradPhi<Real>(_fe_type))
73 : {
74 195 : }
75 :
76 : void
77 5784 : NodalNormalsPreprocessor::initialize()
78 : {
79 5784 : NumericVector<Number> & sln = _aux.solution();
80 5784 : _aux.system().zero_variable(sln, _aux.getVariable(_tid, "nodal_normal_x").number());
81 5784 : _aux.system().zero_variable(sln, _aux.getVariable(_tid, "nodal_normal_y").number());
82 5784 : _aux.system().zero_variable(sln, _aux.getVariable(_tid, "nodal_normal_z").number());
83 : // After zero variables, we should close the solution
84 5784 : sln.close();
85 5784 : }
86 :
87 : void
88 103584 : NodalNormalsPreprocessor::execute()
89 : {
90 103584 : NumericVector<Number> & sln = _aux.solution();
91 :
92 : // Get a reference to our BoundaryInfo object for later use...
93 103584 : BoundaryInfo & boundary_info = _mesh.getMesh().get_boundary_info();
94 :
95 : // Container to catch IDs handed back by BoundaryInfo.
96 103584 : std::vector<BoundaryID> node_boundary_ids;
97 :
98 : // Loop through each node on the current element
99 1319584 : for (unsigned int i = 0; i < _current_elem->n_nodes(); i++)
100 : {
101 : // Extract a pointer to a node
102 1216000 : const Node * node = _current_elem->node_ptr(i);
103 :
104 : // Only continue if the node is on a boundary
105 1216000 : if (_mesh.isBoundaryNode(node->id()))
106 : {
107 : // List of IDs for the boundary
108 277664 : boundary_info.boundary_ids(node, node_boundary_ids);
109 :
110 : // Perform the calculation, the node must be:
111 : // (1) On a boundary to which the object is restricted
112 : // (2) Not on a corner of the boundary
113 367584 : if (hasBoundary(node_boundary_ids, _boundaries) &&
114 89920 : (!_has_corners || !boundary_info.has_boundary_id(node, _corner_boundary_id)))
115 : {
116 : // Perform the caluation of the normal
117 60608 : if (node->n_dofs(_aux.number(),
118 60608 : _fe_problem
119 121216 : .getVariable(_tid,
120 : "nodal_normal_x",
121 : Moose::VarKindType::VAR_AUXILIARY,
122 : Moose::VarFieldType::VAR_FIELD_STANDARD)
123 60608 : .number()) > 0)
124 : {
125 : // but it is not a corner node, they will be treated differently later on
126 : dof_id_type dof_x =
127 52160 : node->dof_number(_aux.number(),
128 52160 : _fe_problem
129 104320 : .getVariable(_tid,
130 : "nodal_normal_x",
131 : Moose::VarKindType::VAR_AUXILIARY,
132 : Moose::VarFieldType::VAR_FIELD_STANDARD)
133 : .number(),
134 : 0);
135 : dof_id_type dof_y =
136 52160 : node->dof_number(_aux.number(),
137 52160 : _fe_problem
138 104320 : .getVariable(_tid,
139 : "nodal_normal_y",
140 : Moose::VarKindType::VAR_AUXILIARY,
141 : Moose::VarFieldType::VAR_FIELD_STANDARD)
142 : .number(),
143 : 0);
144 : dof_id_type dof_z =
145 52160 : node->dof_number(_aux.number(),
146 52160 : _fe_problem
147 104320 : .getVariable(_tid,
148 : "nodal_normal_z",
149 : Moose::VarKindType::VAR_AUXILIARY,
150 : Moose::VarFieldType::VAR_FIELD_STANDARD)
151 : .number(),
152 : 0);
153 :
154 427648 : for (unsigned int qp = 0; qp < _qrule->n_points(); qp++)
155 : {
156 375488 : std::scoped_lock lock(_nodal_normals_mutex);
157 :
158 375488 : sln.add(dof_x, _JxW[qp] * _grad_phi[i][qp](0));
159 375488 : sln.add(dof_y, _JxW[qp] * _grad_phi[i][qp](1));
160 375488 : sln.add(dof_z, _JxW[qp] * _grad_phi[i][qp](2));
161 375488 : }
162 : }
163 : }
164 : }
165 : }
166 103584 : }
167 :
168 : void
169 5302 : NodalNormalsPreprocessor::finalize()
170 : {
171 5302 : _aux.solution().close();
172 5302 : }
|