https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
AutomaticContactPairingGenerator Class Reference

Detects contact surface pairs from a list of candidate boundaries using proximity, stores them in the mesh meta-data, and optionally creates lower-dimensional subdomain blocks for each pair, suitable for use in mortar contact via ContactAction. More...

#include <AutomaticContactPairingGenerator.h>

Inheritance diagram for AutomaticContactPairingGenerator:
[legend]

Classes

struct  CandidateBoundary
 A candidate contact boundary with its sideset area and area-weighted centroid. More...
 

Public Types

using ContactPairs = std::vector< std::pair< std::string, std::string > >
 Type of the mesh meta-data holding the detected (primary, secondary) boundary name pairs.
 
typedef DataFileName DataFileParameterType
 

Public Member Functions

 AutomaticContactPairingGenerator (const InputParameters &parameters)
 
std::unique_ptr< MeshBase > generate () override
 
std::unique_ptr< CSG::CSGBase > generateInternalCSG ()
 
std::unique_ptr< MeshBase > generateInternal ()
 
const std::set< MeshGeneratorName > & getRequestedMeshGenerators () const
 
const std::set< MeshGeneratorName > & getRequestedMeshGeneratorsForSub () const
 
void addParentMeshGenerator (const MeshGenerator &mg, const AddParentChildKey)
 
void addChildMeshGenerator (const MeshGenerator &mg, const AddParentChildKey)
 
const std::set< const MeshGenerator *, Comparator > & getParentMeshGenerators () const
 
const std::set< const MeshGenerator *, Comparator > & getChildMeshGenerators () const
 
const std::set< const MeshGenerator *, Comparator > & getSubMeshGenerators () const
 
bool isParentMeshGenerator (const MeshGeneratorName &name, const bool direct=true) const
 
bool isChildMeshGenerator (const MeshGeneratorName &name, const bool direct=true) const
 
bool isNullMeshName (const MeshGeneratorName &name) const
 
bool hasSaveMesh () const
 
bool hasOutput () const
 
const std::string & getSavedMeshName () const
 
bool hasGenerateData () const
 
bool hasGenerateCSG () const
 
bool isDataOnly () const
 
virtual bool enabled () const
 
std::shared_ptr< MooseObject > getSharedPtr ()
 
std::shared_ptr< const MooseObject > getSharedPtr () const
 
bool isKokkosObject () const
 
MooseApp & getMooseApp () const
 
const std::string & type () const
 
const std::string & name () const
 
std::string typeAndName () const
 
MooseObjectParameterName uniqueParameterName (const std::string &parameter_name) const
 
MooseObjectName uniqueName () const
 
const InputParameters & parameters () const
 
const hit::Node * getHitNode () const
 
bool hasBase () const
 
const std::string & getBase () const
 
const T & getParam (const std::string &name) const
 
std::vector< std::pair< T1, T2 > > getParam (const std::string &param1, const std::string &param2) const
 
const T * queryParam (const std::string &name) const
 
const T & getRenamedParam (const std::string &old_name, const std::string &new_name) const
 
T getCheckedPointerParam (const std::string &name, const std::string &error_string="") const
 
bool isParamValid (const std::string &name) const
 
bool isParamSetByUser (const std::string &name) const
 
void connectControllableParams (const std::string &parameter, const std::string &object_type, const std::string &object_name, const std::string &object_parameter) const
 
void paramError (const std::string &param, Args... args) const
 
void paramWarning (const std::string &param, Args... args) const
 
void paramWarning (const std::string &param, Args... args) const
 
void paramInfo (const std::string &param, Args... args) const
 
std::string messagePrefix (const bool hit_prefix=true) const
 
std::string errorPrefix (const std::string &) const
 
void mooseError (Args &&... args) const
 
void mooseDocumentedError (const std::string &repo_name, const unsigned int issue_num, Args &&... args) const
 
void mooseErrorNonPrefixed (Args &&... args) const
 
void mooseWarning (Args &&... args) const
 
void mooseWarning (Args &&... args) const
 
void mooseWarningNonPrefixed (Args &&... args) const
 
void mooseWarningNonPrefixed (Args &&... args) const
 
void mooseDeprecated (Args &&... args) const
 
