1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkLagrangeHexahedron.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
16 // Hide VTK_DEPRECATED_IN_9_0_0() warnings for this class.
17 #define VTK_DEPRECATION_LEVEL 0
18 
19 #include "vtkLagrangeHexahedron.h"
20 
21 #include "vtkCellData.h"
22 #include "vtkDoubleArray.h"
23 #include "vtkHexahedron.h"
24 #include "vtkIdList.h"
25 #include "vtkLagrangeCurve.h"
26 #include "vtkLagrangeInterpolation.h"
27 #include "vtkLagrangeQuadrilateral.h"
28 #include "vtkLine.h"
29 #include "vtkMath.h"
30 #include "vtkObjectFactory.h"
31 #include "vtkPointData.h"
32 #include "vtkPoints.h"
33 #include "vtkTriangle.h"
34 #include "vtkVector.h"
35 #include "vtkVectorOperators.h"
36 
37 vtkStandardNewMacro(vtkLagrangeHexahedron);
38 
39 vtkLagrangeHexahedron::vtkLagrangeHexahedron() = default;
40 
41 vtkLagrangeHexahedron::~vtkLagrangeHexahedron() = default;
42 
PrintSelf(ostream & os,vtkIndent indent)43 void vtkLagrangeHexahedron::PrintSelf(ostream& os, vtkIndent indent)
44 {
45   this->Superclass::PrintSelf(os, indent);
46 }
47 
GetEdge(int edgeId)48 vtkCell* vtkLagrangeHexahedron::GetEdge(int edgeId)
49 {
50   vtkLagrangeCurve* result = EdgeCell;
51   const auto set_number_of_ids_and_points = [&](const vtkIdType& npts) -> void {
52     result->Points->SetNumberOfPoints(npts);
53     result->PointIds->SetNumberOfIds(npts);
54   };
55   const auto set_ids_and_points = [&](const vtkIdType& face_id, const vtkIdType& vol_id) -> void {
56     result->Points->SetPoint(face_id, this->Points->GetPoint(vol_id));
57     result->PointIds->SetId(face_id, this->PointIds->GetId(vol_id));
58   };
59 
60   this->SetEdgeIdsAndPoints(edgeId, set_number_of_ids_and_points, set_ids_and_points);
61   return result;
62 }
63 
GetFace(int faceId)64 vtkCell* vtkLagrangeHexahedron::GetFace(int faceId)
65 {
66   vtkLagrangeQuadrilateral* result = FaceCell;
67 
68   const auto set_number_of_ids_and_points = [&](const vtkIdType& npts) -> void {
69     result->Points->SetNumberOfPoints(npts);
70     result->PointIds->SetNumberOfIds(npts);
71   };
72   const auto set_ids_and_points = [&](const vtkIdType& face_id, const vtkIdType& vol_id) -> void {
73     result->Points->SetPoint(face_id, this->Points->GetPoint(vol_id));
74     result->PointIds->SetId(face_id, this->PointIds->GetId(vol_id));
75   };
76 
77   this->SetFaceIdsAndPoints(result, faceId, set_number_of_ids_and_points, set_ids_and_points);
78   return result;
79 }
80 
81 /**\brief Populate the linear hex returned by GetApprox() with point-data from one voxel-like
82  * intervals of this cell.
83  *
84  * Ensure that you have called GetOrder() before calling this method
85  * so that this->Order is up to date. This method does no checking
86  * before using it to map connectivity-array offsets.
87  */
GetApproximateHex(int subId,vtkDataArray * scalarsIn,vtkDataArray * scalarsOut)88 vtkHexahedron* vtkLagrangeHexahedron::GetApproximateHex(
89   int subId, vtkDataArray* scalarsIn, vtkDataArray* scalarsOut)
90 {
91   vtkHexahedron* approx = this->GetApprox();
92   bool doScalars = (scalarsIn && scalarsOut);
93   if (doScalars)
94   {
95     scalarsOut->SetNumberOfTuples(8);
96   }
97   int i, j, k;
98   if (!this->SubCellCoordinatesFromId(i, j, k, subId))
99   {
100     vtkErrorMacro("Invalid subId " << subId);
101     return nullptr;
102   }
103   // Get the point coordinates (and optionally scalars) for each of the 8 corners
104   // in the approximating hexahedron spanned by (i, i+1) x (j, j+1) x (k, k+1):
105   for (vtkIdType ic = 0; ic < 8; ++ic)
106   {
107     const vtkIdType corner = this->PointIndexFromIJK(
108       i + ((((ic + 1) / 2) % 2) ? 1 : 0), j + (((ic / 2) % 2) ? 1 : 0), k + ((ic / 4) ? 1 : 0));
109     vtkVector3d cp;
110     this->Points->GetPoint(corner, cp.GetData());
111     approx->Points->SetPoint(ic, cp.GetData());
112     approx->PointIds->SetId(ic, doScalars ? corner : this->PointIds->GetId(corner));
113     if (doScalars)
114     {
115       scalarsOut->SetTuple(ic, scalarsIn->GetTuple(corner));
116     }
117   }
118   return approx;
119 }
120 
InterpolateFunctions(const double pcoords[3],double * weights)121 void vtkLagrangeHexahedron::InterpolateFunctions(const double pcoords[3], double* weights)
122 {
123   vtkLagrangeInterpolation::Tensor3ShapeFunctions(this->GetOrder(), pcoords, weights);
124 }
125 
InterpolateDerivs(const double pcoords[3],double * derivs)126 void vtkLagrangeHexahedron::InterpolateDerivs(const double pcoords[3], double* derivs)
127 {
128   vtkLagrangeInterpolation::Tensor3ShapeDerivatives(this->GetOrder(), pcoords, derivs);
129 }
GetEdgeCell()130 vtkHigherOrderCurve* vtkLagrangeHexahedron::GetEdgeCell()
131 {
132   return EdgeCell;
133 }
GetFaceCell()134 vtkHigherOrderQuadrilateral* vtkLagrangeHexahedron::GetFaceCell()
135 {
136   return FaceCell;
137 }
GetInterpolation()138 vtkHigherOrderInterpolation* vtkLagrangeHexahedron::GetInterpolation()
139 {
140   return Interp;
141 };
142