MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_CoupledRBMFactory_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2013 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_COUPLEDRBMFACTORY_DEF_HPP
47 #define MUELU_COUPLEDRBMFACTORY_DEF_HPP
48 
49 #include <Xpetra_Matrix.hpp>
50 #include <Xpetra_MultiVectorFactory.hpp>
51 #include <Xpetra_VectorFactory.hpp>
52 
54 #include "MueLu_Level.hpp"
55 #include "MueLu_Monitor.hpp"
56 
57 namespace MueLu {
58 
59 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
61 
62 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
64  if (currentLevel.IsAvailable(nspName_, NoFactory::get()) == false && currentLevel.GetLevelID() == 0) {
65  Input(currentLevel, "A");
66  // Input(currentLevel,"Coordinates");
67  }
68  if (currentLevel.GetLevelID() != 0) {
69  currentLevel.DeclareInput("Nullspace", GetFactory(nspName_).get(), this); /* ! "Nullspace" and nspName_ mismatch possible here */
70  }
71 }
72 
73 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
75  FactoryMonitor m(*this, "Structural acoustics nullspace factory", currentLevel);
76  RCP<MultiVector> nullspace;
77  if (currentLevel.GetLevelID() == 0) {
78  if (currentLevel.IsAvailable(nspName_, NoFactory::get())) {
79  nullspace = currentLevel.Get<RCP<MultiVector> >(nspName_, NoFactory::get());
80  GetOStream(Runtime1) << "Use user-given rigid body modes " << nspName_ << ": nullspace dimension=" << nullspace->getNumVectors() << " nullspace length=" << nullspace->getGlobalLength() << std::endl;
81  } else {
82  RCP<Matrix> A = Get<RCP<Matrix> >(currentLevel, "A");
83  RCP<MultiVector> Coords = Get<RCP<MultiVector> >(currentLevel, "Coordinates");
84  GetOStream(Runtime1) << "Generating nullspace for structural acoustics: dimension = " << numPDEs_ << std::endl;
85  RCP<const Map> xmap = A->getDomainMap();
86  nullspace = MultiVectorFactory::Build(xmap, 6);
87  Scalar zero = (Scalar)0.0;
88  nullspace->putScalar(zero);
89  ArrayRCP<Scalar> xnodes, ynodes, znodes;
90  Scalar cx, cy, cz;
91  ArrayRCP<Scalar> nsValues0, nsValues1, nsValues2, nsValues3, nsValues4, nsValues5;
92  int nDOFs = xmap->getLocalNumElements();
93  xnodes = Coords->getDataNonConst(0);
94  ynodes = Coords->getDataNonConst(1);
95  znodes = Coords->getDataNonConst(2);
96  cx = Coords->getVector(0)->meanValue();
97  cy = Coords->getVector(1)->meanValue();
98  cz = Coords->getVector(2)->meanValue();
99  nsValues0 = nullspace->getDataNonConst(0);
100  nsValues1 = nullspace->getDataNonConst(1);
101  nsValues2 = nullspace->getDataNonConst(2);
102  nsValues3 = nullspace->getDataNonConst(3);
103  nsValues4 = nullspace->getDataNonConst(4);
104  nsValues5 = nullspace->getDataNonConst(5);
105  for (int j = 0; j < nDOFs; j += numPDEs_) {
106  Scalar one = (Scalar)1.0;
107  if (xmap->getGlobalElement(j) >= lastAcousticDOF_) {
108  Scalar xdiff = xnodes[j] - cx;
109  Scalar ydiff = ynodes[j] - cy;
110  Scalar zdiff = znodes[j] - cz;
111  // translation
112  nsValues0[j + 0] = one;
113  nsValues1[j + 1] = one;
114  nsValues2[j + 2] = one;
115  // rotate around z-axis (x-y plane)
116  nsValues3[j + 0] = -ydiff;
117  nsValues3[j + 1] = xdiff;
118  // rotate around x-axis (y-z plane)
119  nsValues4[j + 1] = -zdiff;
120  nsValues4[j + 2] = ydiff;
121  // rotate around y-axis (x-z plane)
122  nsValues5[j + 0] = zdiff;
123  nsValues5[j + 2] = -xdiff;
124  } else {
125  // translation
126  nsValues0[j + 0] = one;
127  // insert random values and keep the top row for this node empty
128  nsValues1[j + 1] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
129  nsValues1[j + 2] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
130  nsValues2[j + 1] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
131  nsValues2[j + 2] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
132  nsValues3[j + 1] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
133  nsValues3[j + 2] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
134  nsValues4[j + 1] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
135  nsValues4[j + 2] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
136  nsValues5[j + 1] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
137  nsValues5[j + 2] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
138  }
139  }
140  } // end if "Nullspace" not available
141  } else {
142  nullspace = currentLevel.Get<RCP<MultiVector> >("Nullspace", GetFactory(nspName_).get());
143  }
144  Set(currentLevel, "Nullspace", nullspace);
145 }
146 
147 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
149  GetOStream(Runtime1) << "Generating nullspace for structural acoustics: dimension = " << numPDEs_ << std::endl;
150  RCP<const Map> xmap = A->getDomainMap();
151  nullspace = MultiVectorFactory::Build(xmap, 6);
152  Scalar zero = (Scalar)0.0;
153  nullspace->putScalar(zero);
154  ArrayRCP<Scalar> xnodes, ynodes, znodes;
155  Scalar cx, cy, cz;
156  ArrayRCP<Scalar> nsValues0, nsValues1, nsValues2, nsValues3, nsValues4, nsValues5;
157  int nDOFs = xmap->getLocalNumElements();
158  xnodes = Coords->getDataNonConst(0);
159  ynodes = Coords->getDataNonConst(1);
160  znodes = Coords->getDataNonConst(2);
161  cx = Coords->getVector(0)->meanValue();
162  cy = Coords->getVector(1)->meanValue();
163  cz = Coords->getVector(2)->meanValue();
164  nsValues0 = nullspace->getDataNonConst(0);
165  nsValues1 = nullspace->getDataNonConst(1);
166  nsValues2 = nullspace->getDataNonConst(2);
167  nsValues3 = nullspace->getDataNonConst(3);
168  nsValues4 = nullspace->getDataNonConst(4);
169  nsValues5 = nullspace->getDataNonConst(5);
170  for (int j = 0; j < nDOFs; j += numPDEs_) {
171  Scalar one = (Scalar)1.0;
172  if (xmap->getGlobalElement(j) >= lastAcousticDOF_) {
173  Scalar xdiff = xnodes[j] - cx;
174  Scalar ydiff = ynodes[j] - cy;
175  Scalar zdiff = znodes[j] - cz;
176  // translation
177  nsValues0[j + 0] = one;
178  nsValues1[j + 1] = one;
179  nsValues2[j + 2] = one;
180  // rotate around z-axis (x-y plane)
181  nsValues3[j + 0] = -ydiff;
182  nsValues3[j + 1] = xdiff;
183  // rotate around x-axis (y-z plane)
184  nsValues4[j + 1] = -zdiff;
185  nsValues4[j + 2] = ydiff;
186  // rotate around y-axis (x-z plane)
187  nsValues5[j + 0] = zdiff;
188  nsValues5[j + 2] = -xdiff;
189  } else {
190  // translation
191  nsValues0[j + 0] = one;
192  // insert random values and keep the top row for this node empty
193  nsValues1[j + 1] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
194  nsValues1[j + 2] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
195  nsValues2[j + 1] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
196  nsValues2[j + 2] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
197  nsValues3[j + 1] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
198  nsValues3[j + 2] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
199  nsValues4[j + 1] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
200  nsValues4[j + 2] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
201  nsValues5[j + 1] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
202  nsValues5[j + 2] = (Scalar)(((double)rand()) / ((double)RAND_MAX));
203  }
204  }
205 }
206 
207 } // namespace MueLu
208 
209 #define MUELU_COUPLEDRBMFACTORY_SHORT
210 #endif // MUELU_COUPLEDRBMFACTORY_DEF_HPP
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access). Usage: Level-&gt;Get&lt; RCP&lt;Matrix&gt; &gt;(&quot;A&quot;, factory) if factory == NULL =&gt; use default factory.
void DeclareInput(Level &currentLevel) const
Specifies the data that this class needs, and the factories that generate that data.
void Build(Level &currentLevel) const
Build an object with this factory.
Timer to be used in factories. Similar to Monitor but with additional timers.
static const NoFactory * get()
void BuildRBM(RCP< Matrix > &A, RCP< MultiVector > &Coords, RCP< MultiVector > &nullspace) const
MueLu::DefaultScalar Scalar
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
virtual ~CoupledRBMFactory()
Destructor.
int GetLevelID() const
Return level number.
Definition: MueLu_Level.cpp:76
Description of what is happening (more verbose)
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need&#39;s value has been saved.