void mooseDeprecated (Args &&... args) const
 
void mooseDeprecatedNoTrace (Args &&... args) const
 
void mooseInfo (Args &&... args) const
 
void callMooseError (std::string msg, const bool with_prefix, const hit::Node *node=nullptr, const bool show_trace=true) const
 
std::string getDataFileName (const std::string &param) const
 
std::string getDataFileNameByName (const std::string &relative_path) const
 
std::string getDataFilePath (const std::string &relative_path) const
 
const Parallel::Communicator & comm () const
 
processor_id_type n_processors () const
 
processor_id_type processor_id () const
 

Static Public Member Functions

static InputParameters validParams ()
 
static std::string pairSuffix (const std::pair< BoundaryName, BoundaryName > &pair)
 Name suffix identifying a (primary, secondary) boundary pair, used to build unique object names when there is more than one contact pair.
 
static bool hasGenerateData (const InputParameters &params)
 
static bool hasGenerateCSG (const InputParameters &params)
 
static void callMooseError (MooseApp *const app, const InputParameters &params, std::string msg, const bool with_prefix, const hit::Node *node, const bool show_trace=true)
 
static void setHasGenerateData (InputParameters &params)
 
static void setHasGenerateCSG (InputParameters &params)
 

Public Attributes

 usingCombinedWarningSolutionWarnings
 
const ConsoleStream _console
 

Static Public Attributes

static constexpr auto contact_pairs_property = "contact_pairs"
 Name of the mesh meta-data holding the detected contact pairs.
 
static const std::string data_only_param
 
static const std::string type_param
 
static const std::string name_param
 
static const std::string unique_name_param
 
static const std::string app_param
 
static const std::string moose_base_param
 
static const std::string kokkos_object_param
 
static constexpr auto SYSTEM
 
static constexpr auto NAME
 

Protected Member Functions

virtual void generateData ()
 
virtual std::unique_ptr< CSG::CSGBase > generateCSG ()
 
T & copyMeshProperty (const std::string &target_data_name, const std::string &source_data_name, const std::string &source_mesh)
 
T & copyMeshProperty (const std::string &source_data_name, const std::string &source_mesh)
 
std::unique_ptr< MeshBase > & getMesh (const std::string &param_name, const bool allow_invalid=false)
 
std::vector< std::unique_ptr< MeshBase > * > getMeshes (const std::string &param_name)
 
std::unique_ptr< MeshBase > & getMeshByName (const MeshGeneratorName &mesh_generator_name)
 
std::vector< std::unique_ptr< MeshBase > * > getMeshesByName (const std::vector< MeshGeneratorName > &mesh_generator_names)
 
std::unique_ptr< CSG::CSGBase > & getCSGBase (const std::string &param_name)
 
std::unique_ptr< CSG::CSGBase > & getCSGBaseByName (const MeshGeneratorName &mesh_generator_name)
 
std::vector< std::unique_ptr< CSG::CSGBase > * > getCSGBases (const std::string &param_name)
 
std::vector< std::unique_ptr< CSG::CSGBase > * > getCSGBasesByName (const std::vector< MeshGeneratorName > &mesh_generator_names)
 
void declareMeshForSub (const std::string &param_name)
 
void declareMeshesForSub (const std::string &param_name)
 
void declareMeshForSubByName (const MeshGeneratorName &mesh_generator_name)
 
void declareMeshesForSubByName (const std::vector< MeshGeneratorName > &mesh_generator_names)
 
std::unique_ptr< MeshBase > buildMeshBaseObject (unsigned int dim=libMesh::invalid_uint)
 
std::unique_ptr< ReplicatedMesh > buildReplicatedMesh (unsigned int dim=libMesh::invalid_uint)
 
std::unique_ptr< DistributedMesh > buildDistributedMesh (unsigned int dim=libMesh::invalid_uint)
 
void addMeshSubgenerator (const std::string &type, const std::string &name, Ts... extra_input_parameters)
 
void addMeshSubgenerator (const std::string &type, const std::string &name, InputParameters params)
 
void declareNullMeshName (const MeshGeneratorName &name)
 
void flagInvalidSolutionInternal (const InvalidSolutionID invalid_solution_id) const
 
