46 #ifndef MUELU_REGIONRFACTORY_DEF_HPP
47 #define MUELU_REGIONRFACTORY_DEF_HPP
59 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
65 "Generating factory of the matrix A");
67 "Number of spatial dimensions in the problem.");
69 "Number of local nodes per spatial dimension on the fine grid.");
71 "Fine level nullspace used to construct the coarse level nullspace.");
73 "Fine level coordinates used to construct piece-wise linear prolongator and coarse level coordinates.");
74 validParamList->
set<
bool>(
"keep coarse coords",
false,
"Flag to keep coordinates for special coarse grid solve");
76 return validParamList;
79 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
82 Input(fineLevel,
"A");
83 Input(fineLevel,
"numDimensions");
84 Input(fineLevel,
"lNodesPerDim");
85 Input(fineLevel,
"Nullspace");
86 Input(fineLevel,
"Coordinates");
90 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
95 if (
const char* dbg = std::getenv(
"MUELU_REGIONRFACTORY_DEBUG")) {
96 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
102 *out <<
"Starting RegionRFactory::Build." << std::endl;
105 const int numDimensions = Get<int>(fineLevel,
"numDimensions");
108 Array<LO> lNodesPerDim = Get<Array<LO> >(fineLevel,
"lNodesPerDim");
109 for (
int dim = 0; dim < numDimensions; ++dim) {
110 lFineNodesPerDim[dim] = lNodesPerDim[dim];
113 *out <<
"numDimensions " << numDimensions <<
" and lFineNodesPerDim: " << lFineNodesPerDim
117 if (numDimensions < 1 || numDimensions > 3) {
118 throw std::runtime_error(
"numDimensions must be 1, 2 or 3!");
120 for (
int dim = 0; dim < numDimensions; ++dim) {
121 if (lFineNodesPerDim[dim] % 3 != 1) {
122 throw std::runtime_error(
"The number of fine node in each direction need to be 3n+1");
127 const RCP<Matrix> A = Get<RCP<Matrix> >(fineLevel,
"A");
130 fineCoordinates = Get<RCP<realvaluedmultivector_type> >(fineLevel,
"Coordinates");
131 if (static_cast<int>(fineCoordinates->getNumVectors()) != numDimensions) {
132 throw std::runtime_error(
"The number of vectors in the coordinates is not equal to numDimensions!");
140 if (numDimensions == 1) {
141 throw std::runtime_error(
"RegionRFactory no implemented for 1D case yet.");
142 }
else if (numDimensions == 2) {
143 throw std::runtime_error(
"RegionRFactory no implemented for 2D case yet.");
144 }
else if (numDimensions == 3) {
145 Build3D(numDimensions, lFineNodesPerDim, A, fineCoordinates,
146 R, coarseCoordinates, lCoarseNodesPerDim);
153 if (pL.
isSublist(
"matrixmatrix: kernel params"))
159 *out <<
"Compute P=R^t" << std::endl;
161 Tparams->
set(
"compute global constants: temporaries", Tparams->
get(
"compute global constants: temporaries",
false));
162 Tparams->
set(
"compute global constants", Tparams->
get(
"compute global constants",
false));
166 *out <<
"Compute coarse nullspace" << std::endl;
167 RCP<MultiVector> fineNullspace = Get<RCP<MultiVector> >(fineLevel,
"Nullspace");
168 RCP<MultiVector> coarseNullspace = MultiVectorFactory::Build(R->getRowMap(),
169 fineNullspace->getNumVectors());
173 *out <<
"Set data on coarse level" << std::endl;
174 Set(coarseLevel,
"numDimensions", numDimensions);
175 Set(coarseLevel,
"lNodesPerDim", lCoarseNodesPerDim);
176 Set(coarseLevel,
"Nullspace", coarseNullspace);
177 Set(coarseLevel,
"Coordinates", coarseCoordinates);
178 if (pL.
get<
bool>(
"keep coarse coords")) {
182 R->SetFixedBlockSize(A->GetFixedBlockSize());
183 P->SetFixedBlockSize(A->GetFixedBlockSize());
185 Set(coarseLevel,
"R", R);
186 Set(coarseLevel,
"P", P);
190 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
199 using local_matrix_type =
typename CrsMatrix::local_matrix_type;
200 using local_graph_type =
typename local_matrix_type::staticcrsgraph_type;
201 using row_map_type =
typename local_matrix_type::row_map_type::non_const_type;
202 using entries_type =
typename local_matrix_type::index_type::non_const_type;
203 using values_type =
typename local_matrix_type::values_type::non_const_type;
207 if (
const char* dbg = std::getenv(
"MUELU_REGIONRFACTORY_DEBUG")) {
208 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
215 for (
int dim = 0; dim < numDimensions; ++dim) {
216 lCoarseNodesPerDim[dim] = lFineNodesPerDim[dim] / 3 + 1;
218 *out <<
"lCoarseNodesPerDim " << lCoarseNodesPerDim << std::endl;
221 const LO blkSize = A->GetFixedBlockSize();
222 *out <<
"blkSize " << blkSize << std::endl;
226 const LO numRows = blkSize * lCoarseNodesPerDim[0] * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[2];
227 const LO numCols = blkSize * lFineNodesPerDim[0] * lFineNodesPerDim[1] * lFineNodesPerDim[2];
232 RCP<Map> rowMap = MapFactory::Build(A->getRowMap()->lib(),
235 A->getRowMap()->getIndexBase(),
236 A->getRowMap()->getComm());
238 RCP<Map> coordRowMap = MapFactory::Build(A->getRowMap()->lib(),
240 lCoarseNodesPerDim[0] * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[2],
241 A->getRowMap()->getIndexBase(),
242 A->getRowMap()->getComm());
248 for (
int dim = 0; dim < numDimensions; ++dim) {
249 fineCoordData[dim] = fineCoordinates->getData(dim);
250 coarseCoordData[dim] = coarseCoordinates->getDataNonConst(dim);
257 const LO cornerStencilLength = 27;
258 const LO edgeStencilLength = 45;
259 const LO faceStencilLength = 75;
260 const LO interiorStencilLength = 125;
263 const LO numCorners = 8;
264 const LO numEdges = 4 * (lCoarseNodesPerDim[0] - 2) + 4 * (lCoarseNodesPerDim[1] - 2) + 4 * (lCoarseNodesPerDim[2] - 2);
265 const LO numFaces = 2 * (lCoarseNodesPerDim[0] - 2) * (lCoarseNodesPerDim[1] - 2) + 2 * (lCoarseNodesPerDim[0] - 2) * (lCoarseNodesPerDim[2] - 2) + 2 * (lCoarseNodesPerDim[1] - 2) * (lCoarseNodesPerDim[2] - 2);
266 const LO numInteriors = (lCoarseNodesPerDim[0] - 2) * (lCoarseNodesPerDim[1] - 2) * (lCoarseNodesPerDim[2] - 2);
268 const LO nnz = (numCorners * cornerStencilLength + numEdges * edgeStencilLength + numFaces * faceStencilLength + numInteriors * interiorStencilLength) * blkSize;
273 *out <<
"R statistics:" << std::endl
274 <<
" -numRows= " << numRows << std::endl
275 <<
" -numCols= " << numCols << std::endl
276 <<
" -nnz= " << nnz << std::endl;
278 row_map_type row_map(Kokkos::ViewAllocateWithoutInitializing(
"row_map"), numRows + 1);
279 typename row_map_type::HostMirror row_map_h = Kokkos::create_mirror_view(row_map);
281 entries_type entries(Kokkos::ViewAllocateWithoutInitializing(
"entries"), nnz);
282 typename entries_type::HostMirror entries_h = Kokkos::create_mirror_view(entries);
284 values_type values(Kokkos::ViewAllocateWithoutInitializing(
"values"), nnz);
285 typename values_type::HostMirror values_h = Kokkos::create_mirror_view(values);
290 Array<SC> coeffs({1.0 / 3.0, 2.0 / 3.0, 1.0, 2.0 / 3.0, 1.0 / 3.0});
295 const LO edgeLineOffset = 2 * cornerStencilLength + (lCoarseNodesPerDim[0] - 2) * edgeStencilLength;
296 const LO faceLineOffset = 2 * edgeStencilLength + (lCoarseNodesPerDim[0] - 2) * faceStencilLength;
297 const LO interiorLineOffset = 2 * faceStencilLength + (lCoarseNodesPerDim[0] - 2) * interiorStencilLength;
299 const LO facePlaneOffset = 2 * edgeLineOffset + (lCoarseNodesPerDim[1] - 2) * faceLineOffset;
300 const LO interiorPlaneOffset = 2 * faceLineOffset + (lCoarseNodesPerDim[1] - 2) * interiorLineOffset;
307 LO coordRowIdx = 0, rowIdx = 0, coordColumnOffset = 0, columnOffset = 0, entryOffset = 0;
308 for (
LO l = 0; l < blkSize; ++l) {
309 for (
LO k = 0; k < 3; ++k) {
310 for (
LO j = 0; j < 3; ++j) {
311 for (
LO i = 0; i < 3; ++i) {
312 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i) * blkSize + l;
313 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k + 2] * coeffs[j + 2] * coeffs[i + 2];
318 for (
LO l = 0; l < blkSize; ++l) {
319 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
321 for (
int dim = 0; dim < numDimensions; ++dim) {
322 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
326 coordRowIdx += (lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
327 rowIdx = coordRowIdx * blkSize;
328 coordColumnOffset += (lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0];
329 columnOffset = coordColumnOffset * blkSize;
330 entryOffset += (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset) * blkSize;
331 for (
LO l = 0; l < blkSize; ++l) {
332 for (
LO k = 0; k < 3; ++k) {
333 for (
LO j = 0; j < 3; ++j) {
334 for (
LO i = 0; i < 3; ++i) {
335 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i) * blkSize + l;
336 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i + 2];
341 for (
LO l = 0; l < blkSize; ++l) {
342 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
344 for (
int dim = 0; dim < numDimensions; ++dim) {
345 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
349 coordRowIdx = (lCoarseNodesPerDim[0] - 1);
350 rowIdx = coordRowIdx * blkSize;
351 coordColumnOffset = (lFineNodesPerDim[0] - 1);
352 columnOffset = coordColumnOffset * blkSize;
353 entryOffset = (cornerStencilLength + (lCoarseNodesPerDim[0] - 2) * edgeStencilLength) * blkSize;
354 for (
LO l = 0; l < blkSize; ++l) {
355 for (
LO k = 0; k < 3; ++k) {
356 for (
LO j = 0; j < 3; ++j) {
357 for (
LO i = 0; i < 3; ++i) {
358 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + (i - 2)) * blkSize + l;
359 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k + 2] * coeffs[j + 2] * coeffs[i];
364 for (
LO l = 0; l < blkSize; ++l) {
365 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
367 for (
int dim = 0; dim < numDimensions; ++dim) {
368 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
372 coordRowIdx += (lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
373 rowIdx = coordRowIdx * blkSize;
374 coordColumnOffset += (lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0];
375 columnOffset = coordColumnOffset * blkSize;
376 entryOffset += (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset) * blkSize;
377 for (
LO l = 0; l < blkSize; ++l) {
378 for (
LO k = 0; k < 3; ++k) {
379 for (
LO j = 0; j < 3; ++j) {
380 for (
LO i = 0; i < 3; ++i) {
381 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i - 2) * blkSize + l;
382 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i];
387 for (
LO l = 0; l < blkSize; ++l) {
388 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
390 for (
int dim = 0; dim < numDimensions; ++dim) {
391 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
395 coordRowIdx = (lCoarseNodesPerDim[1] - 1) * lCoarseNodesPerDim[0];
396 rowIdx = coordRowIdx * blkSize;
397 coordColumnOffset = (lFineNodesPerDim[1] - 1) * lFineNodesPerDim[0];
398 columnOffset = coordColumnOffset * blkSize;
399 entryOffset = (edgeLineOffset + (lCoarseNodesPerDim[1] - 2) * faceLineOffset) * blkSize;
400 for (
LO l = 0; l < blkSize; ++l) {
401 for (
LO k = 0; k < 3; ++k) {
402 for (
LO j = 0; j < 3; ++j) {
403 for (
LO i = 0; i < 3; ++i) {
404 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
405 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i + 2];
410 for (
LO l = 0; l < blkSize; ++l) {
411 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
413 for (
int dim = 0; dim < numDimensions; ++dim) {
414 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
418 coordRowIdx += (lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
419 rowIdx = coordRowIdx * blkSize;
420 coordColumnOffset += (lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0];
421 columnOffset = coordColumnOffset * blkSize;
422 entryOffset += (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset) * blkSize;
423 for (
LO l = 0; l < blkSize; ++l) {
424 for (
LO k = 0; k < 3; ++k) {
425 for (
LO j = 0; j < 3; ++j) {
426 for (
LO i = 0; i < 3; ++i) {
427 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
428 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i + 2];
433 for (
LO l = 0; l < blkSize; ++l) {
434 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
436 for (
int dim = 0; dim < numDimensions; ++dim) {
437 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
441 coordRowIdx = (lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] - 1);
442 rowIdx = coordRowIdx * blkSize;
443 coordColumnOffset = (lFineNodesPerDim[1] * lFineNodesPerDim[0] - 1);
444 columnOffset = coordColumnOffset * blkSize;
445 entryOffset = (edgeLineOffset + (lCoarseNodesPerDim[1] - 2) * faceLineOffset +
446 cornerStencilLength + (lCoarseNodesPerDim[0] - 2) * edgeStencilLength) *
448 for (
LO l = 0; l < blkSize; ++l) {
449 for (
LO k = 0; k < 3; ++k) {
450 for (
LO j = 0; j < 3; ++j) {
451 for (
LO i = 0; i < 3; ++i) {
452 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + (i - 2)) * blkSize + l;
453 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i];
458 for (
LO l = 0; l < blkSize; ++l) {
459 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
461 for (
int dim = 0; dim < numDimensions; ++dim) {
462 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
466 coordRowIdx += (lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
467 rowIdx = coordRowIdx * blkSize;
468 coordColumnOffset += (lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0];
469 columnOffset = coordColumnOffset * blkSize;
470 entryOffset += (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset) * blkSize;
471 for (
LO l = 0; l < blkSize; ++l) {
472 for (
LO k = 0; k < 3; ++k) {
473 for (
LO j = 0; j < 3; ++j) {
474 for (
LO i = 0; i < 3; ++i) {
475 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + (i - 2)) * blkSize + l;
476 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
481 for (
LO l = 0; l < blkSize; ++l) {
482 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
484 for (
int dim = 0; dim < numDimensions; ++dim) {
485 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
490 if (lCoarseNodesPerDim[0] - 2 > 0) {
491 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
492 for (
LO edgeIdx = 0; edgeIdx < lCoarseNodesPerDim[0] - 2; ++edgeIdx) {
494 coordRowIdx = (edgeIdx + 1);
495 rowIdx = coordRowIdx * blkSize;
496 coordColumnOffset = (edgeIdx + 1) * 3;
497 columnOffset = coordColumnOffset * blkSize;
498 entryOffset = (cornerStencilLength + edgeIdx * edgeStencilLength) * blkSize;
499 for (
LO l = 0; l < blkSize; ++l) {
500 for (
LO k = 0; k < 3; ++k) {
501 for (
LO j = 0; j < 3; ++j) {
502 for (
LO i = 0; i < 5; ++i) {
503 entries_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i - 2) * blkSize + l;
504 values_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = coeffs[k + 2] * coeffs[j + 2] * coeffs[i];
509 for (
LO l = 0; l < blkSize; ++l) {
510 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
512 for (
int dim = 0; dim < numDimensions; ++dim) {
513 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
517 coordRowIdx = ((lCoarseNodesPerDim[1] - 1) * lCoarseNodesPerDim[0] + edgeIdx + 1);
518 rowIdx = coordRowIdx * blkSize;
519 coordColumnOffset = ((lFineNodesPerDim[1] - 1) * lFineNodesPerDim[0] + (edgeIdx + 1) * 3);
520 columnOffset = coordColumnOffset * blkSize;
521 entryOffset = (edgeLineOffset + (lCoarseNodesPerDim[1] - 2) * faceLineOffset + cornerStencilLength + edgeIdx * edgeStencilLength) * blkSize;
522 for (
LO l = 0; l < blkSize; ++l) {
523 for (
LO k = 0; k < 3; ++k) {
524 for (
LO j = 0; j < 3; ++j) {
525 for (
LO i = 0; i < 5; ++i) {
526 entries_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
527 values_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i];
532 for (
LO l = 0; l < blkSize; ++l) {
533 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
535 for (
int dim = 0; dim < numDimensions; ++dim) {
536 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
540 coordRowIdx = ((lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + edgeIdx + 1);
541 rowIdx = coordRowIdx * blkSize;
542 coordColumnOffset = ((lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (edgeIdx + 1) * 3);
543 columnOffset = coordColumnOffset * blkSize;
544 entryOffset = (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset + cornerStencilLength + edgeIdx * edgeStencilLength) * blkSize;
545 for (
LO l = 0; l < blkSize; ++l) {
546 for (
LO k = 0; k < 3; ++k) {
547 for (
LO j = 0; j < 3; ++j) {
548 for (
LO i = 0; i < 5; ++i) {
549 entries_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i - 2) * blkSize + l;
550 values_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i];
555 for (
LO l = 0; l < blkSize; ++l) {
556 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
558 for (
int dim = 0; dim < numDimensions; ++dim) {
559 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
563 coordRowIdx = ((lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (lCoarseNodesPerDim[1] - 1) * lCoarseNodesPerDim[0] + edgeIdx + 1);
564 rowIdx = coordRowIdx * blkSize;
565 coordColumnOffset = ((lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (lFineNodesPerDim[1] - 1) * lFineNodesPerDim[0] + (edgeIdx + 1) * 3);
566 columnOffset = coordColumnOffset * blkSize;
567 entryOffset = (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset + edgeLineOffset + (lCoarseNodesPerDim[1] - 2) * faceLineOffset + cornerStencilLength + edgeIdx * edgeStencilLength) * blkSize;
568 for (
LO l = 0; l < blkSize; ++l) {
569 for (
LO k = 0; k < 3; ++k) {
570 for (
LO j = 0; j < 3; ++j) {
571 for (
LO i = 0; i < 5; ++i) {
572 entries_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
573 values_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
578 for (
LO l = 0; l < blkSize; ++l) {
579 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
581 for (
int dim = 0; dim < numDimensions; ++dim) {
582 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
588 if (lCoarseNodesPerDim[1] - 2 > 0) {
589 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
590 for (
LO edgeIdx = 0; edgeIdx < lCoarseNodesPerDim[1] - 2; ++edgeIdx) {
592 coordRowIdx = (edgeIdx + 1) * lCoarseNodesPerDim[0];
593 rowIdx = coordRowIdx * blkSize;
594 coordColumnOffset = (edgeIdx + 1) * 3 * lFineNodesPerDim[0];
595 columnOffset = coordColumnOffset * blkSize;
596 entryOffset = (edgeLineOffset + edgeIdx * faceLineOffset) * blkSize;
597 for (
LO l = 0; l < blkSize; ++l) {
598 for (
LO k = 0; k < 3; ++k) {
599 for (
LO j = 0; j < 5; ++j) {
600 for (
LO i = 0; i < 3; ++i) {
601 entries_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
602 values_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i + 2];
607 for (
LO l = 0; l < blkSize; ++l) {
608 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
610 for (
int dim = 0; dim < numDimensions; ++dim) {
611 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
615 coordRowIdx = ((edgeIdx + 1) * lCoarseNodesPerDim[0] + lCoarseNodesPerDim[0] - 1);
616 rowIdx = coordRowIdx * blkSize;
617 coordColumnOffset = ((edgeIdx + 1) * 3 * lFineNodesPerDim[0] + lFineNodesPerDim[0] - 1);
618 columnOffset = coordColumnOffset * blkSize;
619 entryOffset = (edgeLineOffset + edgeIdx * faceLineOffset + edgeStencilLength + (lCoarseNodesPerDim[0] - 2) * faceStencilLength) * blkSize;
620 for (
LO l = 0; l < blkSize; ++l) {
621 for (
LO k = 0; k < 3; ++k) {
622 for (
LO j = 0; j < 5; ++j) {
623 for (
LO i = 0; i < 3; ++i) {
624 entries_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
625 values_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i];
630 for (
LO l = 0; l < blkSize; ++l) {
631 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
633 for (
int dim = 0; dim < numDimensions; ++dim) {
634 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
638 coordRowIdx = ((lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (edgeIdx + 1) * lCoarseNodesPerDim[0]);
639 rowIdx = coordRowIdx * blkSize;
640 coordColumnOffset = ((lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (edgeIdx + 1) * 3 * lFineNodesPerDim[0]);
641 columnOffset = coordColumnOffset * blkSize;
642 entryOffset = (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset + edgeLineOffset + edgeIdx * faceLineOffset) * blkSize;
643 for (
LO l = 0; l < blkSize; ++l) {
644 for (
LO k = 0; k < 3; ++k) {
645 for (
LO j = 0; j < 5; ++j) {
646 for (
LO i = 0; i < 3; ++i) {
647 entries_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
648 values_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i + 2];
653 for (
LO l = 0; l < blkSize; ++l) {
654 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
656 for (
int dim = 0; dim < numDimensions; ++dim) {
657 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
661 coordRowIdx = ((lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (edgeIdx + 1) * lCoarseNodesPerDim[0] + lCoarseNodesPerDim[0] - 1);
662 rowIdx = coordRowIdx * blkSize;
663 coordColumnOffset = ((lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (edgeIdx + 1) * 3 * lFineNodesPerDim[0] + lFineNodesPerDim[0] - 1);
664 columnOffset = coordColumnOffset * blkSize;
665 entryOffset = (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset + edgeLineOffset + edgeIdx * faceLineOffset + edgeStencilLength + (lCoarseNodesPerDim[0] - 2) * faceStencilLength) * blkSize;
666 for (
LO l = 0; l < blkSize; ++l) {
667 for (
LO k = 0; k < 3; ++k) {
668 for (
LO j = 0; j < 5; ++j) {
669 for (
LO i = 0; i < 3; ++i) {
670 entries_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
671 values_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
676 for (
LO l = 0; l < blkSize; ++l) {
677 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
679 for (
int dim = 0; dim < numDimensions; ++dim) {
680 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
686 if (lCoarseNodesPerDim[2] - 2 > 0) {
687 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
688 for (
LO edgeIdx = 0; edgeIdx < lCoarseNodesPerDim[2] - 2; ++edgeIdx) {
690 coordRowIdx = (edgeIdx + 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
691 rowIdx = coordRowIdx * blkSize;
692 coordColumnOffset = (edgeIdx + 1) * 3 * lFineNodesPerDim[1] * lFineNodesPerDim[0];
693 columnOffset = coordColumnOffset * blkSize;
694 entryOffset = (facePlaneOffset + edgeIdx * interiorPlaneOffset) * blkSize;
695 for (
LO l = 0; l < blkSize; ++l) {
696 for (
LO k = 0; k < 5; ++k) {
697 for (
LO j = 0; j < 3; ++j) {
698 for (
LO i = 0; i < 3; ++i) {
699 entries_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i) * blkSize + l;
700 values_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i + 2];
705 for (
LO l = 0; l < blkSize; ++l) {
706 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
708 for (
int dim = 0; dim < numDimensions; ++dim) {
709 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
713 coordRowIdx = ((edgeIdx + 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + lCoarseNodesPerDim[0] - 1);
714 rowIdx = coordRowIdx * blkSize;
715 coordColumnOffset = ((edgeIdx + 1) * 3 * lFineNodesPerDim[1] * lFineNodesPerDim[0] + lFineNodesPerDim[0] - 1);
716 columnOffset = coordColumnOffset * blkSize;
717 entryOffset = (facePlaneOffset + faceLineOffset - edgeStencilLength + edgeIdx * interiorPlaneOffset) * blkSize;
718 for (
LO l = 0; l < blkSize; ++l) {
719 for (
LO k = 0; k < 5; ++k) {
720 for (
LO j = 0; j < 3; ++j) {
721 for (
LO i = 0; i < 3; ++i) {
722 entries_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i - 2) * blkSize + l;
723 values_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i];
728 for (
LO l = 0; l < blkSize; ++l) {
729 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
731 for (
int dim = 0; dim < numDimensions; ++dim) {
732 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
736 coordRowIdx = ((edgeIdx + 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (lCoarseNodesPerDim[1] - 1) * lCoarseNodesPerDim[0]);
737 rowIdx = coordRowIdx * blkSize;
738 coordColumnOffset = ((edgeIdx + 1) * 3 * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (lFineNodesPerDim[1] - 1) * lFineNodesPerDim[0]);
739 columnOffset = coordColumnOffset * blkSize;
740 entryOffset = (facePlaneOffset + edgeIdx * interiorPlaneOffset + faceLineOffset + (lCoarseNodesPerDim[1] - 2) * interiorLineOffset) * blkSize;
741 for (
LO l = 0; l < blkSize; ++l) {
742 for (
LO k = 0; k < 5; ++k) {
743 for (
LO j = 0; j < 3; ++j) {
744 for (
LO i = 0; i < 3; ++i) {
745 entries_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
746 values_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i + 2];
751 for (
LO l = 0; l < blkSize; ++l) {
752 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
754 for (
int dim = 0; dim < numDimensions; ++dim) {
755 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
759 coordRowIdx = ((edgeIdx + 2) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] - 1);
760 rowIdx = coordRowIdx * blkSize;
761 coordColumnOffset = ((edgeIdx + 1) * 3 * lFineNodesPerDim[1] * lFineNodesPerDim[0] + lFineNodesPerDim[1] * lFineNodesPerDim[0] - 1);
762 columnOffset = coordColumnOffset * blkSize;
763 entryOffset = (facePlaneOffset + (edgeIdx + 1) * interiorPlaneOffset - edgeStencilLength) * blkSize;
764 for (
LO l = 0; l < blkSize; ++l) {
765 for (
LO k = 0; k < 5; ++k) {
766 for (
LO j = 0; j < 3; ++j) {
767 for (
LO i = 0; i < 3; ++i) {
768 entries_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
769 values_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
774 for (
LO l = 0; l < blkSize; ++l) {
775 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
777 for (
int dim = 0; dim < numDimensions; ++dim) {
778 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
784 if ((lCoarseNodesPerDim[0] - 2 > 0) && (lCoarseNodesPerDim[1] - 2 > 0)) {
786 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
787 for (
LO faceIdx = 0; faceIdx < (lCoarseNodesPerDim[1] - 2) * (lCoarseNodesPerDim[0] - 2); ++faceIdx) {
789 coordRowIdx = ((gridIdx[1] + 1) * lCoarseNodesPerDim[0] + gridIdx[0] + 1);
790 rowIdx = coordRowIdx * blkSize;
791 coordColumnOffset = 3 * ((gridIdx[1] + 1) * lFineNodesPerDim[0] + gridIdx[0] + 1);
792 columnOffset = coordColumnOffset * blkSize;
793 entryOffset = (edgeLineOffset + edgeStencilLength + gridIdx[1] * faceLineOffset + gridIdx[0] * faceStencilLength) * blkSize;
794 for (
LO l = 0; l < blkSize; ++l) {
795 for (
LO k = 0; k < 3; ++k) {
796 for (
LO j = 0; j < 5; ++j) {
797 for (
LO i = 0; i < 5; ++i) {
798 entries_h(entryOffset + k * 25 + j * 5 + i + faceStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
799 values_h(entryOffset + k * 25 + j * 5 + i + faceStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i];
804 for (
LO l = 0; l < blkSize; ++l) {
805 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
807 for (
int dim = 0; dim < numDimensions; ++dim) {
808 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
812 coordRowIdx += (lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
813 rowIdx = coordRowIdx * blkSize;
814 coordColumnOffset += (lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0];
815 columnOffset = coordColumnOffset * blkSize;
816 entryOffset += (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset) * blkSize;
817 for (
LO l = 0; l < blkSize; ++l) {
818 for (
LO k = 0; k < 3; ++k) {
819 for (
LO j = 0; j < 5; ++j) {
820 for (
LO i = 0; i < 5; ++i) {
821 entries_h(entryOffset + k * 25 + j * 5 + i + faceStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
822 values_h(entryOffset + k * 25 + j * 5 + i + faceStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
827 for (
LO l = 0; l < blkSize; ++l) {
828 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
830 for (
int dim = 0; dim < numDimensions; ++dim) {
831 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
838 if (gridIdx[0] == lCoarseNodesPerDim[0] - 2) {
846 if ((lCoarseNodesPerDim[0] - 2 > 0) && (lCoarseNodesPerDim[2] - 2 > 0)) {
848 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
849 for (
LO faceIdx = 0; faceIdx < (lCoarseNodesPerDim[2] - 2) * (lCoarseNodesPerDim[0] - 2); ++faceIdx) {
851 coordRowIdx = ((gridIdx[2] + 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (gridIdx[0] + 1));
852 rowIdx = coordRowIdx * blkSize;
853 coordColumnOffset = ((gridIdx[2] + 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + gridIdx[0] + 1) * 3;
854 columnOffset = coordColumnOffset * blkSize;
855 entryOffset = (facePlaneOffset + gridIdx[2] * interiorPlaneOffset + edgeStencilLength + gridIdx[0] * faceStencilLength) * blkSize;
856 for (
LO l = 0; l < blkSize; ++l) {
857 for (
LO k = 0; k < 5; ++k) {
858 for (
LO j = 0; j < 3; ++j) {
859 for (
LO i = 0; i < 5; ++i) {
860 entries_h(entryOffset + k * 15 + j * 5 + i + faceStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i - 2) * blkSize + l;
861 values_h(entryOffset + k * 15 + j * 5 + i + faceStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i];
866 for (
LO l = 0; l < blkSize; ++l) {
867 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
869 for (
int dim = 0; dim < numDimensions; ++dim) {
870 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
874 coordRowIdx += (lCoarseNodesPerDim[1] - 1) * lCoarseNodesPerDim[0];
875 rowIdx = coordRowIdx * blkSize;
876 coordColumnOffset += (lFineNodesPerDim[1] - 1) * lFineNodesPerDim[0];
877 columnOffset = coordColumnOffset * blkSize;
878 entryOffset += (faceLineOffset + (lCoarseNodesPerDim[1] - 2) * interiorLineOffset) * blkSize;
879 for (
LO l = 0; l < blkSize; ++l) {
880 for (
LO k = 0; k < 5; ++k) {
881 for (
LO j = 0; j < 3; ++j) {
882 for (
LO i = 0; i < 5; ++i) {
883 entries_h(entryOffset + k * 15 + j * 5 + i + faceStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
884 values_h(entryOffset + k * 15 + j * 5 + i + faceStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
889 for (
LO l = 0; l < blkSize; ++l) {
890 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
892 for (
int dim = 0; dim < numDimensions; ++dim) {
893 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
900 if (gridIdx[0] == lCoarseNodesPerDim[0] - 2) {
908 if ((lCoarseNodesPerDim[1] - 2 > 0) && (lCoarseNodesPerDim[2] - 2 > 0)) {
910 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
911 for (
LO faceIdx = 0; faceIdx < (lCoarseNodesPerDim[2] - 2) * (lCoarseNodesPerDim[1] - 2); ++faceIdx) {
913 coordRowIdx = ((gridIdx[2] + 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (gridIdx[1] + 1) * lCoarseNodesPerDim[0]);
914 rowIdx = coordRowIdx * blkSize;
915 coordColumnOffset = ((gridIdx[2] + 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (gridIdx[1] + 1) * lFineNodesPerDim[0]) * 3;
916 columnOffset = coordColumnOffset * blkSize;
917 entryOffset = (facePlaneOffset + gridIdx[2] * interiorPlaneOffset + faceLineOffset + gridIdx[1] * interiorLineOffset) * blkSize;
918 for (
LO l = 0; l < blkSize; ++l) {
919 for (
LO k = 0; k < 5; ++k) {
920 for (
LO j = 0; j < 5; ++j) {
921 for (
LO i = 0; i < 3; ++i) {
922 entries_h(entryOffset + k * 15 + j * 3 + i + faceStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
923 values_h(entryOffset + k * 15 + j * 3 + i + faceStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i + 2];
928 for (
LO l = 0; l < blkSize; ++l) {
929 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
931 for (
int dim = 0; dim < numDimensions; ++dim) {
932 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
936 coordRowIdx += (lCoarseNodesPerDim[0] - 1);
937 rowIdx = coordRowIdx * blkSize;
938 coordColumnOffset += (lFineNodesPerDim[0] - 1);
939 columnOffset = coordColumnOffset * blkSize;
940 entryOffset += (faceStencilLength + (lCoarseNodesPerDim[0] - 2) * interiorStencilLength) * blkSize;
941 for (
LO l = 0; l < blkSize; ++l) {
942 for (
LO k = 0; k < 5; ++k) {
943 for (
LO j = 0; j < 5; ++j) {
944 for (
LO i = 0; i < 3; ++i) {
945 entries_h(entryOffset + k * 15 + j * 3 + i + faceStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
946 values_h(entryOffset + k * 15 + j * 3 + i + faceStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
951 for (
LO l = 0; l < blkSize; ++l) {
952 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
954 for (
int dim = 0; dim < numDimensions; ++dim) {
955 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
962 if (gridIdx[1] == lCoarseNodesPerDim[1] - 2) {
969 if (numInteriors > 0) {
974 LO countRowEntries = 0;
976 for (
LO k = -2; k < 3; ++k) {
977 for (
LO j = -2; j < 3; ++j) {
978 for (
LO i = -2; i < 3; ++i) {
979 coordColumnOffsets[countRowEntries] = k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i;
987 for (
LO k = 0; k < 5; ++k) {
988 for (
LO j = 0; j < 5; ++j) {
989 for (
LO i = 0; i < 5; ++i) {
990 interiorValues[countValues] = coeffs[k] * coeffs[j] * coeffs[i];
996 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
998 for (
LO interiorIdx = 0; interiorIdx < numInteriors; ++interiorIdx) {
999 coordRowIdx = ((gridIdx[2] + 1) * lCoarseNodesPerDim[0] * lCoarseNodesPerDim[1] + (gridIdx[1] + 1) * lCoarseNodesPerDim[0] + gridIdx[0] + 1);
1000 rowIdx = coordRowIdx * blkSize;
1001 coordColumnOffset = ((gridIdx[2] + 1) * 3 * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (gridIdx[1] + 1) * 3 * lFineNodesPerDim[0] + (gridIdx[0] + 1) * 3);
1002 columnOffset = coordColumnOffset * blkSize;
1003 entryOffset = (facePlaneOffset + faceLineOffset + faceStencilLength + gridIdx[2] * interiorPlaneOffset + gridIdx[1] * interiorLineOffset + gridIdx[0] * interiorStencilLength) * blkSize;
1004 for (
LO l = 0; l < blkSize; ++l) {
1005 row_map_h(rowIdx + 1 + l) = entryOffset + interiorStencilLength * (l + 1);
1010 for (
LO l = 0; l < blkSize; ++l) {
1011 for (
LO entryIdx = 0; entryIdx < interiorStencilLength; ++entryIdx) {
1012 entries_h(entryOffset + entryIdx + interiorStencilLength * l) = columnOffset + coordColumnOffsets[entryIdx] * blkSize + l;
1013 values_h(entryOffset + entryIdx + interiorStencilLength * l) = interiorValues[entryIdx];
1016 for (
int dim = 0; dim < numDimensions; ++dim) {
1017 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
1024 if (gridIdx[0] == lCoarseNodesPerDim[0] - 2) {
1027 if (gridIdx[1] == lCoarseNodesPerDim[1] - 2) {
1035 Kokkos::deep_copy(row_map, row_map_h);
1036 Kokkos::deep_copy(entries, entries_h);
1037 Kokkos::deep_copy(values, values_h);
1039 local_graph_type localGraph(entries, row_map);
1040 local_matrix_type localR(
"R", numCols, values, localGraph);
1042 R = MatrixFactory::Build(localR,
1053 #define MUELU_REGIONRFACTORY_SHORT
1054 #endif // MUELU_REGIONRFACTORY_DEF_HPP
MueLu::DefaultLocalOrdinal LocalOrdinal
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)
static const NoFactory * get()
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultGlobalOrdinal GlobalOrdinal
Class that holds all level-specific information.
bool isSublist(const std::string &name) const
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
static RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Transpose(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op, bool optimizeTranspose=false, const std::string &label=std::string(), const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
basic_FancyOStream & setShowAllFrontMatter(const bool showAllFrontMatter)
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
void Build3D(const int numDimensions, Array< LO > &lFineNodesPerDim, const RCP< Matrix > &A, const RCP< realvaluedmultivector_type > &fineCoordinates, RCP< Matrix > &R, RCP< realvaluedmultivector_type > &coarseCoordinates, Array< LO > &lCoarseNodesPerDim) const
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
int GetLevelID() const
Return level number.
RCP< const ParameterList > GetValidParameterList() const
Input.
std::string toString(const T &t)