10 #ifndef MUELU_REGIONRFACTORY_DEF_HPP
11 #define MUELU_REGIONRFACTORY_DEF_HPP
23 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
29 "Generating factory of the matrix A");
31 "Number of spatial dimensions in the problem.");
33 "Number of local nodes per spatial dimension on the fine grid.");
35 "Fine level nullspace used to construct the coarse level nullspace.");
37 "Fine level coordinates used to construct piece-wise linear prolongator and coarse level coordinates.");
38 validParamList->
set<
bool>(
"keep coarse coords",
false,
"Flag to keep coordinates for special coarse grid solve");
40 return validParamList;
43 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
46 Input(fineLevel,
"A");
47 Input(fineLevel,
"numDimensions");
48 Input(fineLevel,
"lNodesPerDim");
49 Input(fineLevel,
"Nullspace");
50 Input(fineLevel,
"Coordinates");
54 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
59 if (
const char* dbg = std::getenv(
"MUELU_REGIONRFACTORY_DEBUG")) {
60 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
66 *out <<
"Starting RegionRFactory::Build." << std::endl;
69 const int numDimensions = Get<int>(fineLevel,
"numDimensions");
72 Array<LO> lNodesPerDim = Get<Array<LO> >(fineLevel,
"lNodesPerDim");
73 for (
int dim = 0; dim < numDimensions; ++dim) {
74 lFineNodesPerDim[dim] = lNodesPerDim[dim];
77 *out <<
"numDimensions " << numDimensions <<
" and lFineNodesPerDim: " << lFineNodesPerDim
81 if (numDimensions < 1 || numDimensions > 3) {
82 throw std::runtime_error(
"numDimensions must be 1, 2 or 3!");
84 for (
int dim = 0; dim < numDimensions; ++dim) {
85 if (lFineNodesPerDim[dim] % 3 != 1) {
86 throw std::runtime_error(
"The number of fine node in each direction need to be 3n+1");
91 const RCP<Matrix> A = Get<RCP<Matrix> >(fineLevel,
"A");
94 fineCoordinates = Get<RCP<realvaluedmultivector_type> >(fineLevel,
"Coordinates");
95 if (static_cast<int>(fineCoordinates->getNumVectors()) != numDimensions) {
96 throw std::runtime_error(
"The number of vectors in the coordinates is not equal to numDimensions!");
104 if (numDimensions == 1) {
105 throw std::runtime_error(
"RegionRFactory no implemented for 1D case yet.");
106 }
else if (numDimensions == 2) {
107 throw std::runtime_error(
"RegionRFactory no implemented for 2D case yet.");
108 }
else if (numDimensions == 3) {
109 Build3D(numDimensions, lFineNodesPerDim, A, fineCoordinates,
110 R, coarseCoordinates, lCoarseNodesPerDim);
117 if (pL.
isSublist(
"matrixmatrix: kernel params"))
123 *out <<
"Compute P=R^t" << std::endl;
125 Tparams->
set(
"compute global constants: temporaries", Tparams->
get(
"compute global constants: temporaries",
false));
126 Tparams->
set(
"compute global constants", Tparams->
get(
"compute global constants",
false));
130 *out <<
"Compute coarse nullspace" << std::endl;
131 RCP<MultiVector> fineNullspace = Get<RCP<MultiVector> >(fineLevel,
"Nullspace");
132 RCP<MultiVector> coarseNullspace = MultiVectorFactory::Build(R->getRowMap(),
133 fineNullspace->getNumVectors());
137 *out <<
"Set data on coarse level" << std::endl;
138 Set(coarseLevel,
"numDimensions", numDimensions);
139 Set(coarseLevel,
"lNodesPerDim", lCoarseNodesPerDim);
140 Set(coarseLevel,
"Nullspace", coarseNullspace);
141 Set(coarseLevel,
"Coordinates", coarseCoordinates);
142 if (pL.
get<
bool>(
"keep coarse coords")) {
146 R->SetFixedBlockSize(A->GetFixedBlockSize());
147 P->SetFixedBlockSize(A->GetFixedBlockSize());
149 Set(coarseLevel,
"R", R);
150 Set(coarseLevel,
"P", P);
154 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
163 using local_matrix_type =
typename CrsMatrix::local_matrix_type;
164 using local_graph_type =
typename local_matrix_type::staticcrsgraph_type;
165 using row_map_type =
typename local_matrix_type::row_map_type::non_const_type;
166 using entries_type =
typename local_matrix_type::index_type::non_const_type;
167 using values_type =
typename local_matrix_type::values_type::non_const_type;
171 if (
const char* dbg = std::getenv(
"MUELU_REGIONRFACTORY_DEBUG")) {
172 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
179 for (
int dim = 0; dim < numDimensions; ++dim) {
180 lCoarseNodesPerDim[dim] = lFineNodesPerDim[dim] / 3 + 1;
182 *out <<
"lCoarseNodesPerDim " << lCoarseNodesPerDim << std::endl;
185 const LO blkSize = A->GetFixedBlockSize();
186 *out <<
"blkSize " << blkSize << std::endl;
190 const LO numRows = blkSize * lCoarseNodesPerDim[0] * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[2];
191 const LO numCols = blkSize * lFineNodesPerDim[0] * lFineNodesPerDim[1] * lFineNodesPerDim[2];
196 RCP<Map> rowMap = MapFactory::Build(A->getRowMap()->lib(),
199 A->getRowMap()->getIndexBase(),
200 A->getRowMap()->getComm());
202 RCP<Map> coordRowMap = MapFactory::Build(A->getRowMap()->lib(),
204 lCoarseNodesPerDim[0] * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[2],
205 A->getRowMap()->getIndexBase(),
206 A->getRowMap()->getComm());
212 for (
int dim = 0; dim < numDimensions; ++dim) {
213 fineCoordData[dim] = fineCoordinates->getData(dim);
214 coarseCoordData[dim] = coarseCoordinates->getDataNonConst(dim);
221 const LO cornerStencilLength = 27;
222 const LO edgeStencilLength = 45;
223 const LO faceStencilLength = 75;
224 const LO interiorStencilLength = 125;
227 const LO numCorners = 8;
228 const LO numEdges = 4 * (lCoarseNodesPerDim[0] - 2) + 4 * (lCoarseNodesPerDim[1] - 2) + 4 * (lCoarseNodesPerDim[2] - 2);
229 const LO numFaces = 2 * (lCoarseNodesPerDim[0] - 2) * (lCoarseNodesPerDim[1] - 2) + 2 * (lCoarseNodesPerDim[0] - 2) * (lCoarseNodesPerDim[2] - 2) + 2 * (lCoarseNodesPerDim[1] - 2) * (lCoarseNodesPerDim[2] - 2);
230 const LO numInteriors = (lCoarseNodesPerDim[0] - 2) * (lCoarseNodesPerDim[1] - 2) * (lCoarseNodesPerDim[2] - 2);
232 const LO nnz = (numCorners * cornerStencilLength + numEdges * edgeStencilLength + numFaces * faceStencilLength + numInteriors * interiorStencilLength) * blkSize;
237 *out <<
"R statistics:" << std::endl
238 <<
" -numRows= " << numRows << std::endl
239 <<
" -numCols= " << numCols << std::endl
240 <<
" -nnz= " << nnz << std::endl;
242 row_map_type row_map(Kokkos::ViewAllocateWithoutInitializing(
"row_map"), numRows + 1);
243 typename row_map_type::HostMirror row_map_h = Kokkos::create_mirror_view(row_map);
245 entries_type entries(Kokkos::ViewAllocateWithoutInitializing(
"entries"), nnz);
246 typename entries_type::HostMirror entries_h = Kokkos::create_mirror_view(entries);
248 values_type values(Kokkos::ViewAllocateWithoutInitializing(
"values"), nnz);
249 typename values_type::HostMirror values_h = Kokkos::create_mirror_view(values);
254 Array<SC> coeffs({1.0 / 3.0, 2.0 / 3.0, 1.0, 2.0 / 3.0, 1.0 / 3.0});
259 const LO edgeLineOffset = 2 * cornerStencilLength + (lCoarseNodesPerDim[0] - 2) * edgeStencilLength;
260 const LO faceLineOffset = 2 * edgeStencilLength + (lCoarseNodesPerDim[0] - 2) * faceStencilLength;
261 const LO interiorLineOffset = 2 * faceStencilLength + (lCoarseNodesPerDim[0] - 2) * interiorStencilLength;
263 const LO facePlaneOffset = 2 * edgeLineOffset + (lCoarseNodesPerDim[1] - 2) * faceLineOffset;
264 const LO interiorPlaneOffset = 2 * faceLineOffset + (lCoarseNodesPerDim[1] - 2) * interiorLineOffset;
271 LO coordRowIdx = 0, rowIdx = 0, coordColumnOffset = 0, columnOffset = 0, entryOffset = 0;
272 for (
LO l = 0; l < blkSize; ++l) {
273 for (
LO k = 0; k < 3; ++k) {
274 for (
LO j = 0; j < 3; ++j) {
275 for (
LO i = 0; i < 3; ++i) {
276 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i) * blkSize + l;
277 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k + 2] * coeffs[j + 2] * coeffs[i + 2];
282 for (
LO l = 0; l < blkSize; ++l) {
283 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
285 for (
int dim = 0; dim < numDimensions; ++dim) {
286 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
290 coordRowIdx += (lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
291 rowIdx = coordRowIdx * blkSize;
292 coordColumnOffset += (lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0];
293 columnOffset = coordColumnOffset * blkSize;
294 entryOffset += (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset) * blkSize;
295 for (
LO l = 0; l < blkSize; ++l) {
296 for (
LO k = 0; k < 3; ++k) {
297 for (
LO j = 0; j < 3; ++j) {
298 for (
LO i = 0; i < 3; ++i) {
299 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i) * blkSize + l;
300 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i + 2];
305 for (
LO l = 0; l < blkSize; ++l) {
306 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
308 for (
int dim = 0; dim < numDimensions; ++dim) {
309 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
313 coordRowIdx = (lCoarseNodesPerDim[0] - 1);
314 rowIdx = coordRowIdx * blkSize;
315 coordColumnOffset = (lFineNodesPerDim[0] - 1);
316 columnOffset = coordColumnOffset * blkSize;
317 entryOffset = (cornerStencilLength + (lCoarseNodesPerDim[0] - 2) * edgeStencilLength) * blkSize;
318 for (
LO l = 0; l < blkSize; ++l) {
319 for (
LO k = 0; k < 3; ++k) {
320 for (
LO j = 0; j < 3; ++j) {
321 for (
LO i = 0; i < 3; ++i) {
322 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + (i - 2)) * blkSize + l;
323 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k + 2] * coeffs[j + 2] * coeffs[i];
328 for (
LO l = 0; l < blkSize; ++l) {
329 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
331 for (
int dim = 0; dim < numDimensions; ++dim) {
332 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
336 coordRowIdx += (lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
337 rowIdx = coordRowIdx * blkSize;
338 coordColumnOffset += (lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0];
339 columnOffset = coordColumnOffset * blkSize;
340 entryOffset += (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset) * blkSize;
341 for (
LO l = 0; l < blkSize; ++l) {
342 for (
LO k = 0; k < 3; ++k) {
343 for (
LO j = 0; j < 3; ++j) {
344 for (
LO i = 0; i < 3; ++i) {
345 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i - 2) * blkSize + l;
346 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i];
351 for (
LO l = 0; l < blkSize; ++l) {
352 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
354 for (
int dim = 0; dim < numDimensions; ++dim) {
355 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
359 coordRowIdx = (lCoarseNodesPerDim[1] - 1) * lCoarseNodesPerDim[0];
360 rowIdx = coordRowIdx * blkSize;
361 coordColumnOffset = (lFineNodesPerDim[1] - 1) * lFineNodesPerDim[0];
362 columnOffset = coordColumnOffset * blkSize;
363 entryOffset = (edgeLineOffset + (lCoarseNodesPerDim[1] - 2) * faceLineOffset) * blkSize;
364 for (
LO l = 0; l < blkSize; ++l) {
365 for (
LO k = 0; k < 3; ++k) {
366 for (
LO j = 0; j < 3; ++j) {
367 for (
LO i = 0; i < 3; ++i) {
368 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
369 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i + 2];
374 for (
LO l = 0; l < blkSize; ++l) {
375 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
377 for (
int dim = 0; dim < numDimensions; ++dim) {
378 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
382 coordRowIdx += (lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
383 rowIdx = coordRowIdx * blkSize;
384 coordColumnOffset += (lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0];
385 columnOffset = coordColumnOffset * blkSize;
386 entryOffset += (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset) * blkSize;
387 for (
LO l = 0; l < blkSize; ++l) {
388 for (
LO k = 0; k < 3; ++k) {
389 for (
LO j = 0; j < 3; ++j) {
390 for (
LO i = 0; i < 3; ++i) {
391 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
392 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i + 2];
397 for (
LO l = 0; l < blkSize; ++l) {
398 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
400 for (
int dim = 0; dim < numDimensions; ++dim) {
401 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
405 coordRowIdx = (lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] - 1);
406 rowIdx = coordRowIdx * blkSize;
407 coordColumnOffset = (lFineNodesPerDim[1] * lFineNodesPerDim[0] - 1);
408 columnOffset = coordColumnOffset * blkSize;
409 entryOffset = (edgeLineOffset + (lCoarseNodesPerDim[1] - 2) * faceLineOffset +
410 cornerStencilLength + (lCoarseNodesPerDim[0] - 2) * edgeStencilLength) *
412 for (
LO l = 0; l < blkSize; ++l) {
413 for (
LO k = 0; k < 3; ++k) {
414 for (
LO j = 0; j < 3; ++j) {
415 for (
LO i = 0; i < 3; ++i) {
416 entries_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + (i - 2)) * blkSize + l;
417 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i];
422 for (
LO l = 0; l < blkSize; ++l) {
423 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
425 for (
int dim = 0; dim < numDimensions; ++dim) {
426 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
430 coordRowIdx += (lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
431 rowIdx = coordRowIdx * blkSize;
432 coordColumnOffset += (lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0];
433 columnOffset = coordColumnOffset * blkSize;
434 entryOffset += (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset) * blkSize;
435 for (
LO l = 0; l < blkSize; ++l) {
436 for (
LO k = 0; k < 3; ++k) {
437 for (
LO j = 0; j < 3; ++j) {
438 for (
LO i = 0; i < 3; ++i) {
439 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;
440 values_h(entryOffset + k * 9 + j * 3 + i + cornerStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
445 for (
LO l = 0; l < blkSize; ++l) {
446 row_map_h(rowIdx + 1 + l) = entryOffset + cornerStencilLength * (l + 1);
448 for (
int dim = 0; dim < numDimensions; ++dim) {
449 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
454 if (lCoarseNodesPerDim[0] - 2 > 0) {
455 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
456 for (
LO edgeIdx = 0; edgeIdx < lCoarseNodesPerDim[0] - 2; ++edgeIdx) {
458 coordRowIdx = (edgeIdx + 1);
459 rowIdx = coordRowIdx * blkSize;
460 coordColumnOffset = (edgeIdx + 1) * 3;
461 columnOffset = coordColumnOffset * blkSize;
462 entryOffset = (cornerStencilLength + edgeIdx * edgeStencilLength) * blkSize;
463 for (
LO l = 0; l < blkSize; ++l) {
464 for (
LO k = 0; k < 3; ++k) {
465 for (
LO j = 0; j < 3; ++j) {
466 for (
LO i = 0; i < 5; ++i) {
467 entries_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i - 2) * blkSize + l;
468 values_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = coeffs[k + 2] * coeffs[j + 2] * coeffs[i];
473 for (
LO l = 0; l < blkSize; ++l) {
474 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
476 for (
int dim = 0; dim < numDimensions; ++dim) {
477 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
481 coordRowIdx = ((lCoarseNodesPerDim[1] - 1) * lCoarseNodesPerDim[0] + edgeIdx + 1);
482 rowIdx = coordRowIdx * blkSize;
483 coordColumnOffset = ((lFineNodesPerDim[1] - 1) * lFineNodesPerDim[0] + (edgeIdx + 1) * 3);
484 columnOffset = coordColumnOffset * blkSize;
485 entryOffset = (edgeLineOffset + (lCoarseNodesPerDim[1] - 2) * faceLineOffset + cornerStencilLength + edgeIdx * edgeStencilLength) * blkSize;
486 for (
LO l = 0; l < blkSize; ++l) {
487 for (
LO k = 0; k < 3; ++k) {
488 for (
LO j = 0; j < 3; ++j) {
489 for (
LO i = 0; i < 5; ++i) {
490 entries_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
491 values_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i];
496 for (
LO l = 0; l < blkSize; ++l) {
497 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
499 for (
int dim = 0; dim < numDimensions; ++dim) {
500 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
504 coordRowIdx = ((lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + edgeIdx + 1);
505 rowIdx = coordRowIdx * blkSize;
506 coordColumnOffset = ((lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (edgeIdx + 1) * 3);
507 columnOffset = coordColumnOffset * blkSize;
508 entryOffset = (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset + cornerStencilLength + edgeIdx * edgeStencilLength) * blkSize;
509 for (
LO l = 0; l < blkSize; ++l) {
510 for (
LO k = 0; k < 3; ++k) {
511 for (
LO j = 0; j < 3; ++j) {
512 for (
LO i = 0; i < 5; ++i) {
513 entries_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i - 2) * blkSize + l;
514 values_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i];
519 for (
LO l = 0; l < blkSize; ++l) {
520 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
522 for (
int dim = 0; dim < numDimensions; ++dim) {
523 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
527 coordRowIdx = ((lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (lCoarseNodesPerDim[1] - 1) * lCoarseNodesPerDim[0] + edgeIdx + 1);
528 rowIdx = coordRowIdx * blkSize;
529 coordColumnOffset = ((lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (lFineNodesPerDim[1] - 1) * lFineNodesPerDim[0] + (edgeIdx + 1) * 3);
530 columnOffset = coordColumnOffset * blkSize;
531 entryOffset = (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset + edgeLineOffset + (lCoarseNodesPerDim[1] - 2) * faceLineOffset + cornerStencilLength + edgeIdx * edgeStencilLength) * blkSize;
532 for (
LO l = 0; l < blkSize; ++l) {
533 for (
LO k = 0; k < 3; ++k) {
534 for (
LO j = 0; j < 3; ++j) {
535 for (
LO i = 0; i < 5; ++i) {
536 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;
537 values_h(entryOffset + k * 15 + j * 5 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
542 for (
LO l = 0; l < blkSize; ++l) {
543 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
545 for (
int dim = 0; dim < numDimensions; ++dim) {
546 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
552 if (lCoarseNodesPerDim[1] - 2 > 0) {
553 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
554 for (
LO edgeIdx = 0; edgeIdx < lCoarseNodesPerDim[1] - 2; ++edgeIdx) {
556 coordRowIdx = (edgeIdx + 1) * lCoarseNodesPerDim[0];
557 rowIdx = coordRowIdx * blkSize;
558 coordColumnOffset = (edgeIdx + 1) * 3 * lFineNodesPerDim[0];
559 columnOffset = coordColumnOffset * blkSize;
560 entryOffset = (edgeLineOffset + edgeIdx * faceLineOffset) * blkSize;
561 for (
LO l = 0; l < blkSize; ++l) {
562 for (
LO k = 0; k < 3; ++k) {
563 for (
LO j = 0; j < 5; ++j) {
564 for (
LO i = 0; i < 3; ++i) {
565 entries_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
566 values_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i + 2];
571 for (
LO l = 0; l < blkSize; ++l) {
572 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
574 for (
int dim = 0; dim < numDimensions; ++dim) {
575 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
579 coordRowIdx = ((edgeIdx + 1) * lCoarseNodesPerDim[0] + lCoarseNodesPerDim[0] - 1);
580 rowIdx = coordRowIdx * blkSize;
581 coordColumnOffset = ((edgeIdx + 1) * 3 * lFineNodesPerDim[0] + lFineNodesPerDim[0] - 1);
582 columnOffset = coordColumnOffset * blkSize;
583 entryOffset = (edgeLineOffset + edgeIdx * faceLineOffset + edgeStencilLength + (lCoarseNodesPerDim[0] - 2) * faceStencilLength) * blkSize;
584 for (
LO l = 0; l < blkSize; ++l) {
585 for (
LO k = 0; k < 3; ++k) {
586 for (
LO j = 0; j < 5; ++j) {
587 for (
LO i = 0; i < 3; ++i) {
588 entries_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
589 values_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i];
594 for (
LO l = 0; l < blkSize; ++l) {
595 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
597 for (
int dim = 0; dim < numDimensions; ++dim) {
598 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
602 coordRowIdx = ((lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (edgeIdx + 1) * lCoarseNodesPerDim[0]);
603 rowIdx = coordRowIdx * blkSize;
604 coordColumnOffset = ((lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (edgeIdx + 1) * 3 * lFineNodesPerDim[0]);
605 columnOffset = coordColumnOffset * blkSize;
606 entryOffset = (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset + edgeLineOffset + edgeIdx * faceLineOffset) * blkSize;
607 for (
LO l = 0; l < blkSize; ++l) {
608 for (
LO k = 0; k < 3; ++k) {
609 for (
LO j = 0; j < 5; ++j) {
610 for (
LO i = 0; i < 3; ++i) {
611 entries_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
612 values_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i + 2];
617 for (
LO l = 0; l < blkSize; ++l) {
618 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
620 for (
int dim = 0; dim < numDimensions; ++dim) {
621 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
625 coordRowIdx = ((lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (edgeIdx + 1) * lCoarseNodesPerDim[0] + lCoarseNodesPerDim[0] - 1);
626 rowIdx = coordRowIdx * blkSize;
627 coordColumnOffset = ((lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (edgeIdx + 1) * 3 * lFineNodesPerDim[0] + lFineNodesPerDim[0] - 1);
628 columnOffset = coordColumnOffset * blkSize;
629 entryOffset = (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset + edgeLineOffset + edgeIdx * faceLineOffset + edgeStencilLength + (lCoarseNodesPerDim[0] - 2) * faceStencilLength) * blkSize;
630 for (
LO l = 0; l < blkSize; ++l) {
631 for (
LO k = 0; k < 3; ++k) {
632 for (
LO j = 0; j < 5; ++j) {
633 for (
LO i = 0; i < 3; ++i) {
634 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;
635 values_h(entryOffset + k * 15 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
640 for (
LO l = 0; l < blkSize; ++l) {
641 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
643 for (
int dim = 0; dim < numDimensions; ++dim) {
644 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
650 if (lCoarseNodesPerDim[2] - 2 > 0) {
651 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
652 for (
LO edgeIdx = 0; edgeIdx < lCoarseNodesPerDim[2] - 2; ++edgeIdx) {
654 coordRowIdx = (edgeIdx + 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
655 rowIdx = coordRowIdx * blkSize;
656 coordColumnOffset = (edgeIdx + 1) * 3 * lFineNodesPerDim[1] * lFineNodesPerDim[0];
657 columnOffset = coordColumnOffset * blkSize;
658 entryOffset = (facePlaneOffset + edgeIdx * interiorPlaneOffset) * blkSize;
659 for (
LO l = 0; l < blkSize; ++l) {
660 for (
LO k = 0; k < 5; ++k) {
661 for (
LO j = 0; j < 3; ++j) {
662 for (
LO i = 0; i < 3; ++i) {
663 entries_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i) * blkSize + l;
664 values_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i + 2];
669 for (
LO l = 0; l < blkSize; ++l) {
670 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
672 for (
int dim = 0; dim < numDimensions; ++dim) {
673 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
677 coordRowIdx = ((edgeIdx + 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + lCoarseNodesPerDim[0] - 1);
678 rowIdx = coordRowIdx * blkSize;
679 coordColumnOffset = ((edgeIdx + 1) * 3 * lFineNodesPerDim[1] * lFineNodesPerDim[0] + lFineNodesPerDim[0] - 1);
680 columnOffset = coordColumnOffset * blkSize;
681 entryOffset = (facePlaneOffset + faceLineOffset - edgeStencilLength + edgeIdx * interiorPlaneOffset) * blkSize;
682 for (
LO l = 0; l < blkSize; ++l) {
683 for (
LO k = 0; k < 5; ++k) {
684 for (
LO j = 0; j < 3; ++j) {
685 for (
LO i = 0; i < 3; ++i) {
686 entries_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i - 2) * blkSize + l;
687 values_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i];
692 for (
LO l = 0; l < blkSize; ++l) {
693 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
695 for (
int dim = 0; dim < numDimensions; ++dim) {
696 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
700 coordRowIdx = ((edgeIdx + 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (lCoarseNodesPerDim[1] - 1) * lCoarseNodesPerDim[0]);
701 rowIdx = coordRowIdx * blkSize;
702 coordColumnOffset = ((edgeIdx + 1) * 3 * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (lFineNodesPerDim[1] - 1) * lFineNodesPerDim[0]);
703 columnOffset = coordColumnOffset * blkSize;
704 entryOffset = (facePlaneOffset + edgeIdx * interiorPlaneOffset + faceLineOffset + (lCoarseNodesPerDim[1] - 2) * interiorLineOffset) * blkSize;
705 for (
LO l = 0; l < blkSize; ++l) {
706 for (
LO k = 0; k < 5; ++k) {
707 for (
LO j = 0; j < 3; ++j) {
708 for (
LO i = 0; i < 3; ++i) {
709 entries_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
710 values_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i + 2];
715 for (
LO l = 0; l < blkSize; ++l) {
716 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
718 for (
int dim = 0; dim < numDimensions; ++dim) {
719 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
723 coordRowIdx = ((edgeIdx + 2) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] - 1);
724 rowIdx = coordRowIdx * blkSize;
725 coordColumnOffset = ((edgeIdx + 1) * 3 * lFineNodesPerDim[1] * lFineNodesPerDim[0] + lFineNodesPerDim[1] * lFineNodesPerDim[0] - 1);
726 columnOffset = coordColumnOffset * blkSize;
727 entryOffset = (facePlaneOffset + (edgeIdx + 1) * interiorPlaneOffset - edgeStencilLength) * blkSize;
728 for (
LO l = 0; l < blkSize; ++l) {
729 for (
LO k = 0; k < 5; ++k) {
730 for (
LO j = 0; j < 3; ++j) {
731 for (
LO i = 0; i < 3; ++i) {
732 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;
733 values_h(entryOffset + k * 9 + j * 3 + i + edgeStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
738 for (
LO l = 0; l < blkSize; ++l) {
739 row_map_h(rowIdx + 1 + l) = entryOffset + edgeStencilLength * (l + 1);
741 for (
int dim = 0; dim < numDimensions; ++dim) {
742 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
748 if ((lCoarseNodesPerDim[0] - 2 > 0) && (lCoarseNodesPerDim[1] - 2 > 0)) {
750 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
751 for (
LO faceIdx = 0; faceIdx < (lCoarseNodesPerDim[1] - 2) * (lCoarseNodesPerDim[0] - 2); ++faceIdx) {
753 coordRowIdx = ((gridIdx[1] + 1) * lCoarseNodesPerDim[0] + gridIdx[0] + 1);
754 rowIdx = coordRowIdx * blkSize;
755 coordColumnOffset = 3 * ((gridIdx[1] + 1) * lFineNodesPerDim[0] + gridIdx[0] + 1);
756 columnOffset = coordColumnOffset * blkSize;
757 entryOffset = (edgeLineOffset + edgeStencilLength + gridIdx[1] * faceLineOffset + gridIdx[0] * faceStencilLength) * blkSize;
758 for (
LO l = 0; l < blkSize; ++l) {
759 for (
LO k = 0; k < 3; ++k) {
760 for (
LO j = 0; j < 5; ++j) {
761 for (
LO i = 0; i < 5; ++i) {
762 entries_h(entryOffset + k * 25 + j * 5 + i + faceStencilLength * l) = columnOffset + (k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i - 2) * blkSize + l;
763 values_h(entryOffset + k * 25 + j * 5 + i + faceStencilLength * l) = coeffs[k + 2] * coeffs[j] * coeffs[i];
768 for (
LO l = 0; l < blkSize; ++l) {
769 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
771 for (
int dim = 0; dim < numDimensions; ++dim) {
772 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
776 coordRowIdx += (lCoarseNodesPerDim[2] - 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0];
777 rowIdx = coordRowIdx * blkSize;
778 coordColumnOffset += (lFineNodesPerDim[2] - 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0];
779 columnOffset = coordColumnOffset * blkSize;
780 entryOffset += (facePlaneOffset + (lCoarseNodesPerDim[2] - 2) * interiorPlaneOffset) * blkSize;
781 for (
LO l = 0; l < blkSize; ++l) {
782 for (
LO k = 0; k < 3; ++k) {
783 for (
LO j = 0; j < 5; ++j) {
784 for (
LO i = 0; i < 5; ++i) {
785 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;
786 values_h(entryOffset + k * 25 + j * 5 + i + faceStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
791 for (
LO l = 0; l < blkSize; ++l) {
792 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
794 for (
int dim = 0; dim < numDimensions; ++dim) {
795 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
802 if (gridIdx[0] == lCoarseNodesPerDim[0] - 2) {
810 if ((lCoarseNodesPerDim[0] - 2 > 0) && (lCoarseNodesPerDim[2] - 2 > 0)) {
812 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
813 for (
LO faceIdx = 0; faceIdx < (lCoarseNodesPerDim[2] - 2) * (lCoarseNodesPerDim[0] - 2); ++faceIdx) {
815 coordRowIdx = ((gridIdx[2] + 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (gridIdx[0] + 1));
816 rowIdx = coordRowIdx * blkSize;
817 coordColumnOffset = ((gridIdx[2] + 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + gridIdx[0] + 1) * 3;
818 columnOffset = coordColumnOffset * blkSize;
819 entryOffset = (facePlaneOffset + gridIdx[2] * interiorPlaneOffset + edgeStencilLength + gridIdx[0] * faceStencilLength) * blkSize;
820 for (
LO l = 0; l < blkSize; ++l) {
821 for (
LO k = 0; k < 5; ++k) {
822 for (
LO j = 0; j < 3; ++j) {
823 for (
LO i = 0; i < 5; ++i) {
824 entries_h(entryOffset + k * 15 + j * 5 + i + faceStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i - 2) * blkSize + l;
825 values_h(entryOffset + k * 15 + j * 5 + i + faceStencilLength * l) = coeffs[k] * coeffs[j + 2] * coeffs[i];
830 for (
LO l = 0; l < blkSize; ++l) {
831 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
833 for (
int dim = 0; dim < numDimensions; ++dim) {
834 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
838 coordRowIdx += (lCoarseNodesPerDim[1] - 1) * lCoarseNodesPerDim[0];
839 rowIdx = coordRowIdx * blkSize;
840 coordColumnOffset += (lFineNodesPerDim[1] - 1) * lFineNodesPerDim[0];
841 columnOffset = coordColumnOffset * blkSize;
842 entryOffset += (faceLineOffset + (lCoarseNodesPerDim[1] - 2) * interiorLineOffset) * blkSize;
843 for (
LO l = 0; l < blkSize; ++l) {
844 for (
LO k = 0; k < 5; ++k) {
845 for (
LO j = 0; j < 3; ++j) {
846 for (
LO i = 0; i < 5; ++i) {
847 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;
848 values_h(entryOffset + k * 15 + j * 5 + i + faceStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
853 for (
LO l = 0; l < blkSize; ++l) {
854 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
856 for (
int dim = 0; dim < numDimensions; ++dim) {
857 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
864 if (gridIdx[0] == lCoarseNodesPerDim[0] - 2) {
872 if ((lCoarseNodesPerDim[1] - 2 > 0) && (lCoarseNodesPerDim[2] - 2 > 0)) {
874 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
875 for (
LO faceIdx = 0; faceIdx < (lCoarseNodesPerDim[2] - 2) * (lCoarseNodesPerDim[1] - 2); ++faceIdx) {
877 coordRowIdx = ((gridIdx[2] + 1) * lCoarseNodesPerDim[1] * lCoarseNodesPerDim[0] + (gridIdx[1] + 1) * lCoarseNodesPerDim[0]);
878 rowIdx = coordRowIdx * blkSize;
879 coordColumnOffset = ((gridIdx[2] + 1) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (gridIdx[1] + 1) * lFineNodesPerDim[0]) * 3;
880 columnOffset = coordColumnOffset * blkSize;
881 entryOffset = (facePlaneOffset + gridIdx[2] * interiorPlaneOffset + faceLineOffset + gridIdx[1] * interiorLineOffset) * blkSize;
882 for (
LO l = 0; l < blkSize; ++l) {
883 for (
LO k = 0; k < 5; ++k) {
884 for (
LO j = 0; j < 5; ++j) {
885 for (
LO i = 0; i < 3; ++i) {
886 entries_h(entryOffset + k * 15 + j * 3 + i + faceStencilLength * l) = columnOffset + ((k - 2) * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (j - 2) * lFineNodesPerDim[0] + i) * blkSize + l;
887 values_h(entryOffset + k * 15 + j * 3 + i + faceStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i + 2];
892 for (
LO l = 0; l < blkSize; ++l) {
893 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
895 for (
int dim = 0; dim < numDimensions; ++dim) {
896 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
900 coordRowIdx += (lCoarseNodesPerDim[0] - 1);
901 rowIdx = coordRowIdx * blkSize;
902 coordColumnOffset += (lFineNodesPerDim[0] - 1);
903 columnOffset = coordColumnOffset * blkSize;
904 entryOffset += (faceStencilLength + (lCoarseNodesPerDim[0] - 2) * interiorStencilLength) * blkSize;
905 for (
LO l = 0; l < blkSize; ++l) {
906 for (
LO k = 0; k < 5; ++k) {
907 for (
LO j = 0; j < 5; ++j) {
908 for (
LO i = 0; i < 3; ++i) {
909 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;
910 values_h(entryOffset + k * 15 + j * 3 + i + faceStencilLength * l) = coeffs[k] * coeffs[j] * coeffs[i];
915 for (
LO l = 0; l < blkSize; ++l) {
916 row_map_h(rowIdx + 1 + l) = entryOffset + faceStencilLength * (l + 1);
918 for (
int dim = 0; dim < numDimensions; ++dim) {
919 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
926 if (gridIdx[1] == lCoarseNodesPerDim[1] - 2) {
933 if (numInteriors > 0) {
938 LO countRowEntries = 0;
940 for (
LO k = -2; k < 3; ++k) {
941 for (
LO j = -2; j < 3; ++j) {
942 for (
LO i = -2; i < 3; ++i) {
943 coordColumnOffsets[countRowEntries] = k * lFineNodesPerDim[1] * lFineNodesPerDim[0] + j * lFineNodesPerDim[0] + i;
951 for (
LO k = 0; k < 5; ++k) {
952 for (
LO j = 0; j < 5; ++j) {
953 for (
LO i = 0; i < 5; ++i) {
954 interiorValues[countValues] = coeffs[k] * coeffs[j] * coeffs[i];
960 LO coordRowIdx, rowIdx, coordColumnOffset, columnOffset, entryOffset;
962 for (
LO interiorIdx = 0; interiorIdx < numInteriors; ++interiorIdx) {
963 coordRowIdx = ((gridIdx[2] + 1) * lCoarseNodesPerDim[0] * lCoarseNodesPerDim[1] + (gridIdx[1] + 1) * lCoarseNodesPerDim[0] + gridIdx[0] + 1);
964 rowIdx = coordRowIdx * blkSize;
965 coordColumnOffset = ((gridIdx[2] + 1) * 3 * lFineNodesPerDim[1] * lFineNodesPerDim[0] + (gridIdx[1] + 1) * 3 * lFineNodesPerDim[0] + (gridIdx[0] + 1) * 3);
966 columnOffset = coordColumnOffset * blkSize;
967 entryOffset = (facePlaneOffset + faceLineOffset + faceStencilLength + gridIdx[2] * interiorPlaneOffset + gridIdx[1] * interiorLineOffset + gridIdx[0] * interiorStencilLength) * blkSize;
968 for (
LO l = 0; l < blkSize; ++l) {
969 row_map_h(rowIdx + 1 + l) = entryOffset + interiorStencilLength * (l + 1);
974 for (
LO l = 0; l < blkSize; ++l) {
975 for (
LO entryIdx = 0; entryIdx < interiorStencilLength; ++entryIdx) {
976 entries_h(entryOffset + entryIdx + interiorStencilLength * l) = columnOffset + coordColumnOffsets[entryIdx] * blkSize + l;
977 values_h(entryOffset + entryIdx + interiorStencilLength * l) = interiorValues[entryIdx];
980 for (
int dim = 0; dim < numDimensions; ++dim) {
981 coarseCoordData[dim][coordRowIdx] = fineCoordData[dim][coordColumnOffset];
988 if (gridIdx[0] == lCoarseNodesPerDim[0] - 2) {
991 if (gridIdx[1] == lCoarseNodesPerDim[1] - 2) {
999 Kokkos::deep_copy(row_map, row_map_h);
1000 Kokkos::deep_copy(entries, entries_h);
1001 Kokkos::deep_copy(values, values_h);
1003 local_graph_type localGraph(entries, row_map);
1004 local_matrix_type localR(
"R", numCols, values, localGraph);
1006 R = MatrixFactory::Build(localR,
1017 #define MUELU_REGIONRFACTORY_SHORT
1018 #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 &&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)