46 #ifndef MUELU_GEOMETRICINTERPOLATIONPFACTORY_DEF_HPP
47 #define MUELU_GEOMETRICINTERPOLATIONPFACTORY_DEF_HPP
54 #include "MueLu_Aggregates.hpp"
61 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
65 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
68 #undef SET_VALID_ENTRY
72 "Generating factory of the matrix A");
74 "Aggregates generated by StructuredAggregationFactory used to construct a piece-constant prolongator.");
76 "Graph generated by StructuredAggregationFactory used to construct a piece-linear prolongator.");
78 "Fine level coordinates used to construct piece-wise linear prolongator and coarse level coordinates.");
80 "map of the coarse coordinates' GIDs as indexed on the fine mesh.");
82 "map of the coarse coordinates' GIDs as indexed on the coarse mesh.");
84 "Fine level nullspace used to construct the coarse level nullspace.");
86 "Number of spacial dimensions in the problem.");
88 "Number of nodes per spatial dimension on the coarse grid.");
90 return validParamList;
93 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
98 Input(fineLevel,
"A");
99 Input(fineLevel,
"Nullspace");
100 Input(fineLevel,
"numDimensions");
101 Input(fineLevel,
"prolongatorGraph");
102 Input(fineLevel,
"lCoarseNodesPerDim");
104 if( pL.
get<
bool>(
"interp: build coarse coordinates") ||
105 (pL.
get<
int>(
"interp: interpolation order") == 1) ) {
106 Input(fineLevel,
"Coordinates");
107 Input(fineLevel,
"coarseCoordinatesFineMap");
108 Input(fineLevel,
"coarseCoordinatesMap");
113 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
116 return BuildP(fineLevel, coarseLevel);
119 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
126 if(
const char* dbg = std::getenv(
"MUELU_GEOMETRICINTERPOLATIONPFACTORY_DEBUG")) {
127 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
133 *out <<
"Starting GeometricInterpolationPFactory::BuildP." << std::endl;
137 const bool buildCoarseCoordinates = pL.
get<
bool>(
"interp: build coarse coordinates");
138 const int interpolationOrder = pL.
get<
int> (
"interp: interpolation order");
139 const int numDimensions = Get<int>(fineLevel,
"numDimensions");
149 if(buildCoarseCoordinates || (interpolationOrder == 1)) {
151 RCP<const Map> coarseCoordsFineMap = Get< RCP<const Map> >(fineLevel,
"coarseCoordinatesFineMap");
152 RCP<const Map> coarseCoordsMap = Get< RCP<const Map> >(fineLevel,
"coarseCoordinatesMap");
153 fineCoordinates = Get< RCP<realvaluedmultivector_type> >(fineLevel,
"Coordinates");
155 fineCoordinates->getNumVectors());
156 RCP<const Import> coordsImporter = ImportFactory::Build(fineCoordinates->getMap(),
157 coarseCoordsFineMap);
158 coarseCoordinates->doImport(*fineCoordinates, *coordsImporter,
Xpetra::INSERT);
159 coarseCoordinates->replaceMap(coarseCoordsMap);
161 Set(coarseLevel,
"Coordinates", coarseCoordinates);
164 *out <<
"Fine and coarse coordinates have been loaded from the fine level and set on the coarse level." << std::endl;
166 if(interpolationOrder == 0) {
169 BuildConstantP(P, prolongatorGraph, A);
170 }
else if(interpolationOrder == 1) {
175 const size_t dofsPerNode =
static_cast<size_t>(A->GetFixedBlockSize());
176 const size_t numColIndices = prolongatorColMap->getNodeNumElements();
179 "Something went wrong, the number of columns in the prolongator is not a multiple of dofsPerNode!");
180 const size_t numGhostCoords = numColIndices / dofsPerNode;
181 const GO indexBase = prolongatorColMap->getIndexBase();
182 const GO coordIndexBase = fineCoordinates->getMap()->getIndexBase();
185 Array<GO> ghostCoordIndices(numGhostCoords);
186 for(
size_t ghostCoordIdx = 0; ghostCoordIdx < numGhostCoords; ++ghostCoordIdx) {
187 ghostCoordIndices[ghostCoordIdx]
188 = (prolongatorColIndices[ghostCoordIdx*dofsPerNode] - indexBase) / dofsPerNode
191 RCP<Map> ghostCoordMap = MapFactory::Build(fineCoordinates->getMap()->lib(),
192 prolongatorColMap->getGlobalNumElements() / dofsPerNode,
195 fineCoordinates->getMap()->getComm());
199 fineCoordinates->getNumVectors());
200 RCP<const Import> ghostImporter = ImportFactory::Build(coarseCoordinates->getMap(),
202 ghostCoordinates->doImport(*coarseCoordinates, *ghostImporter,
Xpetra::INSERT);
205 BuildLinearP(A, prolongatorGraph, fineCoordinates, ghostCoordinates, numDimensions, P);
208 *out <<
"The prolongator matrix has been built." << std::endl;
213 RCP<MultiVector> fineNullspace = Get< RCP<MultiVector> > (fineLevel,
"Nullspace");
214 RCP<MultiVector> coarseNullspace = MultiVectorFactory::Build(P->getDomainMap(),
215 fineNullspace->getNumVectors());
218 Set(coarseLevel,
"Nullspace", coarseNullspace);
221 *out <<
"The coarse nullspace is constructed and set on the coarse level." << std::endl;
223 Set(coarseLevel,
"P", P);
225 *out <<
"GeometricInterpolationPFactory::BuildP has completed." << std::endl;
229 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
235 if(
const char* dbg = std::getenv(
"MUELU_GEOMETRICINTERPOLATIONPFACTORY_DEBUG")) {
236 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
242 *out <<
"BuildConstantP" << std::endl;
244 std::vector<size_t> strideInfo(1);
245 strideInfo[0] = A->GetFixedBlockSize();
247 StridedMapFactory::Build(prolongatorGraph->getDomainMap(), strideInfo);
249 *out <<
"Call prolongator constructor" << std::endl;
253 P =
rcp(
new CrsMatrixWrap(prolongatorGraph, dummyList));
254 RCP<CrsMatrix> PCrs = rcp_dynamic_cast<CrsMatrixWrap>(P)->getCrsMatrix();
255 PCrs->setAllToScalar(1.0);
256 PCrs->fillComplete();
259 if (A->IsView(
"stridedMaps") ==
true) {
260 P->CreateView(
"stridedMaps", A->getRowMap(
"stridedMaps"), stridedDomainMap);
262 P->CreateView(
"stridedMaps", P->getRangeMap(), stridedDomainMap);
267 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
276 if(
const char* dbg = std::getenv(
"MUELU_GEOMETRICINTERPOLATIONPFACTORY_DEBUG")) {
277 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
283 *out <<
"Entering BuildLinearP" << std::endl;
286 const LO numFineNodes = fineCoordinates->getLocalLength();
287 const LO numGhostNodes = ghostCoordinates->getLocalLength();
290 const real_type realZero = Teuchos::as<real_type>(0.0);
293 for(
int dim = 0; dim < 3; ++dim) {
294 if(dim < numDimensions) {
295 fineCoords[dim] = fineCoordinates->getData(dim);
296 ghostCoords[dim] = ghostCoordinates->getData(dim);
298 fineCoords[dim] = fineZero;
299 ghostCoords[dim] = ghostZero;
303 *out <<
"Coordinates extracted from the multivectors!" << std::endl;
306 const int numInterpolationPoints = 1 << numDimensions;
307 const int dofsPerNode = A->GetFixedBlockSize();
309 std::vector<size_t> strideInfo(1);
310 strideInfo[0] = dofsPerNode;
312 StridedMapFactory::Build(prolongatorGraph->getDomainMap(), strideInfo);
314 *out <<
"The maps of P have been computed" << std::endl;
317 P =
rcp(
new CrsMatrixWrap(prolongatorGraph, dummyList));
318 RCP<CrsMatrix> PCrs = rcp_dynamic_cast<CrsMatrixWrap>(P)->getCrsMatrix();
321 LO interpolationNodeIdx = 0, rowIdx = 0;
326 for(
LO nodeIdx = 0; nodeIdx < numFineNodes; ++nodeIdx) {
327 if(PCrs->getNumEntriesInLocalRow(nodeIdx*dofsPerNode) == 1) {
330 for(
LO dof = 0; dof < dofsPerNode; ++dof) {
331 rowIdx = nodeIdx*dofsPerNode + dof;
332 prolongatorGraph->getLocalRowView(rowIdx, colIndices);
333 PCrs->replaceLocalValues(rowIdx, colIndices, values());
339 for(
int dim = 0; dim < 3; ++dim) {
340 coords[0][dim] = fineCoords[dim][nodeIdx];
342 prolongatorGraph->getLocalRowView(nodeIdx*dofsPerNode, colIndices);
343 for(
int interpolationIdx=0; interpolationIdx < numInterpolationPoints; ++interpolationIdx) {
344 coords[interpolationIdx + 1].
resize(3);
345 interpolationNodeIdx = colIndices[interpolationIdx] / dofsPerNode;
346 for(
int dim = 0; dim < 3; ++dim) {
347 coords[interpolationIdx + 1][dim] = ghostCoords[dim][interpolationNodeIdx];
350 ComputeLinearInterpolationStencil(numDimensions, numInterpolationPoints, coords, stencil);
351 values.
resize(numInterpolationPoints);
352 for(
LO valueIdx = 0; valueIdx < numInterpolationPoints; ++valueIdx) {
353 values[valueIdx] = Teuchos::as<SC>(stencil[valueIdx]);
357 for(
LO dof = 0; dof < dofsPerNode; ++dof) {
358 rowIdx = nodeIdx*dofsPerNode + dof;
359 prolongatorGraph->getLocalRowView(rowIdx, colIndices);
360 PCrs->replaceLocalValues(rowIdx, colIndices, values());
365 *out <<
"The calculation of the interpolation stencils has completed." << std::endl;
367 PCrs->fillComplete();
369 *out <<
"All values in P have been set and expertStaticFillComplete has been performed." << std::endl;
372 if (A->IsView(
"stridedMaps") ==
true) {
373 P->CreateView(
"stridedMaps", A->getRowMap(
"stridedMaps"), stridedDomainMap);
375 P->CreateView(
"stridedMaps", P->getRangeMap(), stridedDomainMap);
381 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
407 int iter = 0, max_iter = 5;
408 real_type functions[4][8], norm_ref = 1.0, norm2 = 1.0, tol = 1.0e-5;
409 paramCoords.
size(numDimensions);
411 while( (iter < max_iter) && (norm2 > tol*norm_ref) ) {
414 solutionDirection.
size(numDimensions);
415 residual.
size(numDimensions);
419 GetInterpolationFunctions(numDimensions, paramCoords, functions);
420 for(
LO i = 0; i < numDimensions; ++i) {
421 residual(i) = coord[0][i];
422 for(
LO k = 0; k < numInterpolationPoints; ++k) {
423 residual(i) -= functions[0][k]*coord[k+1][i];
426 norm_ref += residual(i)*residual(i);
427 if(i == numDimensions - 1) {
428 norm_ref = std::sqrt(norm_ref);
432 for(
LO j = 0; j < numDimensions; ++j) {
433 for(
LO k = 0; k < numInterpolationPoints; ++k) {
434 Jacobian(i,j) += functions[j+1][k]*coord[k+1][i];
445 for(
LO i = 0; i < numDimensions; ++i) {
446 paramCoords(i) = paramCoords(i) + solutionDirection(i);
450 GetInterpolationFunctions(numDimensions, paramCoords, functions);
451 for(
LO i = 0; i < numDimensions; ++i) {
453 for(
LO k = 0; k < numInterpolationPoints; ++k) {
454 tmp -= functions[0][k]*coord[k+1][i];
459 norm2 = std::sqrt(norm2);
463 for(
LO i = 0; i < numInterpolationPoints; ++i) {
464 stencil[i] = functions[0][i];
469 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
474 real_type xi = 0.0, eta = 0.0, zeta = 0.0, denominator = 0.0;
475 if(numDimensions == 1) {
476 xi = parametricCoordinates[0];
478 }
else if(numDimensions == 2) {
479 xi = parametricCoordinates[0];
480 eta = parametricCoordinates[1];
482 }
else if(numDimensions == 3) {
483 xi = parametricCoordinates[0];
484 eta = parametricCoordinates[1];
485 zeta = parametricCoordinates[2];
489 functions[0][0] = (1.0 - xi)*(1.0 - eta)*(1.0 - zeta) / denominator;
490 functions[0][1] = (1.0 + xi)*(1.0 - eta)*(1.0 - zeta) / denominator;
491 functions[0][2] = (1.0 - xi)*(1.0 + eta)*(1.0 - zeta) / denominator;
492 functions[0][3] = (1.0 + xi)*(1.0 + eta)*(1.0 - zeta) / denominator;
493 functions[0][4] = (1.0 - xi)*(1.0 - eta)*(1.0 + zeta) / denominator;
494 functions[0][5] = (1.0 + xi)*(1.0 - eta)*(1.0 + zeta) / denominator;
495 functions[0][6] = (1.0 - xi)*(1.0 + eta)*(1.0 + zeta) / denominator;
496 functions[0][7] = (1.0 + xi)*(1.0 + eta)*(1.0 + zeta) / denominator;
498 functions[1][0] = -(1.0 - eta)*(1.0 - zeta) / denominator;
499 functions[1][1] = (1.0 - eta)*(1.0 - zeta) / denominator;
500 functions[1][2] = -(1.0 + eta)*(1.0 - zeta) / denominator;
501 functions[1][3] = (1.0 + eta)*(1.0 - zeta) / denominator;
502 functions[1][4] = -(1.0 - eta)*(1.0 + zeta) / denominator;
503 functions[1][5] = (1.0 - eta)*(1.0 + zeta) / denominator;
504 functions[1][6] = -(1.0 + eta)*(1.0 + zeta) / denominator;
505 functions[1][7] = (1.0 + eta)*(1.0 + zeta) / denominator;
507 functions[2][0] = -(1.0 - xi)*(1.0 - zeta) / denominator;
508 functions[2][1] = -(1.0 + xi)*(1.0 - zeta) / denominator;
509 functions[2][2] = (1.0 - xi)*(1.0 - zeta) / denominator;
510 functions[2][3] = (1.0 + xi)*(1.0 - zeta) / denominator;
511 functions[2][4] = -(1.0 - xi)*(1.0 + zeta) / denominator;
512 functions[2][5] = -(1.0 + xi)*(1.0 + zeta) / denominator;
513 functions[2][6] = (1.0 - xi)*(1.0 + zeta) / denominator;
514 functions[2][7] = (1.0 + xi)*(1.0 + zeta) / denominator;
516 functions[3][0] = -(1.0 - xi)*(1.0 - eta) / denominator;
517 functions[3][1] = -(1.0 + xi)*(1.0 - eta) / denominator;
518 functions[3][2] = -(1.0 - xi)*(1.0 + eta) / denominator;
519 functions[3][3] = -(1.0 + xi)*(1.0 + eta) / denominator;
520 functions[3][4] = (1.0 - xi)*(1.0 - eta) / denominator;
521 functions[3][5] = (1.0 + xi)*(1.0 - eta) / denominator;
522 functions[3][6] = (1.0 - xi)*(1.0 + eta) / denominator;
523 functions[3][7] = (1.0 + xi)*(1.0 + eta) / denominator;
529 #endif // MUELU_GEOMETRICINTERPOLATIONPFACTORY_DEF_HPP
static Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node >> &map, size_t NumVectors, bool zeroOut=true)
basic_FancyOStream & setShowProcRank(const bool showProcRank)
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.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void GetInterpolationFunctions(const LO numDimensions, const Teuchos::SerialDenseVector< LO, real_type > parametricCoordinates, real_type functions[4][8]) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
Class that holds all level-specific information.
void ComputeLinearInterpolationStencil(const int numDimensions, const int numInterpolationPoints, const Array< Array< real_type > > coord, Array< real_type > &stencil) const
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
void factorWithEquilibration(bool flag)
#define SET_VALID_ENTRY(name)
void BuildLinearP(RCP< Matrix > &A, RCP< const CrsGraph > &prolongatorGraph, RCP< realvaluedmultivector_type > &fineCoordinates, RCP< realvaluedmultivector_type > &ghostCoordinates, const int numDimensions, RCP< Matrix > &P) const
basic_FancyOStream & setShowAllFrontMatter(const bool showAllFrontMatter)
void resize(size_type new_size, const value_type &x=value_type())
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
int size(OrdinalType length_in)
int setVectors(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &X, const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &B)
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
Exception throws to report errors in the internal logical of the program.
void BuildConstantP(RCP< Matrix > &P, RCP< const CrsGraph > &prolongatorGraph, RCP< Matrix > &A) const
typename Teuchos::ScalarTraits< SC >::coordinateType real_type
void BuildP(Level &fineLevel, Level &coarseLevel) const
Abstract Build method.
int setMatrix(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &A)