MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_BlockedCoordinatesTransferFactory_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_BLOCKEDCOORDINATESTRANSFER_FACTORY_DEF_HPP
11#define MUELU_BLOCKEDCOORDINATESTRANSFER_FACTORY_DEF_HPP
12
13#include "Xpetra_ImportFactory.hpp"
14#include "Xpetra_MultiVectorFactory.hpp"
15#include "Xpetra_MapFactory.hpp"
16#include "Xpetra_IO.hpp"
17
19
20#include "MueLu_Level.hpp"
21#include "MueLu_Monitor.hpp"
22
23namespace MueLu {
24
25template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
27 RCP<ParameterList> validParamList = rcp(new ParameterList());
28
29 validParamList->set<RCP<const FactoryBase> >("Coordinates", Teuchos::null, "Factory for coordinates generation");
30 validParamList->set<RCP<const FactoryBase> >("CoarseMap", Teuchos::null, "Generating factory of the coarse map");
31 return validParamList;
32}
33
34template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
36 Input(coarseLevel, "CoarseMap");
37
38 // Make sure the Level knows I need these sub-Factories
39 const size_t numSubFactories = NumFactories();
40 for (size_t i = 0; i < numSubFactories; i++) {
41 const RCP<const FactoryBase>& myFactory = subFactories_[i];
42 coarseLevel.DeclareInput("Coordinates", myFactory.getRawPtr(), this);
43 }
44
45 // call DeclareInput of all user-given transfer factories
46 for (std::vector<RCP<const FactoryBase> >::const_iterator it = subFactories_.begin(); it != subFactories_.end(); ++it)
47 (*it)->CallDeclareInput(coarseLevel);
48}
49
50template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
52 FactoryMonitor m(*this, "Build", coarseLevel);
53
54 typedef Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::coordinateType, LO, GO, NO> dMV;
55 typedef Xpetra::BlockedMultiVector<typename Teuchos::ScalarTraits<Scalar>::coordinateType, LO, GO, NO> dBV;
56
57 GetOStream(Runtime0) << "Transferring (blocked) coordinates" << std::endl;
58
59 const size_t numSubFactories = NumFactories();
60 std::vector<RCP<const Map> > subBlockMaps(numSubFactories);
61 std::vector<RCP<dMV> > subBlockCoords(numSubFactories);
62
63 if (coarseLevel.IsAvailable("Coordinates", this)) {
64 GetOStream(Runtime0) << "Reusing coordinates" << std::endl;
65 return;
66 }
67
68 // Get components
69 for (size_t i = 0; i < numSubFactories; i++) {
70 GetOStream(Runtime1) << "Generating Coordinates for block " << i << "/" << numSubFactories << std::endl;
71 const RCP<const FactoryBase>& myFactory = subFactories_[i];
72 myFactory->CallBuild(coarseLevel);
73 subBlockCoords[i] = coarseLevel.Get<RCP<dMV> >("Coordinates", myFactory.get());
74 subBlockMaps[i] = subBlockCoords[i]->getMap();
75 }
76
77 // Blocked Map
78 RCP<const BlockedMap> coarseCoordMapBlocked;
79
80 {
81 // coarseMap is being used to set up the domain map of tentative P, and therefore, the row map of Ac
82 // Therefore, if we amalgamate coarseMap, logical nodes in the coordinates vector would correspond to
83 // logical blocks in the matrix
84 RCP<const BlockedMap> coarseMap = Get<RCP<const BlockedMap> >(coarseLevel, "CoarseMap");
85 bool thyraMode = coarseMap->getThyraMode();
86
87 ArrayView<const GO> elementAList = coarseMap->getFullMap()->getLocalElementList();
88
89 LO blkSize = 1;
90 if (rcp_dynamic_cast<const StridedMap>(coarseMap->getMap(0, thyraMode)) != Teuchos::null)
91 blkSize = rcp_dynamic_cast<const StridedMap>(coarseMap->getMap(0, thyraMode))->getFixedBlockSize();
92
93 for (size_t i = 1; i < numSubFactories; i++) {
94 LO otherBlkSize = 1;
95 if (rcp_dynamic_cast<const StridedMap>(coarseMap->getMap(i, thyraMode)) != Teuchos::null)
96 otherBlkSize = rcp_dynamic_cast<const StridedMap>(coarseMap->getMap(i, thyraMode))->getFixedBlockSize();
97 TEUCHOS_TEST_FOR_EXCEPTION(otherBlkSize != blkSize, Exceptions::RuntimeError, "BlockedCoordinatesTransferFactory: Subblocks have different Block sizes. This is not yet supported.");
98 }
99
100 GO indexBase = coarseMap->getFullMap()->getIndexBase();
101 size_t numElements = elementAList.size() / blkSize;
102 Array<GO> elementList(numElements);
103
104 // Amalgamate the map
105 for (LO i = 0; i < Teuchos::as<LO>(numElements); i++)
106 elementList[i] = (elementAList[i * blkSize] - indexBase) / blkSize + indexBase;
107
108 RCP<const Map> coarseCoordMap = MapFactory::Build(coarseMap->getFullMap()->lib(),
109 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), elementList, indexBase, coarseMap->getFullMap()->getComm());
110
111 coarseCoordMapBlocked = rcp(new BlockedMap(coarseCoordMap, subBlockMaps, thyraMode));
112 }
113
114 // Build blocked coordinates vector
115 RCP<dBV> bcoarseCoords = rcp(new dBV(coarseCoordMapBlocked, subBlockCoords));
116
117 // Turn the blocked coordinates vector into an unblocked one
118 RCP<dMV> coarseCoords = bcoarseCoords->Merge();
119 Set<RCP<dMV> >(coarseLevel, "Coordinates", coarseCoords);
120}
121
122template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
124 subFactories_.push_back(factory);
125}
126
127} // namespace MueLu
128
129#endif // MUELU_BLOCKEDCOORDINATESTRANSFER_FACTORY_DEF_HPP
std::vector< RCP< const FactoryBase > > subFactories_
list of user-defined sub Factories
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void DeclareInput(Level &finelevel, Level &coarseLevel) const
Specifies the data that this class needs, and the factories that generate that data.
void AddFactory(const RCP< const FactoryBase > &factory)
Add (sub) coords factory in the end of list of factories in BlockedCoordinatesTransferFactory.
Exception throws to report errors in the internal logical of the program.
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
Timer to be used in factories. Similar to Monitor but with additional timers.
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().
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
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.
@ Runtime0
One-liner description of what is happening.
@ Runtime1
Description of what is happening (more verbose).