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 981 : 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 981 : Assembly & assembly)
34 981 : : _amg(amg),
35 981 : _subproblem(subproblem),
36 981 : _fe_problem(fe_problem),
37 981 : _displaced(displaced),
38 981 : _assembly(assembly)
39 : {
40 : // Construct the mortar constraints we will later loop over
41 2311 : for (auto mc : mortar_constraints)
42 1330 : _mortar_constraints.push_back(mc.get());
43 :
44 981 : Moose::Mortar::setupMortarMaterials(_mortar_constraints,
45 : _fe_problem,
46 : _amg,
47 : 0,
48 981 : _secondary_ip_sub_to_mats,
49 981 : _primary_ip_sub_to_mats,
50 981 : _secondary_boundary_mats);
51 981 : }
52 :
53 : void
54 192 : ComputeMortarFunctor::setupMortarMaterials()
55 : {
56 192 : Moose::Mortar::setupMortarMaterials(_mortar_constraints,
57 : _fe_problem,
58 : _amg,
59 : /*thread id*/ 0,
60 192 : _secondary_ip_sub_to_mats,
61 192 : _primary_ip_sub_to_mats,
62 192 : _secondary_boundary_mats);
63 192 : }
64 :
65 : void
66 13807 : ComputeMortarFunctor::operator()(const Moose::ComputeType compute_type,
67 : const std::set<TagID> & vector_tag_ids,
68 : const std::set<TagID> & /*matrix_tag_ids*/)
69 : {
70 : libmesh_parallel_only(_fe_problem.comm());
71 :
72 13807 : unsigned int num_cached = 0;
73 13807 : const auto & vector_tags = _fe_problem.getVectorTags(vector_tag_ids);
74 :
75 13807 : const auto & secondary_elems_to_mortar_segments = _amg.secondariesToMortarSegments();
76 : typedef decltype(secondary_elems_to_mortar_segments.begin()) it_type;
77 :
78 13807 : std::vector<it_type> iterators;
79 13807 : for (auto it = secondary_elems_to_mortar_segments.begin();
80 102551 : it != secondary_elems_to_mortar_segments.end();
81 88744 : ++it)
82 : {
83 88744 : auto * const secondary_elem = _subproblem.mesh().getMesh().query_elem_ptr(it->first);
84 :
85 158492 : if (secondary_elem && secondary_elem->processor_id() == _subproblem.processor_id() &&
86 69748 : !it->second.empty())
87 : {
88 : // This is local and the mortar segment set isn't empty, so include
89 69748 : iterators.push_back(it);
90 : mooseAssert(secondary_elem->active(),
91 : "We loop over active elements when building the mortar segment mesh, so we golly "
92 : "well hope this is active.");
93 : }
94 : }
95 :
96 283025 : auto act_functor = [this, &num_cached, compute_type, &vector_tags]()
97 : {
98 283025 : ++num_cached;
99 :
100 283025 : switch (compute_type)
101 : {
102 191316 : case Moose::ComputeType::Residual:
103 : {
104 393924 : for (auto * const mc : _mortar_constraints)
105 : {
106 202608 : mc->setNormals();
107 202608 : mc->computeResidual();
108 : }
109 :
110 191316 : _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
111 191316 : _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
112 191316 : _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
113 :
114 191316 : if (num_cached % 20 == 0)
115 6937 : _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
116 :
117 191316 : break;
118 : }
119 :
120 88401 : case Moose::ComputeType::Jacobian:
121 : {
122 182562 : for (auto * const mc : _mortar_constraints)
123 : {
124 94161 : mc->setNormals();
125 94161 : mc->computeJacobian();
126 : }
127 :
128 88401 : _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
129 :
130 88401 : if (num_cached % 20 == 0)
131 3868 : _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
132 88401 : break;
133 : }
134 :
135 3308 : case Moose::ComputeType::ResidualAndJacobian:
136 : {
137 6616 : for (auto * const mc : _mortar_constraints)
138 : {
139 3308 : mc->setNormals();
140 3308 : mc->computeResidualAndJacobian();
141 : }
142 :
143 3308 : _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
144 3308 : _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
145 3308 : _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
146 3308 : _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
147 :
148 3308 : if (num_cached % 20 == 0)
149 : {
150 0 : _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
151 0 : _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
152 : }
153 3308 : break;
154 : }
155 : }
156 283025 : };
157 :
158 : PARALLEL_TRY
159 : {
160 : try
161 : {
162 13807 : Moose::Mortar::loopOverMortarSegments(iterators,
163 : _assembly,
164 : _subproblem,
165 : _fe_problem,
166 : _amg,
167 13807 : _displaced,
168 13807 : _mortar_constraints,
169 : 0,
170 13807 : _secondary_ip_sub_to_mats,
171 13807 : _primary_ip_sub_to_mats,
172 13807 : _secondary_boundary_mats,
173 : act_functor,
174 : /*reinit_mortar_user_objects=*/true);
175 : }
176 0 : catch (libMesh::LogicError & e)
177 : {
178 0 : _fe_problem.setException("We caught a libMesh::LogicError: " + std::string(e.what()));
179 0 : }
180 0 : catch (MooseException & e)
181 : {
182 0 : _fe_problem.setException(e.what());
183 0 : }
184 0 : catch (MetaPhysicL::LogicError & e)
185 : {
186 0 : moose::translateMetaPhysicLError(e);
187 0 : }
188 : }
189 13807 : PARALLEL_CATCH;
190 :
191 : // Call any post operations for our mortar constraints
192 30494 : for (auto * const mc : _mortar_constraints)
193 : {
194 16687 : if (_amg.incorrectEdgeDropping())
195 7258 : mc->incorrectEdgeDroppingPost(_amg.getInactiveLMNodes());
196 : else
197 9429 : mc->post();
198 :
199 16687 : mc->zeroInactiveLMDofs(_amg.getInactiveLMNodes(), _amg.getInactiveLMElems());
200 : }
201 :
202 : // Make sure any remaining cached residuals/Jacobians get added
203 13807 : if (_assembly.computingResidual())
204 11307 : _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
205 13807 : if (_assembly.computingJacobian())
206 3672 : _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
207 13807 : }
|