MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_Q2Q1Q2CoarseGridFactory_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef MUELU_Q2Q1Q2COARSEGRIDFACTORY_DEF_HPP
11#define MUELU_Q2Q1Q2COARSEGRIDFACTORY_DEF_HPP
12
13#include <iostream>
14#include <cmath>
15
16#include <Teuchos_SerialDenseMatrix.hpp>
17
18#include <Xpetra_Map.hpp>
19#include <Xpetra_MapFactory.hpp>
20#include <Xpetra_Matrix.hpp>
21#include <Xpetra_MultiVector.hpp>
22#include <Xpetra_MultiVectorFactory.hpp>
23#include <Xpetra_VectorFactory.hpp>
24#include <Xpetra_CrsMatrixWrap.hpp>
25
27#include <MueLu_Level.hpp>
28
29namespace MueLu {
30
31template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
33 GetOStream(Runtime1) << "I constructed a Q2Q1Q2CoarseGridFactory object... Nothing else to do here." << std::endl;
34}
35
36template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
38 // Should be empty. All destruction should be handled by Level-based get stuff and RCP
39}
40
41template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
43 Input(fineLevel, "VElementList");
44 Input(fineLevel, "PElementList");
45 Input(fineLevel, "MElementList");
46
47 Input(coarseLevel, "VElementList");
48 Input(coarseLevel, "PElementList");
49 Input(coarseLevel, "MElementList");
50
51 // currentLevel.DeclareInput(varName_,factory_,this);
52}
53
54template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
56 GetOStream(Runtime1) << "Starting 'build' routine...\n";
57
58 // This will create a list of elements on the coarse grid with a
59 // predictable structure, as well as modify the fine grid list of
60 // elements, if necessary (i.e. if fineLevel.GetLevelID()==0);
61 // BuildCoarseGrid(fineLevel,coarseLevel);
62
63 // This will actually build our prolongator P
64 return BuildCoarseGrid(fineLevel, coarseLevel);
65}
66
67template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
69 GetOStream(Runtime1) << "starting 'BuildCoarseGrid' routine...\n";
70
71 RCP<Teuchos::SerialDenseMatrix<GO, GO> > fineElementPDOFs = Get<RCP<Teuchos::SerialDenseMatrix<GO, GO> > >(fineLevel, "PElementList");
72
73 GO totalFineElements = fineElementPDOFs->numRows();
74
75 // Compute number of coarse grid elements in total:
76 GO totalCoarseElements = totalFineElements / 4;
77 LO nCoarseElements = (int)sqrt(totalCoarseElements);
78
79 // Initialize some counters:
80 size_t EdgeCount = (nCoarseElements + 1) * (nCoarseElements + 1);
81 size_t CenterCount = EdgeCount + 2 * nCoarseElements * (nCoarseElements + 1);
82
83 // Initialize arrays of the proper size:
84 RCP<Teuchos::SerialDenseMatrix<GO, GO> > coarseElementVDOFs = rcp(new Teuchos::SerialDenseMatrix<GO, GO>(totalCoarseElements, 18));
85 RCP<Teuchos::SerialDenseMatrix<GO, GO> > coarseElementPDOFs = rcp(new Teuchos::SerialDenseMatrix<GO, GO>(totalCoarseElements, 4));
86 RCP<Teuchos::SerialDenseMatrix<GO, GO> > coarseElementMDOFs = rcp(new Teuchos::SerialDenseMatrix<GO, GO>(totalCoarseElements, 9));
87
88 for (GO coarseElement = 0; coarseElement < totalCoarseElements; coarseElement++) {
89 // ***************************************************************
90 // This is less of a pain in the ass for magnetics, so I'm
91 // going to build the magnetics list. The velocity follows
92 // by doubling everything (and adding 1 for the y-components)
93 // and the pressure follows by copying the magnetics nodes.
94 // ***************************************************************
95
96 // if (coarseElement is on the Bottom Edge)
97 if (coarseElement < nCoarseElements) {
98 // Bottom nodes
99 (*coarseElementMDOFs)(coarseElement, 0) = coarseElement;
100 (*coarseElementMDOFs)(coarseElement, 1) = coarseElement + 1;
101
102 // Bottom edge
103 (*coarseElementMDOFs)(coarseElement, 4) = EdgeCount++;
104
105 } else {
106 // Bottom Nodes
107 (*coarseElementMDOFs)(coarseElement, 0) = (*coarseElementMDOFs)(coarseElement - nCoarseElements, 3);
108 (*coarseElementMDOFs)(coarseElement, 1) = (*coarseElementMDOFs)(coarseElement - nCoarseElements, 2);
109
110 // Bottom Edge
111 (*coarseElementMDOFs)(coarseElement, 4) = (*coarseElementMDOFs)(coarseElement - nCoarseElements, 6);
112 }
113
114 // Right and Top Edges -- must be determined before left edge
115 (*coarseElementMDOFs)(coarseElement, 5) = EdgeCount++;
116 (*coarseElementMDOFs)(coarseElement, 6) = EdgeCount++;
117
118 // if (coarseElement is on the Left Edge)
119 if (coarseElement % nCoarseElements == 0) {
120 // Top left node
121 (*coarseElementMDOFs)(coarseElement, 3) = (*coarseElementMDOFs)(coarseElement, 0) + nCoarseElements + 1;
122
123 // Left Edge
124 (*coarseElementMDOFs)(coarseElement, 7) = EdgeCount++;
125
126 } else {
127 // Top left node
128 (*coarseElementMDOFs)(coarseElement, 3) = (*coarseElementMDOFs)(coarseElement - 1, 2);
129
130 // Left Edge
131 (*coarseElementMDOFs)(coarseElement, 7) = (*coarseElementMDOFs)(coarseElement - 1, 5);
132 }
133
134 // Top right node -- Must be the last node to be determined!
135 (*coarseElementMDOFs)(coarseElement, 2) = (*coarseElementMDOFs)(coarseElement, 3) + 1;
136
137 // Center Node
138 (*coarseElementMDOFs)(coarseElement, 8) = CenterCount++;
139
140 // With Magnetics built, Pressure and Velocity follow without effort.
141 // First, Velocity:
142 (*coarseElementVDOFs)(coarseElement, 0) = 2 * (*coarseElementMDOFs)(coarseElement, 0);
143 (*coarseElementVDOFs)(coarseElement, 1) = 2 * (*coarseElementMDOFs)(coarseElement, 0) + 1;
144 (*coarseElementVDOFs)(coarseElement, 2) = 2 * (*coarseElementMDOFs)(coarseElement, 1);
145 (*coarseElementVDOFs)(coarseElement, 3) = 2 * (*coarseElementMDOFs)(coarseElement, 1) + 1;
146 (*coarseElementVDOFs)(coarseElement, 4) = 2 * (*coarseElementMDOFs)(coarseElement, 2);
147 (*coarseElementVDOFs)(coarseElement, 5) = 2 * (*coarseElementMDOFs)(coarseElement, 2) + 1;
148 (*coarseElementVDOFs)(coarseElement, 6) = 2 * (*coarseElementMDOFs)(coarseElement, 3);
149 (*coarseElementVDOFs)(coarseElement, 7) = 2 * (*coarseElementMDOFs)(coarseElement, 3) + 1;
150 (*coarseElementVDOFs)(coarseElement, 8) = 2 * (*coarseElementMDOFs)(coarseElement, 4);
151 (*coarseElementVDOFs)(coarseElement, 9) = 2 * (*coarseElementMDOFs)(coarseElement, 4) + 1;
152 (*coarseElementVDOFs)(coarseElement, 10) = 2 * (*coarseElementMDOFs)(coarseElement, 5);
153 (*coarseElementVDOFs)(coarseElement, 11) = 2 * (*coarseElementMDOFs)(coarseElement, 5) + 1;
154 (*coarseElementVDOFs)(coarseElement, 12) = 2 * (*coarseElementMDOFs)(coarseElement, 6);
155 (*coarseElementVDOFs)(coarseElement, 13) = 2 * (*coarseElementMDOFs)(coarseElement, 6) + 1;
156 (*coarseElementVDOFs)(coarseElement, 14) = 2 * (*coarseElementMDOFs)(coarseElement, 7);
157 (*coarseElementVDOFs)(coarseElement, 15) = 2 * (*coarseElementMDOFs)(coarseElement, 7) + 1;
158 (*coarseElementVDOFs)(coarseElement, 16) = 2 * (*coarseElementMDOFs)(coarseElement, 8);
159 (*coarseElementVDOFs)(coarseElement, 17) = 2 * (*coarseElementMDOFs)(coarseElement, 8) + 1;
160
161 // Lastly, Pressure:
162 (*coarseElementPDOFs)(coarseElement, 0) = (*coarseElementMDOFs)(coarseElement, 0);
163 (*coarseElementPDOFs)(coarseElement, 1) = (*coarseElementMDOFs)(coarseElement, 1);
164 (*coarseElementPDOFs)(coarseElement, 2) = (*coarseElementMDOFs)(coarseElement, 2);
165 (*coarseElementPDOFs)(coarseElement, 3) = (*coarseElementMDOFs)(coarseElement, 3);
166
167 } // Loop over elements
168
169 Set(coarseLevel, "VElementList", coarseElementVDOFs);
170 Set(coarseLevel, "PElementList", coarseElementPDOFs);
171 Set(coarseLevel, "MElementList", coarseElementMDOFs);
172
173 // coarseLevel.Keep("VElementList",coarseLevel.GetFactoryManager()->GetFactory("VElementList").get());
174 // coarseLevel.Keep("PElementList",coarseLevel.GetFactoryManager()->GetFactory("PElementList").get());
175 // coarseLevel.Keep("MElementList",coarseLevel.GetFactoryManager()->GetFactory("MElementList").get());
176
177} // BuildCoarseGrid
178
179} // namespace MueLu
180
181#define MUELU_Q2Q1Q2COARSEGRIDFACTORY_SHORT
182#endif // MUELU_Q2Q1Q2COARSEGRIDFACTORY_DEF_HPP
Class that holds all level-specific information.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
void BuildCoarseGrid(Level &fineLevel, Level &coarseLevel) const
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Specifies the data that this class needs, and the factories that generate that data.
Namespace for MueLu classes and methods.
@ Runtime1
Description of what is happening (more verbose)