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 // MueLu: A package for multigrid based preconditioning
4 //
5 // Copyright 2012 NTESS and the MueLu contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef MUELU_LINEDETECTIONFACTORY_DEF_HPP
11 #define MUELU_LINEDETECTIONFACTORY_DEF_HPP
12 
13 #include <Xpetra_Matrix.hpp>
14 //#include <Xpetra_MatrixFactory.hpp>
15 
17 
18 #include "MueLu_Level.hpp"
19 #include "MueLu_MasterList.hpp"
20 #include "MueLu_Monitor.hpp"
21 
22 namespace MueLu {
23 
24 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
26  RCP<ParameterList> validParamList = rcp(new ParameterList());
27 
28 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
29  SET_VALID_ENTRY("linedetection: orientation");
30  SET_VALID_ENTRY("linedetection: num layers");
31 #undef SET_VALID_ENTRY
32 
33  validParamList->set<RCP<const FactoryBase> >("A", Teuchos::null, "Generating factory of the matrix A");
34  validParamList->set<RCP<const FactoryBase> >("Coordinates", Teuchos::null, "Generating factory for coorindates");
35 
36  return validParamList;
37 }
38 
39 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
41  Input(currentLevel, "A");
42 
43  // The factory needs the information about the number of z-layers. While this information is
44  // provided by the user for the finest level, the factory itself is responsible to provide the
45  // corresponding information on the coarser levels. Since a factory cannot be dependent on itself
46  // we use the NoFactory class as generator class, but remove the UserData keep flag, such that
47  // "NumZLayers" is part of the request/release mechanism.
48  // Please note, that this prevents us from having several (independent) CoarsePFactory instances!
49  // TODO: allow factory to dependent on self-generated data for TwoLevelFactories -> introduce ExpertRequest/Release in Level
50  currentLevel.DeclareInput("NumZLayers", NoFactory::get(), this);
51  currentLevel.RemoveKeepFlag("NumZLayers", NoFactory::get(), MueLu::UserData);
52 }
53 
54 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
56  FactoryMonitor m(*this, "Line detection (Ray style)", currentLevel);
57 
58  LO NumZDir = 0;
59  RCP<CoordinateMultiVector> fineCoords;
61  coordinate_type *xptr = NULL, *yptr = NULL, *zptr = NULL;
62 
63  // obtain general variables
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;
69 
70  // collect information provided by user
71  const ParameterList& pL = GetParameterList();
72  const std::string lineOrientation = pL.get<std::string>("linedetection: orientation");
73 
74  // interpret "line orientation" parameter provided by the user on the finest level
75  if (currentLevel.GetLevelID() == 0) {
76  if (lineOrientation == "vertical")
77  Zorientation_ = VERTICAL;
78  else if (lineOrientation == "horizontal")
79  Zorientation_ = HORIZONTAL;
80  else if (lineOrientation == "coordinates")
81  Zorientation_ = GRID_SUPPLIED;
82  else
83  TEUCHOS_TEST_FOR_EXCEPTION(false, Exceptions::RuntimeError, "LineDetectionFactory: The parameter 'semicoarsen: line orientation' must be either 'vertical', 'horizontal' or 'coordinates'.");
84  }
85 
86  // 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!");
87 
88  // obtain number of z layers (variable over levels)
89  // This information is user-provided on the finest level and transferred to the coarser
90  // levels by the SemiCoarsenPFactor using the internal "NumZLayers" variable.
91  if (currentLevel.GetLevelID() == 0) {
92  if (currentLevel.IsAvailable("NumZLayers", NoFactory::get())) {
93  NumZDir = currentLevel.Get<LO>("NumZLayers", NoFactory::get()); // obtain info
94  GetOStream(Runtime1) << "Number of layers for line detection: " << NumZDir << " (information from Level(0))" << std::endl;
95  } else {
96  // check whether user provides information or it can be reconstructed from coordinates
97  NumZDir = pL.get<LO>("linedetection: num layers");
98  if (NumZDir == -1) {
99  bool CoordsAvail = currentLevel.IsAvailable("Coordinates");
100 
101  if (CoordsAvail == true) {
102  // try to reconstruct the number of layers from coordinates
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();
111 
112  LO NumCoords = Ndofs / BlkSize;
113 
114  /* sort coordinates so that we can order things according to lines */
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);
118  coordinate_type* xtemp = Txtemp.getRawPtr();
119  Teuchos::ArrayRCP<coordinate_type> Tytemp = Teuchos::arcp<coordinate_type>(NumCoords);
120  coordinate_type* ytemp = Tytemp.getRawPtr();
121  Teuchos::ArrayRCP<coordinate_type> Tztemp = Teuchos::arcp<coordinate_type>(NumCoords);
122  coordinate_type* ztemp = Tztemp.getRawPtr();
123 
124  // sort coordinates in {x,y,z}vals (returned in {x,y,z}temp) so that we can order things according to lines
125  // switch x and y coordinates for semi-coarsening...
126  sort_coordinates(NumCoords, OrigLoc, xptr, yptr, zptr, xtemp, ytemp, ztemp, true);
127 
128  /* go through each vertical line and populate blockIndices so all */
129  /* dofs within a PDE within a vertical line correspond to one block.*/
130  LO NumBlocks = 0;
131  LO NumNodesPerVertLine = 0;
132  LO index = 0;
133 
134  while (index < NumCoords) {
135  coordinate_type xfirst = xtemp[index];
136  coordinate_type yfirst = ytemp[index];
137  LO next = index + 1;
138  while ((next != NumCoords) && (xtemp[next] == xfirst) &&
139  (ytemp[next] == yfirst))
140  next++;
141  if (NumBlocks == 0) {
142  NumNodesPerVertLine = next - index;
143  }
144  // the number of vertical lines must be the same on all processors
145  // TAW: Sep 14 2015: or zero as we allow "empty" processors
146  // TEUCHOS_TEST_FOR_EXCEPTION(next-index != NumNodesPerVertLine,Exceptions::RuntimeError, "Error code only works for constant block size now!!!\n");
147  NumBlocks++;
148  index = next;
149  }
150 
151  NumZDir = NumNodesPerVertLine;
152  GetOStream(Runtime1) << "Number of layers for line detection: " << NumZDir << " (information reconstructed from provided node coordinates)" << std::endl;
153  } else {
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).");
155  }
156  } else {
157  GetOStream(Runtime1) << "Number of layers for line detection: " << NumZDir << " (information provided by user through 'line detection: num layers')" << std::endl;
158  }
159  } // end else (user provides information or can be reconstructed) on finest level
160  } else {
161  // coarse level information
162  // TODO get rid of NoFactory here and use SemiCoarsenPFactory as source of NumZLayers instead.
163  if (currentLevel.IsAvailable("NumZLayers", NoFactory::get())) {
164  NumZDir = currentLevel.Get<LO>("NumZLayers", NoFactory::get()); // obtain info
165  GetOStream(Runtime1) << "Number of layers for line detection: " << NumZDir << std::endl;
166  } else {
167  TEUCHOS_TEST_FOR_EXCEPTION(false, Exceptions::RuntimeError, "LineDetectionFactory: BuildP: No NumZLayers variable found. This cannot be.");
168  }
169  }
170 
171  // plausibility check and further variable collection
172  if (Zorientation_ == GRID_SUPPLIED) { // On finest level, fetch user-provided coordinates if available...
173  bool CoordsAvail = currentLevel.IsAvailable("Coordinates");
174 
175  if (CoordsAvail == false) {
176  if (currentLevel.GetLevelID() == 0)
177  throw Exceptions::RuntimeError("Coordinates must be supplied if line detection orientation not given.");
178  else
179  throw Exceptions::RuntimeError("Coordinates not generated by previous invocation of LineDetectionFactory's BuildP() method.");
180  }
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();
189  }
190 
191  // perform line detection
192  if (NumZDir > 0) {
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();
198 
199  NumZDir = ML_compute_line_info(LayerId, VertLineId, Ndofs, BlkSize,
200  Zorientation_, NumZDir, xptr, yptr, zptr, *(rowMap->getComm()));
201  // it is NumZDir=NCLayers*NVertLines*DofsPerNode;
202 
203  // store output data on current level
204  // The line detection data is used by the SemiCoarsenPFactory and the line smoothers in Ifpack/Ifpack2
205  Set(currentLevel, "CoarseNumZLayers", NumZDir);
206  Set(currentLevel, "LineDetection_Layers", TLayerId);
207  Set(currentLevel, "LineDetection_VertLineIds", TVertLineId);
208  } else {
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);
212 
213  // store output data on current level
214  // The line detection data is used by the SemiCoarsenPFactory and the line smoothers in Ifpack/Ifpack2
215  Set(currentLevel, "CoarseNumZLayers", NumZDir);
216  Set(currentLevel, "LineDetection_Layers", TLayerId);
217  Set(currentLevel, "LineDetection_VertLineIds", TVertLineId);
218  }
219 
220  // automatically switch to vertical mode on the coarser levels
221  if (Zorientation_ != VERTICAL)
222  Zorientation_ = VERTICAL;
223 }
224 
225 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
227  LO Nnodes, NVertLines, MyNode;
228  LO NumCoords, next; //, subindex, subnext;
229  coordinate_type xfirst, yfirst;
230  coordinate_type *xtemp, *ytemp, *ztemp;
231  LO* OrigLoc;
232  LO i, j, count;
233  LO RetVal;
234 
235  RetVal = 0;
236  if ((MeshNumbering != VERTICAL) && (MeshNumbering != HORIZONTAL)) {
237  if ((xvals == NULL) || (yvals == NULL) || (zvals == NULL)) RetVal = -1;
238  } else {
239  if (NumNodesPerVertLine == -1) RetVal = -4;
240  if (((Ndof / DofsPerNode) % NumNodesPerVertLine) != 0) RetVal = -3;
241  }
242  if ((Ndof % DofsPerNode) != 0) RetVal = -2;
243 
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");
248 
249  Nnodes = Ndof / DofsPerNode;
250  for (MyNode = 0; MyNode < Nnodes; MyNode++) VertLineId[MyNode] = -1;
251  for (MyNode = 0; MyNode < Nnodes; MyNode++) LayerId[MyNode] = -1;
252 
253  if (MeshNumbering == VERTICAL) {
254  for (MyNode = 0; MyNode < Nnodes; MyNode++) {
255  LayerId[MyNode] = MyNode % NumNodesPerVertLine;
256  VertLineId[MyNode] = (MyNode - LayerId[MyNode]) / NumNodesPerVertLine;
257  }
258  } else if (MeshNumbering == HORIZONTAL) {
259  NVertLines = Nnodes / NumNodesPerVertLine;
260  for (MyNode = 0; MyNode < Nnodes; MyNode++) {
261  VertLineId[MyNode] = MyNode % NVertLines;
262  LayerId[MyNode] = (MyNode - VertLineId[MyNode]) / NVertLines;
263  }
264  } else {
265  // coordinates mode: we distinguish between vertical line numbering for semi-coarsening and line smoothing
266  NumCoords = Ndof / DofsPerNode;
267 
268  // reserve temporary memory
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();
277 
278  // build vertical line info for semi-coarsening
279 
280  // sort coordinates in {x,y,z}vals (returned in {x,y,z}temp) so that we can order things according to lines
281  // switch x and y coordinates for semi-coarsening...
282  sort_coordinates(NumCoords, OrigLoc, xvals, yvals, zvals, xtemp, ytemp, ztemp, /*true*/ true);
283 
284  LO NumBlocks = 0;
285  LO index = 0;
286 
287  while (index < NumCoords) {
288  xfirst = xtemp[index];
289  yfirst = ytemp[index];
290  next = index + 1;
291  while ((next != NumCoords) && (xtemp[next] == xfirst) &&
292  (ytemp[next] == yfirst))
293  next++;
294  if (NumBlocks == 0) {
295  NumNodesPerVertLine = next - index;
296  }
297  // The number of vertical lines must be the same on all processors
298  // TAW: Sep 14, 2015: or zero as we allow for empty processors.
299  // TEUCHOS_TEST_FOR_EXCEPTION(next-index != NumNodesPerVertLine,Exceptions::RuntimeError, "Error code only works for constant block size now!!!\n");
300  count = 0;
301  for (j = index; j < next; j++) {
302  VertLineId[OrigLoc[j]] = NumBlocks;
303  LayerId[OrigLoc[j]] = count++;
304  }
305  NumBlocks++;
306  index = next;
307  }
308  }
309 
310  /* check that everyone was assigned */
311 
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"
315  << std::endl;
316  }
317  if (LayerId[i] == -1) {
318  GetOStream(Warnings1) << "Warning: did not assign " << i << " to a Layer?????\n"
319  << std::endl;
320  }
321  }
322 
323  // TAW: Sep 14 2015: relax plausibility checks as we allow for empty processors
324  // MueLu_maxAll(&comm, NumNodesPerVertLine, i);
325  // if (NumNodesPerVertLine == -1) NumNodesPerVertLine = i;
326  // TEUCHOS_TEST_FOR_EXCEPTION(NumNodesPerVertLine != i,Exceptions::RuntimeError, "Different processors have different z direction line lengths?\n");
327 
328  return NumNodesPerVertLine;
329 }
330 
331 /* Private member function to sort coordinates in arrays. This is an expert routine. Do not use or change.*/
332 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
340  bool flipXY) const {
341  if (flipXY == false) { // for line-smoothing
342  for (LO i = 0; i < numCoords; i++) xtemp[i] = xvals[i];
343  } else { // for semi-coarsening
344  for (LO i = 0; i < numCoords; i++) xtemp[i] = yvals[i];
345  }
346  for (LO i = 0; i < numCoords; i++) OrigLoc[i] = i;
347 
348  ML_az_dsort2(xtemp, numCoords, OrigLoc);
349  if (flipXY == false) { // for line-smoothing
350  for (LO i = 0; i < numCoords; i++) ytemp[i] = yvals[OrigLoc[i]];
351  } else {
352  for (LO i = 0; i < numCoords; i++) ytemp[i] = xvals[OrigLoc[i]];
353  }
354 
355  LO index = 0;
356 
357  while (index < numCoords) {
358  coordinate_type xfirst = xtemp[index];
359  LO next = index + 1;
360  while ((next != numCoords) && (xtemp[next] == xfirst))
361  next++;
362  ML_az_dsort2(&(ytemp[index]), next - index, &(OrigLoc[index]));
363  for (LO i = index; i < next; i++) ztemp[i] = zvals[OrigLoc[i]];
364  /* One final sort so that the ztemps are in order */
365  LO subindex = index;
366  while (subindex != next) {
367  coordinate_type yfirst = ytemp[subindex];
368  LO subnext = subindex + 1;
369  while ((subnext != next) && (ytemp[subnext] == yfirst)) subnext++;
370  ML_az_dsort2(&(ztemp[subindex]), subnext - subindex, &(OrigLoc[subindex]));
371  subindex = subnext;
372  }
373  index = next;
374  }
375 }
376 
377 /* Sort coordinates and additional array accordingly (if provided). This is an expert routine borrowed from ML. Do not change.*/
378 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
380  LO l, r, j, i, flag;
381  LO RR2;
382  coordinate_type dRR, dK;
383 
384  // note: we use that routine for sorting coordinates only. No complex coordinates are assumed...
385  typedef Teuchos::ScalarTraits<SC> STS;
386 
387  if (N <= 1) return;
388 
389  l = N / 2 + 1;
390  r = N - 1;
391  l = l - 1;
392  dRR = dlist[l - 1];
393  dK = dlist[l - 1];
394 
395  if (list2 != NULL) {
396  RR2 = list2[l - 1];
397  while (r != 0) {
398  j = l;
399  flag = 1;
400 
401  while (flag == 1) {
402  i = j;
403  j = j + j;
404 
405  if (j > r + 1)
406  flag = 0;
407  else {
408  if (j < r + 1)
409  if (STS::real(dlist[j]) > STS::real(dlist[j - 1])) j = j + 1;
410 
411  if (STS::real(dlist[j - 1]) > STS::real(dK)) {
412  dlist[i - 1] = dlist[j - 1];
413  list2[i - 1] = list2[j - 1];
414  } else {
415  flag = 0;
416  }
417  }
418  }
419  dlist[i - 1] = dRR;
420  list2[i - 1] = RR2;
421 
422  if (l == 1) {
423  dRR = dlist[r];
424  RR2 = list2[r];
425  dK = dlist[r];
426  dlist[r] = dlist[0];
427  list2[r] = list2[0];
428  r = r - 1;
429  } else {
430  l = l - 1;
431  dRR = dlist[l - 1];
432  RR2 = list2[l - 1];
433  dK = dlist[l - 1];
434  }
435  }
436  dlist[0] = dRR;
437  list2[0] = RR2;
438  } else {
439  while (r != 0) {
440  j = l;
441  flag = 1;
442  while (flag == 1) {
443  i = j;
444  j = j + j;
445  if (j > r + 1)
446  flag = 0;
447  else {
448  if (j < r + 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];
452  } else {
453  flag = 0;
454  }
455  }
456  }
457  dlist[i - 1] = dRR;
458  if (l == 1) {
459  dRR = dlist[r];
460  dK = dlist[r];
461  dlist[r] = dlist[0];
462  r = r - 1;
463  } else {
464  l = l - 1;
465  dRR = dlist[l - 1];
466  dK = dlist[l - 1];
467  }
468  }
469  dlist[0] = dRR;
470  }
471 }
472 } // namespace MueLu
473 
474 #endif // MUELU_LINEDETECTIONFACTORY_DEF_HPP
#define SET_VALID_ENTRY(name)
MueLu::DefaultLocalOrdinal LocalOrdinal
T & get(const std::string &name, T def_value)
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
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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:63
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.