surface_zoneGenerator.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2025 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 "surface_zoneGenerator.H"
27 #include "Time.H"
28 #include "polyMesh.H"
29 #include "searchableSurface.H"
30 #include "syncTools.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  namespace zoneGenerators
38  {
41  (
43  surface,
45  );
46  }
47 }
48 
49 
50 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
51 
53 (
54  const word& name,
55  const polyMesh& mesh,
56  const dictionary& dict
57 )
58 :
60  surfacePtr_
61  (
63  (
64  word(dict.lookup("surface")),
65  IOobject
66  (
67  dict.lookupOrDefault
68  (
69  "surfaceName",
70  mesh.objectRegistry::db().name()
71  ),
72  mesh.time().constant(),
73  searchableSurface::geometryDir(mesh.time()),
74  mesh.objectRegistry::db(),
75  IOobject::MUST_READ,
76  IOobject::NO_WRITE
77  ),
78  dict
79  )
80  ),
81  tol_(dict.lookupOrDefault<scalar>("tol", dimless, rootSmall))
82 {}
83 
84 
85 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
86 
88 {}
89 
90 
91 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
92 
94 {
95  const labelList& faceOwner = mesh_.faceOwner();
96  const labelList& faceNeighbour = mesh_.faceNeighbour();
97 
98  // Get a list of "interior" faces; i.e., either internal or coupled
99  labelList interiorFaceFaces(mesh_.nFaces());
100  {
101  forAll(faceNeighbour, facei)
102  {
103  interiorFaceFaces[facei] = facei;
104  }
105  label nInteriorFaces = mesh_.nInternalFaces();
106  forAll(mesh_.boundaryMesh(), patchi)
107  {
108  const polyPatch& patch = mesh_.boundaryMesh()[patchi];
109  if (patch.coupled())
110  {
111  forAll(patch, patchFacei)
112  {
113  const label facei = patch.start() + patchFacei;
114  interiorFaceFaces[nInteriorFaces] = facei;
115  nInteriorFaces++;
116  }
117  }
118  }
119  interiorFaceFaces.resize(nInteriorFaces);
120  }
121 
122  // Create owner and neighbour cell centre lists for all interior faces
123  pointField ownCc(interiorFaceFaces.size());
124  pointField nbrCc(interiorFaceFaces.size());
125  {
126  const pointField& cc = mesh_.cellCentres();
127 
128  vectorField boundaryNbrCc;
129  syncTools::swapBoundaryCellPositions(mesh_, cc, boundaryNbrCc);
130 
131  forAll(ownCc, interiorFacei)
132  {
133  const label facei = interiorFaceFaces[interiorFacei];
134 
135  ownCc[interiorFacei] = cc[faceOwner[facei]];
136  nbrCc[interiorFacei] =
137  mesh_.isInternalFace(facei)
138  ? cc[faceNeighbour[facei]]
139  : boundaryNbrCc[facei - mesh_.nInternalFaces()];
140  }
141  }
142 
143  // Do intersection tests on the vectors between the owner and neighbour
144  // cell centres, extended by the tolerance
145  List<pointIndexHit> hits;
146  pointField normals;
147  surfacePtr_().findLine
148  (
149  ownCc + tol_*(ownCc - nbrCc),
150  nbrCc - tol_*(ownCc - nbrCc),
151  hits
152  );
153  surfacePtr_().getNormal(hits, normals);
154 
155  // Create a list of labels indicating what side of the surface a cell
156  // is on; -1 is below, +1 is above, and 0 is too far from the surface
157  // for the sidedness to be calculable
158  labelList side(mesh_.nCells(), 0);
159  forAll(hits, interiorFacei)
160  {
161  if (hits[interiorFacei].hit())
162  {
163  const label facei = interiorFaceFaces[interiorFacei];
164 
165  const vector d = nbrCc[interiorFacei] - ownCc[interiorFacei];
166  const bool sign = (normals[interiorFacei] & d) < 0;
167 
168  side[faceOwner[facei]] = sign ? -1 : +1;
169 
170  if (mesh_.isInternalFace(facei))
171  {
172  side[faceNeighbour[facei]] = sign ? +1 : -1;
173  }
174  }
175  }
176  labelList boundaryNbrSide;
177  syncTools::swapBoundaryCellList(mesh_, side, boundaryNbrSide);
178 
179  // Select intersected faces and set orientation (flipMap)
180  labelList faceIndices(interiorFaceFaces.size());
181  boolList flipMap(interiorFaceFaces.size());
182 
183  label fi = 0;
184  forAll(interiorFaceFaces, interiorFacei)
185  {
186  const label facei = interiorFaceFaces[interiorFacei];
187 
188  const label ownSide = side[faceOwner[facei]];
189  const label nbrSide =
190  mesh_.isInternalFace(facei)
191  ? side[faceNeighbour[facei]]
192  : boundaryNbrSide[facei - mesh_.nInternalFaces()];
193 
194  if ((ownSide == 1 && nbrSide == -1) || (ownSide == -1 && nbrSide == 1))
195  {
196  faceIndices[fi] = facei;
197  flipMap[fi] = nbrSide > ownSide;
198  fi++;
199  }
200  }
201 
202  faceIndices.setSize(fi);
203  flipMap.setSize(fi);
204 
205  return zoneSet
206  (
207  new faceZone
208  (
209  zoneName_,
210  faceIndices,
211  flipMap,
212  mesh_.faceZones(),
213  moveUpdate_,
214  true
215  )
216  );
217 }
218 
219 
220 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
Macros for easy insertion into run-time selection tables.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
void resize(const label)
Alias for setSize(const label)
Definition: ListI.H:138
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Named list of face indices representing a sub-set of the mesh faces.
Definition: faceZone.H:66
Registry of regIOobjects.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:70
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
static void swapBoundaryCellList(const polyMesh &mesh, const UList< T > &cellData, List< T > &neighbourCellData)
Swap to obtain neighbour cell values for all boundary faces.
static void swapBoundaryCellPositions(const polyMesh &mesh, const UList< point > &cellData, List< point > &neighbourCellData)
Swap to obtain neighbour cell positions for all boundary faces.
Definition: syncTools.C:31
A class for handling words, derived from string.
Definition: word.H:62
Abstract base class for all zoneGenerators, providing runtime selection.
Definition: zoneGenerator.H:57
A zoneGenerator which looks-up and returns a zoneSet containing point, and/or cell and/or faces zones...
Definition: lookup.H:139
A zoneGenerator which constructs a faceZone from a set of patches.
A faceZone zoneGenerator which selects faces based on the intersection of a surface with the vector b...
virtual zoneSet generate() const
Generate and return the zoneSet.
surface(const word &name, const polyMesh &mesh, const dictionary &dict)
Construct from dictionary.
Zone container returned by zoneGenerator::generate.
Definition: zoneSet.H:94
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
label patchi
autoPtr< CompressibleMomentumTransportModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const viscosity &viscosity)
defineTypeNameAndDebug(cylinderHeadPoints, 0)
addToRunTimeSelectionTable(zoneGenerator, cylinderHeadPoints, dictionary)
Namespace for OpenFOAM.
dimensionedScalar sign(const dimensionedScalar &ds)
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
const dimensionSet dimless
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
dictionary dict