MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_Q2Q1Q2CoarseGridFactory_def.hpp
Go to the documentation of this file.
1// @HEADER
2//
3// ***********************************************************************
4//
5// MueLu: A package for multigrid based preconditioning
6// Copyright 2012 Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact
39// Jonathan Hu (jhu@sandia.gov)
40// Andrey Prokopenko (aprokop@sandia.gov)
41// Ray Tuminaro (rstumin@sandia.gov)
42//
43// ***********************************************************************
44//
45// @HEADER
46#ifndef MUELU_Q2Q1Q2COARSEGRIDFACTORY_DEF_HPP
47#define MUELU_Q2Q1Q2COARSEGRIDFACTORY_DEF_HPP
48
49#include <iostream>
50#include <cmath>
51
52#include <Teuchos_SerialDenseMatrix.hpp>
53
54#include <Xpetra_Map.hpp>
55#include <Xpetra_MapFactory.hpp>
56#include <Xpetra_Matrix.hpp>
57#include <Xpetra_MultiVector.hpp>
58#include <Xpetra_MultiVectorFactory.hpp>
59#include <Xpetra_VectorFactory.hpp>
60#include <Xpetra_CrsMatrixWrap.hpp>
61
63#include <MueLu_Level.hpp>
64
65namespace MueLu {
66
67 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
69 GetOStream(Runtime1) << "I constructed a Q2Q1Q2CoarseGridFactory object... Nothing else to do here." << std::endl;
70 }
71
72 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
74 // Should be empty. All destruction should be handled by Level-based get stuff and RCP
75 }
76
77 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
79
80 Input(fineLevel, "VElementList");
81 Input(fineLevel, "PElementList");
82 Input(fineLevel, "MElementList");
83
84 Input(coarseLevel, "VElementList");
85 Input(coarseLevel, "PElementList");
86 Input(coarseLevel, "MElementList");
87
88
89 //currentLevel.DeclareInput(varName_,factory_,this);
90 }
91
92 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
94
95 GetOStream(Runtime1) << "Starting 'build' routine...\n";
96
97 // This will create a list of elements on the coarse grid with a
98 // predictable structure, as well as modify the fine grid list of
99 // elements, if necessary (i.e. if fineLevel.GetLevelID()==0);
100 //BuildCoarseGrid(fineLevel,coarseLevel);
101
102 // This will actually build our prolongator P
103 return BuildCoarseGrid(fineLevel,coarseLevel);
104
105 }
106
107
108 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
110 {
111
112 GetOStream(Runtime1) << "starting 'BuildCoarseGrid' routine...\n";
113
114 RCP<Teuchos::SerialDenseMatrix<GO,GO> > fineElementPDOFs = Get< RCP<Teuchos::SerialDenseMatrix<GO,GO> > >(fineLevel,"PElementList");
115
116 GO totalFineElements = fineElementPDOFs->numRows();
117
118 // Compute number of coarse grid elements in total:
119 GO totalCoarseElements = totalFineElements/4;
120 LO nCoarseElements = (int) sqrt(totalCoarseElements);
121
122 // Initialize some counters:
123 size_t EdgeCount = (nCoarseElements + 1) * (nCoarseElements + 1);
124 size_t CenterCount = EdgeCount + 2 * nCoarseElements * (nCoarseElements + 1);
125
126
127 // Initialize arrays of the proper size:
128 RCP<Teuchos::SerialDenseMatrix<GO,GO> > coarseElementVDOFs = rcp(new Teuchos::SerialDenseMatrix<GO,GO>(totalCoarseElements,18));
129 RCP<Teuchos::SerialDenseMatrix<GO,GO> > coarseElementPDOFs = rcp(new Teuchos::SerialDenseMatrix<GO,GO>(totalCoarseElements,4));
130 RCP<Teuchos::SerialDenseMatrix<GO,GO> > coarseElementMDOFs = rcp(new Teuchos::SerialDenseMatrix<GO,GO>(totalCoarseElements,9));
131
132
133 for ( GO coarseElement=0; coarseElement < totalCoarseElements; coarseElement++ )
134 {
135
136 // ***************************************************************
137 // This is less of a pain in the ass for magnetics, so I'm
138 // going to build the magnetics list. The velocity follows
139 // by doubling everything (and adding 1 for the y-components)
140 // and the pressure follows by copying the magnetics nodes.
141 // ***************************************************************
142
143 //if (coarseElement is on the Bottom Edge)
144 if (coarseElement < nCoarseElements)
145 {
146 //Bottom nodes
147 (*coarseElementMDOFs)(coarseElement,0) = coarseElement;
148 (*coarseElementMDOFs)(coarseElement,1) = coarseElement+1;
149
150 //Bottom edge
151 (*coarseElementMDOFs)(coarseElement,4) = EdgeCount++;
152
153 }
154 else
155 {
156 //Bottom Nodes
157 (*coarseElementMDOFs)(coarseElement,0) = (*coarseElementMDOFs)(coarseElement-nCoarseElements,3);
158 (*coarseElementMDOFs)(coarseElement,1) = (*coarseElementMDOFs)(coarseElement-nCoarseElements,2);
159
160 //Bottom Edge
161 (*coarseElementMDOFs)(coarseElement,4) = (*coarseElementMDOFs)(coarseElement-nCoarseElements,6);
162
163 }
164
165
166 //Right and Top Edges -- must be determined before left edge
167 (*coarseElementMDOFs)(coarseElement,5) = EdgeCount++;
168 (*coarseElementMDOFs)(coarseElement,6) = EdgeCount++;
169
170
171 //if (coarseElement is on the Left Edge)
172 if (coarseElement % nCoarseElements == 0)
173 {
174 //Top left node
175 (*coarseElementMDOFs)(coarseElement,3) = (*coarseElementMDOFs)(coarseElement,0)+nCoarseElements+1;
176
177 //Left Edge
178 (*coarseElementMDOFs)(coarseElement,7) = EdgeCount++;
179
180 }
181 else
182 {
183 //Top left node
184 (*coarseElementMDOFs)(coarseElement,3) = (*coarseElementMDOFs)(coarseElement-1,2);
185
186 //Left Edge
187 (*coarseElementMDOFs)(coarseElement,7) = (*coarseElementMDOFs)(coarseElement-1,5);
188 }
189
190 //Top right node -- Must be the last node to be determined!
191 (*coarseElementMDOFs)(coarseElement,2) = (*coarseElementMDOFs)(coarseElement,3)+1;
192
193 //Center Node
194 (*coarseElementMDOFs)(coarseElement,8) = CenterCount++;
195
196
197
198 // With Magnetics built, Pressure and Velocity follow without effort.
199 // First, Velocity:
200 (*coarseElementVDOFs)(coarseElement,0) = 2*(*coarseElementMDOFs)(coarseElement,0);
201 (*coarseElementVDOFs)(coarseElement,1) = 2*(*coarseElementMDOFs)(coarseElement,0)+1;
202 (*coarseElementVDOFs)(coarseElement,2) = 2*(*coarseElementMDOFs)(coarseElement,1);
203 (*coarseElementVDOFs)(coarseElement,3) = 2*(*coarseElementMDOFs)(coarseElement,1)+1;
204 (*coarseElementVDOFs)(coarseElement,4) = 2*(*coarseElementMDOFs)(coarseElement,2);
205 (*coarseElementVDOFs)(coarseElement,5) = 2*(*coarseElementMDOFs)(coarseElement,2)+1;
206 (*coarseElementVDOFs)(coarseElement,6) = 2*(*coarseElementMDOFs)(coarseElement,3);
207 (*coarseElementVDOFs)(coarseElement,7) = 2*(*coarseElementMDOFs)(coarseElement,3)+1;
208 (*coarseElementVDOFs)(coarseElement,8) = 2*(*coarseElementMDOFs)(coarseElement,4);
209 (*coarseElementVDOFs)(coarseElement,9) = 2*(*coarseElementMDOFs)(coarseElement,4)+1;
210 (*coarseElementVDOFs)(coarseElement,10) = 2*(*coarseElementMDOFs)(coarseElement,5);
211 (*coarseElementVDOFs)(coarseElement,11) = 2*(*coarseElementMDOFs)(coarseElement,5)+1;
212 (*coarseElementVDOFs)(coarseElement,12) = 2*(*coarseElementMDOFs)(coarseElement,6);
213 (*coarseElementVDOFs)(coarseElement,13) = 2*(*coarseElementMDOFs)(coarseElement,6)+1;
214 (*coarseElementVDOFs)(coarseElement,14) = 2*(*coarseElementMDOFs)(coarseElement,7);
215 (*coarseElementVDOFs)(coarseElement,15) = 2*(*coarseElementMDOFs)(coarseElement,7)+1;
216 (*coarseElementVDOFs)(coarseElement,16) = 2*(*coarseElementMDOFs)(coarseElement,8);
217 (*coarseElementVDOFs)(coarseElement,17) = 2*(*coarseElementMDOFs)(coarseElement,8)+1;
218
219 // Lastly, Pressure:
220 (*coarseElementPDOFs)(coarseElement,0) = (*coarseElementMDOFs)(coarseElement,0);
221 (*coarseElementPDOFs)(coarseElement,1) = (*coarseElementMDOFs)(coarseElement,1);
222 (*coarseElementPDOFs)(coarseElement,2) = (*coarseElementMDOFs)(coarseElement,2);
223 (*coarseElementPDOFs)(coarseElement,3) = (*coarseElementMDOFs)(coarseElement,3);
224
225 }// Loop over elements
226
227 Set(coarseLevel,"VElementList",coarseElementVDOFs);
228 Set(coarseLevel,"PElementList",coarseElementPDOFs);
229 Set(coarseLevel,"MElementList",coarseElementMDOFs);
230
231 //coarseLevel.Keep("VElementList",coarseLevel.GetFactoryManager()->GetFactory("VElementList").get());
232 //coarseLevel.Keep("PElementList",coarseLevel.GetFactoryManager()->GetFactory("PElementList").get());
233 //coarseLevel.Keep("MElementList",coarseLevel.GetFactoryManager()->GetFactory("MElementList").get());
234
235 }//BuildCoarseGrid
236
237
238} // namespace MueLu
239
240#define MUELU_Q2Q1Q2COARSEGRIDFACTORY_SHORT
241#endif // MUELU_Q2Q1Q2COARSEGRIDFACTORY_DEF_HPP
void Input(Level &level, const std::string &varName) const
T Get(Level &level, const std::string &varName) const
void Set(Level &level, const std::string &varName, const T &data) const
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.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
Namespace for MueLu classes and methods.
@ Runtime1
Description of what is happening (more verbose).