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
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.
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)....
Namespace for MueLu classes and methods.
@ Runtime0
One-liner description of what is happening.
@ Runtime1
Description of what is happening (more verbose)