Loading...
Searching...
No Matches
ITHACAgeometry.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ██╗████████╗██╗ ██╗ █████╗ ██████╗ █████╗ ███████╗██╗ ██╗
3 ██║╚══██╔══╝██║ ██║██╔══██╗██╔════╝██╔══██╗ ██╔════╝██║ ██║
4 ██║ ██║ ███████║███████║██║ ███████║█████╗█████╗ ██║ ██║
5 ██║ ██║ ██╔══██║██╔══██║██║ ██╔══██║╚════╝██╔══╝ ╚██╗ ██╔╝
6 ██║ ██║ ██║ ██║██║ ██║╚██████╗██║ ██║ ██║ ╚████╔╝
7 ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═══╝
8
9 * In real Time Highly Advanced Computational Applications for Finite Volumes
10 * Copyright (C) 2017 by the ITHACA-FV authors
11-------------------------------------------------------------------------------
12License
13 This file is part of ITHACA-FV
14 ITHACA-FV is free software: you can redistribute it and/or modify
15 it under the terms of the GNU Lesser General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18 ITHACA-FV is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU Lesser General Public License for more details.
22 You should have received a copy of the GNU Lesser General Public License
23 along with ITHACA-FV. If not, see <http://www.gnu.org/licenses/>.
24\*---------------------------------------------------------------------------*/
25#include "ITHACAgeometry.H"
26using namespace ITHACAutilities;
27
28namespace ITHACAutilities
29{
30
31labelList getIndicesFromBox(const fvMesh& mesh, List<label> indices,
32 Eigen::MatrixXd Box, List<vector>& points2Move)
33{
34 points2Move.resize(0);
35 labelList boxIndices;
36 pointField meshPoints(mesh.points());
37
38 for (label j = 0; j < indices.size(); j++)
39 {
40 const polyPatch& patchFound = mesh.boundaryMesh()[indices[j]];
41 labelList labelPatchFound(patchFound.meshPoints());
42
43 for (label i = 0; i < labelPatchFound.size(); i++)
44 {
45 auto px = meshPoints[labelPatchFound[i]].component(0);
46 auto py = meshPoints[labelPatchFound[i]].component(1);
47 auto pz = meshPoints[labelPatchFound[i]].component(2);
48
49 if (px >= min(Box(0, 0), Box(1, 0)) && py >= min(Box(0, 1), Box(1, 1))
50 && pz >= min(Box(0, 2), Box(1, 2)) && px <= max(Box(0, 0), Box(1, 0))
51 && py <= max(Box(0, 1), Box(1, 1)) && pz <= max(Box(0, 2), Box(1, 2)) )
52 {
53 boxIndices.append(labelPatchFound[i]);
54 points2Move.append(meshPoints[labelPatchFound[i]]);
55 }
56 }
57 }
58
59 return boxIndices;
60}
61
62List<label> getIndices(const fvMesh& mesh, int index, int layers)
63{
64 List<label> out;
65 out.resize(1);
66 out[0] = index;
67
68 for (label i = 0; i < layers; i++)
69 {
70 label size = out.size();
71
72 for (label j = 0; j < size; j++)
73 {
74 out.append(mesh.cellCells()[out[j]]);
75 }
76 }
77
78 labelList uniqueIndex;
79 uniqueOrder(out, uniqueIndex);
80 List<label> out2;
81 forAll(uniqueIndex, i)
82 {
83 out2.append(out[uniqueIndex[i]]);
84 }
85 return out2;
86}
87
88List<label> getIndices(const fvMesh& mesh, int index_row,
89 int index_col, int layers)
90{
91 List<label> out;
92 out.resize(2);
93 out[0] = index_row;
94 out[1] = index_col;
95
96 for (label i = 0; i < layers; i++)
97 {
98 label size = out.size();
99
100 for (label j = 0; j < size; j++)
101 {
102 out.append(mesh.cellCells()[out[j]]);
103 }
104 }
105
106 labelList uniqueIndex;
107 uniqueOrder(out, uniqueIndex);
108 List<label> out2;
109 forAll(uniqueIndex, i)
110 {
111 out2.append(out[uniqueIndex[i]]);
112 }
113 return out2;
114}
115
116void getPointsFromPatch(fvMesh& mesh, label ind,
117 List<vector>& points, labelList& indices)
118{
119 pointField meshPoints(mesh.points());
120 const polyPatch& patchFound = mesh.boundaryMesh()[ind];
121 labelList labelPatchFound(patchFound.meshPoints());
122 points.resize(labelPatchFound.size());
123
124 for (label i = 0; i < labelPatchFound.size(); i++)
125 {
126 points[i] = meshPoints[labelPatchFound[i]];
127 }
128
129 indices = labelPatchFound;
130}
131
132List<vector> displacedSegment(List<vector> x0, double mux1,
133 double mux2, double muy1, double muy2)
134{
135 vector minimum = min(x0);
136 vector maximum = max(x0);
137 double l = Foam::sqrt(pow(minimum[0] - maximum[0],
138 2) + pow(minimum[1] - maximum[1], 2));
139 double limin;
140 double limax;
141 List<vector> xdef(x0);
142 List<vector> displ(x0);
143
144 for (label i = 0; i < x0.size(); i++)
145 {
146 limin = Foam::sqrt(pow(x0[i][0] - minimum[0], 2) + pow(x0[i][1] - minimum[1],
147 2));
148 limax = Foam::sqrt(pow(x0[i][0] - maximum[0], 2) + pow(x0[i][1] - maximum[1],
149 2));
150 xdef[i][0] = x0[i][0] + mux1 * (1 - limin / l) + mux2 * (1 - limax / l);
151 xdef[i][1] = x0[i][1] + muy1 * (1 - limin / l) + muy2 * (1 - limax / l);
152 xdef[i][2] = x0[i][2];
153 }
154
155 displ = xdef - x0;
156 return displ;
157}
158
159vector displacePolabel(vector x0, vector x_low, vector x_up,
160 double mux_low, double mux_up, double muy_low, double muy_up, double muz_low,
161 double muz_up)
162{
163 vector direction = x_up - x_low;
164 double t0;
165 double t1;
166 double t2;
167 vector x_low_def(x_low[0] + mux_low, x_low[1] + muy_low, x_low[2] + muz_low);
168 vector x_up_def(x_up[0] + mux_up, x_up[1] + muy_up, x_up[2] + muz_up);
169 vector direction_def = x_up_def - x_low_def;
170
171 if (abs(direction[0]) > 1e-16)
172 {
173 t0 = (x0[0] - x_low[0]) / direction[0];
174 }
175 else
176 {
177 t0 = 0;
178 }
179
180 if (abs(direction[1]) > 1e-16)
181 {
182 t1 = (x0[1] - x_low[1]) / direction[1];
183
184 if (t0 == 0)
185 {
186 t0 = t1;
187 }
188 }
189 else
190 {
191 t1 = t0;
192 }
193
194 if (abs(direction[2]) > 1e-16)
195 {
196 t2 = (x0[2] - x_low[2]) / direction[2];
197
198 if (t1 == 0)
199 {
200 t1 = t2;
201 }
202
203 if (t0 == 0)
204 {
205 t0 = t2;
206 }
207 }
208 else
209 {
210 t2 = t1;
211 }
212
213 Info << abs((x_low + t0 * direction - x0)[0]) << endl;
214 Info << abs((x_low + t1 * direction - x0)[1]) << endl;
215 Info << abs((x_low + t2 * direction - x0)[2]) << endl;
216 M_Assert(abs(abs((x_low + t0 * direction - x0)[0]) + abs((
217 x_low + t0 * direction - x0)[1]) + abs((x_low + t0 * direction - x0)[2])) <
218 1e-6, "The givent polabel is not on the segment");
219 vector def_polabel = x_low_def + t1 * direction_def;
220 Info << def_polabel << endl;
221 return def_polabel;
222}
223
224Field<vector> rotateMesh(fvMesh& mesh, double r1, double r2,
225 vector axis,
226 double alpha, labelList movingPointsIDs,
227 List<double> radii, word angleVariationMethod, double v)
228{
229 M_Assert(angleVariationMethod == "Linear"
230 || angleVariationMethod == "Sinusoidal" || angleVariationMethod == "Sigmoid",
231 "The variation function of the angle from the inner radius to the outer radius must be either Linear or Sinusoidal or Sigmoid");
232 Field<vector> pointRot(mesh.points());
233
234 for (label i = 0; i < movingPointsIDs.size(); i++)
235 {
236 double l = radii[i];
237 vector pointNow = pointRot[movingPointsIDs[i]];
238
239 if (l <= r1)
240 {
241 double theta = alpha / 180 * constant::mathematical::pi;
242 quaternion q(axis, theta);
243 pointRot[movingPointsIDs[i]] = q.transform(pointNow);
244 }
245 else if (l > r1 && l <= r2)
246 {
247 if (angleVariationMethod == "Linear")
248 {
249 double theta = alpha / 180 * constant::mathematical::pi * (r2 - l) / (r2 - r1);
250 quaternion q(axis, theta);
251 pointRot[movingPointsIDs[i]] = q.transform(pointNow);
252 }
253 else if (angleVariationMethod == "Sinusoidal")
254 {
255 double theta = alpha / 180 * constant::mathematical::pi * std::sin(
256 constant::mathematical::pi / 2 * (r2 - l) / (r2 - r1));
257 quaternion q(axis, theta);
258 pointRot[movingPointsIDs[i]] = q.transform(pointNow);
259 }
260 else if (angleVariationMethod == "Sigmoid")
261 {
262 double theta = alpha / 180 * constant::mathematical::pi * (1 - 1 /
263 (1 + std::exp(
264 -v * (l - (r1 + r2) / 2))));
265 quaternion q(axis, theta);
266 pointRot[movingPointsIDs[i]] = q.transform(pointNow);
267 }
268 }
269 }
270
271 return pointRot;
272}
273
274Eigen::MatrixXd rotationMatrix(vector AxisOfRotation,
275 double AngleOfRotation)
276{
277 Eigen::MatrixXd R(3, 3);
278 double theta = AngleOfRotation / 180 * constant::mathematical::pi;
279 scalar di = mag(AxisOfRotation);
280 scalar ux = AxisOfRotation[0] / di;
281 scalar uy = AxisOfRotation[1] / di;
282 scalar uz = AxisOfRotation[2] / di;
283 R(0, 0) = Foam::cos(theta) + ux * ux * (1 - Foam::cos(theta));
284 R(1, 0) = uy * ux * (1 - Foam::cos(theta)) + uz * Foam::sin(theta);
285 R(2, 0) = uz * ux * (1 - Foam::cos(theta)) - uy * Foam::sin(theta);
286 R(0, 1) = ux * uz * (1 - Foam::cos(theta)) - uz * Foam::sin(theta);
287 R(1, 1) = Foam::cos(theta) + uy * uy * (1 - Foam::cos(theta));
288 R(2, 1) = ux * uy * (1 - Foam::cos(theta)) + ux * Foam::sin(theta);
289 R(0, 2) = ux * uz * (1 - Foam::cos(theta)) + uy * Foam::sin(theta);
290 R(1, 2) = uy * uz * (1 - Foam::cos(theta)) - ux * Foam::sin(theta);
291 R(2, 2) = Foam::cos(theta) + uz * uz * (1 - Foam::cos(theta));
292 return R;
293}
294
296 fvMesh& mesh, label BC_ind)
297{
298 Eigen::VectorXd cellFaceDistance;
299 const polyPatch& cPatch = mesh.boundaryMesh()[BC_ind];
300 //Starting index of the face in a patch
301 label faceId_start = cPatch.start() ;
302 //List of cells close to a boundary
303 const labelUList& faceCells = cPatch.faceCells();
304 cellFaceDistance.conservativeResize(cPatch.size());
305 forAll(cPatch, faceI)
306 {
307 // index of each face
308 label faceID = faceId_start + faceI;
309 //id of the owner cell having the face
310 label faceOwner = faceCells[faceI] ;
311 cellFaceDistance(faceI) = mag(mesh.C()[faceOwner] - mesh.Cf()[faceID]);
312 }
313 return (cellFaceDistance);
314}
315
316List<label> getIndicesFromDisc(const fvMesh& mesh, double radius,
317 vector origin, vector axis, List<double>& radii)
318{
319 pointField meshPoints(mesh.points());
320 List<label> indices(meshPoints.size());
321 radii.resize(meshPoints.size());
322 label k = 0;
323
324 for (label i = 0; i < meshPoints.size(); i++)
325 {
326 vector pointNow = meshPoints[i];
327 vector r = pointNow - origin;
328 vector projComponent = (r & axis) / (pow(mag(axis), 2)) * axis;
329 vector d = r - projComponent;
330 double l = Foam::sqrt(pow(d[0],
331 2) + pow(d[1], 2) + pow(d[2], 2));
332
333 if (l < radius)
334 {
335 indices[k] = i;
336 radii[k] = l;
337 k++;
338 }
339 }
340
341 indices.resize(k);
342 radii.resize(k);
343 return indices;
344}
345
346template<typename type_f>
348 GeometricField<type_f, fvPatchField, volMesh>& field, Eigen::MatrixXd Box)
349{
350 M_Assert(Box.rows() == 2
351 && Box.cols() == 3,
352 "The box must be a 2*3 matrix shaped in this way: \nBox = \t|x0, y0, z0|\n\t|x1, yi, z1|\n");
353 List<label> indices(field.internalField().size());
354 int k = 0;
355
356 for (label i = 0; i < field.internalField().size(); i++)
357 {
358 auto cx = field.mesh().C()[i][0];
359 auto cy = field.mesh().C()[i][1];
360 auto cz = field.mesh().C()[i][2];
361
362 if (cx >= Box(0, 0) && cy >= Box(0, 1) && cz >= Box(0, 2) && cx <= Box(1, 0)
363 && cy <= Box(1, 1) && cz <= Box(1, 2) )
364 {
365 indices[k] = i;
366 k++;
367 }
368 }
369
370 indices.resize(k);
371 return indices;
372}
373
374template List<label> getIndicesFromBox(
375 GeometricField<scalar, fvPatchField, volMesh>& field, Eigen::MatrixXd Box);
376template List<label> getIndicesFromBox(
377 GeometricField<vector, fvPatchField, volMesh>& field, Eigen::MatrixXd Box);
378
379template<typename type_f>
380fvMeshSubset* getSubMeshFromBox(
381 GeometricField<type_f, fvPatchField, volMesh>& field, Eigen::MatrixXd Box)
382{
383 List<label> indices = getIndicesFromBox(field, Box);
384 fvMeshSubset* sub;
385 sub = new fvMeshSubset(field.mesh());
386 (field.mesh());
387#if OPENFOAM >= 1812
388 sub->setCellSubset(indices);
389#else
390 sub->setLargeCellSubset(indices);
391#endif
392 return sub;
393}
394
395template fvMeshSubset* getSubMeshFromBox(
396 GeometricField<scalar, fvPatchField, volMesh>& field, Eigen::MatrixXd Box);
397template fvMeshSubset* getSubMeshFromBox(
398 GeometricField<vector, fvPatchField, volMesh>& field, Eigen::MatrixXd Box);
399
400volScalarField meshNonOrtho(fvMesh& mesh,
401 volScalarField& NonOrtho)
402{
403 scalarField sno = (polyMeshTools::faceOrthogonality(mesh, mesh.Sf(),
404 mesh.C())).ref();
405
406 for (label i = 0; i < sno.size(); i++)
407 {
408 sno[i] = Foam::acos(min(1, sno[i])) * 180 / constant::mathematical::pi;
409 }
410
411 surfaceScalarField pippo = mesh.magSf();
412 const fvPatchList& patches = mesh.boundary();
413
414 for (label i = 0; i < pippo.internalField().size(); i++)
415 {
416 pippo.ref()[i] = sno[i];
417 }
418
419 for (label i = 0; i < patches.size(); i++)
420 {
421 if ( patches[i].type() != "empty" )
422 {
423 label start = patches[i].patch().start();
424 label n = patches[i].patch().size();
425
426 for (label k = 0; k < n; k++)
427 {
428 pippo.boundaryFieldRef()[i][k] = sno[start + k];
429 }
430 }
431 }
432
433 NonOrtho = fvc::average(pippo);
434 return NonOrtho;
435}
436
437List<vector> rotatePoints(const List<vector>& originalPoints,
438 vector AxisOfRotation, double AngleOfRotation)
439{
440 double theta = AngleOfRotation / 180 * constant::mathematical::pi;
441 quaternion q(AxisOfRotation, theta);
442 List<vector> rotatedPoints(originalPoints);
443
444 for (label i = 0; i < rotatedPoints.size(); i++)
445 {
446 rotatedPoints[i] = q.transform(rotatedPoints[i]);
447 }
448
449 return rotatedPoints;
450}
451}
forAll(example_CG.gList, solutionI)
Definition CGtest.H:21
Foam::fvMesh & mesh
Definition createMesh.H:47
#define M_Assert(Expr, Msg)
Header file of the geometry namespace.
volScalarField & v
Namespace to implement some useful assign operation of OF fields.
Field< vector > rotateMesh(fvMesh &mesh, double r1, double r2, vector axis, double alpha, labelList movingPointsIDs, List< double > radii, word angleVariationMethod, double v)
A function that rotates the mesh rigidly, by a fixed specified angle for the points lying within a di...
List< label > getIndices(const fvMesh &mesh, int index, int layers)
Gets the indices of the cells around a certain cell.
vector displacePolabel(vector x0, vector x_low, vector x_up, double mux_low, double mux_up, double muy_low, double muy_up, double muz_low, double muz_up)
Displace a Polabel belonging to a given segment.
fvMeshSubset * getSubMeshFromBox(GeometricField< type_f, fvPatchField, volMesh > &field, Eigen::MatrixXd Box)
Gets a subMesh from a box of coordinates and a given field (used only for the mesh).
Eigen::MatrixXd rotationMatrix(vector AxisOfRotation, double AngleOfRotation)
Functions that return a Rotation Matrix given an axis of rotation and an angle in degrees.
List< vector > displacedSegment(List< vector > x0, double mux1, double mux2, double muy1, double muy2)
Get position of displaced segment of points given the displacements of the end points.
List< label > getIndicesFromDisc(const fvMesh &mesh, double radius, vector origin, vector axis, List< double > &radii)
Gets the indices of the points which are inside a disc of a specified radius before carrying out a ro...
volScalarField meshNonOrtho(fvMesh &mesh, volScalarField &NonOrtho)
Returns a scalarField that containes the non-orthogonality value of a given mesh.
void getPointsFromPatch(fvMesh &mesh, label ind, List< vector > &points, labelList &indices)
Get the polabel coordinates and indices from patch.
labelList getIndicesFromBox(const fvMesh &mesh, List< label > indices, Eigen::MatrixXd Box, List< vector > &points2Move)
Gives the indices conteined into a defined box.
Eigen::VectorXd boudaryFaceToCellDistance(fvMesh &mesh, label BC_ind)
Compute the distance between the boundary face center and the boundary cell center.
List< vector > rotatePoints(const List< vector > &originalPoints, vector AxisOfRotation, double AngleOfRotation)
Rotate a list of points in clockwise direction given an axis of rotation and an angle in degrees.
label i
Definition pEqn.H:46