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 : #pragma once 11 : 12 : #include "MooseTypes.h" 13 : #include "MooseHashing.h" 14 : 15 : #include "libmesh/parallel_object.h" 16 : 17 : #include <unordered_map> 18 : #include <set> 19 : 20 : class SubProblem; 21 : class MortarExecutorInterface; 22 : class AutomaticMortarGeneration; 23 : 24 : class MortarInterfaceWarehouse : public libMesh::ParallelObject 25 : { 26 : public: 27 : MortarInterfaceWarehouse(const libMesh::ParallelObject & other); 28 : 29 : /** 30 : * Create mortar generation object 31 : * @param boundary_key The primary-secondary boundary pair on which the AMG objects lives 32 : * @param subdomain_key The primary-secondary subdomain pair on which the AMG objects lives 33 : * @param subproblem A reference to the subproblem 34 : * @param on_displaced Whether the AMG object lives on the displaced mesh 35 : * @param periodic Whether the AMG object will be used for enforcing periodic constraints. Note 36 : * that this changes the direction of the projection normals so one AMG object cannot be used to 37 : * enforce both periodic and non-periodic constraints 38 : * @param debug whether to output mortar segment mesh exodus file for debugging purposes 39 : * @param correct_edge_dropping edge dropping treatment selection 40 : * @param minimum_projection_angle minimum projection angle allowed for building mortar segment 41 : * mesh 42 : */ 43 : void createMortarInterface(const std::pair<BoundaryID, BoundaryID> & boundary_key, 44 : const std::pair<SubdomainID, SubdomainID> & subdomain_key, 45 : SubProblem & subproblem, 46 : bool on_displaced, 47 : bool periodic, 48 : const bool debug, 49 : const bool correct_edge_dropping, 50 : const Real minimum_projection_angle); 51 : 52 : /** 53 : * Getter to retrieve the AutomaticMortarGeneration object corresponding to the boundary and 54 : * subdomain keys. If the AutomaticMortarGeneration object does not yet exist, then we error 55 : */ 56 : const AutomaticMortarGeneration & 57 : getMortarInterface(const std::pair<BoundaryID, BoundaryID> & boundary_key, 58 : const std::pair<SubdomainID, SubdomainID> & /*subdomain_key*/, 59 : bool on_displaced) const; 60 : 61 : /** 62 : * Non-const getter to retrieve the AutomaticMortarGeneration object corresponding to the boundary 63 : * and subdomain keys. If the AutomaticMortarGeneration object does not yet exist, then we error 64 : */ 65 : AutomaticMortarGeneration & 66 : getMortarInterface(const std::pair<BoundaryID, BoundaryID> & boundary_key, 67 : const std::pair<SubdomainID, SubdomainID> & /*subdomain_key*/, 68 : bool on_displaced); 69 : 70 : /** 71 : * Return all automatic mortar generation objects on either the displaced or undisplaced mesh 72 : */ 73 : const std::unordered_map<std::pair<BoundaryID, BoundaryID>, 74 : std::unique_ptr<AutomaticMortarGeneration>> & 75 121202 : getMortarInterfaces(bool on_displaced) const 76 : { 77 121202 : if (on_displaced) 78 60595 : return _displaced_mortar_interfaces; 79 : else 80 60607 : return _mortar_interfaces; 81 : } 82 : 83 : /** 84 : * Returns the mortar covered subdomains 85 : */ 86 62401 : const std::set<SubdomainID> & getMortarSubdomainIDs() const { return _mortar_subdomain_coverage; } 87 : 88 : /** 89 : * Returns the mortar covered boundaries 90 : */ 91 : const std::set<BoundaryID> & getMortarBoundaryIDs() const { return _mortar_boundary_coverage; } 92 : 93 : /** 94 : * Builds mortar segment meshes for each mortar interface 95 : */ 96 : void update(); 97 : 98 : /** 99 : * Returns whether any of the AutomaticMortarGeneration objects are running on a displaced mesh 100 : */ 101 141482 : bool hasDisplacedObjects() const { return _displaced_mortar_interfaces.size(); } 102 : 103 : /** 104 : * Returns whether we have **any** active AutomaticMortarGeneration objects 105 : */ 106 68821 : bool hasObjects() const { return _mortar_interfaces.size(); } 107 : 108 : /** 109 : * Returns the higher dimensional subdomain ids of the interior parents of the given lower-d 110 : * subdomain id 111 : */ 112 : const std::set<SubdomainID> & getHigherDimSubdomainIDs(SubdomainID lower_d_subdomain_id) const; 113 : 114 : /** 115 : * \em Adds \p mei to the container of objects that will have their \p mortarSetup method called 116 : * as soon as the mortar mesh has been generated for the first time 117 : */ 118 : void notifyWhenMortarSetup(MortarExecutorInterface * mei); 119 : 120 : /** 121 : * \em Removes \p mei from the container of objects that will have their \p mortarSetup method 122 : * called as soon as the mortar mesh has been generated for the first time 123 : */ 124 : void dontNotifyWhenMortarSetup(MortarExecutorInterface * mei); 125 : 126 : /** 127 : * @return whether we have performed an initial mortar mesh construction 128 : */ 129 62574 : bool initialized() const { return _mortar_initd; } 130 : 131 : private: 132 : /** 133 : * Builds mortar segment mesh from specific AutomaticMortarGeneration object 134 : */ 135 : void update(AutomaticMortarGeneration & amg); 136 : 137 : typedef std::pair<BoundaryID, BoundaryID> MortarKey; 138 : 139 : /// Map from primary-secondary (in that order) boundary ID pair to the corresponding 140 : /// undisplaced AutomaticMortarGeneration object 141 : std::unordered_map<MortarKey, std::unique_ptr<AutomaticMortarGeneration>> _mortar_interfaces; 142 : 143 : /// Map from primary-secondary (in that order) boundary ID pair to the corresponding 144 : /// displaced AutomaticMortarGeneration object 145 : std::unordered_map<MortarKey, std::unique_ptr<AutomaticMortarGeneration>> 146 : _displaced_mortar_interfaces; 147 : 148 : /// A set containing the subdomain ids covered by all the mortar interfaces in this MortarInterfaceWarehouse 149 : /// object 150 : std::set<SubdomainID> _mortar_subdomain_coverage; 151 : 152 : /// A set containing the boundary ids covered by all the mortar interfaces in this MortarInterfaceWarehouse 153 : /// object 154 : std::set<BoundaryID> _mortar_boundary_coverage; 155 : 156 : /// Map from undisplaced AMG key to whether the undisplaced AMG object is enforcing periodic constraints 157 : std::unordered_map<MortarKey, bool> _periodic_map; 158 : 159 : /// Map from displaced AMG key to whether the displaced AMG object is enforcing periodic constraints 160 : std::unordered_map<MortarKey, bool> _displaced_periodic_map; 161 : 162 : /// Map from undisplaced AMG key to whether the undisplaced AMG object is to output mortar segment mesh 163 : std::unordered_map<MortarKey, bool> _debug_flag_map; 164 : 165 : /// Map from displaced AMG key to whether the displaced AMG object is to output mortar segment mesh 166 : std::unordered_map<MortarKey, bool> _displaced_debug_flag_map; 167 : 168 : /// Map from lower dimensional subdomain ids to corresponding higher simensional subdomain ids 169 : /// (e.g. the ids of the interior parents) 170 : std::unordered_map<SubdomainID, std::set<SubdomainID>> _lower_d_sub_to_higher_d_subs; 171 : 172 : /// A container of objects for whom the \p mortarSetup method will be called after the mortar mesh 173 : /// has been setup for the first time 174 : std::set<MortarExecutorInterface *> _mei_objs; 175 : 176 : /// Whether we have performed any mortar mesh construction 177 : bool _mortar_initd; 178 : };