17 #ifndef dealii_mesh_worker_simple_h 18 #define dealii_mesh_worker_simple_h 20 #include <deal.II/algorithms/any_data.h> 22 #include <deal.II/base/mg_level_object.h> 23 #include <deal.II/base/smartpointer.h> 25 #include <deal.II/lac/block_vector.h> 27 #include <deal.II/meshworker/dof_info.h> 28 #include <deal.II/meshworker/functional.h> 30 #include <deal.II/multigrid/mg_constrained_dofs.h> 38 DEAL_II_NAMESPACE_OPEN
57 template <
typename VectorType>
100 template <
class DOFINFO>
110 template <
class DOFINFO>
117 template <
class DOFINFO>
119 assemble(
const DOFINFO &info1,
const DOFINFO &info2);
167 template <
typename MatrixType>
207 template <
class DOFINFO>
215 template <
class DOFINFO>
223 template <
class DOFINFO>
225 assemble(
const DOFINFO &info1,
const DOFINFO &info2);
231 std::vector<SmartPointer<MatrixType, MatrixSimple<MatrixType>>>
matrix;
247 const unsigned int index,
248 const std::vector<types::global_dof_index> &i1,
249 const std::vector<types::global_dof_index> &i2);
270 template <
typename MatrixType>
314 template <
class DOFINFO>
321 template <
class DOFINFO>
329 template <
class DOFINFO>
331 assemble(
const DOFINFO &info1,
const DOFINFO &info2);
340 const std::vector<types::global_dof_index> &i1,
341 const std::vector<types::global_dof_index> &i2);
349 const std::vector<types::global_dof_index> &i1,
350 const std::vector<types::global_dof_index> &i2,
351 const unsigned int level);
360 const std::vector<types::global_dof_index> &i1,
361 const std::vector<types::global_dof_index> &i2,
370 const std::vector<types::global_dof_index> &i1,
371 const std::vector<types::global_dof_index> &i2,
381 const std::vector<types::global_dof_index> &i1,
382 const std::vector<types::global_dof_index> &i2,
392 const std::vector<types::global_dof_index> &i1,
393 const std::vector<types::global_dof_index> &i2,
454 template <
typename MatrixType,
typename VectorType>
488 template <
class DOFINFO>
495 template <
class DOFINFO>
503 template <
class DOFINFO>
505 assemble(
const DOFINFO &info1,
const DOFINFO &info2);
515 const unsigned int index,
516 const std::vector<types::global_dof_index> &indices);
521 const unsigned int index,
522 const std::vector<types::global_dof_index> &i1,
523 const std::vector<types::global_dof_index> &i2);
529 template <
typename VectorType>
536 template <
typename VectorType>
545 template <
typename MatrixType>
551 template <
typename VectorType>
552 template <
class DOFINFO>
556 info.initialize_vectors(residuals.size());
560 template <
typename VectorType>
561 template <
class DOFINFO>
565 for (
unsigned int k = 0; k < residuals.size(); ++k)
567 VectorType *v = residuals.entry<VectorType *>(k);
568 for (
unsigned int i = 0; i != info.vector(k).n_blocks(); ++i)
570 const std::vector<types::global_dof_index> &ldi =
571 info.vector(k).n_blocks() == 1 ? info.indices :
572 info.indices_by_block[i];
574 if (constraints !=
nullptr)
575 constraints->distribute_local_to_global(info.vector(k).block(i),
579 v->add(ldi, info.vector(k).block(i));
584 template <
typename VectorType>
585 template <
class DOFINFO>
588 const DOFINFO &info2)
597 template <
typename MatrixType>
599 : threshold(threshold)
603 template <
typename MatrixType>
612 template <
typename MatrixType>
616 matrix.resize(m.size());
617 for (
unsigned int i = 0; i < m.size(); ++i)
622 template <
typename MatrixType>
631 template <
typename MatrixType>
632 template <
class DOFINFO>
638 const unsigned int n = info.indices_by_block.size();
641 info.initialize_matrices(matrix.size(), face);
644 info.initialize_matrices(matrix.size() * n * n, face);
646 for (
unsigned int m = 0; m < matrix.size(); ++m)
647 for (
unsigned int i = 0; i < n; ++i)
648 for (
unsigned int j = 0; j < n; ++j, ++k)
650 info.matrix(k,
false).row = i;
651 info.matrix(k,
false).column = j;
654 info.matrix(k,
true).row = i;
655 info.matrix(k,
true).column = j;
663 template <
typename MatrixType>
667 const unsigned int index,
668 const std::vector<types::global_dof_index> &i1,
669 const std::vector<types::global_dof_index> &i2)
674 if (constraints ==
nullptr)
676 for (
unsigned int j = 0; j < i1.size(); ++j)
677 for (
unsigned int k = 0; k < i2.size(); ++k)
678 if (std::fabs(M(j, k)) >= threshold)
679 matrix[index]->add(i1[j], i2[k], M(j, k));
682 constraints->distribute_local_to_global(M, i1, i2, *matrix[index]);
686 template <
typename MatrixType>
687 template <
class DOFINFO>
692 const unsigned int n = info.indices_by_block.size();
695 for (
unsigned int m = 0; m < matrix.size(); ++m)
696 assemble(info.matrix(m,
false).matrix, m, info.indices, info.indices);
699 for (
unsigned int m = 0; m < matrix.size(); ++m)
700 for (
unsigned int k = 0; k < n * n; ++k)
703 info.matrix(k + m * n * n,
false).matrix,
705 info.indices_by_block[info.matrix(k + m * n * n,
false).row],
706 info.indices_by_block[info.matrix(k + m * n * n,
false)
713 template <
typename MatrixType>
714 template <
class DOFINFO>
717 const DOFINFO &info2)
722 info2.indices_by_block.size());
724 const unsigned int n = info1.indices_by_block.size();
728 for (
unsigned int m = 0; m < matrix.size(); ++m)
730 assemble(info1.matrix(m,
false).matrix,
734 assemble(info1.matrix(m,
true).matrix,
738 assemble(info2.matrix(m,
false).matrix,
742 assemble(info2.matrix(m,
true).matrix,
750 for (
unsigned int m = 0; m < matrix.size(); ++m)
751 for (
unsigned int k = 0; k < n * n; ++k)
753 const unsigned int row = info1.matrix(k + m * n * n,
false).row;
754 const unsigned int column =
755 info1.matrix(k + m * n * n,
false).column;
757 assemble(info1.matrix(k + m * n * n,
false).matrix,
759 info1.indices_by_block[row],
760 info1.indices_by_block[column]);
761 assemble(info1.matrix(k + m * n * n,
true).matrix,
763 info1.indices_by_block[row],
764 info2.indices_by_block[column]);
765 assemble(info2.matrix(k + m * n * n,
false).matrix,
767 info2.indices_by_block[row],
768 info2.indices_by_block[column]);
769 assemble(info2.matrix(k + m * n * n,
true).matrix,
771 info2.indices_by_block[row],
772 info1.indices_by_block[column]);
780 template <
typename MatrixType>
782 : threshold(threshold)
786 template <
typename MatrixType>
793 template <
typename MatrixType>
797 mg_constrained_dofs = &c;
801 template <
typename MatrixType>
812 template <
typename MatrixType>
819 interface_out = &out;
823 template <
typename MatrixType>
824 template <
class DOFINFO>
828 const unsigned int n = info.indices_by_block.size();
831 info.initialize_matrices(1, face);
834 info.initialize_matrices(n * n, face);
836 for (
unsigned int i = 0; i < n; ++i)
837 for (
unsigned int j = 0; j < n; ++j, ++k)
839 info.matrix(k,
false).row = i;
840 info.matrix(k,
false).column = j;
843 info.matrix(k,
true).row = i;
844 info.matrix(k,
true).column = j;
851 template <
typename MatrixType>
856 const std::vector<types::global_dof_index> &i1,
857 const std::vector<types::global_dof_index> &i2)
864 for (
unsigned int j = 0; j < i1.size(); ++j)
865 for (
unsigned int k = 0; k < i2.size(); ++k)
866 if (std::fabs(M(j, k)) >= threshold)
867 G.add(i1[j], i2[k], M(j, k));
871 template <
typename MatrixType>
876 const std::vector<types::global_dof_index> &i1,
877 const std::vector<types::global_dof_index> &i2,
878 const unsigned int level)
883 if (mg_constrained_dofs ==
nullptr)
885 for (
unsigned int j = 0; j < i1.size(); ++j)
886 for (
unsigned int k = 0; k < i2.size(); ++k)
887 if (std::fabs(M(j, k)) >= threshold)
888 G.add(i1[j], i2[k], M(j, k));
892 for (
unsigned int j = 0; j < i1.size(); ++j)
893 for (
unsigned int k = 0; k < i2.size(); ++k)
897 if (std::fabs(M(j, k)) < threshold)
907 if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) ||
908 mg_constrained_dofs->at_refinement_edge(level, i2[k]))
913 if ((mg_constrained_dofs->is_boundary_index(level, i1[j]) ||
914 mg_constrained_dofs->is_boundary_index(level, i2[k])) &&
918 G.add(i1[j], i2[k], M(j, k));
924 template <
typename MatrixType>
929 const std::vector<types::global_dof_index> &i1,
930 const std::vector<types::global_dof_index> &i2,
931 const unsigned int level)
936 if (mg_constrained_dofs ==
nullptr)
938 for (
unsigned int j = 0; j < i1.size(); ++j)
939 for (
unsigned int k = 0; k < i2.size(); ++k)
940 if (std::fabs(M(k, j)) >= threshold)
941 G.add(i1[j], i2[k], M(k, j));
945 for (
unsigned int j = 0; j < i1.size(); ++j)
946 for (
unsigned int k = 0; k < i2.size(); ++k)
947 if (std::fabs(M(k, j)) >= threshold)
948 if (!mg_constrained_dofs->at_refinement_edge(level, i2[k]))
949 G.add(i1[j], i2[k], M(k, j));
953 template <
typename MatrixType>
958 const std::vector<types::global_dof_index> &i1,
959 const std::vector<types::global_dof_index> &i2,
960 const unsigned int level)
965 if (mg_constrained_dofs ==
nullptr)
967 for (
unsigned int j = 0; j < i1.size(); ++j)
968 for (
unsigned int k = 0; k < i2.size(); ++k)
969 if (std::fabs(M(j, k)) >= threshold)
970 G.add(i1[j], i2[k], M(j, k));
974 for (
unsigned int j = 0; j < i1.size(); ++j)
975 for (
unsigned int k = 0; k < i2.size(); ++k)
976 if (std::fabs(M(j, k)) >= threshold)
977 if (!mg_constrained_dofs->at_refinement_edge(level, i2[k]))
978 G.add(i1[j], i2[k], M(j, k));
982 template <
typename MatrixType>
987 const std::vector<types::global_dof_index> &i1,
988 const std::vector<types::global_dof_index> &i2,
989 const unsigned int level)
995 for (
unsigned int j = 0; j < i1.size(); ++j)
996 for (
unsigned int k = 0; k < i2.size(); ++k)
997 if (std::fabs(M(j, k)) >= threshold)
1009 if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
1010 !mg_constrained_dofs->at_refinement_edge(level, i2[k]))
1012 if ((!mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
1013 !mg_constrained_dofs->is_boundary_index(level, i2[k])) ||
1014 (mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
1015 mg_constrained_dofs->is_boundary_index(level, i2[k]) &&
1017 G.add(i1[j], i2[k], M(j, k));
1022 template <
typename MatrixType>
1027 const std::vector<types::global_dof_index> &i1,
1028 const std::vector<types::global_dof_index> &i2,
1029 const unsigned int level)
1035 for (
unsigned int j = 0; j < i1.size(); ++j)
1036 for (
unsigned int k = 0; k < i2.size(); ++k)
1037 if (std::fabs(M(k, j)) >= threshold)
1038 if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
1039 !mg_constrained_dofs->at_refinement_edge(level, i2[k]))
1041 if ((!mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
1042 !mg_constrained_dofs->is_boundary_index(level, i2[k])) ||
1043 (mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
1044 mg_constrained_dofs->is_boundary_index(level, i2[k]) &&
1046 G.add(i1[j], i2[k], M(k, j));
1051 template <
typename MatrixType>
1052 template <
class DOFINFO>
1057 const unsigned int level = info.cell->level();
1059 if (info.indices_by_block.size() == 0)
1061 assemble((*matrix)[level],
1062 info.matrix(0,
false).matrix,
1066 if (mg_constrained_dofs !=
nullptr)
1068 assemble_in((*interface_in)[level],
1069 info.matrix(0,
false).matrix,
1073 assemble_out((*interface_out)[level],
1074 info.matrix(0,
false).matrix,
1081 for (
unsigned int k = 0; k < info.n_matrices(); ++k)
1083 const unsigned int row = info.matrix(k,
false).row;
1084 const unsigned int column = info.matrix(k,
false).column;
1086 assemble((*matrix)[level],
1087 info.matrix(k,
false).matrix,
1088 info.indices_by_block[row],
1089 info.indices_by_block[column],
1092 if (mg_constrained_dofs !=
nullptr)
1094 assemble_in((*interface_in)[level],
1095 info.matrix(k,
false).matrix,
1096 info.indices_by_block[row],
1097 info.indices_by_block[column],
1099 assemble_out((*interface_out)[level],
1100 info.matrix(k,
false).matrix,
1101 info.indices_by_block[column],
1102 info.indices_by_block[row],
1109 template <
typename MatrixType>
1110 template <
class DOFINFO>
1113 const DOFINFO &info2)
1117 const unsigned int level1 = info1.cell->level();
1118 const unsigned int level2 = info2.cell->level();
1120 if (info1.indices_by_block.size() == 0)
1122 if (level1 == level2)
1124 assemble((*matrix)[level1],
1125 info1.matrix(0,
false).matrix,
1129 assemble((*matrix)[level1],
1130 info1.matrix(0,
true).matrix,
1134 assemble((*matrix)[level1],
1135 info2.matrix(0,
false).matrix,
1139 assemble((*matrix)[level1],
1140 info2.matrix(0,
true).matrix,
1151 assemble((*matrix)[level1],
1152 info1.matrix(0,
false).matrix,
1158 assemble_up((*flux_up)[level1],
1159 info1.matrix(0,
true).matrix,
1163 assemble_down((*flux_down)[level1],
1164 info2.matrix(0,
true).matrix,
1172 for (
unsigned int k = 0; k < info1.n_matrices(); ++k)
1174 const unsigned int row = info1.matrix(k,
false).row;
1175 const unsigned int column = info1.matrix(k,
false).column;
1177 if (level1 == level2)
1179 assemble((*matrix)[level1],
1180 info1.matrix(k,
false).matrix,
1181 info1.indices_by_block[row],
1182 info1.indices_by_block[column],
1184 assemble((*matrix)[level1],
1185 info1.matrix(k,
true).matrix,
1186 info1.indices_by_block[row],
1187 info2.indices_by_block[column],
1189 assemble((*matrix)[level1],
1190 info2.matrix(k,
false).matrix,
1191 info2.indices_by_block[row],
1192 info2.indices_by_block[column],
1194 assemble((*matrix)[level1],
1195 info2.matrix(k,
true).matrix,
1196 info2.indices_by_block[row],
1197 info1.indices_by_block[column],
1206 assemble((*matrix)[level1],
1207 info1.matrix(k,
false).matrix,
1208 info1.indices_by_block[row],
1209 info1.indices_by_block[column],
1213 assemble_up((*flux_up)[level1],
1214 info1.matrix(k,
true).matrix,
1215 info2.indices_by_block[column],
1216 info1.indices_by_block[row],
1218 assemble_down((*flux_down)[level1],
1219 info2.matrix(k,
true).matrix,
1220 info2.indices_by_block[row],
1221 info1.indices_by_block[column],
1230 template <
typename MatrixType,
typename VectorType>
1236 template <
typename MatrixType,
typename VectorType>
1242 VectorType *p = &rhs;
1243 data.
add(p,
"right hand side");
1249 template <
typename MatrixType,
typename VectorType>
1258 template <
typename MatrixType,
typename VectorType>
1259 template <
class DOFINFO>
1268 template <
typename MatrixType,
typename VectorType>
1273 const unsigned int index,
1274 const std::vector<types::global_dof_index> &indices)
1280 VectorType *v = residuals.entry<VectorType *>(index);
1284 for (
unsigned int i = 0; i < indices.size(); ++i)
1285 (*v)(indices[i]) += vector(i);
1287 for (
unsigned int j = 0; j < indices.size(); ++j)
1288 for (
unsigned int k = 0; k < indices.size(); ++k)
1306 template <
typename MatrixType,
typename VectorType>
1311 const unsigned int index,
1312 const std::vector<types::global_dof_index> &i1,
1313 const std::vector<types::global_dof_index> &i2)
1319 VectorType *v = residuals.entry<VectorType *>(index);
1323 for (
unsigned int j = 0; j < i1.size(); ++j)
1324 for (
unsigned int k = 0; k < i2.size(); ++k)
1333 vector, i1, i2, *v, M,
false);
1340 template <
typename MatrixType,
typename VectorType>
1341 template <
class DOFINFO>
1348 const unsigned int n = info.indices_by_block.size();
1352 for (
unsigned int m = 0; m < MatrixSimple<MatrixType>::matrix.size();
1354 assemble(info.matrix(m,
false).matrix,
1355 info.vector(m).block(0),
1361 for (
unsigned int m = 0; m < MatrixSimple<MatrixType>::matrix.size();
1363 for (
unsigned int k = 0; k < n * n; ++k)
1365 const unsigned int row = info.matrix(k + m * n * n,
false).row;
1366 const unsigned int column =
1367 info.matrix(k + m * n * n,
false).column;
1370 assemble(info.matrix(k + m * n * n,
false).matrix,
1371 info.vector(m).block(row),
1373 info.indices_by_block[row]);
1375 assemble(info.matrix(k + m * n * n,
false).matrix,
1376 info.vector(m).block(row),
1378 info.indices_by_block[row],
1379 info.indices_by_block[column]);
1385 template <
typename MatrixType,
typename VectorType>
1386 template <
class DOFINFO>
1389 const DOFINFO &info2)
1394 info2.indices_by_block.size());
1396 const unsigned int n = info1.indices_by_block.size();
1400 for (
unsigned int m = 0; m < MatrixSimple<MatrixType>::matrix.size();
1403 assemble(info1.matrix(m,
false).matrix,
1404 info1.vector(m).block(0),
1407 assemble(info1.matrix(m,
true).matrix,
1408 info1.vector(m).block(0),
1412 assemble(info2.matrix(m,
false).matrix,
1413 info2.vector(m).block(0),
1416 assemble(info2.matrix(m,
true).matrix,
1417 info2.vector(m).block(0),
1425 for (
unsigned int m = 0; m < MatrixSimple<MatrixType>::matrix.size();
1427 for (
unsigned int k = 0; k < n * n; ++k)
1429 const unsigned int row = info1.matrix(k + m * n * n,
false).row;
1430 const unsigned int column =
1431 info1.matrix(k + m * n * n,
false).column;
1435 assemble(info1.matrix(k + m * n * n,
false).matrix,
1436 info1.vector(m).block(row),
1438 info1.indices_by_block[row]);
1439 assemble(info2.matrix(k + m * n * n,
false).matrix,
1440 info2.vector(m).block(row),
1442 info2.indices_by_block[row]);
1446 assemble(info1.matrix(k + m * n * n,
false).matrix,
1447 info1.vector(m).block(row),
1449 info1.indices_by_block[row],
1450 info1.indices_by_block[column]);
1451 assemble(info2.matrix(k + m * n * n,
false).matrix,
1452 info2.vector(m).block(row),
1454 info2.indices_by_block[row],
1455 info2.indices_by_block[column]);
1457 assemble(info1.matrix(k + m * n * n,
true).matrix,
1458 info1.vector(m).block(row),
1460 info1.indices_by_block[row],
1461 info2.indices_by_block[column]);
1462 assemble(info2.matrix(k + m * n * n,
true).matrix,
1463 info2.vector(m).block(row),
1465 info2.indices_by_block[row],
1466 info1.indices_by_block[column]);
1473 DEAL_II_NAMESPACE_CLOSE
SmartPointer< MGLevelObject< MatrixType >, MGMatrixSimple< MatrixType > > flux_down
static const unsigned int invalid_unsigned_int
void initialize_interfaces(MGLevelObject< MatrixType > &interface_in, MGLevelObject< MatrixType > &interface_out)
SystemSimple(double threshold=1.e-12)
#define AssertDimension(dim1, dim2)
std::vector< SmartPointer< MatrixType, MatrixSimple< MatrixType > > > matrix
void assemble_out(MatrixType &G, const FullMatrix< double > &M, const std::vector< types::global_dof_index > &i1, const std::vector< types::global_dof_index > &i2, const unsigned int level=numbers::invalid_unsigned_int)
void initialize(MGLevelObject< MatrixType > &m)
static ::ExceptionBase & ExcNotInitialized()
SmartPointer< MGLevelObject< MatrixType >, MGMatrixSimple< MatrixType > > matrix
SmartPointer< MGLevelObject< MatrixType >, MGMatrixSimple< MatrixType > > interface_out
void assemble_up(MatrixType &G, const FullMatrix< double > &M, const std::vector< types::global_dof_index > &i1, const std::vector< types::global_dof_index > &i2, const unsigned int level=numbers::invalid_unsigned_int)
void initialize_info(DOFINFO &info, bool face) const
void initialize(MatrixType &m, VectorType &rhs)
void assemble_in(MatrixType &G, const FullMatrix< double > &M, const std::vector< types::global_dof_index > &i1, const std::vector< types::global_dof_index > &i2, const unsigned int level=numbers::invalid_unsigned_int)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
void assemble(const DOFINFO &info)
void initialize_fluxes(MGLevelObject< MatrixType > &flux_up, MGLevelObject< MatrixType > &flux_down)
void initialize(AnyData &results)
MGMatrixSimple(double threshold=1.e-12)
SmartPointer< const AffineConstraints< typename VectorType::value_type >, ResidualSimple< VectorType > > constraints
void initialize_local_blocks(const BlockIndices &)
void assemble_down(MatrixType &G, const FullMatrix< double > &M, const std::vector< types::global_dof_index > &i1, const std::vector< types::global_dof_index > &i2, const unsigned int level=numbers::invalid_unsigned_int)
SmartPointer< MGLevelObject< MatrixType >, MGMatrixSimple< MatrixType > > interface_in
void add(type entry, const std::string &name)
Add a new data object.
SmartPointer< MGLevelObject< MatrixType >, MGMatrixSimple< MatrixType > > flux_up
void assemble(const DOFINFO &info)
void initialize_info(DOFINFO &info, bool face) const
void initialize_info(DOFINFO &info, bool face) const
void assemble(const DOFINFO &info)
void initialize(MatrixType &m)
SmartPointer< const AffineConstraints< typename MatrixType::value_type >, MatrixSimple< MatrixType > > constraints
MatrixSimple(double threshold=1.e-12)
void assemble(const DOFINFO &info)
void initialize_info(DOFINFO &info, bool face) const
static ::ExceptionBase & ExcInternalError()
SmartPointer< const MGConstrainedDoFs, MGMatrixSimple< MatrixType > > mg_constrained_dofs