MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_Utilities_decl.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_UTILITIES_DECL_HPP
11#define MUELU_UTILITIES_DECL_HPP
12
13#include <string>
14
15#include "MueLu_ConfigDefs.hpp"
16
17#include <Teuchos_DefaultComm.hpp>
18#include <Teuchos_ScalarTraits.hpp>
19#include <Teuchos_ParameterList.hpp>
20
21#include <Xpetra_TpetraBlockCrsMatrix_fwd.hpp>
22#include <Xpetra_TpetraOperator.hpp>
23#include <Xpetra_CrsMatrix_fwd.hpp>
24#include <Xpetra_CrsMatrixWrap.hpp>
25#include <Xpetra_Map_fwd.hpp>
26#include <Xpetra_Matrix_fwd.hpp>
27#include <Xpetra_MultiVector_fwd.hpp>
28#include <Xpetra_MultiVectorFactory_fwd.hpp>
29#include <Xpetra_Operator_fwd.hpp>
30#include <Xpetra_Vector_fwd.hpp>
31#include <Xpetra_VectorFactory_fwd.hpp>
32
33#include <Xpetra_MatrixMatrix.hpp>
34
35#include "MueLu_Exceptions.hpp"
36
37#include <Tpetra_CrsMatrix.hpp>
38#include <Tpetra_BlockCrsMatrix.hpp>
39#include <Tpetra_BlockCrsMatrix_Helpers.hpp>
40#include <Tpetra_RowMatrixTransposer.hpp>
41#include <Tpetra_Map.hpp>
42#include <Tpetra_MultiVector.hpp>
43#include <Xpetra_TpetraRowMatrix.hpp>
44#include <Xpetra_TpetraCrsMatrix_fwd.hpp>
45#include <Xpetra_TpetraMultiVector_fwd.hpp>
46
47#include <MueLu_UtilitiesBase.hpp>
48
49namespace MueLu {
50
51template <typename SC, typename LO, typename GO, typename NO>
52void leftRghtDofScalingWithinNode(const Xpetra::Matrix<SC, LO, GO, NO>& Atpetra, size_t blkSize, size_t nSweeps, Teuchos::ArrayRCP<SC>& rowScaling, Teuchos::ArrayRCP<SC>& colScaling);
53
54template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
55Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> importOffRankDroppingInfo(
56 Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>& localDropMap,
57 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& Ain);
58
66template <class Scalar,
69 class Node = DefaultNode>
70class Utilities : public UtilitiesBase<Scalar, LocalOrdinal, GlobalOrdinal, Node> {
71#undef MUELU_UTILITIES_SHORT
73
74 public:
75 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType Magnitude;
76
77 static RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> Transpose(Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Op, bool optimizeTranspose = false, const std::string& label = std::string(), const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
78
79 static RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> RealValuedToScalarMultiVector(RCP<Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::coordinateType, LocalOrdinal, GlobalOrdinal, Node>> X);
80
81 static RCP<Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LocalOrdinal, GlobalOrdinal, Node>> ExtractCoordinatesFromParameterList(ParameterList& paramList);
82
83}; // class Utilities
84
86
116long ExtractNonSerializableData(const Teuchos::ParameterList& inList, Teuchos::ParameterList& serialList, Teuchos::ParameterList& nonSerialList);
117
121void TokenizeStringAndStripWhiteSpace(const std::string& stream, std::vector<std::string>& tokenList, const char* token = ",");
122
125bool IsParamMuemexVariable(const std::string& name);
126
129bool IsParamValidVariable(const std::string& name);
130
158template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
159void leftRghtDofScalingWithinNode(const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Amat, size_t blkSize, size_t nSweeps, Teuchos::ArrayRCP<Scalar>& rowScaling, Teuchos::ArrayRCP<Scalar>& colScaling) {
160 LocalOrdinal nBlks = (Amat.getRowMap()->getLocalNumElements()) / blkSize;
161
162 Teuchos::ArrayRCP<Scalar> rowScaleUpdate(blkSize);
163 Teuchos::ArrayRCP<Scalar> colScaleUpdate(blkSize);
164
165 for (size_t i = 0; i < blkSize; i++) rowScaling[i] = 1.0;
166 for (size_t i = 0; i < blkSize; i++) colScaling[i] = 1.0;
167
168 for (size_t k = 0; k < nSweeps; k++) {
169 LocalOrdinal row = 0;
170 for (size_t i = 0; i < blkSize; i++) rowScaleUpdate[i] = 0.0;
171
172 for (LocalOrdinal i = 0; i < nBlks; i++) {
173 for (size_t j = 0; j < blkSize; j++) {
174 Teuchos::ArrayView<const LocalOrdinal> cols;
175 Teuchos::ArrayView<const Scalar> vals;
176 Amat.getLocalRowView(row, cols, vals);
177
178 for (size_t kk = 0; kk < Teuchos::as<size_t>(vals.size()); kk++) {
179 size_t modGuy = (cols[kk] + 1) % blkSize;
180 if (modGuy == 0) modGuy = blkSize;
181 modGuy--;
182 rowScaleUpdate[j] += rowScaling[j] * (Teuchos::ScalarTraits<Scalar>::magnitude(vals[kk])) * colScaling[modGuy];
183 }
184 row++;
185 }
186 }
187 // combine information across processors
188 Teuchos::ArrayRCP<Scalar> tempUpdate(blkSize);
189 Teuchos::reduceAll(*(Amat.getRowMap()->getComm()), Teuchos::REDUCE_SUM, (LocalOrdinal)blkSize, rowScaleUpdate.getRawPtr(), tempUpdate.getRawPtr());
190 for (size_t i = 0; i < blkSize; i++) rowScaleUpdate[i] = tempUpdate[i];
191
192 /* We want to scale by sqrt(1/rowScaleUpdate), but we'll */
193 /* normalize things by the minimum rowScaleUpdate. That is, the */
194 /* largest scaling is always one (as normalization is arbitrary).*/
195
196 Scalar minUpdate = Teuchos::ScalarTraits<Scalar>::magnitude((rowScaleUpdate[0] / rowScaling[0]) / rowScaling[0]);
197
198 for (size_t i = 1; i < blkSize; i++) {
199 Scalar temp = (rowScaleUpdate[i] / rowScaling[i]) / rowScaling[i];
200 if (Teuchos::ScalarTraits<Scalar>::magnitude(temp) < Teuchos::ScalarTraits<Scalar>::magnitude(minUpdate))
201 minUpdate = Teuchos::ScalarTraits<Scalar>::magnitude(temp);
202 }
203 for (size_t i = 0; i < blkSize; i++) rowScaling[i] *= sqrt(minUpdate / rowScaleUpdate[i]);
204
205 row = 0;
206 for (size_t i = 0; i < blkSize; i++) colScaleUpdate[i] = 0.0;
207
208 for (LocalOrdinal i = 0; i < nBlks; i++) {
209 for (size_t j = 0; j < blkSize; j++) {
210 Teuchos::ArrayView<const LocalOrdinal> cols;
211 Teuchos::ArrayView<const Scalar> vals;
212 Amat.getLocalRowView(row, cols, vals);
213 for (size_t kk = 0; kk < Teuchos::as<size_t>(vals.size()); kk++) {
214 size_t modGuy = (cols[kk] + 1) % blkSize;
215 if (modGuy == 0) modGuy = blkSize;
216 modGuy--;
217 colScaleUpdate[modGuy] += colScaling[modGuy] * (Teuchos::ScalarTraits<Scalar>::magnitude(vals[kk])) * rowScaling[j];
218 }
219 row++;
220 }
221 }
222 Teuchos::reduceAll(*(Amat.getRowMap()->getComm()), Teuchos::REDUCE_SUM, (LocalOrdinal)blkSize, colScaleUpdate.getRawPtr(), tempUpdate.getRawPtr());
223 for (size_t i = 0; i < blkSize; i++) colScaleUpdate[i] = tempUpdate[i];
224
225 /* We want to scale by sqrt(1/colScaleUpdate), but we'll */
226 /* normalize things by the minimum colScaleUpdate. That is, the */
227 /* largest scaling is always one (as normalization is arbitrary).*/
228
229 minUpdate = Teuchos::ScalarTraits<Scalar>::magnitude((colScaleUpdate[0] / colScaling[0]) / colScaling[0]);
230
231 for (size_t i = 1; i < blkSize; i++) {
232 Scalar temp = (colScaleUpdate[i] / colScaling[i]) / colScaling[i];
233 if (Teuchos::ScalarTraits<Scalar>::magnitude(temp) < Teuchos::ScalarTraits<Scalar>::magnitude(minUpdate))
234 minUpdate = Teuchos::ScalarTraits<Scalar>::magnitude(temp);
235 }
236 for (size_t i = 0; i < blkSize; i++) colScaling[i] *= sqrt(minUpdate / colScaleUpdate[i]);
237 }
238}
239
241template <class T>
242std::string toString(const T& what) {
243 std::ostringstream buf;
244 buf << what;
245 return buf.str();
246}
247
248// Generates a communicator whose only members are other ranks of the baseComm on my node
249Teuchos::RCP<const Teuchos::Comm<int>> GenerateNodeComm(RCP<const Teuchos::Comm<int>>& baseComm, int& NodeId, const int reductionFactor);
250
251// Lower case string
252std::string lowerCase(const std::string& s);
253
254template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
255Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> importOffRankDroppingInfo(
256 Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>& localDropMap,
257 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& Ain) {
258 using SC = Scalar;
259 using LO = LocalOrdinal;
260 using GO = GlobalOrdinal;
261 using NO = Node;
262 using MT = typename Teuchos::ScalarTraits<SC>::magnitudeType;
263
264 Teuchos::RCP<const Teuchos::Comm<int>> comm = localDropMap->getComm();
265
266 Teuchos::RCP<Xpetra::Vector<SC, LO, GO, NO>> toggleVec = Xpetra::VectorFactory<SC, LO, GO, NO>::Build(localDropMap);
267 toggleVec->putScalar(1);
268
269 Teuchos::RCP<Xpetra::Vector<SC, LO, GO, NO>> finalVec = Xpetra::VectorFactory<SC, LO, GO, NO>::Build(Ain->getColMap(), true);
270 Teuchos::RCP<Xpetra::Import<LO, GO, NO>> importer = Xpetra::ImportFactory<LO, GO, NO>::Build(localDropMap, Ain->getColMap());
271 finalVec->doImport(*toggleVec, *importer, Xpetra::ABSMAX);
272
273 std::vector<GO> finalDropMapEntries = {};
274 auto finalVec_h_2D = finalVec->getLocalViewHost(Tpetra::Access::ReadOnly);
275 auto finalVec_h_1D = Kokkos::subview(finalVec_h_2D, Kokkos::ALL(), 0);
276 const size_t localLength = finalVec->getLocalLength();
277
278 for (size_t k = 0; k < localLength; ++k) {
279 if (Teuchos::ScalarTraits<SC>::magnitude(finalVec_h_1D(k)) > Teuchos::ScalarTraits<MT>::zero()) {
280 finalDropMapEntries.push_back(finalVec->getMap()->getGlobalElement(k));
281 }
282 }
283
284 Teuchos::RCP<const Xpetra::Map<LO, GO, NO>> finalDropMap = Xpetra::MapFactory<LO, GO, NO>::Build(
285 localDropMap->lib(), Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid(), finalDropMapEntries, 0, comm);
286 return finalDropMap;
287} // importOffRankDroppingInfo
288
289} // namespace MueLu
290
291#define MUELU_UTILITIES_SHORT
292#endif // MUELU_UTILITIES_DECL_HPP
MueLu::DefaultLocalOrdinal LocalOrdinal
MueLu::DefaultScalar Scalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
MueLu::DefaultNode Node
MueLu utility class.
Teuchos::ScalarTraits< Scalar >::magnitudeType Magnitude
static RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Transpose(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op, bool optimizeTranspose=false, const std::string &label=std::string(), const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
static RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > RealValuedToScalarMultiVector(RCP< Xpetra::MultiVector< typename Teuchos::ScalarTraits< Scalar >::coordinateType, LocalOrdinal, GlobalOrdinal, Node > > X)
static RCP< Xpetra::MultiVector< typename Teuchos::ScalarTraits< Scalar >::magnitudeType, LocalOrdinal, GlobalOrdinal, Node > > ExtractCoordinatesFromParameterList(ParameterList &paramList)
Namespace for MueLu classes and methods.
bool IsParamMuemexVariable(const std::string &name)
long ExtractNonSerializableData(const Teuchos::ParameterList &inList, Teuchos::ParameterList &serialList, Teuchos::ParameterList &nonSerialList)
Extract non-serializable data from level-specific sublists and move it to a separate parameter list.
std::string lowerCase(const std::string &s)
void leftRghtDofScalingWithinNode(const Xpetra::Matrix< SC, LO, GO, NO > &Atpetra, size_t blkSize, size_t nSweeps, Teuchos::ArrayRCP< SC > &rowScaling, Teuchos::ArrayRCP< SC > &colScaling)
Tpetra::KokkosClassic::DefaultNode::DefaultNodeType DefaultNode
bool IsParamValidVariable(const std::string &name)
void TokenizeStringAndStripWhiteSpace(const std::string &stream, std::vector< std::string > &tokenList, const char *delimChars)
Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > importOffRankDroppingInfo(Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > &localDropMap, Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &Ain)
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
Teuchos::RCP< const Teuchos::Comm< int > > GenerateNodeComm(RCP< const Teuchos::Comm< int > > &baseComm, int &NodeId, const int reductionFactor)