76 typedef typename Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::coordinateType,
78 realvaluedmultivector_type;
80 for (ParameterList::ConstIterator nonSerialEntry = nonSerialList.begin(); nonSerialEntry != nonSerialList.end(); nonSerialEntry++) {
81 const std::string& levelName = nonSerialEntry->first;
83 if (nonSerialList.isSublist(levelName) && levelName.find(
"level ") == 0 && levelName.size() > 6) {
84 int levelID = strtol(levelName.substr(6).c_str(), 0, 0);
90 RCP<Level> level = H.
GetLevel(levelID);
92 RCP<FactoryManager> M = Teuchos::rcp_dynamic_cast<FactoryManager>(HM.
GetFactoryManager(levelID));
93 TEUCHOS_TEST_FOR_EXCEPTION(M.is_null(),
Exceptions::InvalidArgument,
"MueLu::Utils::AddNonSerializableDataToHierarchy: cannot get FactoryManager");
96 const ParameterList& levelList = nonSerialList.sublist(levelName);
97 for (ParameterList::ConstIterator levelListEntry = levelList.begin(); levelListEntry != levelList.end(); levelListEntry++) {
98 const std::string& name = levelListEntry->first;
99 TEUCHOS_TEST_FOR_EXCEPTION(name !=
"A" && name !=
"P" && name !=
"R" && name !=
"K" && name !=
"M" && name !=
"Mdiag" &&
100 name !=
"D0" && name !=
"Dk_1" && name !=
"Dk_2" &&
101 name !=
"Mk_one" && name !=
"Mk_1_one" && name !=
"M1_beta" && name !=
"M1_alpha" &&
102 name !=
"invMk_1_invBeta" && name !=
"invMk_2_invAlpha" &&
103 name !=
"M1" && name !=
"Ms" && name !=
"M0inv" &&
104 name !=
"Pnodal" && name !=
"NodeMatrix" && name !=
"NodeAggMatrix" &&
105 name !=
"Nullspace" && name !=
"Coordinates" && name !=
"pcoarsen: element to node map" &&
106 name !=
"Node Comm" && name !=
"DualNodeID2PrimalNodeID" && name !=
"Primal interface DOF map" &&
107 name !=
"dropMap1" && name !=
"dropMap2" &&
110 std::string(
"MueLu::Utils::AddNonSerializableDataToHierarchy: parameter list contains unknown data type(") + name +
")");
113 RCP<const Teuchos::Comm<int>> comm;
114 if (!level->GetComm().is_null())
115 comm = level->GetComm();
116 else if (level->IsAvailable(
"A")) {
118 level->Get(
"A", mat);
119 comm = mat->getMap()->getComm();
122 if (!level0->GetComm().is_null())
123 comm = level0->GetComm();
126 level0->Get(
"A", mat);
127 comm = mat->getMap()->getComm();
130 Xpetra::UnderlyingLib lib = level->lib();
134 if (levelListEntry->second.isType<std::string>())
136 mat = Xpetra::IO<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Read(Teuchos::getValue<std::string>(levelListEntry->second), lib, comm);
138 mat = Teuchos::getValue<RCP<Matrix>>(levelListEntry->second);
143 }
else if (name ==
"P" || name ==
"R" || name ==
"K" || name ==
"M") {
144 if (levelListEntry->second.isType<RCP<Operator>>()) {
146 mat = Teuchos::getValue<RCP<Operator>>(levelListEntry->second);
148 RCP<const FactoryBase> fact = M->GetFactory(name);
150 level->Set(name, mat, fact.get());
156 if (levelListEntry->second.isType<std::string>())
158 mat = Xpetra::IO<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Read(Teuchos::getValue<std::string>(levelListEntry->second), lib, comm);
160 mat = Teuchos::getValue<RCP<Matrix>>(levelListEntry->second);
162 RCP<const FactoryBase> fact = M->GetFactory(name);
164 level->Set(name, mat, fact.get());
169 }
else if (name ==
"D0" || name ==
"Dk_1" || name ==
"Dk_2" ||
170 name ==
"Mk_one" || name ==
"Mk_1_one" || name ==
"M1_beta" || name ==
"M1_alpha" ||
171 name ==
"invMk_1_invBeta" || name ==
"invMk_2_invAlpha" ||
172 name ==
"M1" || name ==
"Ms" || name ==
"M0inv" ||
173 name ==
"Pnodal" || name ==
"NodeMatrix" || name ==
"NodeAggMatrix") {
175 if (levelListEntry->second.isType<RCP<Operator>>())
176 level->Set(name, Teuchos::getValue<RCP<Operator>>(levelListEntry->second),
NoFactory::get());
178 level->Set(name, Teuchos::getValue<RCP<Matrix>>(levelListEntry->second),
NoFactory::get());
179 }
else if (name ==
"Mdiag") {
181 level->Set(name, Teuchos::getValue<RCP<Vector>>(levelListEntry->second),
NoFactory::get());
182 }
else if (name ==
"Nullspace") {
183 RCP<MultiVector> vec;
184 if (levelListEntry->second.isType<std::string>()) {
185 TEUCHOS_ASSERT(level->IsAvailable(
"A"));
187 level->Get(
"A", mat);
188 auto map = mat->getMap();
189 vec = Xpetra::IO<Scalar, LocalOrdinal, GlobalOrdinal, Node>::ReadMultiVector(Teuchos::getValue<std::string>(levelListEntry->second), map);
191 vec = Teuchos::getValue<RCP<MultiVector>>(levelListEntry->second);
196 }
else if (name ==
"Material") {
198 level->Set(name, Teuchos::getValue<RCP<MultiVector>>(levelListEntry->second),
NoFactory::get());
199 }
else if (name ==
"BlockNumber") {
201 level->Set(name, Teuchos::getValue<RCP<LocalOrdinalVector>>(levelListEntry->second),
NoFactory::get());
202 }
else if (name ==
"Coordinates")
204 RCP<realvaluedmultivector_type> vec;
205 if (levelListEntry->second.isType<std::string>()) {
206 TEUCHOS_ASSERT(level->IsAvailable(
"A"));
208 level->Get(
"A", mat);
209 size_t blkSize = mat->GetFixedBlockSize();
210 RCP<const Map> nodeMap = mat->getRowMap();
213 RCP<const Map> dofMap = mat->getRowMap();
214 GO indexBase = dofMap->getIndexBase();
215 size_t numLocalDOFs = dofMap->getLocalNumElements();
217 "HierarchyUtils: block size (" << blkSize <<
") is incompatible with the number of local dofs in a row map (" << numLocalDOFs);
218 ArrayView<const GO> GIDs = dofMap->getLocalElementList();
220 Array<GO> nodeGIDs(numLocalDOFs / blkSize);
221 for (
size_t i = 0; i < numLocalDOFs; i += blkSize)
222 nodeGIDs[i / blkSize] = (GIDs[i] - indexBase) / blkSize + indexBase;
224 Xpetra::global_size_t INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
225 nodeMap = MapFactory::Build(dofMap->lib(), INVALID, nodeGIDs(), indexBase, dofMap->getComm());
227 vec = Xpetra::IO<typename Teuchos::ScalarTraits<Scalar>::coordinateType,
LocalOrdinal,
GlobalOrdinal,
Node>::ReadMultiVector(Teuchos::getValue<std::string>(levelListEntry->second), nodeMap);
229 vec = Teuchos::getValue<RCP<realvaluedmultivector_type>>(levelListEntry->second);
233 }
else if (name ==
"Node Comm") {
236 }
else if (name ==
"DualNodeID2PrimalNodeID") {
238 level->Set(name, Teuchos::getValue<RCP<std::map<LO, LO>>>(levelListEntry->second),
NoFactory::get());
239 }
else if (name ==
"Primal interface DOF map") {
241 level->Set(name, Teuchos::getValue<RCP<const Map>>(levelListEntry->second),
NoFactory::get());
242 }
else if (name ==
"dropMap1") {
244 level->Set(name, Teuchos::getValue<RCP<const Map>>(levelListEntry->second),
NoFactory::get());
245 }
else if (name ==
"dropMap2") {
247 level->Set(name, Teuchos::getValue<RCP<const Map>>(levelListEntry->second),
NoFactory::get());
249#ifdef HAVE_MUELU_INTREPID2
250 else if (name ==
"pcoarsen: element to node map") {
252 level->Set(name, Teuchos::getValue<RCP<Kokkos::DynRankView<LocalOrdinal, typename Node::device_type>>>(levelListEntry->second),
NoFactory::get());
256#ifdef HAVE_MUELU_MATLAB
259 size_t typeNameStart = name.find_first_not_of(
' ');
260 size_t typeNameEnd = name.find(
' ', typeNameStart);
261 std::string typeName = name.substr(typeNameStart, typeNameEnd - typeNameStart);
262 std::transform(typeName.begin(), typeName.end(), typeName.begin(), ::tolower);
264 if (typeName ==
"matrix")
265 level->Set(name, Teuchos::getValue<RCP<Matrix>>(levelListEntry->second),
NoFactory::get());
266 else if (typeName ==
"multivector")
267 level->Set(name, Teuchos::getValue<RCP<MultiVector>>(levelListEntry->second),
NoFactory::get());
268 else if (typeName ==
"map")
269 level->Set(name, Teuchos::getValue<RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>>(levelListEntry->second),
NoFactory::get());
270 else if (typeName ==
"ordinalvector")
271 level->Set(name, Teuchos::getValue<RCP<Xpetra::Vector<LocalOrdinal, LocalOrdinal, GlobalOrdinal, Node>>>(levelListEntry->second),
NoFactory::get());
272 else if (typeName ==
"scalar")
273 level->Set(name, Teuchos::getValue<Scalar>(levelListEntry->second),
NoFactory::get());
274 else if (typeName ==
"double")
275 level->Set(name, Teuchos::getValue<double>(levelListEntry->second),
NoFactory::get());
276 else if (typeName ==
"complex")
277 level->Set(name, Teuchos::getValue<std::complex<double>>(levelListEntry->second),
NoFactory::get());
278 else if (typeName ==
"int")
279 level->Set(name, Teuchos::getValue<int>(levelListEntry->second),
NoFactory::get());
280 else if (typeName ==
"string")
281 level->Set(name, Teuchos::getValue<std::string>(levelListEntry->second),
NoFactory::get());
285 throw std::runtime_error(
"Invalid non-serializable data on list");
289 }
else if (nonSerialList.isSublist(levelName) && levelName.find(
"user data") != std::string::npos) {
292 RCP<Level> level = H.
GetLevel(levelID);
294 RCP<FactoryManager> M = Teuchos::rcp_dynamic_cast<FactoryManager>(HM.
GetFactoryManager(levelID));
295 TEUCHOS_TEST_FOR_EXCEPTION(M.is_null(),
Exceptions::InvalidArgument,
"MueLu::Utils::AddNonSerializableDataToHierarchy: cannot get FactoryManager");
298 const ParameterList& userList = nonSerialList.sublist(levelName);
299 for (ParameterList::ConstIterator userListEntry = userList.begin(); userListEntry != userList.end(); userListEntry++) {
300 const std::string& name = userListEntry->first;
302 bool isNumberedNullspace = (name.rfind(
"Nullspace", 0) == 0 && name.length() > 9 && std::isdigit(name.back(), std::locale::classic()));
304 TEUCHOS_TEST_FOR_EXCEPTION(name !=
"P" && name !=
"R" && name !=
"K" && name !=
"M" && name !=
"Mdiag" &&
305 name !=
"D0" && name !=
"Dk_1" && name !=
"Dk_2" &&
306 name !=
"Mk_one" && name !=
"Mk_1_one" && name !=
"M1_beta" && name !=
"M1_alpha" &&
307 name !=
"invMk_1_invBeta" && name !=
"invMk_2_invAlpha" &&
308 name !=
"M1" && name !=
"Ms" && name !=
"M0inv" &&
309 name !=
"NodeMatrix" &&
310 name !=
"Nullspace" && name !=
"Coordinates" && name !=
"Material" &&
311 name !=
"BlockNumber" && name !=
"pcoarsen: element to node map" &&
312 name !=
"Node Comm" && name !=
"DualNodeID2PrimalNodeID" && name !=
"Primal interface DOF map" &&
313 name !=
"dropMap1" && name !=
"dropMap2" &&
314 name !=
"output stream" &&
315 !isNumberedNullspace &&
318 std::string(
"MueLu::Utils::AddNonSerializableDataToHierarchy: user data parameter list contains unknown data type (") + name +
")");
319 if (name ==
"P" || name ==
"R" || name ==
"K" || name ==
"M" ||
320 name ==
"D0" || name ==
"Dk_1" || name ==
"Dk_2" ||
321 name ==
"Mk_one" || name ==
"Mk_1_one" || name ==
"M1_beta" || name ==
"M1_alpha" ||
322 name ==
"invMk_1_invBeta" || name ==
"invMk_2_invAlpha" ||
323 name ==
"M1" || name ==
"Ms" || name ==
"M0inv" ||
324 name ==
"NodeMatrix") {
326 level->Set(name, Teuchos::getValue<RCP<Matrix>>(userListEntry->second),
NoFactory::get());
327 }
else if (name ==
"Mdiag") {
329 level->Set(name, Teuchos::getValue<RCP<Vector>>(userListEntry->second),
NoFactory::get());
330 }
else if (name ==
"Nullspace" || isNumberedNullspace) {
332 level->Set(name, Teuchos::getValue<RCP<MultiVector>>(userListEntry->second),
NoFactory::get());
335 }
else if (name ==
"Material") {
337 level->Set(name, Teuchos::getValue<RCP<MultiVector>>(userListEntry->second),
NoFactory::get());
338 }
else if (name ==
"BlockNumber") {
340 level->Set(name, Teuchos::getValue<RCP<LocalOrdinalVector>>(userListEntry->second),
NoFactory::get());
341 }
else if (name ==
"Coordinates") {
343 level->Set(name, Teuchos::getValue<RCP<realvaluedmultivector_type>>(userListEntry->second),
NoFactory::get());
344 }
else if (name ==
"Node Comm") {
347 }
else if (name ==
"DualNodeID2PrimalNodeID") {
349 level->Set(name, Teuchos::getValue<RCP<std::map<LO, LO>>>(userListEntry->second),
NoFactory::get());
350 }
else if (name ==
"Primal interface DOF map") {
352 level->Set(name, Teuchos::getValue<RCP<const Map>>(userListEntry->second),
NoFactory::get());
353 }
else if (name ==
"dropMap1") {
355 level->Set(name, Teuchos::getValue<RCP<const Map>>(userListEntry->second),
NoFactory::get());
356 }
else if (name ==
"dropMap2") {
358 level->Set(name, Teuchos::getValue<RCP<const Map>>(userListEntry->second),
NoFactory::get());
360#ifdef HAVE_MUELU_INTREPID2
361 else if (name ==
"pcoarsen: element to node map") {
363 level->Set(name, Teuchos::getValue<RCP<Kokkos::DynRankView<LocalOrdinal, typename Node::device_type>>>(userListEntry->second),
NoFactory::get());
366 else if (name ==
"output stream") {
367 H.
SetMueLuOStream(Teuchos::getValue<RCP<Teuchos::FancyOStream>>(userListEntry->second));
370 size_t typeNameStart = name.find_first_not_of(
' ');
371 size_t typeNameEnd = name.find(
' ', typeNameStart);
372 std::string typeName = name.substr(typeNameStart, typeNameEnd - typeNameStart);
373 size_t varNameStart = name.find_first_not_of(
' ', typeNameEnd);
374 std::string varName = name.substr(varNameStart, name.size());
375 std::transform(typeName.begin(), typeName.end(), typeName.begin(), ::tolower);
377 if (typeName ==
"matrix")
378 level->Set(varName, Teuchos::getValue<RCP<Matrix>>(userListEntry->second),
NoFactory::get());
379 else if (typeName ==
"multivector")
380 level->Set(varName, Teuchos::getValue<RCP<MultiVector>>(userListEntry->second),
NoFactory::get());
381 else if (typeName ==
"vector")
382 level->Set(varName, Teuchos::getValue<RCP<Vector>>(userListEntry->second),
NoFactory::get());
383 else if (typeName ==
"map")
384 level->Set(varName, Teuchos::getValue<RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>>(userListEntry->second),
NoFactory::get());
385 else if (typeName ==
"ordinalvector")
386 level->Set(varName, Teuchos::getValue<RCP<Xpetra::Vector<LocalOrdinal, LocalOrdinal, GlobalOrdinal, Node>>>(userListEntry->second),
NoFactory::get());
387 else if (typeName ==
"scalar")
388 level->Set(varName, Teuchos::getValue<Scalar>(userListEntry->second),
NoFactory::get());
389 else if (typeName ==
"double")
390 level->Set(varName, Teuchos::getValue<double>(userListEntry->second),
NoFactory::get());
391 else if (typeName ==
"complex")
392 level->Set(varName, Teuchos::getValue<std::complex<double>>(userListEntry->second),
NoFactory::get());
393 else if (typeName ==
"int")
394 level->Set(varName, Teuchos::getValue<int>(userListEntry->second),
NoFactory::get());
395 else if (typeName ==
"string")
396 level->Set(varName, Teuchos::getValue<std::string>(userListEntry->second),
NoFactory::get());
397 else if (typeName ==
"array<go>")
398 level->Set(varName, Teuchos::getValue<Array<GlobalOrdinal>>(userListEntry->second),
NoFactory::get());
399 else if (typeName ==
"array<lo>")
400 level->Set(varName, Teuchos::getValue<Array<LocalOrdinal>>(userListEntry->second),
NoFactory::get());
401 else if (typeName ==
"arrayrcp<lo>")
402 level->Set(varName, Teuchos::getValue<ArrayRCP<LocalOrdinal>>(userListEntry->second),
NoFactory::get());
403 else if (typeName ==
"arrayrcp<go>")
404 level->Set(varName, Teuchos::getValue<ArrayRCP<GlobalOrdinal>>(userListEntry->second),
NoFactory::get());
406 throw std::runtime_error(
"Invalid non-serializable data on list");