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 955 : 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 955 : Assembly & assembly)
34 955 : : _amg(amg),
35 955 : _subproblem(subproblem),
36 955 : _fe_problem(fe_problem),
37 955 : _displaced(displaced),
38 955 : _assembly(assembly)
39 : {
40 : // Construct the mortar constraints we will later loop over
41 2259 : for (auto mc : mortar_constraints)
42 1304 : _mortar_constraints.push_back(mc.get());
43 :
44 955 : Moose::Mortar::setupMortarMaterials(_mortar_constraints,
45 : _fe_problem,
46 : _amg,
47 : 0,
48 955 : _secondary_ip_sub_to_mats,
49 955 : _primary_ip_sub_to_mats,
50 955 : _secondary_boundary_mats);
51 955 : }
52 :
53 : void
54 13633 : 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 13633 : unsigned int num_cached = 0;
61 13633 : const auto & vector_tags = _fe_problem.getVectorTags(vector_tag_ids);
62 :
63 13633 : const auto & secondary_elems_to_mortar_segments = _amg.secondariesToMortarSegments();
64 : typedef decltype(secondary_elems_to_mortar_segments.begin()) it_type;
65 :
66 13633 : std::vector<it_type> iterators;
67 13633 : for (auto it = secondary_elems_to_mortar_segments.begin();
68 101981 : it != secondary_elems_to_mortar_segments.end();
69 88348 : ++it)
70 : {
71 88348 : auto * const secondary_elem = _subproblem.mesh().getMesh().query_elem_ptr(it->first);
72 :
73 157796 : if (secondary_elem && secondary_elem->processor_id() == _subproblem.processor_id() &&
74 69448 : !it->second.empty())
75 : {
76 : // This is local and the mortar segment set isn't empty, so include
77 69448 : 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 1533849 : auto act_functor = [this, &num_cached, compute_type, &vector_tags]()
85 : {
86 282725 : ++num_cached;
87 :
88 282725 : switch (compute_type)
89 : {
90 191110 : case Moose::ComputeType::Residual:
91 : {
92 393512 : for (auto * const mc : _mortar_constraints)
93 : {
94 202402 : mc->setNormals();
95 202402 : mc->computeResidual();
96 : }
97 :
98 191110 : _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
99 191110 : _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
100 191110 : _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
101 :
102 191110 : if (num_cached % 20 == 0)
103 6937 : _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
104 :
105 191110 : break;
106 : }
107 :
108 88307 : case Moose::ComputeType::Jacobian:
109 : {
110 182374 : for (auto * const mc : _mortar_constraints)
111 : {
112 94067 : mc->setNormals();
113 94067 : mc->computeJacobian();
114 : }
115 :
116 88307 : _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
117 :
118 88307 : if (num_cached % 20 == 0)
119 3868 : _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
120 88307 : break;
121 : }
122 :
123 3308 : case Moose::ComputeType::ResidualAndJacobian:
124 : {
125 6616 : for (auto * const mc : _mortar_constraints)
126 : {
127 3308 : mc->setNormals();
128 3308 : mc->computeResidualAndJacobian();
129 : }
130 :
131 3308 : _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
132 3308 : _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
133 3308 : _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
134 3308 : _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
135 :
136 3308 : if (num_cached % 20 == 0)
137 : {
138 0 : _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
139 0 : _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
140 : }
141 3308 : break;
142 : }
143 : }
144 282725 : };
145 :
146 : PARALLEL_TRY
147 : {
148 : try
149 : {
150 13633 : Moose::Mortar::loopOverMortarSegments(iterators,
151 : _assembly,
152 : _subproblem,
153 : _fe_problem,
154 : _amg,
155 13633 : _displaced,
156 13633 : _mortar_constraints,
157 : 0,
158 13633 : _secondary_ip_sub_to_mats,
159 13633 : _primary_ip_sub_to_mats,
160 13633 : _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 13633 : PARALLEL_CATCH;
178 :
179 : // Call any post operations for our mortar constraints
180 30146 : for (auto * const mc : _mortar_constraints)
181 : {
182 16513 : if (_amg.incorrectEdgeDropping())
183 7084 : mc->incorrectEdgeDroppingPost(_amg.getInactiveLMNodes());
184 : else
185 9429 : mc->post();
186 :
187 16513 : mc->zeroInactiveLMDofs(_amg.getInactiveLMNodes(), _amg.getInactiveLMElems());
188 : }
189 :
190 : // Make sure any remaining cached residuals/Jacobians get added
191 13633 : if (_assembly.computingResidual())
192 11183 : _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
193 13633 : if (_assembly.computingJacobian())
194 3622 : _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
195 13633 : }
|