InvalidSolutionID registerInvalidSolutionInternal (const std::string &message, const bool warning) const
 
const T & getMeshProperty (const std::string &data_name, const std::string &prefix)
 
const T & getMeshProperty (const std::string &data_name)
 
bool hasMeshProperty (const std::string &data_name, const std::string &prefix) const
 
bool hasMeshProperty (const std::string &data_name, const std::string &prefix) const
 
bool hasMeshProperty (const std::string &data_name) const
 
bool hasMeshProperty (const std::string &data_name) const
 
std::string meshPropertyName (const std::string &data_name) const
 
T & declareMeshProperty (const std::string &data_name, Args &&... args)
 
T & declareMeshProperty (const std::string &data_name, const T &data_value)
 
T & declareMeshProperty (const std::string &data_name, Args &&... args)
 
T & declareMeshProperty (const std::string &data_name, const T &data_value)
 
T & setMeshProperty (const std::string &data_name, Args &&... args)
 
T & setMeshProperty (const std::string &data_name, const T &data_value)
 
T & setMeshProperty (const std::string &data_name, Args &&... args)
 
T & setMeshProperty (const std::string &data_name, const T &data_value)
 

Static Protected Member Functions

static std::string meshPropertyName (const std::string &data_name, const std::string &prefix)
 

Protected Attributes

std::unique_ptr< MeshBase > & _input
 
MooseMesh *const _mesh
 
const bool & _enabled
 
MooseApp & _app
 
Factory & _factory
 
ActionFactory & _action_factory
 
const std::string & _type
 
const std::string & _name
 
const InputParameters & _pars
 
const Parallel::Communicator & _communicator
 

Private Member Functions

std::vector< std::pair< BoundaryName, BoundaryName > > findPairsNodeProximity (const MeshBase &mesh) const
 Find pairs by node-proximity KD-tree search; returns deduplicated pairs.
 
std::vector< std::pair< BoundaryName, BoundaryName > > findPairsCentroid (const MeshBase &mesh) const
 Find pairs by sideset centroid distance; returns deduplicated pairs.
 
std::vector< CandidateBoundary > candidateBoundaries (const MeshBase &mesh) const
 Resolve the candidate boundary names to boundary IDs, erroring if any boundary is listed more than once, and compute the area and centroid of each candidate sideset.
 
virtual std::string meshPropertyPrefix (const std::string &) const override final
 
void checkGetMesh (const MeshGeneratorName &mesh_generator_name, const std::string &param_name) const
 
const MeshGeneratorName * getMeshGeneratorNameFromParam (const std::string &param_name, const bool allow_invalid) const
 
const std::vector< MeshGeneratorName > & getMeshGeneratorNamesFromParam (const std::string &param_name) const
 
RestartableDataValue & setMeshPropertyHelper (const std::string &data_name)
 
const RestartableDataValue & getMeshPropertyInternal (const std::string &data_name, const std::string &prefix) const
 
void mooseErrorInternal (Args &&... args) const
 

Static Private Member Functions

static std::pair< BoundaryName, BoundaryName > orderPair (const CandidateBoundary &a, const CandidateBoundary &b)
 Order two paired boundaries as (primary, secondary), with the larger surface as primary.
 
static void removeDuplicatePairs (std::vector< std::pair< BoundaryName, BoundaryName > > &pairs)
 
static const hit::Node * getHitNode (const InputParameters &params)
 
static std::string messagePrefix (const InputParameters &params, const bool hit_prefix)
 

Private Attributes

const std::vector< BoundaryName > & _pairing_boundaries
 Candidate boundaries to pair.
 
const Real _pairing_distance
 Maximum center-to-center or node-to-node distance for pairing.
 
const MooseEnum & _pairing_method
 Pairing method: NODE or CENTROID.
 
const std::string & _prefix
 Prefix prepended to the names of generated subdomain blocks.
 
const bool _create_lower_d_blocks
 Whether to create lower-dimensional subdomain blocks for each detected pair.
 
std::set< MeshGeneratorName > _requested_mesh_generators
 
std::set< MeshGeneratorName > _requested_mesh_generators_for_sub
 
