46 #ifndef MUELU_COORDINATESTRANSFER_FACTORY_KOKKOS_DEF_HPP
47 #define MUELU_COORDINATESTRANSFER_FACTORY_KOKKOS_DEF_HPP
53 #include <Xpetra_MultiVectorFactory.hpp>
54 #include <Xpetra_MapFactory.hpp>
56 #include "MueLu_Aggregates_kokkos.hpp"
59 #include "MueLu_Utilities_kokkos.hpp"
63 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class DeviceType>
70 validParamList->
set<
int > (
"write start", -1,
"First level at which coordinates should be written to file");
71 validParamList->
set<
int > (
"write end", -1,
"Last level at which coordinates should be written to file");
72 validParamList->
set<
bool > (
"structured aggregation",
false,
"Flag specifying that the geometric data is transferred for StructuredAggregationFactory");
73 validParamList->
set<
RCP<const FactoryBase> > (
"lCoarseNodesPerDim", Teuchos::null,
"Factory providing the local number of nodes per spatial dimensions of the mesh");
74 validParamList->
set<
RCP<const FactoryBase> > (
"numDimensions", Teuchos::null,
"Factory providing the number of spatial dimensions of the mesh");
76 return validParamList;
79 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class DeviceType>
81 static bool isAvailableCoords =
false;
84 if(pL.
get<
bool>(
"structured aggregation") ==
true) {
85 Input(fineLevel,
"lCoarseNodesPerDim");
86 Input(fineLevel,
"numDimensions");
89 isAvailableCoords = coarseLevel.
IsAvailable(
"Coordinates",
this);
91 if (isAvailableCoords ==
false) {
92 Input(fineLevel,
"Coordinates");
93 Input(fineLevel,
"Aggregates");
94 Input(fineLevel,
"CoarseMap");
99 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class DeviceType>
105 GetOStream(
Runtime0) <<
"Transferring coordinates" << std::endl;
107 if (coarseLevel.
IsAvailable(
"Coordinates",
this)) {
108 GetOStream(
Runtime0) <<
"Reusing coordinates" << std::endl;
114 if(pL.
get<
bool>(
"structured aggregation") ==
true) {
115 Array<LO> lCoarseNodesPerDir = Get<Array<LO> >(fineLevel,
"lCoarseNodesPerDim");
116 Set<Array<LO> >(coarseLevel,
"lNodesPerDim", lCoarseNodesPerDir);
117 int numDimensions = Get<int>(fineLevel,
"numDimensions");
118 Set<int>(coarseLevel,
"numDimensions", numDimensions);
123 auto aggregates = Get<RCP<Aggregates_kokkos> >(fineLevel,
"Aggregates");
124 auto fineCoords = Get<RCP<doubleMultiVector> >(fineLevel,
"Coordinates");
125 auto coarseMap = Get<RCP<const Map> > (fineLevel,
"CoarseMap");
132 GO indexBase = coarseMap->getIndexBase();
135 if (rcp_dynamic_cast<const StridedMap>(coarseMap) != Teuchos::null)
136 blkSize = rcp_dynamic_cast<
const StridedMap>(coarseMap)->getFixedBlockSize();
143 elementListView = elementAList;
146 auto numElements = elementAList.
size() / blkSize;
148 elementList.
resize(numElements);
151 for (LO i = 0; i < Teuchos::as<LO>(numElements); i++)
152 elementList[i] = (elementAList[i*blkSize]-indexBase)/blkSize + indexBase;
154 elementListView = elementList;
157 auto uniqueMap = fineCoords->getMap();
159 elementListView, indexBase, coarseMap->getComm());
164 if (aggregates->AggregatesCrossProcessors()) {
165 auto nonUniqueMap = aggregates->GetMap();
166 auto importer = ImportFactory::Build(uniqueMap, nonUniqueMap);
174 auto aggGraph = aggregates->GetGraph();
175 auto numAggs = aggGraph.numRows();
177 auto fineCoordsView = fineCoords ->getDeviceLocalView(Xpetra::Access::ReadOnly);
178 auto coarseCoordsView = coarseCoords->getDeviceLocalView(Xpetra::Access::OverwriteAll);
184 const auto dim = fineCoords->getNumVectors();
187 for (
size_t j = 0; j < dim; j++) {
188 Kokkos::parallel_for(
"MueLu:CoordinatesTransferF:Build:coord", Kokkos::RangePolicy<local_ordinal_type, execution_space>(0, numAggs),
189 KOKKOS_LAMBDA(
const LO i) {
193 auto aggregate = aggGraph.rowConst(i);
196 for (
size_t colID = 0; colID < static_cast<size_t>(aggregate.length); colID++)
197 sum += fineCoordsRandomView(aggregate(colID),j);
199 coarseCoordsView(i,j) = sum / aggregate.length;
204 Set<RCP<doubleMultiVector> >(coarseLevel,
"Coordinates", coarseCoords);
206 int writeStart = pL.
get<
int>(
"write start"), writeEnd = pL.
get<
int>(
"write end");
207 if (writeStart == 0 && fineLevel.GetLevelID() == 0 && writeStart <= writeEnd) {
208 std::string fileName =
"coordinates_before_rebalance_level_" +
toString(fineLevel.GetLevelID()) +
".m";
211 if (writeStart <= coarseLevel.GetLevelID() && coarseLevel.GetLevelID() <= writeEnd) {
212 std::string fileName =
"coordinates_before_rebalance_level_" +
toString(coarseLevel.GetLevelID()) +
".m";
219 #endif // MUELU_COORDINATESTRANSFER_FACTORY_KOKKOS_DEF_HPP
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Timer to be used in factories. Similar to Monitor but with additional timers.
One-liner description of what is happening.
RequestMode GetRequestMode() const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
void resize(size_type new_size, const value_type &x=value_type())
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.