MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_RigidBodyModeFactory_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_RIGIDBODYMODEFACTORY_DEF_HPP
11 #define MUELU_RIGIDBODYMODEFACTORY_DEF_HPP
12 
13 #include <Xpetra_Matrix.hpp>
14 #include <Xpetra_MultiVectorFactory.hpp>
15 #include <Xpetra_VectorFactory.hpp>
16 
18 #include "MueLu_Level.hpp"
19 #include "MueLu_Monitor.hpp"
20 
21 namespace MueLu {
22 
23 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
25 
26 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
28  if (currentLevel.IsAvailable(nspName_, NoFactory::get()) == false && currentLevel.GetLevelID() == 0) {
29  Input(currentLevel, "A");
30  // Input(currentLevel,"Coordinates");
31  }
32  if (currentLevel.GetLevelID() != 0) {
33  currentLevel.DeclareInput("Nullspace", GetFactory(nspName_).get(), this); /* ! "Nullspace" and nspName_ mismatch possible here */
34  }
35 }
36 
37 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
39  FactoryMonitor m(*this, "Rigid body mode factory", currentLevel);
40  RCP<MultiVector> nullspace;
41  if (currentLevel.GetLevelID() == 0) {
42  if (currentLevel.IsAvailable(nspName_, NoFactory::get())) {
43  nullspace = currentLevel.Get<RCP<MultiVector> >(nspName_, NoFactory::get());
44  GetOStream(Runtime1) << "Use user-given rigid body modes " << nspName_ << ": nullspace dimension=" << nullspace->getNumVectors() << " nullspace length=" << nullspace->getGlobalLength() << std::endl;
45  } else {
46  RCP<Matrix> A = Get<RCP<Matrix> >(currentLevel, "A");
47  GetOStream(Runtime1) << "Generating rigid body modes: dimension = " << numPDEs_ << std::endl;
48  RCP<const Map> xmap = A->getDomainMap();
49  if (numPDEs_ == 1) {
50  nullspace = MultiVectorFactory::Build(xmap, 1);
51  } else if (numPDEs_ == 2) {
52  nullspace = MultiVectorFactory::Build(xmap, 3);
53  } else if (numPDEs_ == 3) {
54  nullspace = MultiVectorFactory::Build(xmap, 6);
55  }
56  Scalar zero(0.0);
57  nullspace->putScalar(zero);
58  RCP<MultiVector> Coords = Get<RCP<MultiVector> >(currentLevel, "Coordinates");
59  ArrayRCP<Scalar> xnodes, ynodes, znodes;
60  Scalar cx, cy, cz;
61  ArrayRCP<Scalar> nsValues0, nsValues1, nsValues2, nsValues3, nsValues4, nsValues5;
62  int nDOFs = xmap->getLocalNumElements();
63  if (numPDEs_ == 1) {
64  nsValues0 = nullspace->getDataNonConst(0);
65  for (int j = 0; j < nDOFs; j++) {
66  // constant null space for scalar PDE
67  nsValues0[j] = 1.0;
68  }
69  } else if (numPDEs_ == 2) {
70  xnodes = Coords->getDataNonConst(0);
71  ynodes = Coords->getDataNonConst(1);
72  cx = Coords->getVector(0)->meanValue();
73  cy = Coords->getVector(1)->meanValue();
74  nsValues0 = nullspace->getDataNonConst(0);
75  nsValues1 = nullspace->getDataNonConst(1);
76  nsValues2 = nullspace->getDataNonConst(2);
77  for (int j = 0; j < nDOFs; j += numPDEs_) {
78  // translation
79  nsValues0[j + 0] = 1.0;
80  nsValues1[j + 1] = 1.0;
81  // rotate around z-axis (x-y plane)
82  nsValues2[j + 0] = -(ynodes[j] - cy);
83  nsValues2[j + 1] = (xnodes[j] - cx);
84  }
85  } else if (numPDEs_ == 3) {
86  xnodes = Coords->getDataNonConst(0);
87  ynodes = Coords->getDataNonConst(1);
88  znodes = Coords->getDataNonConst(2);
89  cx = Coords->getVector(0)->meanValue();
90  cy = Coords->getVector(1)->meanValue();
91  cz = Coords->getVector(2)->meanValue();
92  nsValues0 = nullspace->getDataNonConst(0);
93  nsValues1 = nullspace->getDataNonConst(1);
94  nsValues2 = nullspace->getDataNonConst(2);
95  nsValues3 = nullspace->getDataNonConst(3);
96  nsValues4 = nullspace->getDataNonConst(4);
97  nsValues5 = nullspace->getDataNonConst(5);
98  for (int j = 0; j < nDOFs; j += numPDEs_) {
99  // translation
100  nsValues0[j + 0] = 1.0;
101  nsValues1[j + 1] = 1.0;
102  nsValues2[j + 2] = 1.0;
103  // rotate around z-axis (x-y plane)
104  nsValues3[j + 0] = -(ynodes[j] - cy);
105  nsValues3[j + 1] = (xnodes[j] - cx);
106  // rotate around x-axis (y-z plane)
107  nsValues4[j + 1] = -(znodes[j] - cz);
108  nsValues4[j + 2] = (ynodes[j] - cy);
109  // rotate around y-axis (x-z plane)
110  nsValues5[j + 0] = (znodes[j] - cz);
111  nsValues5[j + 2] = -(xnodes[j] - cx);
112  }
113  }
114  } // end if "Nullspace" not available
115  } else {
116  nullspace = currentLevel.Get<RCP<MultiVector> >("Nullspace", GetFactory(nspName_).get());
117  }
118  Set(currentLevel, "Nullspace", nullspace);
119 }
120 
121 } // namespace MueLu
122 
123 #define MUELU_RIGIDBODYMODEFACTORY_SHORT
124 #endif // MUELU_RIGIDBODYMODEFACTORY_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.
Timer to be used in factories. Similar to Monitor but with additional timers.
static const NoFactory * get()
MueLu::DefaultScalar Scalar
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:63
void Build(Level &currentLevel) const
Build an object with this factory.
int GetLevelID() const
Return level number.
Definition: MueLu_Level.cpp:51
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()
void DeclareInput(Level &currentLevel) const
Specifies the data that this class needs, and the factories that generate that data.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need&#39;s value has been saved.