std::vector< std::pair< std::string, std::unique_ptr< MeshBase > * > > _requested_meshes
 
std::vector< std::pair< std::string, std::unique_ptr< CSG::CSGBase > * > > _requested_csg_bases
 
std::unique_ptr< MeshBase > _null_mesh
 
std::unique_ptr< CSG::CSGBase > _null_csg_base
 
std::set< const MeshGenerator *, Comparator > _parent_mesh_generators
 
std::set< const MeshGenerator *, Comparator > _child_mesh_generators
 
std::set< const MeshGenerator *, Comparator > _sub_mesh_generators
 
std::set< std::string > _null_mesh_names
 
const std::string & _save_with_name
 
const bool _data_only
 
const ParallelParamObject & _parent
 
const MooseBase & _si_moose_base
 
const FEProblemBase * _si_problem
 
MooseApp & _meta_data_app
 
const MooseObject *const _meta_data_object
 

Detailed Description

Detects contact surface pairs from a list of candidate boundaries using proximity, stores them in the mesh meta-data, and optionally creates lower-dimensional subdomain blocks for each pair, suitable for use in mortar contact via ContactAction.

Definition at line 19 of file AutomaticContactPairingGenerator.h.

Member Typedef Documentation

◆ ContactPairs

using AutomaticContactPairingGenerator::ContactPairs = std::vector<std::pair<std::string, std::string> >

Type of the mesh meta-data holding the detected (primary, secondary) boundary name pairs.

Definition at line 27 of file AutomaticContactPairingGenerator.h.

Constructor & Destructor Documentation

◆ AutomaticContactPairingGenerator()

AutomaticContactPairingGenerator::AutomaticContactPairingGenerator ( const InputParameters &  parameters)

Definition at line 72 of file AutomaticContactPairingGenerator.C.

75 _input(getMesh("input")),
76 _pairing_boundaries(getParam<std::vector<BoundaryName>>("automatic_pairing_boundaries")),
77 _pairing_distance(getParam<Real>("automatic_pairing_distance")),
78 _pairing_method(getParam<MooseEnum>("automatic_pairing_method")),
79 _prefix(getParam<std::string>("prefix")),
80 _create_lower_d_blocks(getParam<bool>("create_lower_d_blocks"))
81{
82 // Declared here, and assigned during generation, so that the pairs are restored from the mesh
83 // meta-data on recover, when generation is skipped
84 declareMeshProperty<ContactPairs>(contact_pairs_property);
85}
const Real _pairing_distance
Maximum center-to-center or node-to-node distance for pairing.
const bool _create_lower_d_blocks
Whether to create lower-dimensional subdomain blocks for each detected pair.
static constexpr auto contact_pairs_property
Name of the mesh meta-data holding the detected contact pairs.
const std::vector< BoundaryName > & _pairing_boundaries
Candidate boundaries to pair.
const MooseEnum & _pairing_method
Pairing method: NODE or CENTROID.
const std::string & _prefix
Prefix prepended to the names of generated subdomain blocks.
std::unique_ptr< MeshBase > & getMesh(const std::string &param_name, const bool allow_invalid=false)
const InputParameters & parameters() const
const T & getParam(const std::string &name) const

Member Function Documentation

◆ candidateBoundaries()

std::vector< AutomaticContactPairingGenerator::CandidateBoundary > AutomaticContactPairingGenerator::candidateBoundaries ( const MeshBase &  mesh) const
private

Resolve the candidate boundary names to boundary IDs, erroring if any boundary is listed more than once, and compute the area and centroid of each candidate sideset.

Areas and centroids are computed in Cartesian coordinates.

Definition at line 139 of file AutomaticContactPairingGenerator.C.

