Nektar++
PtsField.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: PtsField.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2014 Kilian Lackhove
10 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
11 // Department of Aeronautics, Imperial College London (UK), and Scientific
12 // Computing and Imaging Institute, University of Utah (USA).
13 //
14 // License for the specific language governing rights and limitations under
15 // Permission is hereby granted, free of charge, to any person obtaining a
16 // copy of this software and associated documentation files (the "Software"),
17 // to deal in the Software without restriction, including without limitation
18 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
19 // and/or sell copies of the Software, and to permit persons to whom the
20 // Software is furnished to do so, subject to the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be included
23 // in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31 // DEALINGS IN THE SOFTWARE.
32 //
33 // Description: Pts field
34 //
35 ////////////////////////////////////////////////////////////////////////////////
36 
38 
39 namespace Nektar
40 {
41 namespace LibUtilities
42 {
43 
44 /**
45  * @brief Compute the weights for an interpolation of the field values to physical points
46  *
47  * @param physCoords coordinates of the physical points
48  * @param coord_id id of the coordinate to use for interpolation.
49  *
50  * Set coord_id to -1 to use n-D interpolation for an n-dimensional field.
51  * The most suitable algorithm is chosen automatically.
52  */
54  const Array<OneD, Array<OneD, NekDouble> > &physCoords,
55  short coordId)
56 {
57  ASSERTL1(physCoords.num_elements() >= m_dim,
58  "physCoords is smaller than number of dimesnions");
59 
60  int nPhysPts = physCoords[0].num_elements();
61  int lastProg = 0;
62 
65 
66  // interpolate points and transform
67  for (int i = 0; i < nPhysPts; ++i)
68  {
70  for (int j = 0; j < m_dim; ++j)
71  {
72  physPt[j] = physCoords[j][i];
73  }
74 
75  if (m_dim == 1 || coordId >= 0)
76  {
77  if (m_dim == 1)
78  {
79  coordId = 0;
80  }
81 
82  if (m_pts[0].num_elements() <= 2)
83  {
84  CalcW_Linear(i, physPt[coordId]);
85  }
86  else
87  {
88  CalcW_Quadratic(i, physPt[coordId]);
89  }
90  }
91  else
92  {
93  CalcW_Shepard(i, physPt);
94  }
95 
96  int progress = int(100 * i / nPhysPts);
97  if (m_progressCallback && progress > lastProg)
98  {
99  m_progressCallback(i, nPhysPts);
100  lastProg = progress;
101  }
102  }
103 }
104 
105 
106 /**
107  * @brief Compute weights and perform the interpolate of field values to physical points
108  *
109  * @param physCoords coordinates of the physical points
110  * @param intFields interpolated field at the physical points
111  * @param coord_id id of the coordinate to use for interpolation.
112  *
113  * Set coord_id to -1 to use n-D interpolation for an n-dimensional field.
114  * The most suitable algorithm is chosen automatically.
115  */
117  const Array< OneD, Array< OneD, NekDouble > > &physCoords,
118  Array<OneD, Array<OneD, NekDouble> > &intFields,
119  short int coordId)
120 {
121  CalcWeights(physCoords, coordId);
122  Interpolate(intFields);
123 }
124 
125 
126 /**
127  * @brief Perform the interpolate of field values to physical points
128  *
129  * @param intFields interpolated field at the physical points
130  *
131  * The weights must have already been computed by @CalcWeights or set by
132  * @SetWeights.
133  */
135 {
136  ASSERTL1(m_weights[0].num_elements() == m_neighInds[0].num_elements(),
137  "weights / neighInds mismatch")
138  int nFields = m_fieldNames.size();
139  int nPhysPts = m_weights.num_elements();
140 
141  // interpolate points and transform
142  intFields = Array<OneD, Array<OneD, NekDouble> >(nFields);
143  for (int i = 0; i < nFields; ++i)
144  {
145  intFields[i] = Array<OneD, NekDouble>(nPhysPts);
146 
147  for (int j = 0; j < nPhysPts; ++j)
148  {
149  intFields[i][j] = 0.0;
150 
151  int nPts = m_weights[j].num_elements();
152  for (int k = 0; k < nPts; ++k)
153  {
154  unsigned int nIdx = m_neighInds[j][k];
155  intFields[i][j] += m_weights[j][k] * m_pts[m_dim + i][nIdx];
156  }
157  }
158  }
159 }
160 
161 
162 /**
163  * @brief Set the interpolation weights for an interpolation
164  *
165  * @param weights Interpolation weights for each neighbour.
166  * Structure: m_weights[physPtIdx][neighbourIdx]
167  * @param neighbourInds Indices of the relevant neighbours for each physical point.
168  * Structure: m_neighInds[ptIdx][neighbourIdx]
169  */
171  const Array< OneD, Array< OneD, float > > &weights,
172  const Array< OneD, Array< OneD, unsigned int > > &neighbourInds)
173 {
174  ASSERTL0(weights.num_elements() == neighbourInds.num_elements(),
175  "weights and neighbourInds not of same number of physical points")
176 
177  m_weights = weights;
178  m_neighInds = neighbourInds;
179 
180 }
181 
182 /**
183  * @brief Get the interpolation weights and corresponding neighbour indices
184  *
185  * @param weights Interpolation weights for each neighbour.
186  * Structure: m_weights[physPtIdx][neighbourIdx]
187  * @param neighbourInds Indices of the relevant neighbours for each physical point.
188  * Structure: m_neighInds[ptIdx][neighbourIdx]
189  */
191  Array< OneD, Array< OneD, float > > &weights,
192  Array< OneD, Array< OneD, unsigned int > > &neighbourInds) const
193 {
194  weights = m_weights;
195  neighbourInds = m_neighInds;
196 }
197 
198 /**
199  * @brief Set the connectivity data for ePtsTetBlock and ePtsTriBlock
200  *
201  * @param conn Connectivity data
202  * Connectivity data needed for ePtsTetBlock and ePtsTriBlock. For n Blocks with
203  * m elements each, m_ptsConn is a vector of n arrays with 3*m (ePtsTriBlock) or
204  * 4*m (ePtsTetBlock) entries.
205  */
207 {
208  conn = m_ptsConn;
209 }
210 
211 /**
212  * @brief Get the connectivity data for ePtsTetBlock and ePtsTriBlock
213  *
214  * @param conn Connectivity data
215  * Connectivity data needed for ePtsTetBlock and ePtsTriBlock. For n Blocks with
216  * m elements each, m_ptsConn is a vector of n arrays with 3*m (ePtsTriBlock) or
217  * 4*m (ePtsTetBlock) entries.
218  */
220 {
222  "ptsType must be set before connectivity");
223 
224  m_ptsConn = conn;
225 }
226 
227 
228 void PtsField::SetDim(const int ptsDim)
229 {
230  m_dim = ptsDim;
231 }
232 
233 
234 int PtsField::GetDim() const
235 {
236  return m_dim;
237 }
238 
239 
241 {
242  return m_fieldNames.size();
243 }
244 
245 
246 vector<std::string> PtsField::GetFieldNames() const
247 {
248  return m_fieldNames;
249 }
250 
251 
252 std::string PtsField::GetFieldName(const int i) const
253 {
254  return m_fieldNames[i];
255 }
256 
257 
258 void PtsField::SetFieldNames(const vector<std::string> fieldNames)
259 {
260  ASSERTL0(fieldNames.size() == m_pts.num_elements() - m_dim,
261  "Number of given fieldNames does not match the number of stored fields");
262 
263  m_fieldNames = fieldNames;
264 }
265 
266 
268  const string fieldName)
269 {
270  int nTotvars = m_pts.num_elements();
271  int nPts = m_pts[0].num_elements();
272 
273  ASSERTL1(pts.num_elements() == nPts, "Field size mismatch");
274 
275  // redirect existing pts
276  Array<OneD, Array<OneD, NekDouble> > newpts(nTotvars + 1);
277  for (int i = 0; i < nTotvars; ++i)
278  {
279  newpts[i] = m_pts[i];
280  }
281  newpts[nTotvars] = pts;
282 
283  m_pts = newpts;
284 
285  m_fieldNames.push_back(fieldName);
286 }
287 
288 
290 {
291  return m_pts[0].num_elements();
292 }
293 
294 
295 NekDouble PtsField::GetPointVal(const int fieldInd, const int ptInd) const
296 {
297  return m_pts[fieldInd][ptInd];
298 }
299 
300 
302 {
303  pts = m_pts;
304 }
305 
306 
308 {
309  return m_pts[fieldInd];
310 }
311 
312 
314 {
315  ASSERTL1(pts.num_elements() == m_pts.num_elements(),
316  "Pts field count mismatch");
317 
318  m_pts = pts;
319 }
320 
321 
322 vector<int> PtsField::GetPointsPerEdge() const
323 {
324  return m_nPtsPerEdge;
325 }
326 
327 
328 int PtsField::GetPointsPerEdge(const int i) const
329 {
330  return m_nPtsPerEdge[i];
331 }
332 
333 /**
334  * @brief Set the number of points per edge
335  *
336  * @param nPtsPerEdge Number of points per edge. Empty if the point data has no
337  * specific shape (ePtsLine) or is a block (ePtsTetBlock, ePtsTriBlock), size=1
338  * for ePtsLine and 2 for a ePtsPlane
339  */
340 void PtsField::SetPointsPerEdge(const vector< int > nPtsPerEdge)
341 {
343  "SetPointsPerEdge only supported for ePtsLine and ePtsPlane .");
344 
345  int totPts(1);
346  for (int i = 0; i < nPtsPerEdge.size(); ++i)
347  {
348  totPts = totPts * nPtsPerEdge.at(i);
349  }
350 
351  ASSERTL0(totPts == m_pts.num_elements(),
352  "nPtsPerEdge does not match total number of points");
353 
354  m_nPtsPerEdge = nPtsPerEdge;
355 }
356 
357 
359 {
360  return m_ptsType;
361 }
362 
363 
365 {
366  m_ptsType = type;
367 }
368 
369 
370 /**
371  * @brief Compute interpolation weights for a 1D physical point using linear
372  * interpolation.
373  *
374  * @param physPtIdx The index of the physical point in its storage array
375  * @param coord The coordinate of the physical point
376  */
377 void PtsField::CalcW_Linear(const int physPtIdx, const NekDouble coord)
378 {
379  int npts = m_pts[0].num_elements();
380  int i;
381 
382  int numPts = 2;
383  m_neighInds[physPtIdx] = Array<OneD, unsigned int> (numPts);
384  m_weights[physPtIdx] = Array<OneD, float> (numPts, 0.0);
385 
386  for (i = 0; i < npts - 1; ++i)
387  {
388  if ((m_pts[0][i] <= coord) && (coord <= m_pts[0][i + 1]))
389  {
390  NekDouble pdiff = m_pts[0][i + 1] - m_pts[0][i];
391 
392  m_neighInds[physPtIdx][0] = i;
393  m_neighInds[physPtIdx][1] = i + 1;
394 
395  m_weights[physPtIdx][0] = (m_pts[0][i + 1] - coord) / pdiff;
396  m_weights[physPtIdx][1] = (coord - m_pts[0][i]) / pdiff;
397 
398  break;
399  }
400  }
401  ASSERTL0(i != npts - 1, "Failed to find coordinate " +
402  boost::lexical_cast<string>(coord) +
403  " within provided input points");
404 };
405 
406 
407 /**
408  * @brief Compute interpolation weights for a physical point using a modified
409  * Shepard algorithm.
410  *
411  * @param physPtIdx The index of the physical point in its storage array
412  * @param physPt The coordinates of the physical point
413  *
414  * The algorithm is based on Shepard, D. (1968). A two-dimensional interpolation
415  * function for irregularly-spaced data. Proceedings of the 1968 23rd ACM
416  * National Conference. pp. 517–524.
417  *
418  * In order to save memory, for n dimesnions, only 2^n points are considered.
419  * Contrary to Shepard, we use a fixed number of points with fixed weighting
420  * factors 1/d^n.
421  */
422 void PtsField::CalcW_Shepard(const int physPtIdx,
423  const Array<OneD, NekDouble> &physPt)
424 {
425  // find nearest neighbours
426  vector<PtsPoint> neighbourPts;
427  int numPts = pow(float(2), m_dim);
428  numPts = min(numPts, int(m_pts[0].num_elements() / 2));
429  FindNeighbours(physPt, neighbourPts, numPts);
430 
431  m_neighInds[physPtIdx] = Array<OneD, unsigned int> (numPts);
432  for (int i = 0; i < numPts; i++)
433  {
434  m_neighInds[physPtIdx][i] = neighbourPts.at(i).m_idx;
435  }
436 
437  m_weights[physPtIdx] = Array<OneD, float> (numPts, 0.0);
438 
439  // In case d < kVertexTheSameDouble ( d^2 < kNekSqrtTol), use the exact
440  // point and return
441  for (int i = 0; i < numPts; ++i)
442  {
443  if (neighbourPts[i].m_distSq <= NekConstants::kNekSqrtTol)
444  {
445  m_weights[physPtIdx][i] = 1.0;
446  return;
447  }
448  }
449 
450  NekDouble wSum = 0.0;
451  for (int i = 0; i < numPts; ++i)
452  {
453  m_weights[physPtIdx][i] = 1 / pow(double(neighbourPts[i].m_distSq),
454  double(m_dim / float(2)));
455  wSum += m_weights[physPtIdx][i];
456  }
457 
458  for (int i = 0; i < numPts; ++i)
459  {
460  m_weights[physPtIdx][i] = m_weights[physPtIdx][i] / wSum;
461  }
462 
463  ASSERTL0(Vmath::Nnan(numPts, m_weights[physPtIdx], 1) == 0, "NaN found in weights");
464 
465 }
466 
467 /**
468 * @brief Compute interpolation weights for a 1D physical point using quadratic
469 * interpolation.
470 *
471 * @param physPtIdx The index of the physical point in its storage array
472 * @param coord The coordinate of the physical point
473 */
474 void PtsField::CalcW_Quadratic(const int physPtIdx, const NekDouble coord)
475 {
476  int npts = m_pts[0].num_elements();
477  int i;
478 
479  int numPts = 3;
480  m_neighInds[physPtIdx] = Array<OneD, unsigned int> (numPts);
481  m_weights[physPtIdx] = Array<OneD, float> (numPts, 0.0);
482 
483  for (i = 0; i < npts - 1; ++i)
484  {
485  if ((m_pts[0][i] <= coord) && (coord <= m_pts[0][i + 1]))
486  {
487  NekDouble pdiff = m_pts[0][i + 1] - m_pts[0][i];
488  NekDouble h1, h2, h3;
489 
490  if (i < npts - 2)
491  {
492  // forwards stencil
493  NekDouble pdiff2 = m_pts[0][i + 2] - m_pts[0][i + 1];
494 
495  h1 = (m_pts[0][i + 1] - coord)
496  * (m_pts[0][i + 2] - coord)
497  / (pdiff * (pdiff + pdiff2));
498  h2 = (coord - m_pts[0][i])
499  * (m_pts[0][i + 2] - coord)
500  / (pdiff * pdiff2);
501  h3 = (coord - m_pts[0][i])
502  * (coord - m_pts[0][i + 1])
503  / ((pdiff + pdiff2) * pdiff2);
504 
505  m_neighInds[physPtIdx][0] = i;
506  m_neighInds[physPtIdx][1] = i + 1;
507  m_neighInds[physPtIdx][2] = i + 2;
508  }
509  else
510  {
511  // backwards stencil
512  NekDouble pdiff2 = m_pts[0][i] - m_pts[0][i - 1];
513 
514  h1 = (m_pts[0][i + 1] - coord)
515  * (coord - m_pts[0][i - 1])
516  / (pdiff * pdiff2);
517  h2 = (coord - m_pts[0][i])
518  * (coord - m_pts[0][i - 1])
519  / (pdiff * (pdiff + pdiff2));
520  h3 = (m_pts[0][i] - coord)
521  * (m_pts[0][i + 1] - coord)
522  / ((pdiff + pdiff2) * pdiff);
523 
524  m_neighInds[physPtIdx][0] = i;
525  m_neighInds[physPtIdx][1] = i + 1;
526  m_neighInds[physPtIdx][2] = i - 1;
527  }
528 
529 
530  m_weights[physPtIdx][0] = h1;
531  m_weights[physPtIdx][1] = h2;
532  m_weights[physPtIdx][2] = h3;
533 
534  break;
535  }
536  }
537  ASSERTL0(i != npts - 1, "Failed to find coordinate " +
538  boost::lexical_cast<string>(coord) +
539  " within provided input points");
540 };
541 
542 
543 /**
544  * @brief Compute the square of the euclidean distance between point1 and point2
545  *
546  * @param point1 The first point
547  * @param point2 The second point
548  */
550  const Array< OneD, NekDouble > &point2) const
551 {
552  NekDouble d = 0.0;
553  NekDouble tmp;
554  for (int i = 0; i < point1.num_elements(); i++)
555  {
556  tmp = point1[i] - point2[i];
557  d += tmp * tmp;
558  }
559 
560  return d;
561 }
562 
563 
564 /**
565  * @brief Find nearest neighbours using a brute-force "algorithm".
566  *
567  * @param physPt Coordinates of the physical point its neighbours
568  * we are looking for
569  * @param neighbourPts The points we found
570  * @param numPts The number of points to find
571  *
572  * This iterates over all points, computes the (squared) euclidean distance
573  * and chooses the numPts closest points. Thus, its very expensive and
574  * inefficient.
575  */
577  vector< PtsPoint > &neighbourPts,
578  const unsigned int numPts)
579 {
580  int npts = m_pts[0].num_elements();
581 
582  // generate an initial set of intPts
583  for (int i = 0; i < numPts; ++i)
584  {
585  PtsPoint intPt = PtsPoint(-1, Array<OneD, NekDouble>(m_dim), 1E30);
586  neighbourPts.push_back(intPt);
587  }
588 
589  // generate and iterate over all intPts
590  for (int i = 0; i < npts; ++i)
591  {
593  for (int j = 0; j < m_dim; ++j)
594  {
595  coords[j] = m_pts[j][i];
596  }
597  NekDouble d = DistSq(physPt, coords);
598 
599  if (d < neighbourPts.back().m_distSq)
600  {
601  // create new point struct
602  PtsPoint intPt = PtsPoint(i, coords, d);
603 
604  // add it to list, sort the list and remove last point from the sorted
605  // list
606  neighbourPts.push_back(intPt);
607  sort(neighbourPts.begin(), neighbourPts.end());
608  neighbourPts.pop_back();
609  }
610  }
611 }
612 
613 
614 }
615 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
NekDouble GetPointVal(const int fieldInd, const int ptInd) const
Definition: PtsField.cpp:295
Array< OneD, Array< OneD, unsigned int > > m_neighInds
Indices of the relevant neighbours for each physical point. Structure: m_neighInds[ptIdx][neighbourId...
Definition: PtsField.h:223
void SetDim(const int ptsDim)
Definition: PtsField.cpp:228
Array< OneD, Array< OneD, float > > m_weights
Interpolation weights for each neighbour. Structure: m_weights[physPtIdx][neighbourIdx].
Definition: PtsField.h:220
void SetFieldNames(const vector< std::string > fieldNames)
Definition: PtsField.cpp:258
void AddField(const Array< OneD, NekDouble > &pts, const std::string fieldName)
Definition: PtsField.cpp:267
vector< Array< OneD, int > > m_ptsConn
Connectivity data needed for ePtsTetBlock and ePtsTriBlock. For n Blocks with m elements each...
Definition: PtsField.h:215
static const NekDouble kNekSqrtTol
vector< std::string > GetFieldNames() const
Definition: PtsField.cpp:246
std::string GetFieldName(const int i) const
Definition: PtsField.cpp:252
void FindNeighbours(const Array< OneD, NekDouble > &physPtCoords, vector< PtsPoint > &neighbourPts, const unsigned int numPts=1)
Find nearest neighbours using a brute-force "algorithm".
Definition: PtsField.cpp:576
vector< int > m_nPtsPerEdge
Number of points per edge. Empty if the point data has no specific shape (ePtsLine) or is a block (eP...
Definition: PtsField.h:211
void SetPointsPerEdge(const vector< int > nPtsPerEdge)
Set the number of points per edge.
Definition: PtsField.cpp:340
void GetWeights(Array< OneD, Array< OneD, float > > &weights, Array< OneD, Array< OneD, unsigned int > > &neighbourInds) const
Get the interpolation weights and corresponding neighbour indices.
Definition: PtsField.cpp:190
Array< OneD, Array< OneD, NekDouble > > m_pts
Point data. For a n-dimensional field, the first n fields are the points spatial coordinates. Structure: m_pts[fieldIdx][ptIdx].
Definition: PtsField.h:207
void GetPts(Array< OneD, Array< OneD, NekDouble > > &pts) const
Definition: PtsField.cpp:301
void SetWeights(const Array< OneD, Array< OneD, float > > &weights, const Array< OneD, Array< OneD, unsigned int > > &neighbourInds)
Set the interpolation weights for an interpolation.
Definition: PtsField.cpp:170
void CalcW_Quadratic(const int physPtIdx, const NekDouble coord)
Compute interpolation weights for a 1D physical point using quadratic interpolation.
Definition: PtsField.cpp:474
PtsType m_ptsType
Type of the PtsField.
Definition: PtsField.h:217
PtsType GetPtsType() const
Definition: PtsField.cpp:358
int m_dim
Dimension of the pts field.
Definition: PtsField.h:202
int Nnan(int n, const T *x, const int incx)
Return number of NaN elements of x.
Definition: Vmath.cpp:869
vector< std::string > m_fieldNames
Names of the field variables.
Definition: PtsField.h:204
static std::string npts
Definition: InputFld.cpp:43
double NekDouble
NekDouble DistSq(const Array< OneD, NekDouble > &point1, const Array< OneD, NekDouble > &point2) const
Compute the square of the euclidean distance between point1 and point2.
Definition: PtsField.cpp:549
void SetPtsType(const PtsType type)
Definition: PtsField.cpp:364
void CalcW_Shepard(const int physPtIdx, const Array< OneD, NekDouble > &physPtCoords)
Compute interpolation weights for a physical point using a modified Shepard algorithm.
Definition: PtsField.cpp:422
void Interpolate(const Array< OneD, Array< OneD, NekDouble > > &physCoords, Array< OneD, Array< OneD, NekDouble > > &intFields, short int coordId=-1)
Compute weights and perform the interpolate of field values to physical points.
Definition: PtsField.cpp:116
void CalcW_Linear(const int physPtIdx, const NekDouble coord)
Compute interpolation weights for a 1D physical point using linear interpolation. ...
Definition: PtsField.cpp:377
vector< int > GetPointsPerEdge() const
Definition: PtsField.cpp:322
void GetConnectivity(vector< Array< OneD, int > > &conn) const
Set the connectivity data for ePtsTetBlock and ePtsTriBlock.
Definition: PtsField.cpp:206
void SetPts(Array< OneD, Array< OneD, NekDouble > > &pts)
Definition: PtsField.cpp:313
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:191
void CalcWeights(const Array< OneD, Array< OneD, NekDouble > > &physCoords, short int coordId=-1)
Compute the weights for an interpolation of the field values to physical points.
Definition: PtsField.cpp:53
boost::function< void(const int position, const int goal)> m_progressCallback
Definition: PtsField.h:225
void SetConnectivity(const vector< Array< OneD, int > > &conn)
Get the connectivity data for ePtsTetBlock and ePtsTriBlock.
Definition: PtsField.cpp:219