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 : #include "ComputeMortarFunctor.h"
11 : #include "FEProblemBase.h"
12 : #include "SubProblem.h"
13 : #include "Assembly.h"
14 : #include "ADMortarConstraint.h"
15 : #include "AutomaticMortarGeneration.h"
16 : #include "MooseMesh.h"
17 : #include "Assembly.h"
18 : #include "MortarUtils.h"
19 : #include "MaterialBase.h"
20 :
21 : #include "libmesh/fe_base.h"
22 : #include "libmesh/quadrature.h"
23 : #include "libmesh/elem.h"
24 : #include "libmesh/point.h"
25 : #include "libmesh/mesh_base.h"
26 :
27 897 : ComputeMortarFunctor::ComputeMortarFunctor(
28 : const std::vector<std::shared_ptr<MortarConstraintBase>> & mortar_constraints,
29 : const AutomaticMortarGeneration & amg,
30 : SubProblem & subproblem,
31 : FEProblemBase & fe_problem,
32 : bool displaced,
33 897 : Assembly & assembly)
34 897 : : _amg(amg),
35 897 : _subproblem(subproblem),
36 897 : _fe_problem(fe_problem),
37 897 : _displaced(displaced),
38 897 : _assembly(assembly)
39 : {
40 : // Construct the mortar constraints we will later loop over
41 2121 : for (auto mc : mortar_constraints)
42 1224 : _mortar_constraints.push_back(mc.get());
43 :
44 897 : Moose::Mortar::setupMortarMaterials(_mortar_constraints,
45 : _fe_problem,
46 : _amg,
47 : 0,
48 897 : _secondary_ip_sub_to_mats,
49 897 : _primary_ip_sub_to_mats,
50 897 : _secondary_boundary_mats);
51 897 : }
52 :
53 : void
54 13062 : ComputeMortarFunctor::operator()(const Moose::ComputeType compute_type,
55 : const std::set<TagID> & vector_tag_ids,
56 : const std::set<TagID> & /*matrix_tag_ids*/)
57 : {
58 : libmesh_parallel_only(_fe_problem.comm());
59 :
60 13062 : unsigned int num_cached = 0;
61 13062 : const auto & vector_tags = _fe_problem.getVectorTags(vector_tag_ids);
62 :
63 13062 : const auto & secondary_elems_to_mortar_segments = _amg.secondariesToMortarSegments();
64 : typedef decltype(secondary_elems_to_mortar_segments.begin()) it_type;
65 :
66 13062 : std::vector<it_type> iterators;
67 13062 : for (auto it = secondary_elems_to_mortar_segments.begin();
68 97825 : it != secondary_elems_to_mortar_segments.end();
69 84763 : ++it)
70 : {
71 84763 : auto * const secondary_elem = _subproblem.mesh().getMesh().query_elem_ptr(it->first);
72 :
73 150626 : if (secondary_elem && secondary_elem->processor_id() == _subproblem.processor_id() &&
74 65863 : !it->second.empty())
75 : {
76 : // This is local and the mortar segment set isn't empty, so include
77 65863 : iterators.push_back(it);
78 : mooseAssert(secondary_elem->active(),
79 : "We loop over active elements when building the mortar segment mesh, so we golly "
80 : "well hope this is active.");
81 : }
82 : }
83 :
84 1422907 : auto act_functor = [this, &num_cached, compute_type, &vector_tags]()
85 : {
86 261890 : ++num_cached;
87 :
88 261890 : switch (compute_type)
89 : {
90 177834 : case Moose::ComputeType::Residual:
91 : {
92 366432 : for (auto * const mc : _mortar_constraints)
93 : {
94 188598 : mc->setNormals();
95 188598 : mc->computeResidual();
96 : }
97 :
98 177834 : _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
99 177834 : _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
100 177834 : _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
101 :
102 177834 : if (num_cached % 20 == 0)
103 6358 : _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
104 :
105 177834 : break;
106 : }
107 :
108 80796 : case Moose::ComputeType::Jacobian:
109 : {
110 167164 : for (auto * const mc : _mortar_constraints)
111 : {
112 86368 : mc->setNormals();
113 86368 : mc->computeJacobian();
114 : }
115 :
116 80796 : _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
117 :
118 80796 : if (num_cached % 20 == 0)
119 3541 : _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
120 80796 : break;
121 : }
122 :
123 3260 : case Moose::ComputeType::ResidualAndJacobian:
124 : {
125 6520 : for (auto * const mc : _mortar_constraints)
126 : {
127 3260 : mc->setNormals();
128 3260 : mc->computeResidualAndJacobian();
129 : }
130 :
131 3260 : _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
132 3260 : _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
133 3260 : _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
134 3260 : _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
135 :
136 3260 : if (num_cached % 20 == 0)
137 : {
138 0 : _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
139 0 : _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
140 : }
141 3260 : break;
142 : }
143 : }
144 261890 : };
145 :
146 : PARALLEL_TRY
147 : {
148 : try
149 : {
150 13062 : Moose::Mortar::loopOverMortarSegments(iterators,
151 : _assembly,
152 : _subproblem,
153 : _fe_problem,
154 : _amg,
155 13062 : _displaced,
156 13062 : _mortar_constraints,
157 : 0,
158 13062 : _secondary_ip_sub_to_mats,
159 13062 : _primary_ip_sub_to_mats,
160 13062 : _secondary_boundary_mats,
161 : act_functor,
162 : /*reinit_mortar_user_objects=*/true);
163 : }
164 0 : catch (libMesh::LogicError & e)
165 : {
166 0 : _fe_problem.setException("We caught a libMesh::LogicError: " + std::string(e.what()));
167 0 : }
168 0 : catch (MooseException & e)
169 : {
170 0 : _fe_problem.setException(e.what());
171 0 : }
172 0 : catch (MetaPhysicL::LogicError & e)
173 : {
174 0 : moose::translateMetaPhysicLError(e);
175 0 : }
176 : }
177 13062 : PARALLEL_CATCH;
178 :
179 : // Call any post operations for our mortar constraints
180 28803 : for (auto * const mc : _mortar_constraints)
181 : {
182 15741 : if (_amg.incorrectEdgeDropping())
183 6900 : mc->incorrectEdgeDroppingPost(_amg.getInactiveLMNodes());
184 : else
185 8841 : mc->post();
186 :
187 15741 : mc->zeroInactiveLMDofs(_amg.getInactiveLMNodes(), _amg.getInactiveLMElems());
188 : }
189 :
190 : // Make sure any remaining cached residuals/Jacobians get added
191 13062 : if (_assembly.computingResidual())
192 10799 : _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
193 13062 : if (_assembly.computingJacobian())
194 3423 : _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
195 13062 : }
|