56 FactoryMonitor m(*
this,
"Line detection (Ray style)", currentLevel);
59 RCP<CoordinateMultiVector> fineCoords;
60 ArrayRCP<coordinate_type> x, y, z;
64 RCP<Matrix> A = Get<RCP<Matrix> >(currentLevel,
"A");
65 LO BlkSize = A->GetFixedBlockSize();
66 RCP<const Map> rowMap = A->getRowMap();
67 LO Ndofs = rowMap->getLocalNumElements();
68 LO Nnodes = Ndofs / BlkSize;
71 const ParameterList& pL = GetParameterList();
72 const std::string lineOrientation = pL.get<std::string>(
"linedetection: orientation");
76 if (lineOrientation ==
"vertical")
78 else if (lineOrientation ==
"horizontal")
80 else if (lineOrientation ==
"coordinates")
83 TEUCHOS_TEST_FOR_EXCEPTION(
false,
Exceptions::RuntimeError,
"LineDetectionFactory: The parameter 'semicoarsen: line orientation' must be either 'vertical', 'horizontal' or 'coordinates'.");
94 GetOStream(
Runtime1) <<
"Number of layers for line detection: " << NumZDir <<
" (information from Level(0))" << std::endl;
97 NumZDir = pL.get<LO>(
"linedetection: num layers");
99 bool CoordsAvail = currentLevel.
IsAvailable(
"Coordinates");
101 if (CoordsAvail ==
true) {
103 fineCoords = Get<RCP<CoordinateMultiVector> >(currentLevel,
"Coordinates");
104 TEUCHOS_TEST_FOR_EXCEPTION(fineCoords->getNumVectors() != 3,
Exceptions::RuntimeError,
"Three coordinates arrays must be supplied if line detection orientation not given.");
105 x = fineCoords->getDataNonConst(0);
106 y = fineCoords->getDataNonConst(1);
107 z = fineCoords->getDataNonConst(2);
108 xptr = x.getRawPtr();
109 yptr = y.getRawPtr();
110 zptr = z.getRawPtr();
112 LO NumCoords = Ndofs / BlkSize;
115 Teuchos::ArrayRCP<LO> TOrigLoc = Teuchos::arcp<LO>(NumCoords);
116 LO* OrigLoc = TOrigLoc.getRawPtr();
117 Teuchos::ArrayRCP<coordinate_type> Txtemp = Teuchos::arcp<coordinate_type>(NumCoords);
119 Teuchos::ArrayRCP<coordinate_type> Tytemp = Teuchos::arcp<coordinate_type>(NumCoords);
121 Teuchos::ArrayRCP<coordinate_type> Tztemp = Teuchos::arcp<coordinate_type>(NumCoords);
126 sort_coordinates(NumCoords, OrigLoc, xptr, yptr, zptr, xtemp, ytemp, ztemp,
true);
131 LO NumNodesPerVertLine = 0;
134 while (index < NumCoords) {
138 while ((next != NumCoords) && (xtemp[next] == xfirst) &&
139 (ytemp[next] == yfirst))
141 if (NumBlocks == 0) {
142 NumNodesPerVertLine = next - index;
151 NumZDir = NumNodesPerVertLine;
152 GetOStream(
Runtime1) <<
"Number of layers for line detection: " << NumZDir <<
" (information reconstructed from provided node coordinates)" << std::endl;
154 TEUCHOS_TEST_FOR_EXCEPTION(
false,
Exceptions::RuntimeError,
"LineDetectionFactory: BuildP: User has to provide valid number of layers (e.g. using the 'line detection: num layers' parameter).");
157 GetOStream(
Runtime1) <<
"Number of layers for line detection: " << NumZDir <<
" (information provided by user through 'line detection: num layers')" << std::endl;
165 GetOStream(
Runtime1) <<
"Number of layers for line detection: " << NumZDir << std::endl;
167 TEUCHOS_TEST_FOR_EXCEPTION(
false,
Exceptions::RuntimeError,
"LineDetectionFactory: BuildP: No NumZLayers variable found. This cannot be.");
173 bool CoordsAvail = currentLevel.
IsAvailable(
"Coordinates");
175 if (CoordsAvail ==
false) {
179 throw Exceptions::RuntimeError(
"Coordinates not generated by previous invocation of LineDetectionFactory's BuildP() method.");
181 fineCoords = Get<RCP<CoordinateMultiVector> >(currentLevel,
"Coordinates");
182 TEUCHOS_TEST_FOR_EXCEPTION(fineCoords->getNumVectors() != 3,
Exceptions::RuntimeError,
"Three coordinates arrays must be supplied if line detection orientation not given.");
183 x = fineCoords->getDataNonConst(0);
184 y = fineCoords->getDataNonConst(1);
185 z = fineCoords->getDataNonConst(2);
186 xptr = x.getRawPtr();
187 yptr = y.getRawPtr();
188 zptr = z.getRawPtr();
193 LO *LayerId, *VertLineId;
194 Teuchos::ArrayRCP<LO> TLayerId = Teuchos::arcp<LO>(Nnodes);
195 LayerId = TLayerId.getRawPtr();
196 Teuchos::ArrayRCP<LO> TVertLineId = Teuchos::arcp<LO>(Nnodes);
197 VertLineId = TVertLineId.getRawPtr();
199 NumZDir = ML_compute_line_info(LayerId, VertLineId, Ndofs, BlkSize,
200 Zorientation_, NumZDir, xptr, yptr, zptr, *(rowMap->getComm()));
205 Set(currentLevel,
"CoarseNumZLayers", NumZDir);
206 Set(currentLevel,
"LineDetection_Layers", TLayerId);
207 Set(currentLevel,
"LineDetection_VertLineIds", TVertLineId);
209 Teuchos::ArrayRCP<LO> TLayerId = Teuchos::arcp<LO>(0);
210 Teuchos::ArrayRCP<LO> TVertLineId = Teuchos::arcp<LO>(0);
211 Teuchos::ArrayRCP<LO> TVertLineIdSmoo = Teuchos::arcp<LO>(0);
215 Set(currentLevel,
"CoarseNumZLayers", NumZDir);
216 Set(currentLevel,
"LineDetection_Layers", TLayerId);
217 Set(currentLevel,
"LineDetection_VertLineIds", TVertLineId);
226LocalOrdinal LineDetectionFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::ML_compute_line_info(
LocalOrdinal LayerId[],
LocalOrdinal VertLineId[],
LocalOrdinal Ndof,
LocalOrdinal DofsPerNode,
LocalOrdinal MeshNumbering,
LocalOrdinal NumNodesPerVertLine,
typename Teuchos::ScalarTraits<Scalar>::coordinateType* xvals,
typename Teuchos::ScalarTraits<Scalar>::coordinateType* yvals,
typename Teuchos::ScalarTraits<Scalar>::coordinateType* zvals,
const Teuchos::Comm<int>& )
const {
227 LO Nnodes, NVertLines, MyNode;
237 if ((xvals == NULL) || (yvals == NULL) || (zvals == NULL)) RetVal = -1;
239 if (NumNodesPerVertLine == -1) RetVal = -4;
240 if (((Ndof / DofsPerNode) % NumNodesPerVertLine) != 0) RetVal = -3;
242 if ((Ndof % DofsPerNode) != 0) RetVal = -2;
244 TEUCHOS_TEST_FOR_EXCEPTION(RetVal == -1,
Exceptions::RuntimeError,
"Not semicoarsening as no mesh numbering information or coordinates are given\n");
245 TEUCHOS_TEST_FOR_EXCEPTION(RetVal == -4,
Exceptions::RuntimeError,
"Not semicoarsening as the number of z nodes is not given.\n");
246 TEUCHOS_TEST_FOR_EXCEPTION(RetVal == -3,
Exceptions::RuntimeError,
"Not semicoarsening as the total number of nodes is not evenly divisible by the number of z direction nodes .\n");
247 TEUCHOS_TEST_FOR_EXCEPTION(RetVal == -2,
Exceptions::RuntimeError,
"Not semicoarsening as something is off with the number of degrees-of-freedom per node.\n");
249 Nnodes = Ndof / DofsPerNode;
250 for (MyNode = 0; MyNode < Nnodes; MyNode++) VertLineId[MyNode] = -1;
251 for (MyNode = 0; MyNode < Nnodes; MyNode++) LayerId[MyNode] = -1;
254 for (MyNode = 0; MyNode < Nnodes; MyNode++) {
255 LayerId[MyNode] = MyNode % NumNodesPerVertLine;
256 VertLineId[MyNode] = (MyNode - LayerId[MyNode]) / NumNodesPerVertLine;
259 NVertLines = Nnodes / NumNodesPerVertLine;
260 for (MyNode = 0; MyNode < Nnodes; MyNode++) {
261 VertLineId[MyNode] = MyNode % NVertLines;
262 LayerId[MyNode] = (MyNode - VertLineId[MyNode]) / NVertLines;
266 NumCoords = Ndof / DofsPerNode;
269 Teuchos::ArrayRCP<LO> TOrigLoc = Teuchos::arcp<LO>(NumCoords);
270 OrigLoc = TOrigLoc.getRawPtr();
271 Teuchos::ArrayRCP<coordinate_type> Txtemp = Teuchos::arcp<coordinate_type>(NumCoords);
272 xtemp = Txtemp.getRawPtr();
273 Teuchos::ArrayRCP<coordinate_type> Tytemp = Teuchos::arcp<coordinate_type>(NumCoords);
274 ytemp = Tytemp.getRawPtr();
275 Teuchos::ArrayRCP<coordinate_type> Tztemp = Teuchos::arcp<coordinate_type>(NumCoords);
276 ztemp = Tztemp.getRawPtr();
282 sort_coordinates(NumCoords, OrigLoc, xvals, yvals, zvals, xtemp, ytemp, ztemp,
true);
287 while (index < NumCoords) {
288 xfirst = xtemp[index];
289 yfirst = ytemp[index];
291 while ((next != NumCoords) && (xtemp[next] == xfirst) &&
292 (ytemp[next] == yfirst))
294 if (NumBlocks == 0) {
295 NumNodesPerVertLine = next - index;
301 for (j = index; j < next; j++) {
302 VertLineId[OrigLoc[j]] = NumBlocks;
303 LayerId[OrigLoc[j]] = count++;
312 for (i = 0; i < Nnodes; i++) {
313 if (VertLineId[i] == -1) {
314 GetOStream(
Warnings1) <<
"Warning: did not assign " << i <<
" to a vertical line?????\n"
317 if (LayerId[i] == -1) {
318 GetOStream(
Warnings1) <<
"Warning: did not assign " << i <<
" to a Layer?????\n"
328 return NumNodesPerVertLine;
334 typename Teuchos::ScalarTraits<Scalar>::coordinateType* xvals,
335 typename Teuchos::ScalarTraits<Scalar>::coordinateType* yvals,
336 typename Teuchos::ScalarTraits<Scalar>::coordinateType* zvals,
337 typename Teuchos::ScalarTraits<Scalar>::coordinateType* xtemp,
338 typename Teuchos::ScalarTraits<Scalar>::coordinateType* ytemp,
339 typename Teuchos::ScalarTraits<Scalar>::coordinateType* ztemp,
341 if (flipXY ==
false) {
342 for (LO i = 0; i < numCoords; i++) xtemp[i] = xvals[i];
344 for (LO i = 0; i < numCoords; i++) xtemp[i] = yvals[i];
346 for (LO i = 0; i < numCoords; i++) OrigLoc[i] = i;
348 ML_az_dsort2(xtemp, numCoords, OrigLoc);
349 if (flipXY ==
false) {
350 for (LO i = 0; i < numCoords; i++) ytemp[i] = yvals[OrigLoc[i]];
352 for (LO i = 0; i < numCoords; i++) ytemp[i] = xvals[OrigLoc[i]];
357 while (index < numCoords) {
360 while ((next != numCoords) && (xtemp[next] == xfirst))
362 ML_az_dsort2(&(ytemp[index]), next - index, &(OrigLoc[index]));
363 for (LO i = index; i < next; i++) ztemp[i] = zvals[OrigLoc[i]];
366 while (subindex != next) {
368 LO subnext = subindex + 1;
369 while ((subnext != next) && (ytemp[subnext] == yfirst)) subnext++;
370 ML_az_dsort2(&(ztemp[subindex]), subnext - subindex, &(OrigLoc[subindex]));
385 typedef Teuchos::ScalarTraits<SC> STS;
409 if (STS::real(dlist[j]) > STS::real(dlist[j - 1])) j = j + 1;
411 if (STS::real(dlist[j - 1]) > STS::real(dK)) {
412 dlist[i - 1] = dlist[j - 1];
413 list2[i - 1] = list2[j - 1];
449 if (STS::real(dlist[j]) > STS::real(dlist[j - 1])) j = j + 1;
450 if (STS::real(dlist[j - 1]) > STS::real(dK)) {
451 dlist[i - 1] = dlist[j - 1];