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
simple.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) 2011 - 2024 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
14#ifndef dealii_mesh_worker_simple_h
15#define dealii_mesh_worker_simple_h
16
17#include <deal.II/base/config.h>
18
20
23
25
28
30
31/*
32 * The header containing the classes MeshWorker::Assembler::MatrixSimple,
33 * MeshWorker::Assembler::MGMatrixSimple, MeshWorker::Assembler::ResidualSimple,
34 * and MeshWorker::Assembler::SystemSimple.
35 */
36
38
39namespace MeshWorker
40{
41 namespace Assembler
42 {
55 template <typename VectorType>
57 {
58 public:
65 void
66 initialize(AnyData &results);
67
71 void
72 initialize(
74
82 template <class DOFINFO>
83 void
84 initialize_info(DOFINFO &info, bool face) const;
85
92 template <class DOFINFO>
93 void
94 assemble(const DOFINFO &info);
95
99 template <class DOFINFO>
100 void
101 assemble(const DOFINFO &info1, const DOFINFO &info2);
102
103 protected:
108
115 };
116
117
148 template <typename MatrixType>
150 {
151 public:
156 MatrixSimple(double threshold = 1.e-12);
157
161 void
162 initialize(MatrixType &m);
163
167 void
168 initialize(std::vector<MatrixType> &m);
169
177 void
178 initialize(
180
188 template <class DOFINFO>
189 void
190 initialize_info(DOFINFO &info, bool face) const;
191
196 template <class DOFINFO>
197 void
198 assemble(const DOFINFO &info);
199
204 template <class DOFINFO>
205 void
206 assemble(const DOFINFO &info1, const DOFINFO &info2);
207
208 protected:
212 std::vector<ObserverPointer<MatrixType, MatrixSimple<MatrixType>>> matrix;
213
219 const double threshold;
220
221 private:
226 void
227 assemble(const FullMatrix<double> &M,
228 const unsigned int index,
229 const std::vector<types::global_dof_index> &i1,
230 const std::vector<types::global_dof_index> &i2);
231
238 };
239
240
250 template <typename MatrixType>
252 {
253 public:
258 MGMatrixSimple(double threshold = 1.e-12);
259
263 void
264 initialize(MGLevelObject<MatrixType> &m);
265
269 void
270 initialize(const MGConstrainedDoFs &mg_constrained_dofs);
271
276 void
277 initialize_fluxes(MGLevelObject<MatrixType> &flux_up,
278 MGLevelObject<MatrixType> &flux_down);
279
284 void
285 initialize_interfaces(MGLevelObject<MatrixType> &interface_in,
286 MGLevelObject<MatrixType> &interface_out);
294 template <class DOFINFO>
295 void
296 initialize_info(DOFINFO &info, bool face) const;
297
301 template <class DOFINFO>
302 void
303 assemble(const DOFINFO &info);
304
309 template <class DOFINFO>
310 void
311 assemble(const DOFINFO &info1, const DOFINFO &info2);
312
313 private:
317 void
318 assemble(MatrixType &G,
319 const FullMatrix<double> &M,
320 const std::vector<types::global_dof_index> &i1,
321 const std::vector<types::global_dof_index> &i2);
322
326 void
327 assemble(MatrixType &G,
328 const FullMatrix<double> &M,
329 const std::vector<types::global_dof_index> &i1,
330 const std::vector<types::global_dof_index> &i2,
331 const unsigned int level);
332
337 void
338 assemble_up(MatrixType &G,
339 const FullMatrix<double> &M,
340 const std::vector<types::global_dof_index> &i1,
341 const std::vector<types::global_dof_index> &i2,
342 const unsigned int level = numbers::invalid_unsigned_int);
347 void
348 assemble_down(MatrixType &G,
349 const FullMatrix<double> &M,
350 const std::vector<types::global_dof_index> &i1,
351 const std::vector<types::global_dof_index> &i2,
352 const unsigned int level = numbers::invalid_unsigned_int);
353
358 void
359 assemble_in(MatrixType &G,
360 const FullMatrix<double> &M,
361 const std::vector<types::global_dof_index> &i1,
362 const std::vector<types::global_dof_index> &i2,
363 const unsigned int level = numbers::invalid_unsigned_int);
364
369 void
370 assemble_out(MatrixType &G,
371 const FullMatrix<double> &M,
372 const std::vector<types::global_dof_index> &i1,
373 const std::vector<types::global_dof_index> &i2,
374 const unsigned int level = numbers::invalid_unsigned_int);
375
381
388
395
402
414
420 const double threshold;
421 };
422
423
433 template <typename MatrixType, typename VectorType>
434 class DEAL_II_DEPRECATED SystemSimple : private MatrixSimple<MatrixType>,
435 private ResidualSimple<VectorType>
436 {
437 public:
441 SystemSimple(double threshold = 1.e-12);
442
446 void
447 initialize(MatrixType &m, VectorType &rhs);
448
456 void
457 initialize(
459
467 template <class DOFINFO>
468 void
469 initialize_info(DOFINFO &info, bool face) const;
470
474 template <class DOFINFO>
475 void
476 assemble(const DOFINFO &info);
477
482 template <class DOFINFO>
483 void
484 assemble(const DOFINFO &info1, const DOFINFO &info2);
485
486 private:
491 void
492 assemble(const FullMatrix<double> &M,
493 const Vector<double> &vector,
494 const unsigned int index,
495 const std::vector<types::global_dof_index> &indices);
496
497 void
498 assemble(const FullMatrix<double> &M,
499 const Vector<double> &vector,
500 const unsigned int index,
501 const std::vector<types::global_dof_index> &i1,
502 const std::vector<types::global_dof_index> &i2);
503 };
504
505
506 //----------------------------------------------------------------------//
507
508 template <typename VectorType>
509 inline void
511 {
512 residuals = results;
513 }
514
515
516
517 template <typename VectorType>
518 inline void
524
525
526
527 template <typename VectorType>
528 template <class DOFINFO>
529 inline void
531 {
532 info.initialize_vectors(residuals.size());
533 }
534
535
536
537 template <typename VectorType>
538 template <class DOFINFO>
539 inline void
541 {
542 for (unsigned int k = 0; k < residuals.size(); ++k)
543 {
544 VectorType *v = residuals.entry<VectorType *>(k);
545 for (unsigned int i = 0; i != info.vector(k).n_blocks(); ++i)
546 {
547 const std::vector<types::global_dof_index> &ldi =
548 info.vector(k).n_blocks() == 1 ? info.indices :
549 info.indices_by_block[i];
550
551 if (constraints != nullptr)
552 constraints->distribute_local_to_global(info.vector(k).block(i),
553 ldi,
554 *v);
555 else
556 v->add(ldi, info.vector(k).block(i));
557 }
558 }
559 }
560
561 template <typename VectorType>
562 template <class DOFINFO>
563 inline void
565 const DOFINFO &info2)
566 {
567 assemble(info1);
568 assemble(info2);
569 }
570
571
572 //----------------------------------------------------------------------//
573
574 template <typename MatrixType>
576 : threshold(threshold)
577 {}
578
579
580 template <typename MatrixType>
581 inline void
583 {
584 matrix.resize(1);
585 matrix[0] = &m;
586 }
587
588
589 template <typename MatrixType>
590 inline void
591 MatrixSimple<MatrixType>::initialize(std::vector<MatrixType> &m)
592 {
593 matrix.resize(m.size());
594 for (unsigned int i = 0; i < m.size(); ++i)
595 matrix[i] = &m[i];
596 }
597
598
599 template <typename MatrixType>
600 inline void
606
607
608 template <typename MatrixType>
609 template <class DOFINFO>
610 inline void
611 MatrixSimple<MatrixType>::initialize_info(DOFINFO &info, bool face) const
612 {
613 Assert(matrix.size() != 0, ExcNotInitialized());
614
615 const unsigned int n = info.indices_by_block.size();
616
617 if (n == 0)
618 info.initialize_matrices(matrix.size(), face);
619 else
620 {
621 info.initialize_matrices(matrix.size() * n * n, face);
622 unsigned int k = 0;
623 for (unsigned int m = 0; m < matrix.size(); ++m)
624 for (unsigned int i = 0; i < n; ++i)
625 for (unsigned int j = 0; j < n; ++j, ++k)
626 {
627 info.matrix(k, false).row = i;
628 info.matrix(k, false).column = j;
629 if (face)
630 {
631 info.matrix(k, true).row = i;
632 info.matrix(k, true).column = j;
633 }
634 }
635 }
636 }
637
638
639
640 template <typename MatrixType>
641 inline void
643 const FullMatrix<double> &M,
644 const unsigned int index,
645 const std::vector<types::global_dof_index> &i1,
646 const std::vector<types::global_dof_index> &i2)
647 {
648 AssertDimension(M.m(), i1.size());
649 AssertDimension(M.n(), i2.size());
650
651 if (constraints == nullptr)
652 {
653 for (unsigned int j = 0; j < i1.size(); ++j)
654 for (unsigned int k = 0; k < i2.size(); ++k)
655 if (std::fabs(M(j, k)) >= threshold)
656 matrix[index]->add(i1[j], i2[k], M(j, k));
657 }
658 else
659 constraints->distribute_local_to_global(M, i1, i2, *matrix[index]);
660 }
661
662
663 template <typename MatrixType>
664 template <class DOFINFO>
665 inline void
667 {
668 Assert(!info.level_cell, ExcMessage("Cell may not access level dofs"));
669 const unsigned int n = info.indices_by_block.size();
670
671 if (n == 0)
672 for (unsigned int m = 0; m < matrix.size(); ++m)
673 assemble(info.matrix(m, false).matrix, m, info.indices, info.indices);
674 else
675 {
676 for (unsigned int m = 0; m < matrix.size(); ++m)
677 for (unsigned int k = 0; k < n * n; ++k)
678 {
679 assemble(
680 info.matrix(k + m * n * n, false).matrix,
681 m,
682 info.indices_by_block[info.matrix(k + m * n * n, false).row],
683 info.indices_by_block[info.matrix(k + m * n * n, false)
684 .column]);
685 }
686 }
687 }
688
689
690 template <typename MatrixType>
691 template <class DOFINFO>
692 inline void
694 const DOFINFO &info2)
695 {
696 Assert(!info1.level_cell, ExcMessage("Cell may not access level dofs"));
697 Assert(!info2.level_cell, ExcMessage("Cell may not access level dofs"));
698 AssertDimension(info1.indices_by_block.size(),
699 info2.indices_by_block.size());
700
701 const unsigned int n = info1.indices_by_block.size();
702
703 if (n == 0)
704 {
705 for (unsigned int m = 0; m < matrix.size(); ++m)
706 {
707 assemble(info1.matrix(m, false).matrix,
708 m,
709 info1.indices,
710 info1.indices);
711 assemble(info1.matrix(m, true).matrix,
712 m,
713 info1.indices,
714 info2.indices);
715 assemble(info2.matrix(m, false).matrix,
716 m,
717 info2.indices,
718 info2.indices);
719 assemble(info2.matrix(m, true).matrix,
720 m,
721 info2.indices,
722 info1.indices);
723 }
724 }
725 else
726 {
727 for (unsigned int m = 0; m < matrix.size(); ++m)
728 for (unsigned int k = 0; k < n * n; ++k)
729 {
730 const unsigned int row = info1.matrix(k + m * n * n, false).row;
731 const unsigned int column =
732 info1.matrix(k + m * n * n, false).column;
733
734 assemble(info1.matrix(k + m * n * n, false).matrix,
735 m,
736 info1.indices_by_block[row],
737 info1.indices_by_block[column]);
738 assemble(info1.matrix(k + m * n * n, true).matrix,
739 m,
740 info1.indices_by_block[row],
741 info2.indices_by_block[column]);
742 assemble(info2.matrix(k + m * n * n, false).matrix,
743 m,
744 info2.indices_by_block[row],
745 info2.indices_by_block[column]);
746 assemble(info2.matrix(k + m * n * n, true).matrix,
747 m,
748 info2.indices_by_block[row],
749 info1.indices_by_block[column]);
750 }
751 }
752 }
753
754
755 //----------------------------------------------------------------------//
756
757 template <typename MatrixType>
759 : threshold(threshold)
760 {}
761
762
763 template <typename MatrixType>
764 inline void
769
770 template <typename MatrixType>
771 inline void
773 {
774 mg_constrained_dofs = &c;
775 }
776
777
778 template <typename MatrixType>
779 inline void
783 {
784 flux_up = &up;
785 flux_down = &down;
786 }
787
788
789 template <typename MatrixType>
790 inline void
794 {
795 interface_in = &in;
796 interface_out = &out;
797 }
798
799
800 template <typename MatrixType>
801 template <class DOFINFO>
802 inline void
803 MGMatrixSimple<MatrixType>::initialize_info(DOFINFO &info, bool face) const
804 {
805 const unsigned int n = info.indices_by_block.size();
806
807 if (n == 0)
808 info.initialize_matrices(1, face);
809 else
810 {
811 info.initialize_matrices(n * n, face);
812 unsigned int k = 0;
813 for (unsigned int i = 0; i < n; ++i)
814 for (unsigned int j = 0; j < n; ++j, ++k)
815 {
816 info.matrix(k, false).row = i;
817 info.matrix(k, false).column = j;
818 if (face)
819 {
820 info.matrix(k, true).row = i;
821 info.matrix(k, true).column = j;
822 }
823 }
824 }
825 }
826
827
828 template <typename MatrixType>
829 inline void
831 MatrixType &G,
832 const FullMatrix<double> &M,
833 const std::vector<types::global_dof_index> &i1,
834 const std::vector<types::global_dof_index> &i2)
835 {
836 AssertDimension(M.m(), i1.size());
837 AssertDimension(M.n(), i2.size());
838 Assert(mg_constrained_dofs == 0, ExcInternalError());
839 // TODO: Possibly remove this function all together
840
841 for (unsigned int j = 0; j < i1.size(); ++j)
842 for (unsigned int k = 0; k < i2.size(); ++k)
843 if (std::fabs(M(j, k)) >= threshold)
844 G.add(i1[j], i2[k], M(j, k));
845 }
846
847
848 template <typename MatrixType>
849 inline void
851 MatrixType &G,
852 const FullMatrix<double> &M,
853 const std::vector<types::global_dof_index> &i1,
854 const std::vector<types::global_dof_index> &i2,
855 const unsigned int level)
856 {
857 AssertDimension(M.m(), i1.size());
858 AssertDimension(M.n(), i2.size());
859
860 if (mg_constrained_dofs == nullptr)
861 {
862 for (unsigned int j = 0; j < i1.size(); ++j)
863 for (unsigned int k = 0; k < i2.size(); ++k)
864 if (std::fabs(M(j, k)) >= threshold)
865 G.add(i1[j], i2[k], M(j, k));
866 }
867 else
868 {
869 for (unsigned int j = 0; j < i1.size(); ++j)
870 for (unsigned int k = 0; k < i2.size(); ++k)
871 {
872 // Only enter the local values into the global matrix,
873 // if the value is larger than the threshold
874 if (std::fabs(M(j, k)) < threshold)
875 continue;
876
877 // Do not enter, if either the row or the column
878 // corresponds to an index on the refinement edge. The
879 // level problems are solved with homogeneous
880 // Dirichlet boundary conditions, therefore we
881 // eliminate these rows and columns. The corresponding
882 // matrix entries are entered by assemble_in() and
883 // assemble_out().
884 if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) ||
885 mg_constrained_dofs->at_refinement_edge(level, i2[k]))
886 continue;
887
888 // At the boundary, only enter the term on the
889 // diagonal, but not the coupling terms
890 if ((mg_constrained_dofs->is_boundary_index(level, i1[j]) ||
891 mg_constrained_dofs->is_boundary_index(level, i2[k])) &&
892 (i1[j] != i2[k]))
893 continue;
894
895 G.add(i1[j], i2[k], M(j, k));
896 }
897 }
898 }
899
900
901 template <typename MatrixType>
902 inline void
904 MatrixType &G,
905 const FullMatrix<double> &M,
906 const std::vector<types::global_dof_index> &i1,
907 const std::vector<types::global_dof_index> &i2,
908 const unsigned int level)
909 {
910 AssertDimension(M.n(), i1.size());
911 AssertDimension(M.m(), i2.size());
912
913 if (mg_constrained_dofs == nullptr)
914 {
915 for (unsigned int j = 0; j < i1.size(); ++j)
916 for (unsigned int k = 0; k < i2.size(); ++k)
917 if (std::fabs(M(k, j)) >= threshold)
918 G.add(i1[j], i2[k], M(k, j));
919 }
920 else
921 {
922 for (unsigned int j = 0; j < i1.size(); ++j)
923 for (unsigned int k = 0; k < i2.size(); ++k)
924 if (std::fabs(M(k, j)) >= threshold)
925 if (!mg_constrained_dofs->at_refinement_edge(level, i2[k]))
926 G.add(i1[j], i2[k], M(k, j));
927 }
928 }
929
930 template <typename MatrixType>
931 inline void
933 MatrixType &G,
934 const FullMatrix<double> &M,
935 const std::vector<types::global_dof_index> &i1,
936 const std::vector<types::global_dof_index> &i2,
937 const unsigned int level)
938 {
939 AssertDimension(M.m(), i1.size());
940 AssertDimension(M.n(), i2.size());
941
942 if (mg_constrained_dofs == nullptr)
943 {
944 for (unsigned int j = 0; j < i1.size(); ++j)
945 for (unsigned int k = 0; k < i2.size(); ++k)
946 if (std::fabs(M(j, k)) >= threshold)
947 G.add(i1[j], i2[k], M(j, k));
948 }
949 else
950 {
951 for (unsigned int j = 0; j < i1.size(); ++j)
952 for (unsigned int k = 0; k < i2.size(); ++k)
953 if (std::fabs(M(j, k)) >= threshold)
954 if (!mg_constrained_dofs->at_refinement_edge(level, i2[k]))
955 G.add(i1[j], i2[k], M(j, k));
956 }
957 }
958
959 template <typename MatrixType>
960 inline void
962 MatrixType &G,
963 const FullMatrix<double> &M,
964 const std::vector<types::global_dof_index> &i1,
965 const std::vector<types::global_dof_index> &i2,
966 const unsigned int level)
967 {
968 AssertDimension(M.m(), i1.size());
969 AssertDimension(M.n(), i2.size());
970 Assert(mg_constrained_dofs != nullptr, ExcInternalError());
971
972 for (unsigned int j = 0; j < i1.size(); ++j)
973 for (unsigned int k = 0; k < i2.size(); ++k)
974 if (std::fabs(M(j, k)) >= threshold)
975 // Enter values into matrix only if j corresponds to a
976 // degree of freedom on the refinement edge, k does
977 // not, and both are not on the boundary. This is part
978 // the difference between the complete matrix with no
979 // boundary condition at the refinement edge and
980 // the matrix assembled above by assemble().
981
982 // Thus the logic is: enter the row if it is
983 // constrained by hanging node constraints (actually,
984 // the whole refinement edge), but not if it is
985 // constrained by a boundary constraint.
986 if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
987 !mg_constrained_dofs->at_refinement_edge(level, i2[k]))
988 {
989 if ((!mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
990 !mg_constrained_dofs->is_boundary_index(level, i2[k])) ||
991 (mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
992 mg_constrained_dofs->is_boundary_index(level, i2[k]) &&
993 i1[j] == i2[k]))
994 G.add(i1[j], i2[k], M(j, k));
995 }
996 }
997
998
999 template <typename MatrixType>
1000 inline void
1002 MatrixType &G,
1003 const FullMatrix<double> &M,
1004 const std::vector<types::global_dof_index> &i1,
1005 const std::vector<types::global_dof_index> &i2,
1006 const unsigned int level)
1007 {
1008 AssertDimension(M.n(), i1.size());
1009 AssertDimension(M.m(), i2.size());
1010 Assert(mg_constrained_dofs != nullptr, ExcInternalError());
1011
1012 for (unsigned int j = 0; j < i1.size(); ++j)
1013 for (unsigned int k = 0; k < i2.size(); ++k)
1014 if (std::fabs(M(k, j)) >= threshold)
1015 if (mg_constrained_dofs->at_refinement_edge(level, i1[j]) &&
1016 !mg_constrained_dofs->at_refinement_edge(level, i2[k]))
1017 {
1018 if ((!mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
1019 !mg_constrained_dofs->is_boundary_index(level, i2[k])) ||
1020 (mg_constrained_dofs->is_boundary_index(level, i1[j]) &&
1021 mg_constrained_dofs->is_boundary_index(level, i2[k]) &&
1022 i1[j] == i2[k]))
1023 G.add(i1[j], i2[k], M(k, j));
1024 }
1025 }
1026
1027
1028 template <typename MatrixType>
1029 template <class DOFINFO>
1030 inline void
1032 {
1033 Assert(info.level_cell, ExcMessage("Cell must access level dofs"));
1034 const unsigned int level = info.cell->level();
1035
1036 if (info.indices_by_block.empty())
1037 {
1038 assemble((*matrix)[level],
1039 info.matrix(0, false).matrix,
1040 info.indices,
1041 info.indices,
1042 level);
1043 if (mg_constrained_dofs != nullptr)
1044 {
1045 assemble_in((*interface_in)[level],
1046 info.matrix(0, false).matrix,
1047 info.indices,
1048 info.indices,
1049 level);
1050 assemble_out((*interface_out)[level],
1051 info.matrix(0, false).matrix,
1052 info.indices,
1053 info.indices,
1054 level);
1055 }
1056 }
1057 else
1058 for (unsigned int k = 0; k < info.n_matrices(); ++k)
1059 {
1060 const unsigned int row = info.matrix(k, false).row;
1061 const unsigned int column = info.matrix(k, false).column;
1062
1063 assemble((*matrix)[level],
1064 info.matrix(k, false).matrix,
1065 info.indices_by_block[row],
1066 info.indices_by_block[column],
1067 level);
1068
1069 if (mg_constrained_dofs != nullptr)
1070 {
1071 assemble_in((*interface_in)[level],
1072 info.matrix(k, false).matrix,
1073 info.indices_by_block[row],
1074 info.indices_by_block[column],
1075 level);
1076 assemble_out((*interface_out)[level],
1077 info.matrix(k, false).matrix,
1078 info.indices_by_block[column],
1079 info.indices_by_block[row],
1080 level);
1081 }
1082 }
1083 }
1084
1085
1086 template <typename MatrixType>
1087 template <class DOFINFO>
1088 inline void
1090 const DOFINFO &info2)
1091 {
1092 Assert(info1.level_cell, ExcMessage("Cell must access level dofs"));
1093 Assert(info2.level_cell, ExcMessage("Cell must access level dofs"));
1094 const unsigned int level1 = info1.cell->level();
1095 const unsigned int level2 = info2.cell->level();
1096
1097 if (info1.indices_by_block.empty())
1098 {
1099 if (level1 == level2)
1100 {
1101 assemble((*matrix)[level1],
1102 info1.matrix(0, false).matrix,
1103 info1.indices,
1104 info1.indices,
1105 level1);
1106 assemble((*matrix)[level1],
1107 info1.matrix(0, true).matrix,
1108 info1.indices,
1109 info2.indices,
1110 level1);
1111 assemble((*matrix)[level1],
1112 info2.matrix(0, false).matrix,
1113 info2.indices,
1114 info2.indices,
1115 level1);
1116 assemble((*matrix)[level1],
1117 info2.matrix(0, true).matrix,
1118 info2.indices,
1119 info1.indices,
1120 level1);
1121 }
1122 else
1123 {
1124 Assert(level1 > level2, ExcInternalError());
1125 // Do not add info2.M1,
1126 // which is done by
1127 // the coarser cell
1128 assemble((*matrix)[level1],
1129 info1.matrix(0, false).matrix,
1130 info1.indices,
1131 info1.indices,
1132 level1);
1133 if (level1 > 0)
1134 {
1135 assemble_up((*flux_up)[level1],
1136 info1.matrix(0, true).matrix,
1137 info2.indices,
1138 info1.indices,
1139 level1);
1140 assemble_down((*flux_down)[level1],
1141 info2.matrix(0, true).matrix,
1142 info2.indices,
1143 info1.indices,
1144 level1);
1145 }
1146 }
1147 }
1148 else
1149 for (unsigned int k = 0; k < info1.n_matrices(); ++k)
1150 {
1151 const unsigned int row = info1.matrix(k, false).row;
1152 const unsigned int column = info1.matrix(k, false).column;
1153
1154 if (level1 == level2)
1155 {
1156 assemble((*matrix)[level1],
1157 info1.matrix(k, false).matrix,
1158 info1.indices_by_block[row],
1159 info1.indices_by_block[column],
1160 level1);
1161 assemble((*matrix)[level1],
1162 info1.matrix(k, true).matrix,
1163 info1.indices_by_block[row],
1164 info2.indices_by_block[column],
1165 level1);
1166 assemble((*matrix)[level1],
1167 info2.matrix(k, false).matrix,
1168 info2.indices_by_block[row],
1169 info2.indices_by_block[column],
1170 level1);
1171 assemble((*matrix)[level1],
1172 info2.matrix(k, true).matrix,
1173 info2.indices_by_block[row],
1174 info1.indices_by_block[column],
1175 level1);
1176 }
1177 else
1178 {
1179 Assert(level1 > level2, ExcInternalError());
1180 // Do not add info2.M1,
1181 // which is done by
1182 // the coarser cell
1183 assemble((*matrix)[level1],
1184 info1.matrix(k, false).matrix,
1185 info1.indices_by_block[row],
1186 info1.indices_by_block[column],
1187 level1);
1188 if (level1 > 0)
1189 {
1190 assemble_up((*flux_up)[level1],
1191 info1.matrix(k, true).matrix,
1192 info2.indices_by_block[column],
1193 info1.indices_by_block[row],
1194 level1);
1195 assemble_down((*flux_down)[level1],
1196 info2.matrix(k, true).matrix,
1197 info2.indices_by_block[row],
1198 info1.indices_by_block[column],
1199 level1);
1200 }
1201 }
1202 }
1203 }
1204
1205 //----------------------------------------------------------------------//
1206
1207 template <typename MatrixType, typename VectorType>
1211
1212
1213 template <typename MatrixType, typename VectorType>
1214 inline void
1216 VectorType &rhs)
1217 {
1218 AnyData data;
1219 VectorType *p = &rhs;
1220 data.add(p, "right hand side");
1221
1224 }
1225
1226 template <typename MatrixType, typename VectorType>
1227 inline void
1233
1234
1235 template <typename MatrixType, typename VectorType>
1236 template <class DOFINFO>
1237 inline void
1244
1245 template <typename MatrixType, typename VectorType>
1246 inline void
1248 const FullMatrix<double> &M,
1249 const Vector<double> &vector,
1250 const unsigned int index,
1251 const std::vector<types::global_dof_index> &indices)
1252 {
1253 AssertDimension(M.m(), indices.size());
1254 AssertDimension(M.n(), indices.size());
1255
1257 VectorType *v = residuals.entry<VectorType *>(index);
1258
1260 {
1261 for (unsigned int i = 0; i < indices.size(); ++i)
1262 (*v)(indices[i]) += vector(i);
1263
1264 for (unsigned int j = 0; j < indices.size(); ++j)
1265 for (unsigned int k = 0; k < indices.size(); ++k)
1266 if (std::fabs(M(j, k)) >= MatrixSimple<MatrixType>::threshold)
1267 MatrixSimple<MatrixType>::matrix[index]->add(indices[j],
1268 indices[k],
1269 M(j, k));
1270 }
1271 else
1272 {
1273 ResidualSimple<VectorType>::constraints->distribute_local_to_global(
1274 M,
1275 vector,
1276 indices,
1278 *v,
1279 true);
1280 }
1281 }
1282
1283 template <typename MatrixType, typename VectorType>
1284 inline void
1286 const FullMatrix<double> &M,
1287 const Vector<double> &vector,
1288 const unsigned int index,
1289 const std::vector<types::global_dof_index> &i1,
1290 const std::vector<types::global_dof_index> &i2)
1291 {
1292 AssertDimension(M.m(), i1.size());
1293 AssertDimension(M.n(), i2.size());
1294
1296 VectorType *v = residuals.entry<VectorType *>(index);
1297
1299 {
1300 for (unsigned int j = 0; j < i1.size(); ++j)
1301 for (unsigned int k = 0; k < i2.size(); ++k)
1302 if (std::fabs(M(j, k)) >= MatrixSimple<MatrixType>::threshold)
1303 MatrixSimple<MatrixType>::matrix[index]->add(i1[j],
1304 i2[k],
1305 M(j, k));
1306 }
1307 else
1308 {
1309 ResidualSimple<VectorType>::constraints->distribute_local_to_global(
1310 vector, i1, i2, *v, M, false);
1311 ResidualSimple<VectorType>::constraints->distribute_local_to_global(
1312 M, i1, i2, *MatrixSimple<MatrixType>::matrix[index]);
1313 }
1314 }
1315
1316
1317 template <typename MatrixType, typename VectorType>
1318 template <class DOFINFO>
1319 inline void
1321 {
1324 Assert(!info.level_cell, ExcMessage("Cell may not access level dofs"));
1325 const unsigned int n = info.indices_by_block.size();
1326
1327 if (n == 0)
1328 {
1329 for (unsigned int m = 0; m < MatrixSimple<MatrixType>::matrix.size();
1330 ++m)
1331 assemble(info.matrix(m, false).matrix,
1332 info.vector(m).block(0),
1333 m,
1334 info.indices);
1335 }
1336 else
1337 {
1338 for (unsigned int m = 0; m < MatrixSimple<MatrixType>::matrix.size();
1339 ++m)
1340 for (unsigned int k = 0; k < n * n; ++k)
1341 {
1342 const unsigned int row = info.matrix(k + m * n * n, false).row;
1343 const unsigned int column =
1344 info.matrix(k + m * n * n, false).column;
1345
1346 if (row == column)
1347 assemble(info.matrix(k + m * n * n, false).matrix,
1348 info.vector(m).block(row),
1349 m,
1350 info.indices_by_block[row]);
1351 else
1352 assemble(info.matrix(k + m * n * n, false).matrix,
1353 info.vector(m).block(row),
1354 m,
1355 info.indices_by_block[row],
1356 info.indices_by_block[column]);
1357 }
1358 }
1359 }
1360
1361
1362 template <typename MatrixType, typename VectorType>
1363 template <class DOFINFO>
1364 inline void
1366 const DOFINFO &info2)
1367 {
1368 Assert(!info1.level_cell, ExcMessage("Cell may not access level dofs"));
1369 Assert(!info2.level_cell, ExcMessage("Cell may not access level dofs"));
1370 AssertDimension(info1.indices_by_block.size(),
1371 info2.indices_by_block.size());
1372
1373 const unsigned int n = info1.indices_by_block.size();
1374
1375 if (n == 0)
1376 {
1377 for (unsigned int m = 0; m < MatrixSimple<MatrixType>::matrix.size();
1378 ++m)
1379 {
1380 assemble(info1.matrix(m, false).matrix,
1381 info1.vector(m).block(0),
1382 m,
1383 info1.indices);
1384 assemble(info1.matrix(m, true).matrix,
1385 info1.vector(m).block(0),
1386 m,
1387 info1.indices,
1388 info2.indices);
1389 assemble(info2.matrix(m, false).matrix,
1390 info2.vector(m).block(0),
1391 m,
1392 info2.indices);
1393 assemble(info2.matrix(m, true).matrix,
1394 info2.vector(m).block(0),
1395 m,
1396 info2.indices,
1397 info1.indices);
1398 }
1399 }
1400 else
1401 {
1402 for (unsigned int m = 0; m < MatrixSimple<MatrixType>::matrix.size();
1403 ++m)
1404 for (unsigned int k = 0; k < n * n; ++k)
1405 {
1406 const unsigned int row = info1.matrix(k + m * n * n, false).row;
1407 const unsigned int column =
1408 info1.matrix(k + m * n * n, false).column;
1409
1410 if (row == column)
1411 {
1412 assemble(info1.matrix(k + m * n * n, false).matrix,
1413 info1.vector(m).block(row),
1414 m,
1415 info1.indices_by_block[row]);
1416 assemble(info2.matrix(k + m * n * n, false).matrix,
1417 info2.vector(m).block(row),
1418 m,
1419 info2.indices_by_block[row]);
1420 }
1421 else
1422 {
1423 assemble(info1.matrix(k + m * n * n, false).matrix,
1424 info1.vector(m).block(row),
1425 m,
1426 info1.indices_by_block[row],
1427 info1.indices_by_block[column]);
1428 assemble(info2.matrix(k + m * n * n, false).matrix,
1429 info2.vector(m).block(row),
1430 m,
1431 info2.indices_by_block[row],
1432 info2.indices_by_block[column]);
1433 }
1434 assemble(info1.matrix(k + m * n * n, true).matrix,
1435 info1.vector(m).block(row),
1436 m,
1437 info1.indices_by_block[row],
1438 info2.indices_by_block[column]);
1439 assemble(info2.matrix(k + m * n * n, true).matrix,
1440 info2.vector(m).block(row),
1441 m,
1442 info2.indices_by_block[row],
1443 info1.indices_by_block[column]);
1444 }
1445 }
1446 }
1447 } // namespace Assembler
1448} // namespace MeshWorker
1449
1451
1452#endif
type entry(const std::string &name)
Access to stored data object by name.
Definition any_data.h:349
size_type n() const
size_type m() const
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)
Definition simple.h:1001
ObserverPointer< MGLevelObject< MatrixType >, MGMatrixSimple< MatrixType > > flux_up
Definition simple.h:387
void initialize_fluxes(MGLevelObject< MatrixType > &flux_up, MGLevelObject< MatrixType > &flux_down)
Definition simple.h:780
void initialize_interfaces(MGLevelObject< MatrixType > &interface_in, MGLevelObject< MatrixType > &interface_out)
Definition simple.h:791
ObserverPointer< MGLevelObject< MatrixType >, MGMatrixSimple< MatrixType > > interface_in
Definition simple.h:401
ObserverPointer< MGLevelObject< MatrixType >, MGMatrixSimple< MatrixType > > flux_down
Definition simple.h:394
void assemble(const DOFINFO &info)
Definition simple.h:1031
void initialize_info(DOFINFO &info, bool face) const
Definition simple.h:803
ObserverPointer< MGLevelObject< MatrixType >, MGMatrixSimple< MatrixType > > matrix
Definition simple.h:380
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)
Definition simple.h:961
MGMatrixSimple(double threshold=1.e-12)
Definition simple.h:758
ObserverPointer< MGLevelObject< MatrixType >, MGMatrixSimple< MatrixType > > interface_out
Definition simple.h:408
void initialize(MGLevelObject< MatrixType > &m)
Definition simple.h:765
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)
Definition simple.h:932
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)
Definition simple.h:903
ObserverPointer< const MGConstrainedDoFs, MGMatrixSimple< MatrixType > > mg_constrained_dofs
Definition simple.h:413
std::vector< ObserverPointer< MatrixType, MatrixSimple< MatrixType > > > matrix
Definition simple.h:212
void initialize(MatrixType &m)
Definition simple.h:582
MatrixSimple(double threshold=1.e-12)
Definition simple.h:575
void initialize_info(DOFINFO &info, bool face) const
Definition simple.h:611
ObserverPointer< const AffineConstraints< typename MatrixType::value_type >, MatrixSimple< MatrixType > > constraints
Definition simple.h:237
void assemble(const DOFINFO &info)
Definition simple.h:666
void assemble(const DOFINFO &info)
Definition simple.h:540
void initialize_info(DOFINFO &info, bool face) const
Definition simple.h:530
ObserverPointer< const AffineConstraints< typename VectorType::value_type >, ResidualSimple< VectorType > > constraints
Definition simple.h:114
void initialize(AnyData &results)
Definition simple.h:510
SystemSimple(double threshold=1.e-12)
Definition simple.h:1208
void assemble(const DOFINFO &info)
Definition simple.h:1320
void initialize(MatrixType &m, VectorType &rhs)
Definition simple.h:1215
void initialize_info(DOFINFO &info, bool face) const
Definition simple.h:1238
#define DEAL_II_DEPRECATED
Definition config.h:294
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
unsigned int level
Definition grid_out.cc:4642
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< index_type > data
Definition mpi.cc:734
std::size_t size
Definition mpi.cc:733
constexpr unsigned int invalid_unsigned_int
Definition types.h:228