MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_LineDetectionFactory_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef MUELU_LINEDETECTIONFACTORY_DEF_HPP
47 #define MUELU_LINEDETECTIONFACTORY_DEF_HPP
48 
49 #include <Xpetra_Matrix.hpp>
50 //#include <Xpetra_MatrixFactory.hpp>
51 
53 
54 #include "MueLu_Level.hpp"
55 #include "MueLu_MasterList.hpp"
56 #include "MueLu_Monitor.hpp"
57 
58 namespace MueLu {
59 
60 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
62  RCP<ParameterList> validParamList = rcp(new ParameterList());
63 
64 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
65  SET_VALID_ENTRY("linedetection: orientation");
66  SET_VALID_ENTRY("linedetection: num layers");
67 #undef SET_VALID_ENTRY
68 
69  validParamList->set<RCP<const FactoryBase> >("A", Teuchos::null, "Generating factory of the matrix A");
70  validParamList->set<RCP<const FactoryBase> >("Coordinates", Teuchos::null, "Generating factory for coorindates");
71 
72  return validParamList;
73 }
74 
75 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
77  Input(currentLevel, "A");
78 
79  // The factory needs the information about the number of z-layers. While this information is
80  // provided by the user for the finest level, the factory itself is responsible to provide the
81  // corresponding information on the coarser levels. Since a factory cannot be dependent on itself
82  // we use the NoFactory class as generator class, but remove the UserData keep flag, such that
83  // "NumZLayers" is part of the request/release mechanism.
84  // Please note, that this prevents us from having several (independent) CoarsePFactory instances!
85  // TODO: allow factory to dependent on self-generated data for TwoLevelFactories -> introduce ExpertRequest/Release in Level
86  currentLevel.DeclareInput("NumZLayers", NoFactory::get(), this);
87  currentLevel.RemoveKeepFlag("NumZLayers", NoFactory::get(), MueLu::UserData);
88 }
89 
90 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
92  FactoryMonitor m(*this, "Line detection (Ray style)", currentLevel);
93 
94  LO NumZDir = 0;
95  RCP<CoordinateMultiVector> fineCoords;
97  coordinate_type *xptr = NULL, *yptr = NULL, *zptr = NULL;
98 
99  // obtain general variables
100  RCP<Matrix> A = Get<RCP<Matrix> >(currentLevel, "A");
101  LO BlkSize = A->GetFixedBlockSize();
102  RCP<const Map> rowMap = A->getRowMap();
103  LO Ndofs = rowMap->getLocalNumElements();
104  LO Nnodes = Ndofs / BlkSize;
105 
106  // collect information provided by user
107  const ParameterList& pL = GetParameterList();
108  const std::string lineOrientation = pL.get<std::string>("linedetection: orientation");
109 
110  // interpret "line orientation" parameter provided by the user on the finest level
111  if (currentLevel.GetLevelID() == 0) {
112  if (lineOrientation == "vertical")
113  Zorientation_ = VERTICAL;
114  else if (lineOrientation == "horizontal")
115  Zorientation_ = HORIZONTAL;
116  else if (lineOrientation == "coordinates")
117  Zorientation_ = GRID_SUPPLIED;
118  else
119  TEUCHOS_TEST_FOR_EXCEPTION(false, Exceptions::RuntimeError, "LineDetectionFactory: The parameter 'semicoarsen: line orientation' must be either 'vertical', 'horizontal' or 'coordinates'.");
120  }
121 
122  // TEUCHOS_TEST_FOR_EXCEPTION(Zorientation_!=VERTICAL, Exceptions::RuntimeError, "LineDetectionFactory: The 'horizontal' or 'coordinates' have not been tested!!!. Please remove this exception check and carefully test these modes!");
123 
124  // obtain number of z layers (variable over levels)
125  // This information is user-provided on the finest level and transferred to the coarser
126  // levels by the SemiCoarsenPFactor using the internal "NumZLayers" variable.
127  if (currentLevel.GetLevelID() == 0) {
128  if (currentLevel.IsAvailable("NumZLayers", NoFactory::get())) {
129  NumZDir = currentLevel.Get<LO>("NumZLayers", NoFactory::get()); // obtain info
130  GetOStream(Runtime1) << "Number of layers for line detection: " << NumZDir << " (information from Level(0))" << std::endl;
131  } else {
132  // check whether user provides information or it can be reconstructed from coordinates
133  NumZDir = pL.get<LO>("linedetection: num layers");
134  if (NumZDir == -1) {
135  bool CoordsAvail = currentLevel.IsAvailable("Coordinates");
136 
137  if (CoordsAvail == true) {
138  // try to reconstruct the number of layers from coordinates
139  fineCoords = Get<RCP<CoordinateMultiVector> >(currentLevel, "Coordinates");
140  TEUCHOS_TEST_FOR_EXCEPTION(fineCoords->getNumVectors() != 3, Exceptions::RuntimeError, "Three coordinates arrays must be supplied if line detection orientation not given.");
141  x = fineCoords->getDataNonConst(0);
142  y = fineCoords->getDataNonConst(1);
143  z = fineCoords->getDataNonConst(2);
144  xptr = x.getRawPtr();
145  yptr = y.getRawPtr();
146  zptr = z.getRawPtr();
147 
148  LO NumCoords = Ndofs / BlkSize;
149 
150  /* sort coordinates so that we can order things according to lines */
151  Teuchos::ArrayRCP<LO> TOrigLoc = Teuchos::arcp<LO>(NumCoords);
152  LO* OrigLoc = TOrigLoc.getRawPtr();
153  Teuchos::ArrayRCP<coordinate_type> Txtemp = Teuchos::arcp<coordinate_type>(NumCoords);
154  coordinate_type* xtemp = Txtemp.getRawPtr();
155  Teuchos::ArrayRCP<coordinate_type> Tytemp = Teuchos::arcp<coordinate_type>(NumCoords);
156  coordinate_type* ytemp = Tytemp.getRawPtr();
157  Teuchos::ArrayRCP<coordinate_type> Tztemp = Teuchos::arcp<coordinate_type>(NumCoords);
158  coordinate_type* ztemp = Tztemp.getRawPtr();
159 
160  // sort coordinates in {x,y,z}vals (returned in {x,y,z}temp) so that we can order things according to lines
161  // switch x and y coordinates for semi-coarsening...
162  sort_coordinates(NumCoords, OrigLoc, xptr, yptr, zptr, xtemp, ytemp, ztemp, true);
163 
164  /* go through each vertical line and populate blockIndices so all */
165  /* dofs within a PDE within a vertical line correspond to one block.*/
166  LO NumBlocks = 0;
167  LO NumNodesPerVertLine = 0;
168  LO index = 0;
169 
170  while (index < NumCoords) {
171  coordinate_type xfirst = xtemp[index];
172  coordinate_type yfirst = ytemp[index];
173  LO next = index + 1;
174  while ((next != NumCoords) && (xtemp[next] == xfirst) &&
175  (ytemp[next] == yfirst))
176  next++;
177  if (NumBlocks == 0) {
178  NumNodesPerVertLine = next - index;
179  }
180  // the number of vertical lines must be the same on all processors
181  // TAW: Sep 14 2015: or zero as we allow "empty" processors
182  // TEUCHOS_TEST_FOR_EXCEPTION(next-index != NumNodesPerVertLine,Exceptions::RuntimeError, "Error code only works for constant block size now!!!\n");
183  NumBlocks++;
184  index = next;
185  }
186 
187  NumZDir = NumNodesPerVertLine;
188  GetOStream(Runtime1) << "Number of layers for line detection: " << NumZDir << " (information reconstructed from provided node coordinates)" << std::endl;
189  } else {
190  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).");
191  }
192  } else {
193  GetOStream(Runtime1) << "Number of layers for line detection: " << NumZDir << " (information provided by user through 'line detection: num layers')" << std::endl;
194  }
195  } // end else (user provides information or can be reconstructed) on finest level
196  } else {
197  // coarse level information
198  // TODO get rid of NoFactory here and use SemiCoarsenPFactory as source of NumZLayers instead.
199  if (currentLevel.IsAvailable("NumZLayers", NoFactory::get())) {
200  NumZDir = currentLevel.Get<LO>("NumZLayers", NoFactory::get()); // obtain info
201  GetOStream(Runtime1) << "Number of layers for line detection: " << NumZDir << std::endl;
202  } else {
203  TEUCHOS_TEST_FOR_EXCEPTION(false, Exceptions::RuntimeError, "LineDetectionFactory: BuildP: No NumZLayers variable found. This cannot be.");
204  }
205  }
206 
207  // plausibility check and further variable collection
208  if (Zorientation_ == GRID_SUPPLIED) { // On finest level, fetch user-provided coordinates if available...
209  bool CoordsAvail = currentLevel.IsAvailable("Coordinates");
210 
211  if (CoordsAvail == false) {
212  if (currentLevel.GetLevelID() == 0)
213  throw Exceptions::RuntimeError("Coordinates must be supplied if line detection orientation not given.");
214  else
215  throw Exceptions::RuntimeError("Coordinates not generated by previous invocation of LineDetectionFactory's BuildP() method.");
216  }
217  fineCoords = Get<RCP<CoordinateMultiVector> >(currentLevel, "Coordinates");
218  TEUCHOS_TEST_FOR_EXCEPTION(fineCoords->getNumVectors() != 3, Exceptions::RuntimeError, "Three coordinates arrays must be supplied if line detection orientation not given.");
219  x = fineCoords->getDataNonConst(0);
220  y = fineCoords->getDataNonConst(1);
221  z = fineCoords->getDataNonConst(2);
222  xptr = x.getRawPtr();
223  yptr = y.getRawPtr();
224  zptr = z.getRawPtr();
225  }
226 
227  // perform line detection
228  if (NumZDir > 0) {
229  LO *LayerId, *VertLineId;
230  Teuchos::ArrayRCP<LO> TLayerId = Teuchos::arcp<LO>(Nnodes);
231  LayerId = TLayerId.getRawPtr();
232  Teuchos::ArrayRCP<LO> TVertLineId = Teuchos::arcp<LO>(Nnodes);
233  VertLineId = TVertLineId.getRawPtr();
234 
235  NumZDir = ML_compute_line_info(LayerId, VertLineId, Ndofs, BlkSize,
236  Zorientation_, NumZDir, xptr, yptr, zptr, *(rowMap->getComm()));
237  // it is NumZDir=NCLayers*NVertLines*DofsPerNode;
238 
239  // store output data on current level
240  // The line detection data is used by the SemiCoarsenPFactory and the line smoothers in Ifpack/Ifpack2
241  Set(currentLevel, "CoarseNumZLayers", NumZDir);
242  Set(currentLevel, "LineDetection_Layers", TLayerId);
243  Set(currentLevel, "LineDetection_VertLineIds", TVertLineId);
244  } else {
245  Teuchos::ArrayRCP<LO> TLayerId = Teuchos::arcp<LO>(0);
246  Teuchos::ArrayRCP<LO> TVertLineId = Teuchos::arcp<LO>(0);
247  Teuchos::ArrayRCP<LO> TVertLineIdSmoo = Teuchos::arcp<LO>(0);
248 
249  // store output data on current level
250  // The line detection data is used by the SemiCoarsenPFactory and the line smoothers in Ifpack/Ifpack2
251  Set(currentLevel, "CoarseNumZLayers", NumZDir);
252  Set(currentLevel, "LineDetection_Layers", TLayerId);
253  Set(currentLevel, "LineDetection_VertLineIds", TVertLineId);
254  }
255 
256  // automatically switch to vertical mode on the coarser levels
257  if (Zorientation_ != VERTICAL)
258  Zorientation_ = VERTICAL;
259 }
260 
261 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
263  LO Nnodes, NVertLines, MyNode;
264  LO NumCoords, next; //, subindex, subnext;
265  coordinate_type xfirst, yfirst;
266  coordinate_type *xtemp, *ytemp, *ztemp;
267  LO* OrigLoc;
268  LO i, j, count;
269  LO RetVal;
270 
271  RetVal = 0;
272  if ((MeshNumbering != VERTICAL) && (MeshNumbering != HORIZONTAL)) {
273  if ((xvals == NULL) || (yvals == NULL) || (zvals == NULL)) RetVal = -1;
274  } else {
275  if (NumNodesPerVertLine == -1) RetVal = -4;
276  if (((Ndof / DofsPerNode) % NumNodesPerVertLine) != 0) RetVal = -3;
277  }
278  if ((Ndof % DofsPerNode) != 0) RetVal = -2;
279 
280  TEUCHOS_TEST_FOR_EXCEPTION(RetVal == -1, Exceptions::RuntimeError, "Not semicoarsening as no mesh numbering information or coordinates are given\n");
281  TEUCHOS_TEST_FOR_EXCEPTION(RetVal == -4, Exceptions::RuntimeError, "Not semicoarsening as the number of z nodes is not given.\n");
282  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");
283  TEUCHOS_TEST_FOR_EXCEPTION(RetVal == -2, Exceptions::RuntimeError, "Not semicoarsening as something is off with the number of degrees-of-freedom per node.\n");
284 
285  Nnodes = Ndof / DofsPerNode;
286  for (MyNode = 0; MyNode < Nnodes; MyNode++) VertLineId[MyNode] = -1;
287  for (MyNode = 0; MyNode < Nnodes; MyNode++) LayerId[MyNode] = -1;
288 
289  if (MeshNumbering == VERTICAL) {
290  for (MyNode = 0; MyNode < Nnodes; MyNode++) {
291  LayerId[MyNode] = MyNode % NumNodesPerVertLine;
292  VertLineId[MyNode] = (MyNode - LayerId[MyNode]) / NumNodesPerVertLine;
293  }
294  } else if (MeshNumbering == HORIZONTAL) {
295  NVertLines = Nnodes / NumNodesPerVertLine;
296  for (MyNode = 0; MyNode < Nnodes; MyNode++) {
297  VertLineId[MyNode] = MyNode % NVertLines;
298  LayerId[MyNode] = (MyNode - VertLineId[MyNode]) / NVertLines;
299  }
300  } else {
301  // coordinates mode: we distinguish between vertical line numbering for semi-coarsening and line smoothing
302  NumCoords = Ndof / DofsPerNode;
303 
304  // reserve temporary memory
305  Teuchos::ArrayRCP<LO> TOrigLoc = Teuchos::arcp<LO>(NumCoords);
306  OrigLoc = TOrigLoc.getRawPtr();
307  Teuchos::ArrayRCP<coordinate_type> Txtemp = Teuchos::arcp<coordinate_type>(NumCoords);
308  xtemp = Txtemp.getRawPtr();
309  Teuchos::ArrayRCP<coordinate_type> Tytemp = Teuchos::arcp<coordinate_type>(NumCoords);
310  ytemp = Tytemp.getRawPtr();
311  Teuchos::ArrayRCP<coordinate_type> Tztemp = Teuchos::arcp<coordinate_type>(NumCoords);
312  ztemp = Tztemp.getRawPtr();
313 
314  // build vertical line info for semi-coarsening
315 
316  // sort coordinates in {x,y,z}vals (returned in {x,y,z}temp) so that we can order things according to lines
317  // switch x and y coordinates for semi-coarsening...
318  sort_coordinates(NumCoords, OrigLoc, xvals, yvals, zvals, xtemp, ytemp, ztemp, /*true*/ true);
319 
320  LO NumBlocks = 0;
321  LO index = 0;
322 
323  while (index < NumCoords) {
324  xfirst = xtemp[index];
325  yfirst = ytemp[index];
326  next = index + 1;
327  while ((next != NumCoords) && (xtemp[next] == xfirst) &&
328  (ytemp[next] == yfirst))
329  next++;
330  if (NumBlocks == 0) {
331  NumNodesPerVertLine = next - index;
332  }
333  // The number of vertical lines must be the same on all processors
334  // TAW: Sep 14, 2015: or zero as we allow for empty processors.
335  // TEUCHOS_TEST_FOR_EXCEPTION(next-index != NumNodesPerVertLine,Exceptions::RuntimeError, "Error code only works for constant block size now!!!\n");
336  count = 0;
337  for (j = index; j < next; j++) {
338  VertLineId[OrigLoc[j]] = NumBlocks;
339  LayerId[OrigLoc[j]] = count++;
340  }
341  NumBlocks++;
342  index = next;
343  }
344  }
345 
346  /* check that everyone was assigned */
347 
348  for (i = 0; i < Nnodes; i++) {
349  if (VertLineId[i] == -1) {
350  GetOStream(Warnings1) << "Warning: did not assign " << i << " to a vertical line?????\n"
351  << std::endl;
352  }
353  if (LayerId[i] == -1) {
354  GetOStream(Warnings1) << "Warning: did not assign " << i << " to a Layer?????\n"
355  << std::endl;
356  }
357  }
358 
359  // TAW: Sep 14 2015: relax plausibility checks as we allow for empty processors
360  // MueLu_maxAll(&comm, NumNodesPerVertLine, i);
361  // if (NumNodesPerVertLine == -1) NumNodesPerVertLine = i;
362  // TEUCHOS_TEST_FOR_EXCEPTION(NumNodesPerVertLine != i,Exceptions::RuntimeError, "Different processors have different z direction line lengths?\n");
363 
364  return NumNodesPerVertLine;
365 }
366 
367 /* Private member function to sort coordinates in arrays. This is an expert routine. Do not use or change.*/
368 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
376  bool flipXY) const {
377  if (flipXY == false) { // for line-smoothing
378  for (LO i = 0; i < numCoords; i++) xtemp[i] = xvals[i];
379  } else { // for semi-coarsening
380  for (LO i = 0; i < numCoords; i++) xtemp[i] = yvals[i];
381  }
382  for (LO i = 0; i < numCoords; i++) OrigLoc[i] = i;
383 
384  ML_az_dsort2(xtemp, numCoords, OrigLoc);
385  if (flipXY == false) { // for line-smoothing
386  for (LO i = 0; i < numCoords; i++) ytemp[i] = yvals[OrigLoc[i]];
387  } else {
388  for (LO i = 0; i < numCoords; i++) ytemp[i] = xvals[OrigLoc[i]];
389  }
390 
391  LO index = 0;
392 
393  while (index < numCoords) {
394  coordinate_type xfirst = xtemp[index];
395  LO next = index + 1;
396  while ((next != numCoords) && (xtemp[next] == xfirst))
397  next++;
398  ML_az_dsort2(&(ytemp[index]), next - index, &(OrigLoc[index]));
399  for (LO i = index; i < next; i++) ztemp[i] = zvals[OrigLoc[i]];
400  /* One final sort so that the ztemps are in order */
401  LO subindex = index;
402  while (subindex != next) {
403  coordinate_type yfirst = ytemp[subindex];
404  LO subnext = subindex + 1;
405  while ((subnext != next) && (ytemp[subnext] == yfirst)) subnext++;
406  ML_az_dsort2(&(ztemp[subindex]), subnext - subindex, &(OrigLoc[subindex]));
407  subindex = subnext;
408  }
409  index = next;
410  }
411 }
412 
413 /* Sort coordinates and additional array accordingly (if provided). This is an expert routine borrowed from ML. Do not change.*/
414 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
416  LO l, r, j, i, flag;
417  LO RR2;
418  coordinate_type dRR, dK;
419 
420  // note: we use that routine for sorting coordinates only. No complex coordinates are assumed...
421  typedef Teuchos::ScalarTraits<SC> STS;
422 
423  if (N <= 1) return;
424 
425  l = N / 2 + 1;
426  r = N - 1;
427  l = l - 1;
428  dRR = dlist[l - 1];
429  dK = dlist[l - 1];
430 
431  if (list2 != NULL) {
432  RR2 = list2[l - 1];
433  while (r != 0) {
434  j = l;
435  flag = 1;
436 
437  while (flag == 1) {
438  i = j;
439  j = j + j;
440 
441  if (j > r + 1)
442  flag = 0;
443  else {
444  if (j < r + 1)
445  if (STS::real(dlist[j]) > STS::real(dlist[j - 1])) j = j + 1;
446 
447  if (STS::real(dlist[j - 1]) > STS::real(dK)) {
448  dlist[i - 1] = dlist[j - 1];
449  list2[i - 1] = list2[j - 1];
450  } else {
451  flag = 0;
452  }
453  }
454  }
455  dlist[i - 1] = dRR;
456  list2[i - 1] = RR2;
457 
458  if (l == 1) {
459  dRR = dlist[r];
460  RR2 = list2[r];
461  dK = dlist[r];
462  dlist[r] = dlist[0];
463  list2[r] = list2[0];
464  r = r - 1;
465  } else {
466  l = l - 1;
467  dRR = dlist[l - 1];
468  RR2 = list2[l - 1];
469  dK = dlist[l - 1];
470  }
471  }
472  dlist[0] = dRR;
473  list2[0] = RR2;
474  } else {
475  while (r != 0) {
476  j = l;
477  flag = 1;
478  while (flag == 1) {
479  i = j;
480  j = j + j;
481  if (j > r + 1)
482  flag = 0;
483  else {
484  if (j < r + 1)
485  if (STS::real(dlist[j]) > STS::real(dlist[j - 1])) j = j + 1;
486  if (STS::real(dlist[j - 1]) > STS::real(dK)) {
487  dlist[i - 1] = dlist[j - 1];
488  } else {
489  flag = 0;
490  }
491  }
492  }
493  dlist[i - 1] = dRR;
494  if (l == 1) {
495  dRR = dlist[r];
496  dK = dlist[r];
497  dlist[r] = dlist[0];
498  r = r - 1;
499  } else {
500  l = l - 1;
501  dRR = dlist[l - 1];
502  dK = dlist[l - 1];
503  }
504  }
505  dlist[0] = dRR;
506  }
507 }
508 } // namespace MueLu
509 
510 #endif // MUELU_LINEDETECTIONFACTORY_DEF_HPP
#define SET_VALID_ENTRY(name)
MueLu::DefaultLocalOrdinal LocalOrdinal
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.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
T * getRawPtr() const
User data are always kept. This flag is set automatically when Level::Set(&quot;data&quot;, data) is used...
LocalOrdinal LO
typename Teuchos::ScalarTraits< SC >::coordinateType coordinate_type
static const NoFactory * get()
void Build(Level &currentLevel) const
Build method.
Additional warnings.
T * getRawPtr() const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void ML_az_dsort2(coordinate_type dlist[], LO N, LO list2[]) const
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
void sort_coordinates(LO numCoords, LO *OrigLoc, coordinate_type *xvals, coordinate_type *yvals, coordinate_type *zvals, coordinate_type *xtemp, coordinate_type *ytemp, coordinate_type *ztemp, bool flipXY=false) const
void RemoveKeepFlag(const std::string &ename, const FactoryBase *factory, KeepType keep=MueLu::All)
LO ML_compute_line_info(LO LayerId[], LO VertLineId[], LO Ndof, LO DofsPerNode, LO MeshNumbering, LO NumNodesPerVertLine, coordinate_type *xvals, coordinate_type *yvals, coordinate_type *zvals, const Teuchos::Comm< int > &comm) const
Exception throws to report errors in the internal logical of the program.
Description of what is happening (more verbose)
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
void DeclareInput(Level &currentLevel) const
Input.