Skip to content

Commit 9a7c038

Browse files
FFD box fix for nonplanar faces (#1742)
* FFD box uses supporting point in the middle of the face to avoid ambiguous definition of nonplanar faces * implementation of github review comments (formatting and deleting memory) * Apply suggestions from code review Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com>
1 parent 88c8392 commit 9a7c038

1 file changed

Lines changed: 61 additions & 75 deletions

File tree

Common/src/grid_movement/CFreeFormDefBox.cpp

Lines changed: 61 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -102,19 +102,34 @@ CFreeFormDefBox::CFreeFormDefBox(const unsigned short Degree[], unsigned short B
102102
CFreeFormDefBox::~CFreeFormDefBox(void) {
103103
unsigned short iOrder, jOrder, kOrder, iCornerPoints, iDim;
104104

105-
for (iOrder = 0; iOrder < lOrder; iOrder++)
106-
for (jOrder = 0; jOrder < mOrder; jOrder++)
105+
for (iOrder = 0; iOrder < lOrder; iOrder++) {
106+
for (jOrder = 0; jOrder < mOrder; jOrder++) {
107107
for (kOrder = 0; kOrder < nOrder; kOrder++) {
108108
delete [] Coord_Control_Points[iOrder][jOrder][kOrder];
109109
delete [] ParCoord_Control_Points[iOrder][jOrder][kOrder];
110110
delete [] Coord_Control_Points_Copy[iOrder][jOrder][kOrder];
111+
if (Coord_SupportCP != nullptr) delete [] Coord_SupportCP[iOrder][jOrder][kOrder];
111112
}
113+
delete [] Coord_Control_Points[iOrder][jOrder];
114+
delete [] ParCoord_Control_Points[iOrder][jOrder];
115+
delete [] Coord_Control_Points_Copy[iOrder][jOrder];
116+
if (Coord_SupportCP != nullptr) delete [] Coord_SupportCP[iOrder][jOrder];
117+
}
118+
delete [] Coord_Control_Points[iOrder];
119+
delete [] ParCoord_Control_Points[iOrder];
120+
delete [] Coord_Control_Points_Copy[iOrder];
121+
if (Coord_SupportCP != nullptr) delete [] Coord_SupportCP[iOrder];
122+
}
123+
112124
delete [] Coord_Control_Points;
113125
delete [] ParCoord_Control_Points;
114126
delete [] Coord_Control_Points_Copy;
127+
delete [] Coord_SupportCP;
115128

116129
delete [] ParamCoord;
130+
delete [] ParamCoord_;
117131
delete [] cart_coord;
132+
delete [] cart_coord_;
118133
delete [] Gradient;
119134

120135
for (iCornerPoints = 0; iCornerPoints < nCornerPoints; iCornerPoints++)
@@ -969,26 +984,37 @@ su2double *CFreeFormDefBox::GetParametricCoord_Iterative(unsigned long iPoint, s
969984
}
970985

971986
bool CFreeFormDefBox::GetPointFFD(CGeometry *geometry, CConfig *config, unsigned long iPoint) const {
972-
su2double Coord[3] = {0.0, 0.0, 0.0};
973-
unsigned short iVar, jVar, iDim;
974-
su2double X_0, Y_0, Z_0, Xbar, Ybar, Zbar;
975987

976-
bool Inside = false;
988+
bool Inside = true;
977989
bool cylindrical = (config->GetFFD_CoordSystem() == CYLINDRICAL);
978990
bool spherical = (config->GetFFD_CoordSystem() == SPHERICAL);
979991
bool polar = (config->GetFFD_CoordSystem() == POLAR);
980992

981-
unsigned short Index[5][7] = {
982-
{0, 1, 2, 5, 0, 1, 2},
983-
{0, 2, 7, 5, 0, 2, 7},
984-
{0, 2, 3, 7, 0, 2, 3},
985-
{0, 5, 7, 4, 0, 5, 7},
986-
{2, 7, 5, 6, 2, 7, 5}};
993+
/*--- indices of the FFD box. Note that the front face is labelled 0,1,2,3 and the back face is 4,5,6,7 ---*/
994+
995+
unsigned short Index[6][5] = {
996+
{0,1,2,3,0}, // front side
997+
{1,5,6,2,1}, // right side
998+
{2,6,7,3,2}, // top side
999+
{3,7,4,0,3}, // left side
1000+
{4,5,1,0,4}, // bottom side
1001+
{4,7,6,5,4}}; // back side
1002+
1003+
/*--- The current approach is to subdivide each of the 6 faces of the hexahedral FFD box into 4 triangles
1004+
by defining a supporting middle point. This allows nonplanar FFD boxes.
1005+
Note that the definition of the FFD box is as follows: the FFD box is a 6-sided die and we are looking at the side "1".
1006+
The opposite side is side "6".
1007+
If we are looking at side "1", we define the nodes counterclockwise.
1008+
If we are looking at side "6", we define the face clockwise ---*/
1009+
9871010
unsigned short nDim = geometry->GetnDim();
9881011

989-
for (iDim = 0; iDim < nDim; iDim++)
1012+
su2double Coord[3] = {0.0, 0.0, 0.0};
1013+
for (unsigned short iDim = 0; iDim < nDim; iDim++)
9901014
Coord[iDim] = geometry->nodes->GetCoord(iPoint, iDim);
9911015

1016+
su2double X_0, Y_0, Z_0, Xbar, Ybar, Zbar;
1017+
9921018
if (cylindrical) {
9931019

9941020
X_0 = config->GetFFD_Axis(0); Y_0 = config->GetFFD_Axis(1); Z_0 = config->GetFFD_Axis(2);
@@ -1013,78 +1039,38 @@ bool CFreeFormDefBox::GetPointFFD(CGeometry *geometry, CConfig *config, unsigned
10131039

10141040
}
10151041

1016-
/*--- 1st tetrahedron {V0, V1, V2, V5}
1017-
2nd tetrahedron {V0, V2, V7, V5}
1018-
3th tetrahedron {V0, V2, V3, V7}
1019-
4th tetrahedron {V0, V5, V7, V4}
1020-
5th tetrahedron {V2, V7, V5, V6} ---*/
1042+
/*--- loop over the faces of the FFD box ---*/
1043+
1044+
for (unsigned short iVar = 0; iVar < 6; iVar++) {
1045+
1046+
su2double P[3] = {0.0, 0.0, 0.0};
1047+
1048+
/*--- every face needs an interpolated middle point for the triangles ---*/
1049+
1050+
for (int p = 0; p < 4; p++){
1051+
P[0] += 0.25*Coord_Corner_Points[Index[iVar][p]][0];
1052+
P[1] += 0.25*Coord_Corner_Points[Index[iVar][p]][1];
1053+
P[2] += 0.25*Coord_Corner_Points[Index[iVar][p]][2];
1054+
}
1055+
1056+
/*--- loop over the 4 triangles making up the FFD box. The sign is equal for all distances ---*/
10211057

1022-
for (iVar = 0; iVar < 5; iVar++) {
1023-
Inside = true;
1024-
for (jVar = 0; jVar < 4; jVar++) {
1058+
for (unsigned short jVar = 0; jVar < 4; jVar++) {
10251059
su2double Distance_Point = geometry->Point2Plane_Distance(Coord,
1060+
Coord_Corner_Points[Index[iVar][jVar]],
10261061
Coord_Corner_Points[Index[iVar][jVar+1]],
1027-
Coord_Corner_Points[Index[iVar][jVar+2]],
1028-
Coord_Corner_Points[Index[iVar][jVar+3]]);
1029-
1030-
su2double Distance_Vertex = geometry->Point2Plane_Distance(Coord_Corner_Points[Index[iVar][jVar]],
1031-
Coord_Corner_Points[Index[iVar][jVar+1]],
1032-
Coord_Corner_Points[Index[iVar][jVar+2]],
1033-
Coord_Corner_Points[Index[iVar][jVar+3]]);
1034-
if (Distance_Point*Distance_Vertex < 0.0) Inside = false;
1062+
P);
1063+
if (Distance_Point < 0) {
1064+
Inside = false;
1065+
return Inside;
1066+
}
10351067
}
1036-
if (Inside) break;
10371068
}
10381069

10391070
return Inside;
10401071

10411072
}
10421073

1043-
void CFreeFormDefBox::SetDeformationZone(CGeometry *geometry, CConfig *config, unsigned short iFFDBox) const {
1044-
su2double *Coord;
1045-
unsigned short iMarker, iVar, jVar;
1046-
unsigned long iVertex, iPoint;
1047-
bool Inside = false;
1048-
1049-
unsigned short Index[5][7] = {
1050-
{0, 1, 2, 5, 0, 1, 2},
1051-
{0, 2, 7, 5, 0, 2, 7},
1052-
{0, 2, 3, 7, 0, 2, 3},
1053-
{0, 5, 7, 4, 0, 5, 7},
1054-
{2, 7, 5, 6, 2, 7, 5}};
1055-
1056-
for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) {
1057-
if (config->GetMarker_All_DV(iMarker) == YES) {
1058-
for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) {
1059-
iPoint = geometry->vertex[iMarker][iVertex]->GetNode();
1060-
1061-
Coord = geometry->nodes->GetCoord(iPoint);
1062-
1063-
/*--- 1st tetrahedron {V0, V1, V2, V5}
1064-
2nd tetrahedron {V0, V2, V7, V5}
1065-
3th tetrahedron {V0, V2, V3, V7}
1066-
4th tetrahedron {V0, V5, V7, V4}
1067-
5th tetrahedron {V2, V7, V5, V6} ---*/
1068-
1069-
for (iVar = 0; iVar < 5; iVar++) {
1070-
Inside = true;
1071-
for (jVar = 0; jVar < 4; jVar++) {
1072-
su2double Distance_Point = geometry->Point2Plane_Distance(Coord,
1073-
Coord_Corner_Points[Index[iVar][jVar+1]],
1074-
Coord_Corner_Points[Index[iVar][jVar+2]],
1075-
Coord_Corner_Points[Index[iVar][jVar+3]]);
1076-
su2double Distance_Vertex = geometry->Point2Plane_Distance(Coord_Corner_Points[Index[iVar][jVar]],
1077-
Coord_Corner_Points[Index[iVar][jVar+1]],
1078-
Coord_Corner_Points[Index[iVar][jVar+2]],
1079-
Coord_Corner_Points[Index[iVar][jVar+3]]);
1080-
if (Distance_Point*Distance_Vertex < 0.0) Inside = false;
1081-
}
1082-
if (Inside) break;
1083-
}
1084-
}
1085-
}
1086-
}
1087-
}
10881074

10891075
su2double CFreeFormDefBox::GetDerivative1(su2double *uvw, unsigned short val_diff, unsigned short *ijk, unsigned short *lmn) const {
10901076

0 commit comments

Comments
 (0)