17 #ifndef dealii_mesh_worker_assembler_h 18 #define dealii_mesh_worker_assembler_h 20 #include <deal.II/base/smartpointer.h> 21 #include <deal.II/base/mg_level_object.h> 22 #include <deal.II/lac/block_vector.h> 23 #include <deal.II/meshworker/dof_info.h> 24 #include <deal.II/meshworker/functional.h> 25 #include <deal.II/meshworker/simple.h> 26 #include <deal.II/multigrid/mg_constrained_dofs.h> 27 #include <deal.II/algorithms/any_data.h> 30 DEAL_II_NAMESPACE_OPEN
106 template <
typename VectorType>
126 template <
class DOFINFO>
133 template <
class DOFINFO>
139 template <
class DOFINFO>
141 const DOFINFO &info2);
148 const std::vector<types::global_dof_index> &dof);
195 template <
typename MatrixType,
typename number =
double>
223 template <
class DOFINFO>
230 template <
class DOFINFO>
236 template <
class DOFINFO>
238 const DOFINFO &info2);
246 const unsigned int block_row,
247 const unsigned int block_col,
248 const std::vector<types::global_dof_index> &dof1,
249 const std::vector<types::global_dof_index> &dof2);
301 template <
typename MatrixType,
typename number =
double>
347 template <
class DOFINFO>
354 template <
class DOFINFO>
360 template <
class DOFINFO>
362 const DOFINFO &info2);
370 const unsigned int block_row,
371 const unsigned int block_col,
372 const std::vector<types::global_dof_index> &dof1,
373 const std::vector<types::global_dof_index> &dof2,
374 const unsigned int level1,
375 const unsigned int level2,
383 const unsigned int block_row,
384 const unsigned int block_col,
385 const std::vector<types::global_dof_index> &dof1,
386 const std::vector<types::global_dof_index> &dof2,
387 const unsigned int level1,
388 const unsigned int level2);
395 const unsigned int block_row,
396 const unsigned int block_col,
397 const std::vector<types::global_dof_index> &dof1,
398 const std::vector<types::global_dof_index> &dof2,
399 const unsigned int level1,
400 const unsigned int level2);
407 const unsigned int block_row,
408 const unsigned int block_col,
409 const std::vector<types::global_dof_index> &dof1,
410 const std::vector<types::global_dof_index> &dof2,
411 const unsigned int level1,
412 const unsigned int level2);
419 const unsigned int block_row,
420 const unsigned int block_col,
421 const std::vector<types::global_dof_index> &dof1,
422 const std::vector<types::global_dof_index> &dof2,
423 const unsigned int level1,
424 const unsigned int level2);
431 const unsigned int block_row,
432 const unsigned int block_col,
433 const std::vector<types::global_dof_index> &dof1,
434 const std::vector<types::global_dof_index> &dof2,
435 const unsigned int level1,
436 const unsigned int level2);
489 template <
typename VectorType>
498 template <
typename VectorType>
507 template <
typename VectorType>
508 template <
class DOFINFO>
511 (DOFINFO &info,
bool)
const 513 info.initialize_vectors(residuals.size());
516 template <
typename VectorType>
521 const std::vector<types::global_dof_index> &dof)
523 if (constraints == 0)
525 for (
unsigned int b=0; b<local.
n_blocks(); ++b)
526 for (
unsigned int j=0; j<local.
block(b).size(); ++j)
536 const unsigned int jcell = this->block_info->local().local_to_global(b, j);
537 global(dof[jcell]) += local.
block(b)(j);
541 constraints->distribute_local_to_global(local, dof, global);
545 template <
typename VectorType>
546 template <
class DOFINFO>
549 (
const DOFINFO &info)
551 for (
unsigned int i=0; i<residuals.size(); ++i)
552 assemble(*(residuals.entry<VectorType>(i)), info.vector(i), info.indices);
556 template <
typename VectorType>
557 template <
class DOFINFO>
560 (
const DOFINFO &info1,
561 const DOFINFO &info2)
563 for (
unsigned int i=0; i<residuals.size(); ++i)
565 assemble(*(residuals.entry<VectorType>(i)), info1.vector(i), info1.indices);
566 assemble(*(residuals.entry<VectorType>(i)), info2.vector(i), info2.indices);
573 template <
typename MatrixType,
typename number>
582 template <
typename MatrixType,
typename number>
594 template <
typename MatrixType,
typename number>
604 template <
typename MatrixType,
typename number>
605 template <
class DOFINFO>
611 info.initialize_matrices(*matrices, face);
616 template <
typename MatrixType,
typename number>
621 const unsigned int block_row,
622 const unsigned int block_col,
623 const std::vector<types::global_dof_index> &dof1,
624 const std::vector<types::global_dof_index> &dof2)
626 if (constraints ==
nullptr)
628 for (
unsigned int j=0; j<local.n_rows(); ++j)
629 for (
unsigned int k=0; k<local.n_cols(); ++k)
630 if (std::fabs(local(j,k)) >= threshold)
640 const unsigned int jcell = this->block_info->local().local_to_global(block_row, j);
641 const unsigned int kcell = this->block_info->local().local_to_global(block_col, k);
643 global.
add(dof1[jcell], dof2[kcell], local(j,k));
649 std::vector<types::global_dof_index> sliced_row_indices (bi.
block_size(block_row));
650 for (
unsigned int i=0; i<sliced_row_indices.size(); ++i)
651 sliced_row_indices[i] = dof1[bi.
block_start(block_row)+i];
653 std::vector<types::global_dof_index> sliced_col_indices (bi.
block_size(block_col));
654 for (
unsigned int i=0; i<sliced_col_indices.size(); ++i)
655 sliced_col_indices[i] = dof2[bi.
block_start(block_col)+i];
657 constraints->distribute_local_to_global(local,
658 sliced_row_indices, sliced_col_indices, global);
663 template <
typename MatrixType,
typename number>
664 template <
class DOFINFO>
668 for (
unsigned int i=0; i<matrices->size(); ++i)
675 assemble(matrices->block(i), info.matrix(i,
false).matrix, row, col, info.indices, info.indices);
680 template <
typename MatrixType,
typename number>
681 template <
class DOFINFO>
684 const DOFINFO &info2)
686 for (
unsigned int i=0; i<matrices->size(); ++i)
693 assemble(matrices->block(i), info1.matrix(i,
false).matrix, row, col, info1.indices, info1.indices);
694 assemble(matrices->block(i), info1.matrix(i,
true).matrix, row, col, info1.indices, info2.indices);
695 assemble(matrices->block(i), info2.matrix(i,
false).matrix, row, col, info2.indices, info2.indices);
696 assemble(matrices->block(i), info2.matrix(i,
true).matrix, row, col, info2.indices, info1.indices);
703 template <
typename MatrixType,
typename number>
712 template <
typename MatrixType,
typename number>
719 AssertDimension(block_info->local().size(), block_info->global().size());
724 template <
typename MatrixType,
typename number>
729 mg_constrained_dofs = &mg_c;
733 template <
typename MatrixType,
typename number>
734 template <
class DOFINFO>
740 info.initialize_matrices(*matrices, face);
745 template <
typename MatrixType,
typename number>
756 template <
typename MatrixType,
typename number>
767 template <
typename MatrixType,
typename number>
772 const unsigned int block_row,
773 const unsigned int block_col,
774 const std::vector<types::global_dof_index> &dof1,
775 const std::vector<types::global_dof_index> &dof2,
776 const unsigned int level1,
777 const unsigned int level2,
780 for (
unsigned int j=0; j<local.n_rows(); ++j)
781 for (
unsigned int k=0; k<local.n_cols(); ++k)
782 if (std::fabs(local(j,k)) >= threshold)
792 const unsigned int jcell = this->block_info->local().local_to_global(block_row, j);
793 const unsigned int kcell = this->block_info->local().local_to_global(block_col, k);
803 const unsigned int jglobal = this->block_info->level(level1).global_to_local(dof1[jcell]).second;
804 const unsigned int kglobal = this->block_info->level(level2).global_to_local(dof2[kcell]).second;
806 if (mg_constrained_dofs == 0)
809 global.add(kglobal, jglobal, local(j,k));
811 global.add(jglobal, kglobal, local(j,k));
815 if (!mg_constrained_dofs->at_refinement_edge(level1, jglobal) &&
816 !mg_constrained_dofs->at_refinement_edge(level2, kglobal))
818 if (mg_constrained_dofs->set_boundary_values())
820 if ((!mg_constrained_dofs->is_boundary_index(level1, jglobal) &&
821 !mg_constrained_dofs->is_boundary_index(level2, kglobal))
823 (mg_constrained_dofs->is_boundary_index(level1, jglobal) &&
824 mg_constrained_dofs->is_boundary_index(level2, kglobal) &&
828 global.add(kglobal, jglobal, local(j,k));
830 global.add(jglobal, kglobal, local(j,k));
836 global.add(kglobal, jglobal, local(j,k));
838 global.add(jglobal, kglobal, local(j,k));
846 template <
typename MatrixType,
typename number>
851 const unsigned int block_row,
852 const unsigned int block_col,
853 const std::vector<types::global_dof_index> &dof1,
854 const std::vector<types::global_dof_index> &dof2,
855 const unsigned int level1,
856 const unsigned int level2)
858 for (
unsigned int j=0; j<local.n_rows(); ++j)
859 for (
unsigned int k=0; k<local.n_cols(); ++k)
860 if (std::fabs(local(j,k)) >= threshold)
870 const unsigned int jcell = this->block_info->local().local_to_global(block_row, j);
871 const unsigned int kcell = this->block_info->local().local_to_global(block_col, k);
881 const unsigned int jglobal = this->block_info->level(level1).global_to_local(dof1[jcell]).second;
882 const unsigned int kglobal = this->block_info->level(level2).global_to_local(dof2[kcell]).second;
884 if (mg_constrained_dofs == 0)
885 global.add(jglobal, kglobal, local(j,k));
888 if (!mg_constrained_dofs->non_refinement_edge_index(level1, jglobal) &&
889 !mg_constrained_dofs->non_refinement_edge_index(level2, kglobal))
891 if (!mg_constrained_dofs->at_refinement_edge(level1, jglobal) &&
892 !mg_constrained_dofs->at_refinement_edge(level2, kglobal))
893 global.add(jglobal, kglobal, local(j,k));
899 template <
typename MatrixType,
typename number>
904 const unsigned int block_row,
905 const unsigned int block_col,
906 const std::vector<types::global_dof_index> &dof1,
907 const std::vector<types::global_dof_index> &dof2,
908 const unsigned int level1,
909 const unsigned int level2)
911 for (
unsigned int j=0; j<local.n_rows(); ++j)
912 for (
unsigned int k=0; k<local.n_cols(); ++k)
913 if (std::fabs(local(j,k)) >= threshold)
923 const unsigned int jcell = this->block_info->local().local_to_global(block_row, j);
924 const unsigned int kcell = this->block_info->local().local_to_global(block_col, k);
934 const unsigned int jglobal = this->block_info->level(level1).global_to_local(dof1[jcell]).second;
935 const unsigned int kglobal = this->block_info->level(level2).global_to_local(dof2[kcell]).second;
937 if (mg_constrained_dofs == 0)
938 global.add(jglobal, kglobal, local(j,k));
941 if (!mg_constrained_dofs->non_refinement_edge_index(level1, jglobal) &&
942 !mg_constrained_dofs->non_refinement_edge_index(level2, kglobal))
944 if (!mg_constrained_dofs->at_refinement_edge(level1, jglobal) &&
945 !mg_constrained_dofs->at_refinement_edge(level2, kglobal))
946 global.add(jglobal, kglobal, local(j,k));
952 template <
typename MatrixType,
typename number>
957 const unsigned int block_row,
958 const unsigned int block_col,
959 const std::vector<types::global_dof_index> &dof1,
960 const std::vector<types::global_dof_index> &dof2,
961 const unsigned int level1,
962 const unsigned int level2)
964 for (
unsigned int j=0; j<local.n_rows(); ++j)
965 for (
unsigned int k=0; k<local.n_cols(); ++k)
966 if (std::fabs(local(k,j)) >= threshold)
976 const unsigned int jcell = this->block_info->local().local_to_global(block_row, j);
977 const unsigned int kcell = this->block_info->local().local_to_global(block_col, k);
987 const unsigned int jglobal = this->block_info->level(level1).global_to_local(dof1[jcell]).second;
988 const unsigned int kglobal = this->block_info->level(level2).global_to_local(dof2[kcell]).second;
990 if (mg_constrained_dofs == 0)
991 global.add(jglobal, kglobal, local(k,j));
994 if (!mg_constrained_dofs->non_refinement_edge_index(level1, jglobal) &&
995 !mg_constrained_dofs->non_refinement_edge_index(level2, kglobal))
997 if (!mg_constrained_dofs->at_refinement_edge(level1, jglobal) &&
998 !mg_constrained_dofs->at_refinement_edge(level2, kglobal))
999 global.add(jglobal, kglobal, local(k,j));
1005 template <
typename MatrixType,
typename number>
1008 (MatrixType &global,
1010 const unsigned int block_row,
1011 const unsigned int block_col,
1012 const std::vector<types::global_dof_index> &dof1,
1013 const std::vector<types::global_dof_index> &dof2,
1014 const unsigned int level1,
1015 const unsigned int level2)
1020 for (
unsigned int j=0; j<local.n_rows(); ++j)
1021 for (
unsigned int k=0; k<local.n_cols(); ++k)
1022 if (std::fabs(local(j,k)) >= threshold)
1032 const unsigned int jcell = this->block_info->local().local_to_global(block_row, j);
1033 const unsigned int kcell = this->block_info->local().local_to_global(block_col, k);
1043 const unsigned int jglobal = this->block_info->level(level1).global_to_local(dof1[jcell]).second;
1044 const unsigned int kglobal = this->block_info->level(level2).global_to_local(dof2[kcell]).second;
1046 if (mg_constrained_dofs == 0)
1047 global.add(jglobal, kglobal, local(j,k));
1050 if (mg_constrained_dofs->at_refinement_edge(level1, jglobal) &&
1051 !mg_constrained_dofs->at_refinement_edge(level2, kglobal))
1053 if (mg_constrained_dofs->set_boundary_values())
1055 if ((!mg_constrained_dofs->is_boundary_index(level1, jglobal) &&
1056 !mg_constrained_dofs->is_boundary_index(level2, kglobal))
1058 (mg_constrained_dofs->is_boundary_index(level1, jglobal) &&
1059 mg_constrained_dofs->is_boundary_index(level2, kglobal) &&
1060 jglobal == kglobal))
1061 global.add(jglobal, kglobal, local(j,k));
1064 global.add(jglobal, kglobal, local(j,k));
1070 template <
typename MatrixType,
typename number>
1073 (MatrixType &global,
1075 const unsigned int block_row,
1076 const unsigned int block_col,
1077 const std::vector<types::global_dof_index> &dof1,
1078 const std::vector<types::global_dof_index> &dof2,
1079 const unsigned int level1,
1080 const unsigned int level2)
1085 for (
unsigned int j=0; j<local.n_rows(); ++j)
1086 for (
unsigned int k=0; k<local.n_cols(); ++k)
1087 if (std::fabs(local(k,j)) >= threshold)
1097 const unsigned int jcell = this->block_info->local().local_to_global(block_row, j);
1098 const unsigned int kcell = this->block_info->local().local_to_global(block_col, k);
1108 const unsigned int jglobal = this->block_info->level(level1).global_to_local(dof1[jcell]).second;
1109 const unsigned int kglobal = this->block_info->level(level2).global_to_local(dof2[kcell]).second;
1111 if (mg_constrained_dofs == 0)
1112 global.add(jglobal, kglobal, local(k,j));
1115 if (mg_constrained_dofs->at_refinement_edge(level1, jglobal) &&
1116 !mg_constrained_dofs->at_refinement_edge(level2, kglobal))
1118 if (mg_constrained_dofs->set_boundary_values())
1120 if ((!mg_constrained_dofs->is_boundary_index(level1, jglobal) &&
1121 !mg_constrained_dofs->is_boundary_index(level2, kglobal))
1123 (mg_constrained_dofs->is_boundary_index(level1, jglobal) &&
1124 mg_constrained_dofs->is_boundary_index(level2, kglobal) &&
1125 jglobal == kglobal))
1126 global.add(jglobal, kglobal, local(k,j));
1129 global.add(jglobal, kglobal, local(k,j));
1136 template <
typename MatrixType,
typename number>
1137 template <
class DOFINFO>
1141 const unsigned int level = info.cell->level();
1143 for (
unsigned int i=0; i<matrices->size(); ++i)
1147 const unsigned int row = matrices->block(i)[level].row;
1148 const unsigned int col = matrices->block(i)[level].column;
1150 assemble(matrices->block(i)[level].matrix, info.matrix(i,
false).matrix, row, col,
1151 info.indices, info.indices, level, level);
1152 if (mg_constrained_dofs != 0)
1154 if (interface_in != 0)
1155 assemble_in(interface_in->block(i)[level], info.matrix(i,
false).matrix, row, col,
1156 info.indices, info.indices, level, level);
1157 if (interface_out != 0)
1158 assemble_in(interface_out->block(i)[level], info.matrix(i,
false).matrix, row, col,
1159 info.indices, info.indices, level, level);
1161 assemble_in(matrices->block_in(i)[level], info.matrix(i,
false).matrix, row, col,
1162 info.indices, info.indices, level, level);
1163 assemble_out(matrices->block_out(i)[level], info.matrix(i,
false).matrix, row, col,
1164 info.indices, info.indices, level, level);
1170 template <
typename MatrixType,
typename number>
1171 template <
class DOFINFO>
1174 (
const DOFINFO &info1,
1175 const DOFINFO &info2)
1177 const unsigned int level1 = info1.cell->level();
1178 const unsigned int level2 = info2.cell->level();
1180 for (
unsigned int i=0; i<matrices->size(); ++i)
1186 const unsigned int row = o[level1].row;
1187 const unsigned int col = o[level1].column;
1189 if (level1 == level2)
1191 if (mg_constrained_dofs == 0)
1193 assemble(o[level1].matrix, info1.matrix(i,
false).matrix, row, col,
1194 info1.indices, info1.indices, level1, level1);
1195 assemble(o[level1].matrix, info1.matrix(i,
true).matrix, row, col,
1196 info1.indices, info2.indices, level1, level2);
1197 assemble(o[level1].matrix, info2.matrix(i,
false).matrix, row, col,
1198 info2.indices, info2.indices, level2, level2);
1199 assemble(o[level1].matrix, info2.matrix(i,
true).matrix, row, col,
1200 info2.indices, info1.indices, level2, level1);
1204 assemble_fluxes(o[level1].matrix, info1.matrix(i,
false).matrix, row, col,
1205 info1.indices, info1.indices, level1, level1);
1206 assemble_fluxes(o[level1].matrix, info1.matrix(i,
true).matrix, row, col,
1207 info1.indices, info2.indices, level1, level2);
1208 assemble_fluxes(o[level1].matrix, info2.matrix(i,
false).matrix, row, col,
1209 info2.indices, info2.indices, level2, level2);
1210 assemble_fluxes(o[level1].matrix, info2.matrix(i,
true).matrix, row, col,
1211 info2.indices, info1.indices, level2, level1);
1217 if (flux_up->size() != 0)
1222 assemble_fluxes(o[level1].matrix, info1.matrix(i,
false).matrix, row, col,
1223 info1.indices, info1.indices, level1, level1);
1224 assemble_up(flux_up->block(i)[level1].matrix, info1.matrix(i,
true).matrix, row, col,
1225 info1.indices, info2.indices, level1, level2);
1226 assemble_down(flux_down->block(i)[level1].matrix, info2.matrix(i,
true).matrix, row, col,
1227 info2.indices, info1.indices, level2, level1);
1235 DEAL_II_NAMESPACE_CLOSE
SmartPointer< const BlockInfo, MatrixLocalBlocksToGlobalBlocks< MatrixType, number > > block_info
MatrixPtrVectorPtr interface_out
void assemble_down(MatrixType &global, const FullMatrix< number > &local, const unsigned int block_row, const unsigned int block_col, const std::vector< types::global_dof_index > &dof1, const std::vector< types::global_dof_index > &dof2, const unsigned int level1, const unsigned int level2)
#define AssertDimension(dim1, dim2)
void initialize_edge_flux(MatrixPtrVector &up, MatrixPtrVector &down)
void initialize(const BlockInfo *block_info, AnyData &residuals)
void initialize_info(DOFINFO &info, bool face) const
void add(const size_type i, const size_type j, const typename MatrixType::value_type value)
MGMatrixLocalBlocksToGlobalBlocks(double threshold=1.e-12)
size_type block_size(const unsigned int i) const
void initialize_info(DOFINFO &info, bool face) const
SmartPointer< const ConstraintMatrix, MatrixLocalBlocksToGlobalBlocks< MatrixType, number > > constraints
SmartPointer< const MGConstrainedDoFs, MGMatrixLocalBlocksToGlobalBlocks< MatrixType, number > > mg_constrained_dofs
unsigned int global_dof_index
MatrixPtrVectorPtr flux_up
#define Assert(cond, exc)
void assemble_fluxes(MatrixType &global, const FullMatrix< number > &local, const unsigned int block_row, const unsigned int block_col, const std::vector< types::global_dof_index > &dof1, const std::vector< types::global_dof_index > &dof2, const unsigned int level1, const unsigned int level2)
SmartPointer< const BlockInfo, MGMatrixLocalBlocksToGlobalBlocks< MatrixType, number > > block_info
void assemble(const DOFINFO &info)
MatrixPtrVectorPtr flux_down
SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
void initialize(const BlockInfo *block_info, MatrixBlockVector< MatrixType > &matrices)
SmartPointer< const BlockInfo, ResidualLocalBlocksToGlobalBlocks< VectorType > > block_info
void assemble_out(MatrixType &global, const FullMatrix< number > &local, const unsigned int block_row, const unsigned int block_col, const std::vector< types::global_dof_index > &dof1, const std::vector< types::global_dof_index > &dof2, const unsigned int level1, const unsigned int level2)
unsigned int n_blocks() const
void initialize_interfaces(MatrixPtrVector &interface_in, MatrixPtrVector &interface_out)
SmartPointer< const ConstraintMatrix, ResidualLocalBlocksToGlobalBlocks< VectorType > > constraints
void assemble_up(MatrixType &global, const FullMatrix< number > &local, const unsigned int block_row, const unsigned int block_col, const std::vector< types::global_dof_index > &dof1, const std::vector< types::global_dof_index > &dof2, const unsigned int level1, const unsigned int level2)
void assemble(const DOFINFO &info)
size_type block_start(const unsigned int i) const
A small class collecting the different BlockIndices involved in global, multilevel and local computat...
void assemble(const DOFINFO &info)
static ::ExceptionBase & ExcNotImplemented()
MatrixPtrVectorPtr interface_in
SmartPointer< MatrixBlockVector< MatrixType >, MatrixLocalBlocksToGlobalBlocks< MatrixType, number > > matrices
BlockType & block(const unsigned int i)
void initialize_info(DOFINFO &info, bool face) const
MatrixLocalBlocksToGlobalBlocks(double threshold=1.e-12)
MatrixPtrVectorPtr matrices
void initialize(const BlockInfo *block_info, MatrixPtrVector &matrices)
void assemble_in(MatrixType &global, const FullMatrix< number > &local, const unsigned int block_row, const unsigned int block_col, const std::vector< types::global_dof_index > &dof1, const std::vector< types::global_dof_index > &dof2, const unsigned int level1, const unsigned int level2)