140{
141 // A boundary listed more than once, either repeated or as both a name and an ID, would otherwise
142 // be paired with itself
143 std::vector<CandidateBoundary> candidates;
144 for (const auto & bname : _pairing_boundaries)
145 {
146 const BoundaryID bid = MooseMeshUtils::getBoundaryID(bname, mesh);
147 const auto it =
148 std::find_if(candidates.begin(),
149 candidates.end(),
150 [bid](const CandidateBoundary & candidate) { return candidate.id == bid; });
151 if (it != candidates.end())
152 {
153 if (it->name == bname)
154 mooseError("Boundary '",
155 bname,
156 "' is listed more than once in 'automatic_pairing_boundaries'. Each boundary "
157 "may be listed only once.");
158 else
159 mooseError("Boundaries '",
160 it->name,
161 "' and '",
162 bname,
163 "' in 'automatic_pairing_boundaries' refer to the same boundary (ID ",
164 bid,
165 "). Each boundary may be listed only once.");
166 }
167 candidates.push_back({bname, bid, 0, Point(0, 0, 0)});
168 }
169
170 // Accumulate the area and area-weighted centroid of each candidate sideset. On a distributed
171 // mesh, each process accumulates over the sides of its local elements so that ghosted sides are
172 // counted once, and the partial sums are then summed across processes
173 const bool serial = mesh.is_serial();
174 libMesh::ElemSideBuilder side_builder;
175 for (const auto & [eid, side, bid] : mesh.get_boundary_info().build_side_list())
176 {
177 const auto it = std::find_if(candidates.begin(),
178 candidates.end(),
179 [bid = bid](const CandidateBoundary & candidate)
180 { return candidate.id == bid; });
181 if (it == candidates.end())
182 continue;
183
184 const Elem & elem = *mesh.elem_ptr(eid);
185 if (!serial && elem.processor_id() != mesh.processor_id())
186 continue;
187
188 const Elem & side_elem = side_builder(elem, side);
189 const Real area = side_elem.volume();
190 it->area += area;
191 it->centroid += side_elem.true_centroid() * area;
192 }
193
194 if (!serial)
195 {
196 // Pack the areas and weighted centroids so that a single reduction suffices
197 std::vector<Real> sums;
198 sums.reserve(candidates.size() * (1 + Moose::dim));
199 for (const auto & candidate : candidates)
200 {
201 sums.push_back(candidate.area);
202 for (const auto d : make_range(Moose::dim))
203 sums.push_back(candidate.centroid(d));
204 }
205 mesh.comm().sum(sums);
206
207 auto sum_it = sums.begin();
208 for (auto & candidate : candidates)
209 {
210 candidate.area = *sum_it++;
211 for (const auto d : make_range(Moose::dim))
212 candidate.centroid(d) = *sum_it++;
213 }
214 }
215
216 for (auto & candidate : candidates)
217 if (candidate.area > 0)
218 candidate.centroid /= candidate.area;
219
220 return candidates;
221}
boundary_id_type BoundaryID
unsigned int dim
void mooseError(Args &&... args) const
MeshBase & mesh
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
static constexpr std::size_t dim
if(subdm)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)

Referenced by findPairsCentroid(), and findPairsNodeProximity().

◆ findPairsCentroid()

std::vector< std::pair< BoundaryName, BoundaryName > > AutomaticContactPairingGenerator::findPairsCentroid ( const MeshBase &  mesh) const
private

Find pairs by sideset centroid distance; returns deduplicated pairs.

Definition at line 318 of file AutomaticContactPairingGenerator.C.

319{
320 const auto candidates = candidateBoundaries(mesh);
321 for (const auto & candidate : candidates)
322 if (candidate.area == 0)
323 mooseError("Boundary '", candidate.name, "' not found in mesh.");
324
325 // Find all pairs within distance
326 std::vector<std::pair<BoundaryName, BoundaryName>> pairs;
327 for (const auto i : index_range(candidates))
328 for (const auto j : make_range(i + 1, candidates.size()))
329 if ((candidates[i].centroid - candidates[j].centroid).norm() <= _pairing_distance)
330 pairs.push_back(orderPair(candidates[i], candidates[j]));
331
333 return pairs;
334}
for(PetscInt i=0;i< nvars;++i)
static std::pair< BoundaryName, BoundaryName > orderPair(const CandidateBoundary &a, const CandidateBoundary &b)
Order two paired boundaries as (primary, secondary), with the larger surface as primary.
static void removeDuplicatePairs(std::vector< std::pair< BoundaryName, BoundaryName > > &pairs)
std::vector< CandidateBoundary > candidateBoundaries(const MeshBase &mesh) const
Resolve the candidate boundary names to boundary IDs, erroring if any boundary is listed more than on...
const std::string & name() const
auto norm(const T &a)
auto index_range(const T &sizable)

