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 116833 : getMortarInterfaces(bool on_displaced) const 76 : { 77 116833 : if (on_displaced) 78 58400 : return _displaced_mortar_interfaces; 79 : else 80 58433 : return _mortar_interfaces; 81 : } 82 : 83 : /** 84 : * Returns the mortar covered subdomains 85 : */ 86 59733 : 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 : * Invalidates cached MSM node/element ID offsets on all mortar interfaces so they are 100 : * recomputed on the next update(). Call when mesh topology changes. 101 : */ 102 : void meshChanged(); 103 : 104 : /** 105 : * Returns whether any of the AutomaticMortarGeneration objects are running on a displaced mesh 106 : */ 107 128004 : bool hasDisplacedObjects() const { return _displaced_mortar_interfaces.size(); } 108 : 109 : /** 110 : * Returns whether we have **any** active AutomaticMortarGeneration objects 111 : */ 112 65711 : bool hasObjects() const { return _mortar_interfaces.size(); } 113 : 114 : /** 115 : * Returns the higher dimensional subdomain ids of the interior parents of the given lower-d 116 : * subdomain id 117 : */ 118 : const std::set<SubdomainID> & getHigherDimSubdomainIDs(SubdomainID lower_d_subdomain_id) const; 119 : 120 : /** 121 : * \em Adds \p mei to the container of objects that will have their \p mortarSetup method called 122 : * as soon as the mortar mesh has been generated for the first time 123 : */ 124 : void notifyWhenMortarSetup(MortarExecutorInterface * mei); 125 : 126 : /** 127 : * \em Removes \p mei from the container of objects that will have their \p mortarSetup method 128 : * called as soon as the mortar mesh has been generated for the first time 129 : */ 130 : void dontNotifyWhenMortarSetup(MortarExecutorInterface * mei); 131 : 132 : /** 133 : * @return whether we have performed an initial mortar mesh construction 134 : */ 135 59881 : bool initialized() const { return _mortar_initd; } 136 : 137 : private: 138 : /** 139 : * Builds mortar segment mesh from specific AutomaticMortarGeneration object 140 : */ 141 : void update(AutomaticMortarGeneration & amg); 142 : 143 : typedef std::pair<BoundaryID, BoundaryID> MortarKey; 144 : 145 : /// Map from primary-secondary (in that order) boundary ID pair to the corresponding 146 : /// undisplaced AutomaticMortarGeneration object 147 : std::unordered_map<MortarKey, std::unique_ptr<AutomaticMortarGeneration>> _mortar_interfaces; 148 : 149 : /// Map from primary-secondary (in that order) boundary ID pair to the corresponding 150 : /// displaced AutomaticMortarGeneration object 151 : std::unordered_map<MortarKey, std::unique_ptr<AutomaticMortarGeneration>> 152 : _displaced_mortar_interfaces; 153 : 154 : /// A set containing the subdomain ids covered by all the mortar interfaces in this MortarInterfaceWarehouse 155 : /// object 156 : std::set<SubdomainID> _mortar_subdomain_coverage; 157 : 158 : /// A set containing the boundary ids covered by all the mortar interfaces in this MortarInterfaceWarehouse 159 : /// object 160 : std::set<BoundaryID> _mortar_boundary_coverage; 161 : 162 : /// Map from undisplaced AMG key to whether the undisplaced AMG object is enforcing periodic constraints 163 : std::unordered_map<MortarKey, bool> _periodic_map; 164 : 165 : /// Map from displaced AMG key to whether the displaced AMG object is enforcing periodic constraints 166 : std::unordered_map<MortarKey, bool> _displaced_periodic_map; 167 : 168 : /// Map from undisplaced AMG key to whether the undisplaced AMG object is to output mortar segment mesh 169 : std::unordered_map<MortarKey, bool> _debug_flag_map; 170 : 171 : /// Map from displaced AMG key to whether the displaced AMG object is to output mortar segment mesh 172 : std::unordered_map<MortarKey, bool> _displaced_debug_flag_map; 173 : 174 : /// Map from lower dimensional subdomain ids to corresponding higher simensional subdomain ids 175 : /// (e.g. the ids of the interior parents) 176 : std::unordered_map<SubdomainID, std::set<SubdomainID>> _lower_d_sub_to_higher_d_subs; 177 : 178 : /// A container of objects for whom the \p mortarSetup method will be called after the mortar mesh 179 : /// has been setup for the first time 180 : std::set<MortarExecutorInterface *> _mei_objs; 181 : 182 : /// Whether we have performed any mortar mesh construction 183 : bool _mortar_initd; 184 : };