deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
fe_coupling_values.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2023 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_fe_coupling_values_h
14#define dealii_fe_coupling_values_h
15
16#include <deal.II/base/config.h>
17
19
21#include <deal.II/base/point.h>
25
27
29
30// Forward declaration
31#ifndef DOXYGEN
32template <int dim, int spacedim>
33class FEValuesBase;
34#endif
35
37{
49 {
90 const unsigned int n_inner_quadrature_points =
92 const std::vector<unsigned int> &dof_renumbering = {},
93 const std::vector<unsigned int> &quadrature_renumbering = {});
94
98 RenumberingData(const RenumberingData &other) = delete;
99
103 const unsigned int n_inner_dofs;
104
108 const unsigned int n_dofs;
109
114 const unsigned int n_inner_quadrature_points;
115
119 const unsigned int n_quadrature_points;
120
124 const std::vector<unsigned int> dof_renumbering;
125
129 const std::vector<unsigned int> quadrature_renumbering;
130
143 };
144
166 template <typename ViewType>
168 {
169 public:
173 using value_type = typename ViewType::value_type;
174
178 using gradient_type = typename ViewType::gradient_type;
179
184 template <typename Number>
186 typename ViewType::template solution_value_type<Number>;
187
192 template <typename Number>
194 typename ViewType::template solution_gradient_type<Number>;
195
209 RenumberedView(const ViewType &view, const RenumberingData &data);
210
228 value(const unsigned int shape_function, const unsigned int q_point) const;
229
247 gradient(const unsigned int shape_function,
248 const unsigned int q_point) const;
249
264 template <typename Number>
265 void
267 std::vector<solution_value_type<Number>> &values) const;
268
289 template <class InputVector>
290 void
292 const InputVector &dof_values,
294 &values) const;
295
311 template <typename Number>
312 void
314 const ReadVector<Number> &fe_function,
315 std::vector<solution_gradient_type<Number>> &gradients) const;
316
337 template <class InputVector>
338 void
340 const InputVector &dof_values,
342 &gradients) const;
343
344 private:
350
351
368 template <typename Number>
369 std::string
370 get_unique_container_name(const std::string &prefix,
371 const unsigned int size,
372 const Number &exemplar_number) const;
373
378 template <typename InputVector>
379 const InputVector &
380 outer_to_inner_dofs(const InputVector &outer_vector) const;
381
386 template <typename ValueType>
387 std::vector<ValueType> &
388 outer_to_inner_values(std::vector<ValueType> &outer_values) const;
389
395 template <typename ValueType>
396 void
397 inner_to_outer_values(const std::vector<ValueType> &inner_values,
398 std::vector<ValueType> &outer_values) const;
399
403 const ViewType &view;
404 };
405} // namespace FEValuesViews
406
407
433{
442
453 unrolled,
454
465 matching,
466
475 reorder,
476
487};
488
533{
541
555};
556
728template <int dim1, int dim2 = dim1, int spacedim = dim1>
730{
731public:
737
774 const FEValuesBase<dim1, spacedim> &fe_values_1,
775 const FEValuesBase<dim2, spacedim> &fe_values_2,
779
814 void
816 const FEValuesBase<dim1, spacedim> &fe_values_1,
817 const FEValuesBase<dim2, spacedim> &fe_values_2,
821
822
827 template <typename Extractor>
829 get_first_extractor(const Extractor &extractor) const;
830
835 template <typename Extractor>
837 get_second_extractor(const Extractor &extractor) const;
838
844 double
845 JxW(const unsigned int quadrature_point) const;
846
854 std::pair<Point<spacedim>, Point<spacedim>>
855 quadrature_point(const unsigned int quadrature_point) const;
856
866
874
882
897
938 std::vector<types::global_dof_index>
940 const std::vector<types::global_dof_index> &dof_indices_1,
941 const std::vector<types::global_dof_index> &dof_indices_2,
942 const types::global_dof_index dofs_offset_1 = 0,
943 const types::global_dof_index dofs_offset_2 = 0) const;
944
950 std::pair<unsigned int, unsigned int>
951 coupling_dof_to_dof_indices(const unsigned int coupling_dof_index) const;
952
958 std::pair<unsigned int, unsigned int>
960 const unsigned int quadrature_point) const;
961
972 template <typename Extractor>
976 const FEValuesExtractors::FirstCoupling<Extractor> &extractor) const;
977
983 template <typename Extractor>
987 const FEValuesExtractors::SecondCoupling<Extractor> &extractor) const;
988
998 unsigned int
1000
1005 unsigned int
1007
1012 unsigned int
1014
1018 unsigned int
1020
1021private:
1026
1031
1036
1041
1045 std::unique_ptr<const FEValuesViews::RenumberingData> first_renumbering_data;
1046
1050 std::unique_ptr<const FEValuesViews::RenumberingData> second_renumbering_data;
1051
1056
1062 unsigned int n_coupling_dofs_;
1063};
1064
1065
1066#ifndef DOXYGEN
1067
1068
1069/*------------------------ Inline functions: namespace FEValuesViews --------*/
1070
1071namespace FEValuesViews
1072{
1074 const unsigned int n_inner_dofs,
1075 const unsigned int n_inner_quadrature_points,
1076 const std::vector<unsigned int> &dof_renumbering,
1077 const std::vector<unsigned int> &quadrature_renumbering)
1078 : n_inner_dofs(n_inner_dofs)
1079 , n_dofs(dof_renumbering.empty() ? n_inner_dofs : dof_renumbering.size())
1080 , n_inner_quadrature_points(n_inner_quadrature_points)
1081 , n_quadrature_points(quadrature_renumbering.empty() ?
1082 n_inner_quadrature_points :
1083 quadrature_renumbering.size())
1084 , dof_renumbering(dof_renumbering)
1085 , quadrature_renumbering(quadrature_renumbering)
1086 {
1087 // Check that the renumbering vectors are valid.
1088 if constexpr (running_in_debug_mode())
1089 {
1090 // While for dofs we admit invalid values, this is not the case for
1091 // quadrature points.
1092 for (const auto i : dof_renumbering)
1093 Assert(i < n_inner_dofs || i == numbers::invalid_unsigned_int,
1094 ExcIndexRange(i, 0, n_inner_dofs));
1095
1096 for (const auto q : quadrature_renumbering)
1097 AssertIndexRange(q, n_inner_quadrature_points);
1098 }
1099 }
1100
1101
1102
1103 template <typename ViewType>
1104 RenumberedView<ViewType>::RenumberedView(const ViewType &view,
1105 const RenumberingData &data)
1106 : view(view)
1107 , data(data)
1108 {}
1109
1110
1111
1112 template <typename ViewType>
1113 template <typename Number>
1114 inline std::string
1115 RenumberedView<ViewType>::get_unique_container_name(
1116 const std::string &prefix,
1117 const unsigned int size,
1118 const Number &exemplar_number) const
1119 {
1120 return prefix + "_" + Utilities::int_to_string(size) + "_" +
1121 Utilities::type_to_string(exemplar_number);
1122 }
1123
1124
1125
1126 template <typename ViewType>
1127 typename RenumberedView<ViewType>::value_type
1128 RenumberedView<ViewType>::value(const unsigned int shape_function,
1129 const unsigned int q_point) const
1130 {
1131 AssertIndexRange(shape_function, data.n_dofs);
1132 AssertIndexRange(q_point, data.n_quadrature_points);
1133
1134 const auto inner_shape_function = data.dof_renumbering.empty() ?
1135 shape_function :
1136 data.dof_renumbering[shape_function];
1137 const auto inner_q_point = data.quadrature_renumbering.empty() ?
1138 q_point :
1139 data.quadrature_renumbering[q_point];
1140 if (inner_shape_function == numbers::invalid_unsigned_int)
1141 return value_type(0);
1142 else
1143 {
1144 AssertIndexRange(inner_shape_function, data.n_inner_dofs);
1145 AssertIndexRange(inner_q_point, data.n_inner_quadrature_points);
1146 return view.value(inner_shape_function, inner_q_point);
1147 }
1148 }
1149
1150
1151
1152 template <typename ViewType>
1153 typename RenumberedView<ViewType>::gradient_type
1154 RenumberedView<ViewType>::gradient(const unsigned int shape_function,
1155 const unsigned int q_point) const
1156 {
1157 AssertIndexRange(shape_function, data.n_dofs);
1158 AssertIndexRange(q_point, data.n_quadrature_points);
1159
1160 const auto inner_shape_function = data.dof_renumbering.empty() ?
1161 shape_function :
1162 data.dof_renumbering[shape_function];
1163 const auto inner_q_point = data.quadrature_renumbering.empty() ?
1164 q_point :
1165 data.quadrature_renumbering[q_point];
1166 if (inner_shape_function == numbers::invalid_unsigned_int)
1167 return gradient_type();
1168 else
1169 return view.gradient(inner_shape_function, inner_q_point);
1170 }
1171
1172
1173
1174 template <typename ViewType>
1175 template <typename ValueType>
1176 std::vector<ValueType> &
1177 RenumberedView<ViewType>::outer_to_inner_values(
1178 std::vector<ValueType> &outer_values) const
1179 {
1180 AssertDimension(outer_values.size(), data.n_quadrature_points);
1181 if (data.quadrature_renumbering.empty())
1182 {
1183 return outer_values;
1184 }
1185 else
1186 {
1187 const auto name =
1188 get_unique_container_name("RenumberedView::outer_to_inner_values",
1189 data.n_inner_quadrature_points,
1190 outer_values[0]);
1191 auto &inner_values =
1192 data.data_storage.get()
1193 .template get_or_add_object_with_name<std::vector<ValueType>>(
1194 name, data.n_inner_quadrature_points);
1195 return inner_values;
1196 }
1197 }
1198
1199
1200
1201 template <typename ViewType>
1202 template <typename VectorType>
1203 const VectorType &
1204 RenumberedView<ViewType>::outer_to_inner_dofs(
1205 const VectorType &outer_dofs) const
1206 {
1207 AssertDimension(outer_dofs.size(), data.n_dofs);
1208 if (data.dof_renumbering.empty())
1209 {
1210 return outer_dofs;
1211 }
1212 else
1213 {
1214 const auto name =
1215 get_unique_container_name("RenumberedView::outer_to_inner_dofs",
1216 data.n_inner_dofs,
1217 outer_dofs[0]);
1218
1219 auto &inner_dofs = data.data_storage.get()
1220 .template get_or_add_object_with_name<VectorType>(
1221 name, data.n_inner_dofs);
1222 for (unsigned int i = 0; i < data.n_dofs; ++i)
1223 {
1224 const auto inner_i = data.dof_renumbering[i];
1225 if (inner_i != numbers::invalid_unsigned_int)
1226 {
1227 AssertIndexRange(inner_i, data.n_inner_dofs);
1228 inner_dofs[inner_i] = outer_dofs[i];
1229 }
1230 }
1231 return inner_dofs;
1232 }
1233 }
1234
1235
1236
1237 template <typename ViewType>
1238 template <typename ValueType>
1239 void
1240 RenumberedView<ViewType>::inner_to_outer_values(
1241 const std::vector<ValueType> &inner_values,
1242 std::vector<ValueType> &outer_values) const
1243 {
1244 AssertDimension(outer_values.size(), data.n_quadrature_points);
1245 AssertDimension(inner_values.size(), data.n_inner_quadrature_points);
1246 if (data.quadrature_renumbering.empty())
1247 {
1248 Assert(&inner_values == &outer_values, ExcInternalError());
1249 return;
1250 }
1251 for (unsigned int i = 0; i < data.quadrature_renumbering.size(); ++i)
1252 {
1253 outer_values[i] = inner_values[data.quadrature_renumbering[i]];
1254 }
1255 }
1256
1257
1258
1259 template <typename ViewType>
1260 template <typename Number>
1261 void
1262 RenumberedView<ViewType>::get_function_values(
1263 const ReadVector<Number> &fe_function,
1264 std::vector<solution_value_type<Number>> &values) const
1265 {
1266 auto &inner_values = outer_to_inner_values(values);
1267 view.get_function_values(fe_function, inner_values);
1268 inner_to_outer_values(inner_values, values);
1269 }
1270
1271
1272
1273 template <typename ViewType>
1274 template <typename InputVector>
1275 void
1276 RenumberedView<ViewType>::get_function_values_from_local_dof_values(
1277 const InputVector &dof_values,
1278 std::vector<solution_value_type<typename InputVector::value_type>> &values)
1279 const
1280 {
1281 const auto &inner_dof_values = outer_to_inner_dofs(dof_values);
1282 auto &inner_values = outer_to_inner_values(values);
1283
1284 view.get_function_values_from_local_dof_values(inner_dof_values,
1285 inner_values);
1286 inner_to_outer_values(inner_values, values);
1287 }
1288
1289
1290 template <typename ViewType>
1291 template <typename Number>
1292 void
1293 RenumberedView<ViewType>::get_function_gradients(
1294 const ReadVector<Number> &fe_function,
1295 std::vector<solution_gradient_type<Number>> &gradients) const
1296 {
1297 auto &inner_gradients = outer_to_inner_values(gradients);
1298 view.get_function_gradients(fe_function, inner_gradients);
1299 inner_to_outer_values(inner_gradients, gradients);
1300 }
1301
1302
1303
1304 template <typename ViewType>
1305 template <typename InputVector>
1306 void
1307 RenumberedView<ViewType>::get_function_gradients_from_local_dof_values(
1308 const InputVector &dof_values,
1309 std::vector<solution_gradient_type<typename InputVector::value_type>>
1310 &gradients) const
1311 {
1312 const auto &inner_dof_values = outer_to_inner_dofs(dof_values);
1313 auto &inner_gradients = outer_to_inner_values(gradients);
1314
1315 view.get_function_gradients_from_local_dof_values(inner_dof_values,
1316 inner_gradients);
1317 inner_to_outer_values(inner_gradients, gradients);
1318 }
1319} // namespace FEValuesViews
1320
1321/*-------------- Inline functions FECouplingValues ---------------------*/
1322
1323template <int dim1, int dim2, int spacedim>
1324std::vector<types::global_dof_index>
1326 const std::vector<types::global_dof_index> &dof_indices_1,
1327 const std::vector<types::global_dof_index> &dof_indices_2,
1328 const types::global_dof_index dofs_offset_1,
1329 const types::global_dof_index dofs_offset_2) const
1330{
1332 n_coupling_dofs_ != numbers::invalid_unsigned_int,
1333 ExcMessage(
1334 "Dofs are independent. You cannot ask for coupling dof indices."));
1335 AssertDimension(dof_indices_1.size(), first_fe_values->dofs_per_cell);
1336 AssertDimension(dof_indices_2.size(), second_fe_values->dofs_per_cell);
1337
1338 std::vector<types::global_dof_index> coupling_dof_indices(
1339 dof_indices_1.size() + dof_indices_2.size());
1340 unsigned int idx = 0;
1341 for (const auto &i : dof_indices_1)
1342 coupling_dof_indices[idx++] = i + dofs_offset_1;
1343 for (const auto &i : dof_indices_2)
1344 coupling_dof_indices[idx++] = i + dofs_offset_2;
1345 return coupling_dof_indices;
1346}
1347
1348
1349
1350template <int dim1, int dim2, int spacedim>
1352 : first_fe_values(nullptr)
1353 , second_fe_values(nullptr)
1354 , quadrature_coupling_type(QuadratureCouplingType::unrolled)
1355 , n_quadrature_points_(0)
1356 , n_coupling_dofs_(numbers::invalid_unsigned_int)
1357{}
1358
1359
1360
1361template <int dim1, int dim2, int spacedim>
1363 const FEValuesBase<dim1, spacedim> &fe_values_1,
1364 const FEValuesBase<dim2, spacedim> &fe_values_2,
1365 const DoFCouplingType &dof_coupling_type,
1366 const QuadratureCouplingType &quadrature_coupling_type)
1367 : FECouplingValues() // delegate to other constructor
1368{
1369 reinit(fe_values_1, fe_values_2, dof_coupling_type, quadrature_coupling_type);
1370}
1371
1372
1373
1374template <int dim1, int dim2, int spacedim>
1375void
1377 const FEValuesBase<dim1, spacedim> &fe_values_1,
1378 const FEValuesBase<dim2, spacedim> &fe_values_2,
1379 const DoFCouplingType &dof_coupling_type,
1380 const QuadratureCouplingType &quadrature_coupling_type)
1381{
1382 first_fe_values = &fe_values_1;
1383 second_fe_values = &fe_values_2;
1384 this->dof_coupling_type = dof_coupling_type;
1385 this->quadrature_coupling_type = quadrature_coupling_type;
1386
1387 // Gather information about the inner objects
1388 unsigned int first_n_inner_dofs = fe_values_1.dofs_per_cell;
1389 unsigned int second_n_inner_dofs = fe_values_2.dofs_per_cell;
1390
1391 unsigned int first_n_inner_quadrature_points =
1392 fe_values_1.n_quadrature_points;
1393 unsigned int second_n_inner_quadrature_points =
1394 fe_values_2.n_quadrature_points;
1395
1396 // Initialize counters and renumbering vectors to zero
1397 std::vector<unsigned int> first_dofs_map;
1398 std::vector<unsigned int> second_dofs_map;
1399
1400 std::vector<unsigned int> first_quad_map;
1401 std::vector<unsigned int> second_quad_map;
1402
1403 // Local relative tolerance for comparing quadrature points
1404 const double tol = std::min(fe_values_1.get_cell()->diameter(),
1405 fe_values_2.get_cell()->diameter()) *
1406 1e-6;
1407
1408 // Now fill the renumbering vectors
1409 switch (dof_coupling_type)
1410 {
1412 {
1413 n_coupling_dofs_ = numbers::invalid_unsigned_int;
1414 first_dofs_map.clear();
1415 second_dofs_map.clear();
1416 break;
1417 }
1419 {
1420 n_coupling_dofs_ =
1421 fe_values_1.dofs_per_cell + fe_values_2.dofs_per_cell;
1422
1423 first_dofs_map.resize(n_coupling_dofs_);
1424 second_dofs_map.resize(n_coupling_dofs_);
1425
1426 unsigned int idx = 0;
1427 for (const unsigned int &i : fe_values_1.dof_indices())
1428 {
1429 first_dofs_map[idx] = i;
1430 second_dofs_map[idx++] = numbers::invalid_unsigned_int;
1431 }
1432 for (const unsigned int &i : fe_values_2.dof_indices())
1433 {
1434 first_dofs_map[idx] = numbers::invalid_unsigned_int;
1435 second_dofs_map[idx++] = i;
1436 }
1437 // Make sure we have the right number of dofs
1438 AssertDimension(idx, n_coupling_dofs_);
1439 break;
1440 }
1441 default:
1443 }
1444 // Compute the quadrature maps
1445 switch (quadrature_coupling_type)
1446 {
1448 {
1449 const auto &quadrature_points_1 = fe_values_1.get_quadrature_points();
1450 const auto &quadrature_points_2 = fe_values_2.get_quadrature_points();
1451
1452 n_quadrature_points_ =
1453 quadrature_points_1.size() * quadrature_points_2.size();
1454
1455 first_quad_map.resize(n_quadrature_points_);
1456 second_quad_map.resize(n_quadrature_points_);
1457
1458 unsigned int idx = 0;
1459 for (const unsigned int &i : fe_values_1.quadrature_point_indices())
1460 for (const unsigned int &j : fe_values_2.quadrature_point_indices())
1461 {
1462 first_quad_map[idx] = i;
1463 second_quad_map[idx] = j;
1464 ++idx;
1465 }
1466 break;
1467 }
1469 {
1470 Assert(fe_values_1.get_quadrature_points().size() ==
1471 fe_values_2.get_quadrature_points().size(),
1472 ExcMessage("The two FEValuesBase objects must have the same "
1473 "number of quadrature points"));
1474
1475 n_quadrature_points_ = fe_values_1.get_quadrature_points().size();
1476
1477 first_quad_map.clear();
1478 second_quad_map.clear();
1479
1480 break;
1481 }
1483 {
1484 const auto &quadrature_points_1 = fe_values_1.get_quadrature_points();
1485 const auto &quadrature_points_2 = fe_values_2.get_quadrature_points();
1486
1487 Assert(quadrature_points_1.size() == quadrature_points_2.size(),
1488 ExcMessage("The two FEValuesBase objects must have the same "
1489 "number of quadrature points"));
1490
1491 for (const unsigned int &i : fe_values_1.quadrature_point_indices())
1492 {
1493 Assert(quadrature_points_1[i].distance(quadrature_points_2[i]) <
1494 tol,
1495 ExcMessage(
1496 "The two FEValuesBase objects must have the same "
1497 "quadrature points"));
1498 }
1499
1500 n_quadrature_points_ = fe_values_1.get_quadrature_points().size();
1501
1502 first_quad_map.clear();
1503 second_quad_map.clear();
1504
1505 break;
1506 }
1508 {
1509 const auto &quadrature_points_1 = fe_values_1.get_quadrature_points();
1510 const auto &quadrature_points_2 = fe_values_2.get_quadrature_points();
1511
1512 Assert(quadrature_points_1.size() == quadrature_points_2.size(),
1513 ExcMessage("The two FEValuesBase objects must have the same "
1514 "number of quadrature points"));
1515
1516 n_quadrature_points_ = fe_values_1.get_quadrature_points().size();
1517
1518 // The first is the id. The second is renumbered.
1519 first_quad_map.clear();
1520 second_quad_map.resize(fe_values_1.get_quadrature_points().size());
1521
1522 // [TODO]: Avoid quadratic complexity here
1523 for (const unsigned int &i : fe_values_1.quadrature_point_indices())
1524 {
1526 for (const unsigned int &j :
1527 fe_values_2.quadrature_point_indices())
1528 if (quadrature_points_1[i].distance(quadrature_points_2[j]) <
1529 tol)
1530 {
1531 id = i;
1532 second_quad_map[i] = j;
1533 break;
1534 }
1536 ExcMessage(
1537 "The two FEValuesBase objects must have the same "
1538 "quadrature points, even if not in the same order."));
1539 }
1540 break;
1541 }
1543 {
1544 const auto &quadrature_points_1 = fe_values_1.get_quadrature_points();
1545 const auto &quadrature_points_2 = fe_values_2.get_quadrature_points();
1546
1547 // [TODO]: Avoid quadratic complexity here
1548 for (const unsigned int &i : fe_values_1.quadrature_point_indices())
1549 {
1550 for (const unsigned int &j :
1551 fe_values_2.quadrature_point_indices())
1552 if (quadrature_points_1[i].distance(quadrature_points_2[j]) <
1553 tol)
1554 {
1555 first_quad_map.emplace_back(i);
1556 second_quad_map.emplace_back(j);
1557 break;
1558 }
1559 }
1560 n_quadrature_points_ = first_quad_map.size();
1561
1562 break;
1563 }
1564 default:
1565 Assert(false, ExcInternalError());
1566 }
1567
1568 first_renumbering_data = std::make_unique<FEValuesViews::RenumberingData>(
1569 first_n_inner_dofs,
1570 first_n_inner_quadrature_points,
1571 first_dofs_map,
1572 first_quad_map);
1573
1574 second_renumbering_data = std::make_unique<FEValuesViews::RenumberingData>(
1575 second_n_inner_dofs,
1576 second_n_inner_quadrature_points,
1577 second_dofs_map,
1578 second_quad_map);
1579}
1580
1581
1582template <int dim1, int dim2, int spacedim>
1583inline double
1584FECouplingValues<dim1, dim2, spacedim>::JxW(const unsigned int q) const
1585{
1586 AssertIndexRange(q, n_quadrature_points_);
1587
1588 const auto first_q = first_renumbering_data->quadrature_renumbering.empty() ?
1589 q :
1590 first_renumbering_data->quadrature_renumbering[q];
1591
1592 if (quadrature_coupling_type == QuadratureCouplingType::tensor_product ||
1593 quadrature_coupling_type == QuadratureCouplingType::unrolled)
1594 {
1595 const auto second_q =
1596 second_renumbering_data->quadrature_renumbering.empty() ?
1597 q :
1598 second_renumbering_data->quadrature_renumbering[q];
1599 return first_fe_values->JxW(first_q) * second_fe_values->JxW(second_q);
1600 }
1601 else
1602 return first_fe_values->JxW(first_q);
1603}
1604
1605
1606
1607template <int dim1, int dim2, int spacedim>
1610{
1612 0U, n_quadrature_points_);
1613}
1614
1615
1616
1617template <int dim1, int dim2, int spacedim>
1620{
1621 AssertThrow(n_coupling_dofs_ != numbers::invalid_unsigned_int,
1622 ExcMessage(
1623 "Dofs are independent. You cannot ask for coupling dofs."));
1625 0U, n_coupling_dofs_);
1626}
1627
1628
1629
1630template <int dim1, int dim2, int spacedim>
1633{
1635 0U, n_first_dofs());
1636}
1637
1638
1639
1640template <int dim1, int dim2, int spacedim>
1643{
1645 0U, n_second_dofs());
1646}
1647
1648
1649
1650template <int dim1, int dim2, int spacedim>
1651inline unsigned int
1653{
1654 AssertThrow(n_coupling_dofs_ != numbers::invalid_unsigned_int,
1655 ExcMessage(
1656 "Dofs are independent. You cannot ask for coupling dofs."));
1657 return n_coupling_dofs_;
1658}
1659
1660
1661
1662template <int dim1, int dim2, int spacedim>
1663inline unsigned int
1665{
1666 return first_renumbering_data->n_dofs;
1667}
1668
1669
1670
1671template <int dim1, int dim2, int spacedim>
1672inline unsigned int
1674{
1675 return second_renumbering_data->n_dofs;
1676}
1677
1678
1679
1680template <int dim1, int dim2, int spacedim>
1681inline unsigned int
1683{
1684 return n_quadrature_points_;
1685}
1686
1687
1688
1689template <int dim1, int dim2, int spacedim>
1690std::pair<Point<spacedim>, Point<spacedim>>
1692 const unsigned int quadrature_point) const
1693{
1694 AssertIndexRange(quadrature_point, n_quadrature_points_);
1695 const auto first_q = first_fe_values->quadrature_point(
1696 first_renumbering_data->quadrature_renumbering.empty() ?
1697 quadrature_point :
1698 first_renumbering_data->quadrature_renumbering[quadrature_point]);
1699
1700 const auto second_q = second_fe_values->quadrature_point(
1701 second_renumbering_data->quadrature_renumbering.empty() ?
1702 quadrature_point :
1703 second_renumbering_data->quadrature_renumbering[quadrature_point]);
1704
1705 return {first_q, second_q};
1706}
1707
1708
1709
1710template <int dim1, int dim2, int spacedim>
1711std::pair<unsigned int, unsigned int>
1714 const unsigned int quadrature_point) const
1715{
1716 AssertIndexRange(quadrature_point, n_quadrature_points_);
1717 const auto first_id =
1718 first_renumbering_data->quadrature_renumbering.empty() ?
1719 quadrature_point :
1720 first_renumbering_data->quadrature_renumbering[quadrature_point];
1721
1722 const auto second_id =
1723 second_renumbering_data->quadrature_renumbering.empty() ?
1724 quadrature_point :
1725 second_renumbering_data->quadrature_renumbering[quadrature_point];
1726 return std::make_pair(first_id, second_id);
1727}
1728
1729
1730
1731template <int dim1, int dim2, int spacedim>
1732std::pair<unsigned int, unsigned int>
1734 const unsigned int coupling_dof_index) const
1735{
1736 AssertIndexRange(coupling_dof_index, n_coupling_dofs_);
1737 const auto first_id =
1738 first_renumbering_data->dof_renumbering.empty() ?
1739 coupling_dof_index :
1740 first_renumbering_data->dof_renumbering[coupling_dof_index];
1741
1742 const auto second_id =
1743 second_renumbering_data->dof_renumbering.empty() ?
1744 coupling_dof_index :
1745 second_renumbering_data->dof_renumbering[coupling_dof_index];
1746 return std::make_pair(first_id, second_id);
1747}
1748
1749
1750
1751template <int dim1, int dim2, int spacedim>
1752template <typename Extractor>
1755 const Extractor &extractor) const
1756{
1758}
1759
1760
1761
1762template <int dim1, int dim2, int spacedim>
1763template <typename Extractor>
1766 const Extractor &extractor) const
1767{
1769}
1770
1771
1772
1773template <int dim1, int dim2, int spacedim>
1774template <typename Extractor>
1778 const FEValuesExtractors::FirstCoupling<Extractor> &extractor) const
1779{
1782 (*first_fe_values)[extractor.extractor], *first_renumbering_data);
1783}
1784
1785
1786
1787template <int dim1, int dim2, int spacedim>
1788template <typename Extractor>
1792 const FEValuesExtractors::SecondCoupling<Extractor> &extractor) const
1793{
1796 (*second_fe_values)[extractor.extractor], *second_renumbering_data);
1797}
1798
1799#endif // DOXYGEN
1800
1802
1803#endif
*  *  for(const auto &cell :triangulation.active_cell_iterators())
unsigned int n_quadrature_points() const
std::pair< Point< spacedim >, Point< spacedim > > quadrature_point(const unsigned int quadrature_point) const
const FEValuesViews::RenumberedView< FEValuesViews::View< dim2, spacedim, Extractor > > operator[](const FEValuesExtractors::SecondCoupling< Extractor > &extractor) const
std::vector< types::global_dof_index > get_coupling_dof_indices(const std::vector< types::global_dof_index > &dof_indices_1, const std::vector< types::global_dof_index > &dof_indices_2, const types::global_dof_index dofs_offset_1=0, const types::global_dof_index dofs_offset_2=0) const
FEValuesExtractors::FirstCoupling< Extractor > get_first_extractor(const Extractor &extractor) const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > first_dof_indices() const
FECouplingValues(const FEValuesBase< dim1, spacedim > &fe_values_1, const FEValuesBase< dim2, spacedim > &fe_values_2, const DoFCouplingType &dof_coupling_type=DoFCouplingType::independent, const QuadratureCouplingType &quadrature_coupling_type=QuadratureCouplingType::tensor_product)
unsigned int n_quadrature_points_
std_cxx20::ranges::iota_view< unsigned int, unsigned int > quadrature_point_indices() const
unsigned int n_coupling_dofs_
unsigned int n_coupling_dofs() const
QuadratureCouplingType quadrature_coupling_type
const FEValuesViews::RenumberedView< FEValuesViews::View< dim1, spacedim, Extractor > > operator[](const FEValuesExtractors::FirstCoupling< Extractor > &extractor) const
std::pair< unsigned int, unsigned int > coupling_quadrature_to_quadrature_indices(const unsigned int quadrature_point) const
ObserverPointer< const FEValuesBase< dim1, spacedim > > first_fe_values
double JxW(const unsigned int quadrature_point) const
ObserverPointer< const FEValuesBase< dim2, spacedim > > second_fe_values
std::unique_ptr< const FEValuesViews::RenumberingData > first_renumbering_data
std_cxx20::ranges::iota_view< unsigned int, unsigned int > coupling_dof_indices() const
unsigned int n_second_dofs() const
FEValuesExtractors::SecondCoupling< Extractor > get_second_extractor(const Extractor &extractor) const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > second_dof_indices() const
DoFCouplingType dof_coupling_type
unsigned int n_first_dofs() const
void reinit(const FEValuesBase< dim1, spacedim > &fe_values_1, const FEValuesBase< dim2, spacedim > &fe_values_2, const DoFCouplingType &dof_coupling_type=DoFCouplingType::independent, const QuadratureCouplingType &quadrature_coupling_type=QuadratureCouplingType::tensor_product)
std::pair< unsigned int, unsigned int > coupling_dof_to_dof_indices(const unsigned int coupling_dof_index) const
std::unique_ptr< const FEValuesViews::RenumberingData > second_renumbering_data
Triangulation< dim, spacedim >::cell_iterator get_cell() const
const std::vector< Point< spacedim > > & get_quadrature_points() const
const unsigned int dofs_per_cell
const unsigned int n_quadrature_points
void get_function_values_from_local_dof_values(const InputVector &dof_values, std::vector< solution_value_type< typename InputVector::value_type > > &values) const
void get_function_gradients_from_local_dof_values(const InputVector &dof_values, std::vector< solution_gradient_type< typename InputVector::value_type > > &gradients) const
const InputVector & outer_to_inner_dofs(const InputVector &outer_vector) const
gradient_type gradient(const unsigned int shape_function, const unsigned int q_point) const
typename ViewType::value_type value_type
void get_function_gradients(const ReadVector< Number > &fe_function, std::vector< solution_gradient_type< Number > > &gradients) const
void inner_to_outer_values(const std::vector< ValueType > &inner_values, std::vector< ValueType > &outer_values) const
std::vector< ValueType > & outer_to_inner_values(std::vector< ValueType > &outer_values) const
typename ViewType::gradient_type gradient_type
void get_function_values(const ReadVector< Number > &fe_function, std::vector< solution_value_type< Number > > &values) const
RenumberedView(const ViewType &view, const RenumberingData &data)
typename ViewType::template solution_value_type< Number > solution_value_type
std::string get_unique_container_name(const std::string &prefix, const unsigned int size, const Number &exemplar_number) const
typename ViewType::template solution_gradient_type< Number > solution_gradient_type
value_type value(const unsigned int shape_function, const unsigned int q_point) const
Definition point.h:111
A class that provides a separate storage location on each thread that accesses the object.
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
constexpr bool running_in_debug_mode()
Definition config.h:76
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
QuadratureCouplingType
DoFCouplingType
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::vector< index_type > data
Definition mpi.cc:734
std::size_t size
Definition mpi.cc:733
typename ::internal::FEValuesViews::ViewType< dim, spacedim, Extractor >::type View
Tpetra::Vector< Number, LO, GO, NodeType< MemorySpace > > VectorType
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
*  *  if(update_pressure &update_flags) *  compute_pressure(constitutive_request
*  *  *  *  std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters   const
std::string type_to_string(const T &t)
Definition utilities.h:994
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition utilities.cc:464
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:43
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
const std::vector< unsigned int > dof_renumbering
RenumberingData(const unsigned int n_inner_dofs=numbers::invalid_unsigned_int, const unsigned int n_inner_quadrature_points=numbers::invalid_unsigned_int, const std::vector< unsigned int > &dof_renumbering={}, const std::vector< unsigned int > &quadrature_renumbering={})
const unsigned int n_inner_quadrature_points
const std::vector< unsigned int > quadrature_renumbering
RenumberingData(const RenumberingData &other)=delete
Threads::ThreadLocalStorage< GeneralDataStorage > data_storage