Referenced by generate().

◆ findPairsNodeProximity()

std::vector< std::pair< BoundaryName, BoundaryName > > AutomaticContactPairingGenerator::findPairsNodeProximity ( const MeshBase &  mesh) const
private

Find pairs by node-proximity KD-tree search; returns deduplicated pairs.

Definition at line 241 of file AutomaticContactPairingGenerator.C.

242{
243 const auto candidates = candidateBoundaries(mesh);
244 const auto find_candidate = [&candidates](const BoundaryID bid) -> const CandidateBoundary &
245 {
246 const auto it =
247 std::find_if(candidates.begin(),
248 candidates.end(),
249 [bid](const CandidateBoundary & candidate) { return candidate.id == bid; });
250 mooseAssert(it != candidates.end(), "Boundary not in candidate list");
251 return *it;
252 };
253
254 // Collect nodes on candidate boundaries, from both sidesets and nodesets. On a distributed mesh,
255 // each process contributes the boundary nodes it owns, which it sees together with all of their
256 // boundary sides through the default point-neighbor ghosting, and the lists are then gathered so
257 // that every process searches the complete set
258 const bool serial = mesh.is_serial();
259 std::vector<NodeBoundaryIDInfo> node_bid_list;
260 for (const auto & candidate : candidates)
261 for (const auto node_id : MooseMeshUtils::getBoundaryNodes(mesh, candidate.id))
262 {
263 const Node & node = mesh.node_ref(node_id);
264 if (serial || node.processor_id() == mesh.processor_id())
265 node_bid_list.emplace_back(node, candidate.id);
266 }
267
268 if (!serial)
269 mesh.comm().allgather(node_bid_list);
270
271 // Sort by boundary id for deterministic ordering
272 std::sort(node_bid_list.begin(),
273 node_bid_list.end(),
274 [](const NodeBoundaryIDInfo & a, const NodeBoundaryIDInfo & b)
275 { return a.second < b.second; });
276
277 using KDTreeType = nanoflann::KDTreeSingleIndexAdaptor<
278 nanoflann::L2_Simple_Adaptor<Real, PointListAdaptor<NodeBoundaryIDInfo>, Real, std::size_t>,
281 std::size_t>;
282
283 const unsigned int max_leaf_size = 20;
284 auto point_list =
285 PointListAdaptor<NodeBoundaryIDInfo>(node_bid_list.begin(), node_bid_list.end());
286 auto kd_tree = std::make_unique<KDTreeType>(
287 Moose::dim, point_list, nanoflann::KDTreeSingleIndexAdaptorParams(max_leaf_size));
288 kd_tree->buildIndex();
289
290 nanoflann::SearchParameters search_params;
291 std::vector<nanoflann::ResultItem<std::size_t, Real>> ret_matches;
292 std::vector<std::pair<BoundaryName, BoundaryName>> pairs;
293
294 for (const auto & [entry_node, entry_bid] : node_bid_list)
295 {
296 ret_matches.clear();
297 kd_tree->radiusSearch(
298 &entry_node(0), _pairing_distance * _pairing_distance, ret_matches, search_params);
299
300 for (const auto & [pair_idx, _] : ret_matches)
301 {
302 const auto & [pair_node, pair_bid] = node_bid_list[pair_idx];
303 libmesh_ignore(pair_node);
304
305 // Skip nodes on the same boundary
306 if (pair_bid == entry_bid)
307 continue;
308
309 pairs.push_back(orderPair(find_candidate(entry_bid), find_candidate(pair_bid)));
310 }
311 }
312
314 return pairs;
315}
std::pair< Point, BoundaryID > NodeBoundaryIDInfo
std::set< dof_id_type > getBoundaryNodes(const MeshBase &mesh, const BoundaryID boundary_id)
void libmesh_ignore(const Args &...)
SearchParams SearchParameters

Referenced by generate().

◆ generate()

std::unique_ptr< MeshBase > AutomaticContactPairingGenerator::generate ( )
overridevirtual

Implements MeshGenerator.

Definition at line 88 of file AutomaticContactPairingGenerator.C.

