MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
23 namespace MueLu {
24 
25 template <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 
34 template <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 
50 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
52  FactoryMonitor m(*this, "Build", coarseLevel);
53 
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 
122 template <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 DeclareInput(Level &finelevel, Level &coarseLevel) const
Specifies the data that this class needs, and the factories that generate that data.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access). Usage: Level-&gt;Get&lt; RCP&lt;Matrix&gt; &gt;(&quot;A&quot;, factory) if factory == NULL =&gt; use default factory.
virtual void CallBuild(Level &requestedLevel) const =0
GlobalOrdinal GO
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
size_type size() const
LocalOrdinal LO
One-liner description of what is happening.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
T * get() const
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
T * getRawPtr() const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:63
void AddFactory(const RCP< const FactoryBase > &factory)
Add (sub) coords factory in the end of list of factories in BlockedCoordinatesTransferFactory.
Node NO
Exception throws to report errors in the internal logical of the program.
Description of what is happening (more verbose)
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need&#39;s value has been saved.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.