46#ifndef MUELU_BLOCKEDCOORDINATESTRANSFER_FACTORY_DEF_HPP
47#define MUELU_BLOCKEDCOORDINATESTRANSFER_FACTORY_DEF_HPP
49#include "Xpetra_ImportFactory.hpp"
50#include "Xpetra_MultiVectorFactory.hpp"
51#include "Xpetra_MapFactory.hpp"
52#include "Xpetra_IO.hpp"
54#include "MueLu_CoarseMapFactory.hpp"
55#include "MueLu_Aggregates.hpp"
63 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
65 RCP<ParameterList> validParamList = rcp(
new ParameterList());
67 validParamList->set<RCP<const FactoryBase> >(
"Coordinates", Teuchos::null,
"Factory for coordinates generation");
68 validParamList->set<RCP<const FactoryBase> >(
"CoarseMap", Teuchos::null,
"Generating factory of the coarse map");
69 return validParamList;
72 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
74 Input(coarseLevel,
"CoarseMap");
77 const size_t numSubFactories = NumFactories();
78 for(
size_t i=0; i<numSubFactories; i++) {
79 const RCP<const FactoryBase>& myFactory = subFactories_[i];
80 coarseLevel.
DeclareInput(
"Coordinates", myFactory.getRawPtr(),
this);
84 for (std::vector<RCP<const FactoryBase> >::const_iterator it = subFactories_.begin(); it != subFactories_.end(); ++it)
85 (*it)->CallDeclareInput(coarseLevel);
88 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
92 typedef Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::coordinateType,LO,GO,NO> dMV;
93 typedef Xpetra::BlockedMultiVector<typename Teuchos::ScalarTraits<Scalar>::coordinateType,LO,GO,NO> dBV;
95 GetOStream(
Runtime0) <<
"Transferring (blocked) coordinates" << std::endl;
97 const size_t numSubFactories = NumFactories();
98 std::vector<RCP<const Map> > subBlockMaps(numSubFactories);
99 std::vector<RCP<dMV> > subBlockCoords(numSubFactories);
101 if (coarseLevel.
IsAvailable(
"Coordinates",
this)) {
102 GetOStream(
Runtime0) <<
"Reusing coordinates" << std::endl;
107 for(
size_t i=0; i<numSubFactories; i++) {
108 GetOStream(
Runtime1) <<
"Generating Coordinates for block " << i <<
"/"<<numSubFactories <<std::endl;
109 const RCP<const FactoryBase>& myFactory = subFactories_[i];
110 myFactory->CallBuild(coarseLevel);
111 subBlockCoords[i] = coarseLevel.
Get<RCP<dMV> >(
"Coordinates", myFactory.get());
112 subBlockMaps[i] = subBlockCoords[i]->getMap();
116 RCP<const BlockedMap> coarseCoordMapBlocked;
122 RCP<const BlockedMap> coarseMap = Get< RCP<const BlockedMap> >(coarseLevel,
"CoarseMap");
123 bool thyraMode = coarseMap->getThyraMode();
125 ArrayView<const GO> elementAList = coarseMap->getFullMap()->getLocalElementList();
128 if (rcp_dynamic_cast<const StridedMap>(coarseMap->getMap(0, thyraMode)) != Teuchos::null)
129 blkSize = rcp_dynamic_cast<const StridedMap>(coarseMap->getMap(0, thyraMode))->getFixedBlockSize();
131 for(
size_t i=1; i<numSubFactories; i++) {
133 if (rcp_dynamic_cast<const StridedMap>(coarseMap->getMap(i, thyraMode)) != Teuchos::null)
134 otherBlkSize = rcp_dynamic_cast<const StridedMap>(coarseMap->getMap(i, thyraMode))->getFixedBlockSize();
135 TEUCHOS_TEST_FOR_EXCEPTION(otherBlkSize != blkSize,
Exceptions::RuntimeError,
"BlockedCoordinatesTransferFactory: Subblocks have different Block sizes. This is not yet supported.");
138 GO indexBase = coarseMap->getFullMap()->getIndexBase();
139 size_t numElements = elementAList.size() / blkSize;
140 Array<GO> elementList(numElements);
143 for (LO i = 0; i < Teuchos::as<LO>(numElements); i++)
144 elementList[i] = (elementAList[i*blkSize]-indexBase)/blkSize + indexBase;
146 RCP<const Map> coarseCoordMap = MapFactory::Build(coarseMap->getFullMap()->lib(),
147 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), elementList, indexBase, coarseMap->getFullMap()->getComm());
149 coarseCoordMapBlocked = rcp(
new BlockedMap(coarseCoordMap, subBlockMaps, thyraMode));
153 RCP<dBV> bcoarseCoords = rcp(
new dBV(coarseCoordMapBlocked,subBlockCoords));
156 RCP<dMV> coarseCoords = bcoarseCoords->Merge();
157 Set<RCP<dMV> >(coarseLevel,
"Coordinates", coarseCoords);
160 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
162 subFactories_.push_back(factory);
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)