10#ifndef MUELU_NULLSPACEFACTORY_DEF_HPP
11#define MUELU_NULLSPACEFACTORY_DEF_HPP
15#include <Xpetra_Matrix.hpp>
16#include <Xpetra_MultiVectorFactory.hpp>
21#include "Xpetra_Access.hpp"
25template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
27 RCP<ParameterList> validParamList = rcp(
new ParameterList());
29#define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
32 validParamList->set<std::string>(
"Fine level nullspace",
"Nullspace",
"Variable name which is used to store null space multi vector on the finest level (default=\"Nullspace\"). For block matrices also \"Nullspace1\" to \"Nullspace9\" are accepted to describe the null space vectors for the (i,i) block (i=1..9).");
34 validParamList->set<RCP<const FactoryBase>>(
"A", Teuchos::null,
"Generating factory of the fine level matrix (only needed if default null space is generated)");
35 validParamList->set<RCP<const FactoryBase>>(
"Nullspace", Teuchos::null,
"Generating factory of the fine level null space");
36 validParamList->set<RCP<const FactoryBase>>(
"Coordinates", Teuchos::null,
"Generating factory of the coordinates");
41 validParamList->set<RCP<const FactoryBase>>(
"Nullspace1", Teuchos::null,
"Generating factory of the fine level null space associated with the (1,1) block in your n x n block matrix.");
42 validParamList->set<RCP<const FactoryBase>>(
"Nullspace2", Teuchos::null,
"Generating factory of the fine level null space associated with the (2,2) block in your n x n block matrix.");
43 validParamList->set<RCP<const FactoryBase>>(
"Nullspace3", Teuchos::null,
"Generating factory of the fine level null space associated with the (3,3) block in your n x n block matrix.");
44 validParamList->set<RCP<const FactoryBase>>(
"Nullspace4", Teuchos::null,
"Generating factory of the fine level null space associated with the (4,4) block in your n x n block matrix.");
45 validParamList->set<RCP<const FactoryBase>>(
"Nullspace5", Teuchos::null,
"Generating factory of the fine level null space associated with the (5,5) block in your n x n block matrix.");
46 validParamList->set<RCP<const FactoryBase>>(
"Nullspace6", Teuchos::null,
"Generating factory of the fine level null space associated with the (6,6) block in your n x n block matrix.");
47 validParamList->set<RCP<const FactoryBase>>(
"Nullspace7", Teuchos::null,
"Generating factory of the fine level null space associated with the (7,7) block in your n x n block matrix.");
48 validParamList->set<RCP<const FactoryBase>>(
"Nullspace8", Teuchos::null,
"Generating factory of the fine level null space associated with the (8,8) block in your n x n block matrix.");
49 validParamList->set<RCP<const FactoryBase>>(
"Nullspace9", Teuchos::null,
"Generating factory of the fine level null space associated with the (9,9) block in your n x n block matrix.");
51 return validParamList;
54template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
57 std::string nspName = pL.get<std::string>(
"Fine level nullspace");
63 Input(currentLevel,
"A");
67 pL.get<
bool>(
"nullspace: calculate rotations")) {
69 Input(currentLevel,
"Coordinates");
79 "MueLu::NullspaceFactory::DeclareInput(): You must declare an existing factory which "
80 "produces the variable \"Nullspace\" in the NullspaceFactory (e.g. a TentativePFactory).");
85template <
class NullspaceType,
class CoordsType,
class MeanCoordsType,
class LO>
93 typedef typename NullspaceType::value_type
SC;
94 typedef Kokkos::ArithTraits<SC>
ATS;
97 NullspaceFunctor(NullspaceType nullspace_, CoordsType coords_, MeanCoordsType mean_, LO numPDEs_, LO nullspaceDim_)
103 static_assert(
static_cast<int>(NullspaceType::rank) == 2,
"Nullspace needs to be a rank 2 view.");
104 static_assert(
static_cast<int>(CoordsType::rank) == 2,
"Coords needs to be a rank 2 view.");
105 static_assert(
static_cast<int>(MeanCoordsType::rank) == 1,
"Mean needs to be a rank 1 view.");
108 KOKKOS_INLINE_FUNCTION
111 for (LO i = 0; i <
numPDEs; i++)
130template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
134 RCP<MultiVector> nullspace;
138 std::string nspName = pL.get<std::string>(
"Fine level nullspace");
142 RCP<RealValuedMultiVector> Coords;
150 <<
" nullspace dimension=" << nullspace->getNumVectors()
151 <<
" nullspace length=" << nullspace->getGlobalLength() << std::endl;
159 if (A->IsView(
"stridedMaps") ==
true) {
160 Xpetra::viewLabel_t oldView = A->SwitchToView(
"stridedMaps");
161 TEUCHOS_TEST_FOR_EXCEPTION(rcp_dynamic_cast<const StridedMap>(A->getRowMap()).is_null(),
Exceptions::BadCast,
162 "MueLu::CoalesceFactory::Build: cast to strided row map failed.");
163 numPDEs = rcp_dynamic_cast<const StridedMap>(A->getRowMap())->getFixedBlockSize();
164 oldView = A->SwitchToView(oldView);
167 LO nullspaceDim = numPDEs;
173 if (Coords->getNumVectors() > 1) nullspaceDim++;
174 if (Coords->getNumVectors() > 2) nullspaceDim += 2;
176 meanView =
MeanCoordsType(
"mean coords", Coords->getNumVectors());
177 Teuchos::Array<coordinate_type> hostMeans(Coords->getNumVectors());
178 Coords->meanValue(hostMeans);
179 Kokkos::View<typename RealValuedMultiVector::impl_scalar_type*, Kokkos::HostSpace> hostMeanView(hostMeans.getRawPtr(), hostMeans.size());
180 Kokkos::deep_copy(meanView, hostMeanView);
181 coordsView = Coords->getDeviceLocalView(Xpetra::Access::ReadOnly);
182 GetOStream(
Runtime1) <<
"Generating nullspace with rotations: dimension = " << nullspaceDim << std::endl;
184 GetOStream(
Runtime1) <<
"Generating canonical nullspace: dimension = " << numPDEs << std::endl;
186 nullspace = MultiVectorFactory::Build(A->getDomainMap(), nullspaceDim);
194 nullspace = currentLevel.
Get<RCP<MultiVector>>(
"Nullspace",
GetFactory(nspName).get());
198 Set(currentLevel,
"Nullspace", nullspace);
202template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
204 RCP<BlockedMultiVector> bnsp = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(nullspace);
205 if (bnsp.is_null() ==
true) {
206 auto nullspaceView = nullspace->getDeviceLocalView(Xpetra::Access::OverwriteAll);
208 int numBlocks = nullspace->getLocalLength() / numPDEs;
209 if (nullspaceDim > numPDEs)
210 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks != coordsView.extent_int(0),
Exceptions::RuntimeError,
"MueLu::NullspaceFactory::fillNullspaceVector(): number of coordinates does not match ndofs/numPDEs.");
212 NullspaceFunctor<
decltype(nullspaceView),
decltype(coordsView),
decltype(meanView), LO> nullspaceFunctor(nullspaceView, coordsView, meanView, numPDEs, nullspaceDim);
213 Kokkos::parallel_for(
"MueLu:NullspaceF:Build:for",
range_type(0, numBlocks), nullspaceFunctor);
230 RCP<const BlockedMap> bmap = bnsp->getBlockedMap();
231 for (
size_t r = 0; r < bmap->getNumMaps(); r++) {
232 Teuchos::RCP<MultiVector> part = bnsp->getMultiVector(r);
#define SET_VALID_ENTRY(name)
MueLu::DefaultLocalOrdinal LocalOrdinal
Exception indicating invalid cast attempted.
Exception throws to report errors in the internal logical of the program.
Timer to be used in factories. Similar to Monitor but with additional timers.
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
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Default implementation of FactoryAcceptor::GetFactory().
Class that holds all level-specific information.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput().
int GetLevelID() const
Return level number.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
static const NoFactory * get()
void fillNullspaceVector(const RCP< MultiVector > &nullspace, LocalOrdinal numPDEs, LocalOrdinal nullspaceDim, CoordsType coordsView, MeanCoordsType meanView) const
void Build(Level ¤tLevel) const
Build an object with this factory.
Kokkos::View< typename RealValuedMultiVector::impl_scalar_type *, typename Node::memory_space > MeanCoordsType
typename RealValuedMultiVector::dual_view_type::t_dev_const_um CoordsType
Kokkos::RangePolicy< local_ordinal_type, execution_space > range_type
RCP< const ParameterList > GetValidParameterList() const
Define valid parameters for internal factory parameters.
void DeclareInput(Level ¤tLevel) const
Specifies the data that this class needs, and the factories that generate that data.
KOKKOS_INLINE_FUNCTION void operator()(const LO j) const
NullspaceType::value_type SC
Kokkos::ArithTraits< SC > ATS
NullspaceFunctor(NullspaceType nullspace_, CoordsType coords_, MeanCoordsType mean_, LO numPDEs_, LO nullspaceDim_)
virtual const Teuchos::ParameterList & GetParameterList() const
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).