17 #include "libmesh/quadrature.h" 18 #include "libmesh/elem.h" 19 #include "libmesh/point.h" 41 const Elem * primal_elem,
42 unsigned int sub_elem_index,
43 const QBase & qrule_msm,
44 std::vector<Point> & q_pts);
67 template <
typename Iterators,
typename Consumers,
typename ActionFunctor>
70 const Iterators & secondary_elems_to_mortar_segments,
76 const Consumers & consumers,
78 const std::map<
SubdomainID, std::deque<MaterialBase *>> & secondary_ip_sub_to_mats,
79 const std::map<
SubdomainID, std::deque<MaterialBase *>> & primary_ip_sub_to_mats,
80 const std::deque<MaterialBase *> & secondary_boundary_mats,
81 const ActionFunctor act,
82 const bool reinit_mortar_user_objects)
86 const auto primary_boundary_id = primary_secondary_boundary_id_pair.first;
87 const auto secondary_boundary_id = primary_secondary_boundary_id_pair.second;
90 unsigned int secondary_sub_elem_index = 0, primary_sub_elem_index = 0;
93 secondary_sub_elem_index = amg.
mortarSegmentMesh().get_elem_integer_index(
"secondary_sub_elem");
94 primary_sub_elem_index = amg.
mortarSegmentMesh().get_elem_integer_index(
"primary_sub_elem");
102 const auto & JxW_msm = assembly.
jxWMortar();
105 std::unordered_set<unsigned int> needed_mat_props;
106 for (
const auto & consumer : consumers)
108 const auto & mp_deps = consumer->getMatPropDependencies();
109 needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
115 for (
const auto elem_to_msm : secondary_elems_to_mortar_segments)
117 const Elem * secondary_face_elem = subproblem.
mesh().
getMesh().elem_ptr(elem_to_msm->first);
119 const Elem * secondary_ip = secondary_face_elem->interior_parent();
120 unsigned int secondary_side_id = secondary_ip->which_side_am_i(secondary_face_elem);
121 const auto & secondary_ip_mats =
122 libmesh_map_find(secondary_ip_sub_to_mats, secondary_ip->subdomain_id());
124 const auto & msm_elems = elem_to_msm->second;
132 std::vector<Point> secondary_xi_pts, primary_xi_pts;
134 std::vector<Real> JxW;
137 unsigned int expected_length = 0;
141 for (
const auto msm_elem : msm_elems)
149 if (msm_elem->dim() == 1)
151 for (
unsigned int qp = 0; qp < qrule_msm->n_points(); qp++)
153 const Real eta = qrule_msm->qp(qp)(0);
156 const Real xi1_eta = 0.5 * (1 - eta) * msinfo.
xi1_a + 0.5 * (1 + eta) * msinfo.
xi1_b;
157 secondary_xi_pts.push_back(xi1_eta);
160 const Real xi2_eta = 0.5 * (1 - eta) * msinfo.
xi2_a + 0.5 * (1 + eta) * msinfo.
xi2_b;
161 primary_xi_pts.push_back(xi2_eta);
169 secondary_sub_elem_index,
173 msm_elem, msinfo.
primary_elem, primary_sub_elem_index, *qrule_msm, primary_xi_pts);
178 std::copy(std::begin(JxW_msm), std::end(JxW_msm), std::back_inserter(JxW));
182 expected_length += qrule_msm->n_points();
183 mooseAssert(secondary_xi_pts.size() == expected_length,
184 "Fewer than expected secondary quadrature points");
185 mooseAssert(primary_xi_pts.size() == expected_length,
186 "Fewer than expected primary quadrature points");
189 mooseAssert(JxW.size() == expected_length,
"Fewer than expected JxW values computed");
196 assembly.
reinitDual(secondary_face_elem, secondary_xi_pts, JxW);
198 unsigned int n_segment = 0;
201 for (
const auto msm_elem : msm_elems)
206 std::vector<Point> xi1_pts, xi2_pts;
212 const Elem * primary_ip = msinfo.
primary_elem->interior_parent();
213 unsigned int primary_side_id = primary_ip->which_side_am_i(msinfo.
primary_elem);
214 const auto & primary_ip_mats =
215 libmesh_map_find(primary_ip_sub_to_mats, primary_ip->subdomain_id());
223 const unsigned int start = (n_segment - 1) * qrule_msm->n_points();
224 const unsigned int end = n_segment * qrule_msm->n_points();
226 xi1_pts.begin(), secondary_xi_pts.begin() + start, secondary_xi_pts.begin() + end);
227 xi2_pts.insert(xi2_pts.begin(), primary_xi_pts.begin() + start, primary_xi_pts.begin() + end);
229 const Elem * reinit_secondary_elem = secondary_ip;
234 reinit_secondary_elem = fe_problem.
mesh().
elemPtr(reinit_secondary_elem->id());
250 reinit_secondary_elem, secondary_side_id, TOLERANCE, &xi1_pts,
nullptr, tid);
252 const Elem * reinit_primary_elem = primary_ip;
257 reinit_primary_elem = fe_problem.
mesh().
elemPtr(reinit_primary_elem->id());
261 reinit_primary_elem, primary_side_id, TOLERANCE, &xi2_pts,
nullptr, tid);
289 secondary_boundary_id, tid,
false, &secondary_boundary_mats);
291 if (reinit_mortar_user_objects)
314 template <
typename Consumers>
320 std::map<
SubdomainID, std::deque<MaterialBase *>> & secondary_ip_sub_to_mats,
321 std::map<
SubdomainID, std::deque<MaterialBase *>> & primary_ip_sub_to_mats,
322 std::deque<MaterialBase *> & secondary_boundary_mats)
324 secondary_ip_sub_to_mats.clear();
325 primary_ip_sub_to_mats.clear();
326 secondary_boundary_mats.clear();
329 auto get_required_sub_mats =
330 [&mat_warehouse, tid, &consumers](
334 if (mat_warehouse[mat_data_type].hasActiveBlockObjects(sub_id, tid))
345 for (
const auto secondary_ip_sub : secondary_ip_sub_ids)
346 secondary_ip_sub_to_mats.emplace(
351 for (
const auto primary_ip_sub : primary_ip_sub_ids)
352 primary_ip_sub_to_mats.emplace(
357 const auto secondary_boundary = boundary_pr.second;
358 if (mat_warehouse.hasActiveBoundaryObjects(secondary_boundary, tid))
360 auto & boundary_mats = mat_warehouse.getActiveBoundaryObjects(secondary_boundary, tid);
361 secondary_boundary_mats =
virtual MooseMesh & mesh()=0
void setActiveMaterialProperties(const std::unordered_set< unsigned int > &mat_prop_ids, const THREAD_ID tid)
Record and set the material properties required by the current computing thread.
void reinitNeighborLowerDElem(const Elem *elem, const THREAD_ID tid=0)
reinitialize a neighboring lower dimensional element
const std::pair< BoundaryID, BoundaryID > & primarySecondaryBoundaryIDPair() const
virtual void reinitLowerDElem(const Elem *lower_d_elem, const THREAD_ID tid, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr)
Keeps track of stuff related to assembling.
const std::map< SubdomainID, std::vector< std::shared_ptr< T > > > & getActiveBlockObjects(THREAD_ID tid=0) const
virtual Elem * elemPtr(const dof_id_type i)
void setupMortarMaterials(const Consumers &consumers, FEProblemBase &fe_problem, const AutomaticMortarGeneration &amg, const THREAD_ID tid, std::map< SubdomainID, std::deque< MaterialBase *>> &secondary_ip_sub_to_mats, std::map< SubdomainID, std::deque< MaterialBase *>> &primary_ip_sub_to_mats, std::deque< MaterialBase *> &secondary_boundary_mats)
This function creates containers of materials necessary to execute the mortar method for a supplied s...
MaterialDataType
MaterialData types.
void reinitMortarUserObjects(BoundaryID primary_boundary_id, BoundaryID secondary_boundary_id, bool displaced)
Call reinit on mortar user objects with matching primary boundary ID, secondary boundary ID...
void reinitMaterialsBoundary(BoundaryID boundary_id, const THREAD_ID tid, bool swap_stateful=true, const std::deque< MaterialBase *> *reinit_mats=nullptr)
reinit materials on a boundary
const libMesh::QBase *const & qRuleMortar() const
Returns a reference to the quadrature rule for the mortar segments.
const std::set< SubdomainID > & primaryIPSubIDs() const
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
const MaterialWarehouse & getRegularMaterialsWarehouse() const
void reinitMaterialsFace(SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful=true, const std::deque< MaterialBase *> *reinit_mats=nullptr)
reinit materials on element faces
const std::set< SubdomainID > & secondaryIPSubIDs() const
This class is a container/interface for the objects involved in automatic generation of mortar spaces...
virtual void reinitElemFaceRef(const Elem *elem, unsigned int side, Real tolerance, const std::vector< Point > *const pts, const std::vector< Real > *const weights=nullptr, const THREAD_ID tid=0) override
reinitialize FE objects on a given element on a given side at a given set of reference points and the...
const Elem * primary_elem
bool needDual() const
Indicates whether dual shape functions are used (computation is now repeated on each element so expen...
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
void reinitMaterialsNeighbor(SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful=true, const std::deque< MaterialBase *> *reinit_mats=nullptr)
reinit materials on the neighboring element face
virtual void reinitNeighborFaceRef(const Elem *neighbor_elem, unsigned int neighbor_side, Real tolerance, const std::vector< Point > *const pts, const std::vector< Real > *const weights=nullptr, const THREAD_ID tid=0) override
reinitialize FE objects on a given neighbor element on a given side at a given set of reference point...
void loopOverMortarSegments(const Iterators &secondary_elems_to_mortar_segments, Assembly &assembly, SubProblem &subproblem, FEProblemBase &fe_problem, const AutomaticMortarGeneration &amg, const bool displaced, const Consumers &consumers, const THREAD_ID tid, const std::map< SubdomainID, std::deque< MaterialBase *>> &secondary_ip_sub_to_mats, const std::map< SubdomainID, std::deque< MaterialBase *>> &primary_ip_sub_to_mats, const std::deque< MaterialBase *> &secondary_boundary_mats, const ActionFunctor act, const bool reinit_mortar_user_objects)
This method will loop over pairs of secondary elements and their corresponding mortar segments...
const Elem * secondary_elem
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Holds xi^(1), xi^(2), and other data for a given mortar segment.
Generic class for solving transient nonlinear problems.
static std::deque< MaterialBase * > buildRequiredMaterials(const Consumers &mat_consumers, const std::vector< std::shared_ptr< MaterialBase >> &mats, const bool allow_stateful)
Build the materials required by a set of consumer objects.
const std::unordered_map< const Elem *, MortarSegmentInfo > & mortarSegmentMeshElemToInfo() const
virtual MooseMesh & mesh() override
const MeshBase & mortarSegmentMesh() const
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
const std::vector< Real > & jxWMortar() const
Returns a reference to JxW for mortar segment elements.
void reinitMortarElem(const Elem *elem, const THREAD_ID tid=0)
Reinit a mortar element to obtain a valid JxW.
void projectQPoints3d(const Elem *msm_elem, const Elem *primal_elem, unsigned int sub_elem_index, const QBase &qrule_msm, std::vector< Point > &q_pts)
3D projection operator for mapping qpoints on mortar segments to secondary or primary elements ...
void reinitDual(const Elem *elem, const std::vector< Point > &pts, const std::vector< Real > &JxW)
Reintialize dual basis coefficients based on a customized quadrature rule.