89{
90 auto mesh = std::move(_input);
91
92 std::vector<std::pair<BoundaryName, BoundaryName>> pairs;
93 if (_pairing_method == "NODE")
94 pairs = findPairsNodeProximity(*mesh);
95 else
96 pairs = findPairsCentroid(*mesh);
97
98 // Mortar contact needs at least one pair to build its lower-dimensional blocks, while node-face
99 // contact may proceed with none
100 if (pairs.empty() && _create_lower_d_blocks)
101 mooseError("No contact pairs found within distance ",
103 " among boundaries ",
105
106 setMeshProperty<ContactPairs>(contact_pairs_property, ContactPairs(pairs.begin(), pairs.end()));
107
109 return mesh;
110
111 const bool multiple_pairs = pairs.size() > 1;
112 for (const auto & pair : pairs)
113 {
114 const auto & [primary_boundary, secondary_boundary] = pair;
115 const std::string suffix = multiple_pairs ? pairSuffix(pair) : "";
116 const std::string primary_name = _prefix + "_primary_subdomain" + suffix;
117 const std::string secondary_name = _prefix + "_secondary_subdomain" + suffix;
118
120 *mesh, {primary_boundary}, MooseMeshUtils::getNextFreeSubdomainID(*mesh), primary_name);
122 *mesh, {secondary_boundary}, MooseMeshUtils::getNextFreeSubdomainID(*mesh), secondary_name);
123 }
124
125 return mesh;
126}
static std::string pairSuffix(const std::pair< BoundaryName, BoundaryName > &pair)
Name suffix identifying a (primary, secondary) boundary pair, used to build unique object names when ...
std::vector< std::pair< BoundaryName, BoundaryName > > findPairsCentroid(const MeshBase &mesh) const
Find pairs by sideset centroid distance; returns deduplicated pairs.
std::vector< std::pair< BoundaryName, BoundaryName > > findPairsNodeProximity(const MeshBase &mesh) const
Find pairs by node-proximity KD-tree search; returns deduplicated pairs.
std::vector< std::pair< std::string, std::string > > ContactPairs
Type of the mesh meta-data holding the detected (primary, secondary) boundary name pairs.
void createSubdomainFromSidesets(MeshBase &mesh, std::vector< BoundaryName > boundary_names, const SubdomainID new_subdomain_id, const SubdomainName &new_subdomain_name)
SubdomainID getNextFreeSubdomainID(MeshBase &input_mesh)
std::string stringify(const T &t)

◆ orderPair()

std::pair< BoundaryName, BoundaryName > AutomaticContactPairingGenerator::orderPair ( const CandidateBoundary &  a,
const CandidateBoundary &  b 
)
staticprivate

Order two paired boundaries as (primary, secondary), with the larger surface as primary.

Definition at line 224 of file AutomaticContactPairingGenerator.C.

226{
227 // The larger surface is chosen as primary, which places the Lagrange multipliers on the smaller
228 // surface and reduces the number of secondary elements that are only partially covered by the
229 // primary surface. Areas that agree to within libMesh's relative TOLERANCE (e.g. matching
230 // surfaces whose computed areas differ only by roundoff) fall back to the larger boundary ID so
231 // that the assignment is deterministic
232 const Real area_tol = TOLERANCE * std::max(a.area, b.area);
233 const bool a_is_primary = std::abs(a.area - b.area) > area_tol ? a.area > b.area : a.id > b.id;
234 if (a_is_primary)
235 return {a.name, b.name};
236 else
237 return {b.name, a.name};
238}

Referenced by findPairsCentroid(), and findPairsNodeProximity().

◆ pairSuffix()

std::string AutomaticContactPairingGenerator::pairSuffix ( const std::pair< BoundaryName, BoundaryName > &  pair)
static

Name suffix identifying a (primary, secondary) boundary pair, used to build unique object names when there is more than one contact pair.

Definition at line 129 of file AutomaticContactPairingGenerator.C.

130{
131 // Labeling each boundary keeps the suffix unambiguous when boundary names contain underscores,
132 // e.g. (top_left, bottom) -> _p_top_left_s_bottom and (top, left_bottom) -> _p_top_s_left_bottom.
133 // The single-letter labels keep generated names short, since exodus output truncates names to 32
134 // characters by default
135 return "_p_" + pair.first + "_s_" + pair.second;
136}

