https://mooseframework.inl.gov
Loading...
Searching...
No Matches
OrientSurfaceMeshGenerator.C
Go to the documentation of this file.
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
11#include "Parser.h"
12#include "InputParameters.h"
13#include "CastUniquePointer.h"
14
15#include "libmesh/fe_base.h"
16#include "libmesh/mesh_generation.h"
17#include "libmesh/mesh.h"
18#include "libmesh/string_to_enum.h"
19#include "libmesh/quadrature_gauss.h"
20#include "libmesh/point_locator_base.h"
21#include "libmesh/distributed_mesh.h"
22#include "libmesh/elem.h"
23
24#include <typeinfo>
25
27
30{
32
33 // NOTE: libmesh tetrahedralization code actually has a clever heuristic
34 // to re-orient elements starting from the known orientation of the "bottom-most"
35 // surface element. We could import that logic here, once we identify and separate connected
36 // (contiguous) components of the mesh.
37
38 // Which elements to apply the change on
39 params.setDocString(
40 "included_subdomains",
41 "Subdomain names or ids for the elements that may have their normal modified.");
42
43 // How to set the normal
44 params.renameParam("normal",
45 "normal_to_align_with",
46 "Direction vector that element normals should be pointing in the same "
47 "direction as (dot product > 0)");
48 params.addParam<std::vector<dof_id_type>>(
49 "element_ids_to_flood_from",
50 "IDs of elements to start flooding and changing the subdomains from");
51
52 // This mesh generator does not modify the subdomains
53 params.suppressParameter<std::vector<SubdomainName>>("new_subdomain");
54 // This mesh generator is specifically intended to flip normals
55 params.set<bool>("flip_inverted_normals") = true;
56 params.suppressParameter<bool>("flip_inverted_normals");
57 params.set<bool>("consider_flipped_normals") = true;
58 params.set<bool>("_using_normal") = true;
59
60 params.addClassDescription("Change the orientation of (part of) the surface mesh.");
61 return params;
62}
63
65 : SurfaceMeshGeneratorBase(parameters), _num_flipped(0)
66{
67 if (!isParamValid("element_ids_to_flood_from") && !isParamSetByUser("normal_to_align_with"))
68 paramError("normal_to_align_with",
69 "Either a 'normal_to_align_with' or 'element_ids_to_flood_from' must be specified "
70 "to select the behavior of this mesh generator.");
71}
72
73std::unique_ptr<MeshBase>
75{
76 std::unique_ptr<MeshBase> mesh = std::move(_input);
77 setup(*mesh);
78
79 auto & binfo = mesh->get_boundary_info();
80 bool normal_is_input = isParamSetByUser("normal_to_align_with");
81
82 if (!isParamValid("element_ids_to_flood_from"))
83 // We'll need to loop over all of the elements to adjust normals with the fixed normal option
84 for (auto & elem : mesh->element_ptr_range())
85 {
86 // Nothing to do with edges or 3D elements
87 if (elem->dim() != 2)
88 continue;
89
90 // Check if element should be used to paint from
91 if (_included_subdomain_ids.size() &&
92 std::find(_included_subdomain_ids.begin(),
94 elem->subdomain_id()) == _included_subdomain_ids.end())
95 continue;
96
97 // Compute the normal
98 const auto normal = get2DElemNormal(elem);
99
100 if (normal * _normal < 0)
101 {
102 elem->flip(&binfo);
103 _num_flipped++;
104 }
105 }
106 else
107 // We'll flood and re-adjust orientations starting from a few given elements
108 // NOTE: user's responsibility to make sure these surface elements' orientations are consistent
109 for (const auto eid : getParam<std::vector<dof_id_type>>("element_ids_to_flood_from"))
110 {
111 auto elem = mesh->elem_ptr(eid);
112
113 // Nothing to do with edges or 3D elements
114 if (elem->dim() != 2)
115 continue;
116
117 // Compute the normal
118 const auto normal = normal_is_input ? _normal : get2DElemNormal(elem);
119
120 flood(elem, normal, *elem, elem->subdomain_id(), *mesh);
121 }
122
123 if (_num_flipped)
124 _console << "Flipped the orientation of " << _num_flipped << " surface elements." << std::endl;
125
126 return dynamic_pointer_cast<MeshBase>(mesh);
127}
registerMooseObject("MooseApp", OrientSurfaceMeshGenerator)
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void suppressParameter(const std::string &name)
This method suppresses an inherited parameter so that it isn't required or valid in the derived class...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void renameParam(const std::string &old_name, const std::string &new_name, const std::string &new_docstring)
Rename a parameter and provide a new documentation string.
void setDocString(const std::string &name, const std::string &doc)
Set the doc string of a parameter.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
Definition MooseBase.h:205
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
This class will re-orient surface elements based on user-specified settings.
OrientSurfaceMeshGenerator(const InputParameters &parameters)
unsigned int _num_flipped
Keeps track of the number of element orientation flips, for output purposes.
static InputParameters validParams()
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
Point get2DElemNormal(const Elem *const elem) const
Get the normal of the 2D element.
void flood(Elem *const elem, const Point &normal, const Elem &starting_elem, const subdomain_id_type &sub_id, MeshBase &mesh)
This method implements a recursive flood routine to paint (applying an operation) to elements on mesh...
static InputParameters validParams()
void setup(MeshBase &mesh)
Sets up various data structures.
std::vector< subdomain_id_type > _included_subdomain_ids
A list of included subdomain ids that the element has to be priorly a part of, extracted from the 'in...
std::unique_ptr< MeshBase > & _input
the mesh to add the subdomains to
Point _normal
if specified, then surface elements are only considered if their normal is close to this
MeshBase & mesh