MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
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 
29 namespace MueLu {
30 
31 template <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 
36 template <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 
41 template <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 
54 template <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 
67 template <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
GlobalOrdinal GO
LocalOrdinal LO
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:63
Description of what is happening (more verbose)
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.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.