Referenced by generate(), and ContactAction::pairSuffix().

◆ removeDuplicatePairs()

void AutomaticContactPairingGenerator::removeDuplicatePairs ( std::vector< std::pair< BoundaryName, BoundaryName > > &  pairs)
staticprivate

Definition at line 337 of file AutomaticContactPairingGenerator.C.

339{
340 std::sort(pairs.begin(), pairs.end());
341 pairs.erase(std::unique(pairs.begin(), pairs.end()), pairs.end());
342}

Referenced by findPairsCentroid(), and findPairsNodeProximity().

◆ validParams()

InputParameters AutomaticContactPairingGenerator::validParams ( )
static

Definition at line 44 of file AutomaticContactPairingGenerator.C.

45{
47 params.addRequiredParam<MeshGeneratorName>("input", "The mesh to modify");
48 params.addRequiredParam<std::vector<BoundaryName>>(
49 "automatic_pairing_boundaries",
50 "List of boundary names to consider when automatically detecting contact pairs.");
51 params.addRequiredParam<Real>(
52 "automatic_pairing_distance",
53 "Maximum distance (node-to-node or centroid-to-centroid) at which two boundaries are "
54 "considered a contact pair.");
56 "automatic_pairing_method",
57 MooseEnum("NODE CENTROID"),
58 "Strategy used to detect pairs: NODE uses a KD-tree over boundary nodes; "
59 "CENTROID uses sideset center-of-gravity distances.");
60 params.addRequiredParam<std::string>(
61 "prefix", "Prefix prepended to the names of generated subdomain blocks.");
62 params.addRequiredParam<bool>(
63 "create_lower_d_blocks",
64 "Whether to create primary and secondary lower-dimensional subdomain blocks for each "
65 "detected pair.");
67 "Detects contact surface pairs by proximity, stores them in the mesh meta-data, and "
68 "optionally creates lower-dimensional subdomain blocks for use in mortar contact.");
69 return params;
70}
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
static InputParameters validParams()

Member Data Documentation

◆ _create_lower_d_blocks

const bool AutomaticContactPairingGenerator::_create_lower_d_blocks
private

Whether to create lower-dimensional subdomain blocks for each detected pair.

Definition at line 51 of file AutomaticContactPairingGenerator.h.

Referenced by generate().

◆ _input

std::unique_ptr<MeshBase>& AutomaticContactPairingGenerator::_input
protected

Definition at line 39 of file AutomaticContactPairingGenerator.h.

Referenced by generate().

◆ _pairing_boundaries

const std::vector<BoundaryName>& AutomaticContactPairingGenerator::_pairing_boundaries
private

Candidate boundaries to pair.

Definition at line 43 of file AutomaticContactPairingGenerator.h.

Referenced by candidateBoundaries(), and generate().

◆ _pairing_distance

const Real AutomaticContactPairingGenerator::_pairing_distance
private

Maximum center-to-center or node-to-node distance for pairing.

Definition at line 45 of file AutomaticContactPairingGenerator.h.

Referenced by findPairsCentroid(), findPairsNodeProximity(), and generate().

◆ _pairing_method

const MooseEnum& AutomaticContactPairingGenerator::_pairing_method
private

Pairing method: NODE or CENTROID.

Definition at line 47 of file AutomaticContactPairingGenerator.h.

Referenced by generate().

◆ _prefix

const std::string& AutomaticContactPairingGenerator::_prefix
private

Prefix prepended to the names of generated subdomain blocks.

Definition at line 49 of file AutomaticContactPairingGenerator.h.

Referenced by generate().

◆ contact_pairs_property

constexpr auto AutomaticContactPairingGenerator::contact_pairs_property = "contact_pairs"
staticconstexpr

Name of the mesh meta-data holding the detected contact pairs.

Definition at line 30 of file AutomaticContactPairingGenerator.h.

Referenced by AutomaticContactPairingGenerator(), generate(), and ContactAction::getAutomaticContactPairs().


The documentation for this class was generated from the following files: