treeBoundBox.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "treeBoundBox.H"
27 #include "ListOps.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 const Foam::scalar Foam::treeBoundBox::great(GREAT);
32 
34 (
35  vector(-GREAT, -GREAT, -GREAT),
36  vector(GREAT, GREAT, GREAT)
37 );
38 
39 
41 (
42  vector(GREAT, GREAT, GREAT),
43  vector(-GREAT, -GREAT, -GREAT)
44 );
45 
46 
48 const Foam::label facesArray[6][4] =
49 {
50  {0, 4, 6, 2}, // left
51  {1, 3, 7, 5}, // right
52  {0, 1, 5, 4}, // bottom
53  {2, 6, 7, 3}, // top
54  {0, 2, 3, 1}, // back
55  {4, 5, 7, 6} // front
56 };
58 
59 
61 (
62  initListList<face, label, 6, 4>(facesArray)
63 );
64 
65 
67 const Foam::label edgesArray[12][2] =
68 {
69  {0, 1}, // 0
70  {1, 3},
71  {2, 3}, // 2
72  {0, 2},
73  {4, 5}, // 4
74  {5, 7},
75  {6, 7}, // 6
76  {4, 6},
77  {0, 4}, // 8
78  {1, 5},
79  {3, 7}, // 10
80  {2, 6}
81 };
83 
84 
86 (
87  //initListList<edge, label, 12, 2>(edgesArray)
88  calcEdges(edgesArray)
89 );
90 
91 
93 (
94  calcFaceNormals()
95 );
96 
97 
98 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
99 
101 {
102  edgeList edges(12);
103  forAll(edges, edgeI)
104  {
105  edges[edgeI][0] = edgesArray[edgeI][0];
106  edges[edgeI][1] = edgesArray[edgeI][1];
107  }
108  return edges;
109 }
110 
111 
113 {
114  FixedList<vector, 6> normals;
115  normals[LEFT] = vector(-1, 0, 0);
116  normals[RIGHT] = vector( 1, 0, 0);
117  normals[BOTTOM] = vector( 0, -1, 0);
118  normals[TOP] = vector( 0, 1, 0);
119  normals[BACK] = vector( 0, 0, -1);
120  normals[FRONT] = vector( 0, 0, 1);
121  return normals;
122 }
123 
124 
125 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
126 
128 :
129  boundBox(points, false)
130 {
131  if (points.empty())
132  {
134  << "cannot find bounding box for zero-sized pointField, "
135  << "returning zero" << endl;
136 
137  return;
138  }
139 }
140 
141 
143 (
144  const UList<point>& points,
145  const labelUList& indices
146 )
147 :
148  boundBox(points, indices, false)
149 {
150  if (points.empty() || indices.empty())
151  {
153  << "cannot find bounding box for zero-sized pointField, "
154  << "returning zero" << endl;
155 
156  return;
157  }
158 }
159 
160 
161 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
162 
164 {
166 
167  pointField& points = tPts();
168 
169  forAll(points, octant)
170  {
171  points[octant] = corner(octant);
172  }
173 
174  return tPts;
175 }
176 
177 
179 {
180  return subBbox(midpoint(), octant);
181 }
182 
183 
184 // Octant to bounding box using permutation only.
186 (
187  const point& mid,
188  const direction octant
189 ) const
190 {
191  if (octant > 7)
192  {
194  << "octant should be [0..7]"
195  << abort(FatalError);
196  }
197 
198  // start with a copy of this bounding box and adjust limits accordingly
199  treeBoundBox subBb(*this);
200  point& bbMin = subBb.min();
201  point& bbMax = subBb.max();
202 
203  if (octant & treeBoundBox::RIGHTHALF)
204  {
205  bbMin.x() = mid.x(); // mid -> max
206  }
207  else
208  {
209  bbMax.x() = mid.x(); // min -> mid
210  }
211 
212  if (octant & treeBoundBox::TOPHALF)
213  {
214  bbMin.y() = mid.y(); // mid -> max
215  }
216  else
217  {
218  bbMax.y() = mid.y(); // min -> mid
219  }
220 
221  if (octant & treeBoundBox::FRONTHALF)
222  {
223  bbMin.z() = mid.z(); // mid -> max
224  }
225  else
226  {
227  bbMax.z() = mid.z(); // min -> mid
228  }
229 
230  return subBb;
231 }
232 
233 
234 // line intersection. Returns true if line (start to end) inside
235 // bb or intersects bb. Sets pt to intersection.
236 //
237 // Sutherlands algorithm:
238 // loop
239 // - start = intersection of line with one of the planes bounding
240 // the bounding box
241 // - stop if start inside bb (return true)
242 // - stop if start and end in same 'half' (e.g. both above bb)
243 // (return false)
244 //
245 // Uses posBits to efficiently determine 'half' in which start and end
246 // point are.
247 //
248 // Note:
249 // - sets coordinate to exact position: e.g. pt.x() = min().x()
250 // since plane intersect routine might have truncation error.
251 // This makes sure that posBits tests 'inside'
253 (
254  const point& overallStart,
255  const vector& overallVec,
256  const point& start,
257  const point& end,
258  point& pt,
259  direction& ptOnFaces
260 ) const
261 {
262  const direction endBits = posBits(end);
263  pt = start;
264 
265  // Allow maximum of 3 clips.
266  for (label i = 0; i < 4; ++i)
267  {
268  direction ptBits = posBits(pt);
269 
270  if (ptBits == 0)
271  {
272  // pt inside bb
273  ptOnFaces = faceBits(pt);
274  return true;
275  }
276 
277  if ((ptBits & endBits) != 0)
278  {
279  // pt and end in same block outside of bb
280  ptOnFaces = faceBits(pt);
281  return false;
282  }
283 
284  if (ptBits & LEFTBIT)
285  {
286  // Intersect with plane V=min, n=-1,0,0
287  if (Foam::mag(overallVec.x()) > VSMALL)
288  {
289  scalar s = (min().x() - overallStart.x())/overallVec.x();
290  pt.x() = min().x();
291  pt.y() = overallStart.y() + overallVec.y()*s;
292  pt.z() = overallStart.z() + overallVec.z()*s;
293  }
294  else
295  {
296  // Vector not in x-direction. But still intersecting bb planes.
297  // So must be close - just snap to bb.
298  pt.x() = min().x();
299  }
300  }
301  else if (ptBits & RIGHTBIT)
302  {
303  // Intersect with plane V=max, n=1,0,0
304  if (Foam::mag(overallVec.x()) > VSMALL)
305  {
306  scalar s = (max().x() - overallStart.x())/overallVec.x();
307  pt.x() = max().x();
308  pt.y() = overallStart.y() + overallVec.y()*s;
309  pt.z() = overallStart.z() + overallVec.z()*s;
310  }
311  else
312  {
313  pt.x() = max().x();
314  }
315  }
316  else if (ptBits & BOTTOMBIT)
317  {
318  // Intersect with plane V=min, n=0,-1,0
319  if (Foam::mag(overallVec.y()) > VSMALL)
320  {
321  scalar s = (min().y() - overallStart.y())/overallVec.y();
322  pt.x() = overallStart.x() + overallVec.x()*s;
323  pt.y() = min().y();
324  pt.z() = overallStart.z() + overallVec.z()*s;
325  }
326  else
327  {
328  pt.x() = min().y();
329  }
330  }
331  else if (ptBits & TOPBIT)
332  {
333  // Intersect with plane V=max, n=0,1,0
334  if (Foam::mag(overallVec.y()) > VSMALL)
335  {
336  scalar s = (max().y() - overallStart.y())/overallVec.y();
337  pt.x() = overallStart.x() + overallVec.x()*s;
338  pt.y() = max().y();
339  pt.z() = overallStart.z() + overallVec.z()*s;
340  }
341  else
342  {
343  pt.y() = max().y();
344  }
345  }
346  else if (ptBits & BACKBIT)
347  {
348  // Intersect with plane V=min, n=0,0,-1
349  if (Foam::mag(overallVec.z()) > VSMALL)
350  {
351  scalar s = (min().z() - overallStart.z())/overallVec.z();
352  pt.x() = overallStart.x() + overallVec.x()*s;
353  pt.y() = overallStart.y() + overallVec.y()*s;
354  pt.z() = min().z();
355  }
356  else
357  {
358  pt.z() = min().z();
359  }
360  }
361  else if (ptBits & FRONTBIT)
362  {
363  // Intersect with plane V=max, n=0,0,1
364  if (Foam::mag(overallVec.z()) > VSMALL)
365  {
366  scalar s = (max().z() - overallStart.z())/overallVec.z();
367  pt.x() = overallStart.x() + overallVec.x()*s;
368  pt.y() = overallStart.y() + overallVec.y()*s;
369  pt.z() = max().z();
370  }
371  else
372  {
373  pt.z() = max().z();
374  }
375  }
376  }
377 
378  // Can end up here if the end point is on the edge of the boundBox
379  return true;
380 }
381 
382 
384 (
385  const point& start,
386  const point& end,
387  point& pt
388 ) const
389 {
390  direction ptBits;
391  return intersects(start, end-start, start, end, pt, ptBits);
392 }
393 
394 
395 bool Foam::treeBoundBox::contains(const vector& dir, const point& pt) const
396 {
397  //
398  // Compare all components against min and max of bb
399  //
400  for (direction cmpt=0; cmpt<3; cmpt++)
401  {
402  if (pt[cmpt] < min()[cmpt])
403  {
404  return false;
405  }
406  else if (pt[cmpt] == min()[cmpt])
407  {
408  // On edge. Outside if direction points outwards.
409  if (dir[cmpt] < 0)
410  {
411  return false;
412  }
413  }
414 
415  if (pt[cmpt] > max()[cmpt])
416  {
417  return false;
418  }
419  else if (pt[cmpt] == max()[cmpt])
420  {
421  // On edge. Outside if direction points outwards.
422  if (dir[cmpt] > 0)
423  {
424  return false;
425  }
426  }
427  }
428 
429  // All components inside bb
430  return true;
431 }
432 
433 
434 // Code position of pt on bounding box faces
436 {
437  direction faceBits = 0;
438  if (pt.x() == min().x())
439  {
440  faceBits |= LEFTBIT;
441  }
442  else if (pt.x() == max().x())
443  {
444  faceBits |= RIGHTBIT;
445  }
446 
447  if (pt.y() == min().y())
448  {
449  faceBits |= BOTTOMBIT;
450  }
451  else if (pt.y() == max().y())
452  {
453  faceBits |= TOPBIT;
454  }
455 
456  if (pt.z() == min().z())
457  {
458  faceBits |= BACKBIT;
459  }
460  else if (pt.z() == max().z())
461  {
462  faceBits |= FRONTBIT;
463  }
464  return faceBits;
465 }
466 
467 
468 // Code position of point relative to box
470 {
471  direction posBits = 0;
472 
473  if (pt.x() < min().x())
474  {
475  posBits |= LEFTBIT;
476  }
477  else if (pt.x() > max().x())
478  {
479  posBits |= RIGHTBIT;
480  }
481 
482  if (pt.y() < min().y())
483  {
484  posBits |= BOTTOMBIT;
485  }
486  else if (pt.y() > max().y())
487  {
488  posBits |= TOPBIT;
489  }
490 
491  if (pt.z() < min().z())
492  {
493  posBits |= BACKBIT;
494  }
495  else if (pt.z() > max().z())
496  {
497  posBits |= FRONTBIT;
498  }
499  return posBits;
500 }
501 
502 
503 // nearest and furthest corner coordinate.
504 // !names of treeBoundBox::min() and treeBoundBox::max() are confusing!
506 (
507  const point& pt,
508  point& nearest,
509  point& furthest
510 ) const
511 {
512  scalar nearX, nearY, nearZ;
513  scalar farX, farY, farZ;
514 
515  if (Foam::mag(min().x() - pt.x()) < Foam::mag(max().x() - pt.x()))
516  {
517  nearX = min().x();
518  farX = max().x();
519  }
520  else
521  {
522  nearX = max().x();
523  farX = min().x();
524  }
525 
526  if (Foam::mag(min().y() - pt.y()) < Foam::mag(max().y() - pt.y()))
527  {
528  nearY = min().y();
529  farY = max().y();
530  }
531  else
532  {
533  nearY = max().y();
534  farY = min().y();
535  }
536 
537  if (Foam::mag(min().z() - pt.z()) < Foam::mag(max().z() - pt.z()))
538  {
539  nearZ = min().z();
540  farZ = max().z();
541  }
542  else
543  {
544  nearZ = max().z();
545  farZ = min().z();
546  }
547 
548  nearest = point(nearX, nearY, nearZ);
549  furthest = point(farX, farY, farZ);
550 }
551 
552 
553 Foam::scalar Foam::treeBoundBox::maxDist(const point& pt) const
554 {
555  point near, far;
556  calcExtremities(pt, near, far);
557 
558  return Foam::mag(far - pt);
559 }
560 
561 
562 // Distance comparator
563 // Compare all vertices of bounding box against all of other bounding
564 // box to see if all vertices of one are nearer
566 (
567  const point& pt,
568  const treeBoundBox& other
569 ) const
570 {
571  //
572  // Distance point <-> nearest and furthest away vertex of this
573  //
574 
575  point nearThis, farThis;
576 
577  // get nearest and furthest away vertex
578  calcExtremities(pt, nearThis, farThis);
579 
580  const scalar minDistThis =
581  sqr(nearThis.x() - pt.x())
582  + sqr(nearThis.y() - pt.y())
583  + sqr(nearThis.z() - pt.z());
584  const scalar maxDistThis =
585  sqr(farThis.x() - pt.x())
586  + sqr(farThis.y() - pt.y())
587  + sqr(farThis.z() - pt.z());
588 
589  //
590  // Distance point <-> other
591  //
592 
593  point nearOther, farOther;
594 
595  // get nearest and furthest away vertex
596  other.calcExtremities(pt, nearOther, farOther);
597 
598  const scalar minDistOther =
599  sqr(nearOther.x() - pt.x())
600  + sqr(nearOther.y() - pt.y())
601  + sqr(nearOther.z() - pt.z());
602  const scalar maxDistOther =
603  sqr(farOther.x() - pt.x())
604  + sqr(farOther.y() - pt.y())
605  + sqr(farOther.z() - pt.z());
606 
607  //
608  // Categorize
609  //
610  if (maxDistThis < minDistOther)
611  {
612  // All vertices of this are nearer to point than any vertex of other
613  return -1;
614  }
615  else if (minDistThis > maxDistOther)
616  {
617  // All vertices of this are further from point than any vertex of other
618  return 1;
619  }
620  else
621  {
622  // Mixed bag
623  return 0;
624  }
625 }
626 
627 
628 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
629 
630 bool Foam::operator==(const treeBoundBox& a, const treeBoundBox& b)
631 {
632  return operator==
633  (
634  static_cast<const boundBox&>(a),
635  static_cast<const boundBox&>(b)
636  );
637 }
638 
639 
640 bool Foam::operator!=(const treeBoundBox& a, const treeBoundBox& b)
641 {
642  return !(a == b);
643 }
644 
645 
646 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
647 
648 Foam::Ostream& Foam::operator<<(Ostream& os, const treeBoundBox& bb)
649 {
650  return os << static_cast<const boundBox&>(bb);
651 }
652 
653 
654 Foam::Istream& Foam::operator>>(Istream& is, treeBoundBox& bb)
655 {
656  return is >> static_cast<boundBox&>(bb);
657 }
658 
659 
660 // ************************************************************************* //
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
Foam::boundBox::max
const point & max() const
Maximum describing the bounding box.
Definition: boundBoxI.H:60
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::treeBoundBox::points
tmp< pointField > points() const
Vertex coordinates. In octant coding.
Definition: treeBoundBox.C:163
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:118
Foam::treeBoundBox
Standard boundBox + extra functionality for use in octree.
Definition: treeBoundBox.H:75
Foam::treeBoundBox::RIGHTHALF
@ RIGHTHALF
Definition: treeBoundBox.H:105
Foam::treeBoundBox::calcExtremities
void calcExtremities(const point &pt, point &nearest, point &furthest) const
Calculate nearest and furthest (to point) vertex coords of.
Definition: treeBoundBox.C:506
Foam::treeBoundBox::posBits
direction posBits(const point &) const
Position of point relative to bounding box.
Definition: treeBoundBox.C:469
Foam::treeBoundBox::greatBox
static const treeBoundBox greatBox
As per boundBox::greatBox, but with GREAT instead of VGREAT.
Definition: treeBoundBox.H:96
Foam::operator==
tmp< fvMatrix< Type > > operator==(const fvMatrix< Type > &, const fvMatrix< Type > &)
Foam::treeBoundBox::subBbox
treeBoundBox subBbox(const direction) const
Sub box given by octant number. Midpoint calculated.
Definition: treeBoundBox.C:178
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::treeBoundBox::edges
static const edgeList edges
Edge to point addressing.
Definition: treeBoundBox.H:157
Foam::treeBoundBox::treeBoundBox
treeBoundBox()
Construct null setting points to zero.
Definition: treeBoundBoxI.H:31
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::treeBoundBox::faceNormals
static const FixedList< vector, 6 > faceNormals
Per face the unit normal.
Definition: treeBoundBox.H:160
Foam::treeBoundBox::calcFaceNormals
static FixedList< vector, 6 > calcFaceNormals()
To initialise faceNormals.
Definition: treeBoundBox.C:112
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:28
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:57
treeBoundBox.H
Foam::treeBoundBox::intersects
bool intersects(const point &overallStart, const vector &overallVec, const point &start, const point &end, point &pt, direction &ptBits) const
Intersects segment; set point to intersection position and face,.
Definition: treeBoundBox.C:253
Foam::treeBoundBox::faces
static const faceList faces
Face to point addressing.
Definition: treeBoundBox.H:154
Foam::boundBox::min
const point & min() const
Minimum describing the bounding box.
Definition: boundBoxI.H:54
Foam::operator<<
Ostream & operator<<(Ostream &, const edgeMesh &)
Definition: edgeMeshIO.C:130
Foam::treeBoundBox::FRONTHALF
@ FRONTHALF
Definition: treeBoundBox.H:107
Foam::Vector::x
const Cmpt & x() const
Definition: VectorI.H:65
Foam::treeBoundBox::maxDist
scalar maxDist(const point &) const
Returns distance point to furthest away corner.
Definition: treeBoundBox.C:553
Foam::operator!=
bool operator!=(const particle &, const particle &)
Definition: particle.C:147
Foam::FatalError
error FatalError
Foam::treeBoundBox::calcEdges
static edgeList calcEdges(const label[12][2])
To initialise edges.
Definition: treeBoundBox.C:100
Foam::Vector::z
const Cmpt & z() const
Definition: VectorI.H:77
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
s
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::treeBoundBox::invertedBox
static const treeBoundBox invertedBox
As per boundBox::invertedBox, but with GREAT instead of VGREAT.
Definition: treeBoundBox.H:99
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:49
Foam::treeBoundBox::contains
bool contains(const vector &dir, const point &) const
Contains point (inside or on edge) and moving in direction.
Definition: treeBoundBox.C:395
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::treeBoundBox::faceBits
direction faceBits(const point &) const
Code position of point on bounding box faces.
Definition: treeBoundBox.C:435
Foam::FixedList
A 1D vector of objects of type <T> with a fixed size <Size>.
Definition: FixedList.H:53
Foam::treeBoundBox::TOPHALF
@ TOPHALF
Definition: treeBoundBox.H:106
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::operator>>
Istream & operator>>(Istream &, edgeMesh &)
Definition: edgeMeshIO.C:141
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::treeBoundBox::distanceCmp
label distanceCmp(const point &, const treeBoundBox &other) const
Compare distance to point with other bounding box.
Definition: treeBoundBox.C:566
Foam::direction
unsigned char direction
Definition: direction.H:43
Foam::treeBoundBox::great
static const scalar great
The great value used for greatBox and invertedBox.
Definition: treeBoundBox.H:93
Foam::boundBox
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:55
Foam::UList::empty
bool empty() const
Return true if the UList is empty (ie, size() is zero).
Definition: UListI.H:313
Foam::Vector::y
const Cmpt & y() const
Definition: VectorI.H:71
ListOps.H
Various functions to operate on Lists.
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:53
Foam::point
vector point
Point is a vector.
Definition: point.H:41
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:259
y
scalar y
Definition: LISASMDCalcMethod1.H:14