projectFace.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016 OpenFOAM Foundation
9  Copyright (C) 2019-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU 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 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "projectFace.H"
30 #include "unitConversion.H"
32 #include "blockDescriptor.H"
33 #include "OBJstream.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40 namespace blockFaces
41 {
44 }
45 }
46 
47 
48 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49 
50 const Foam::searchableSurface& Foam::blockFaces::projectFace::lookupSurface
51 (
52  const searchableSurfaces& geometry,
53  Istream& is
54 ) const
55 {
56  const word name(is);
57 
58  for (const searchableSurface& geom : geometry)
59  {
60  if (geom.name() == name)
61  {
62  return geom;
63  }
64  }
65 
67  << "Cannot find surface " << name << " in geometry"
68  << exit(FatalIOError);
69 
70  return geometry[0];
71 }
72 
73 
74 Foam::label Foam::blockFaces::projectFace::index
75 (
76  const labelPair& n,
77  const labelPair& coord
78 )
79 {
80  return coord.first() + coord.second()*n.first();
81 }
82 
83 
84 void Foam::blockFaces::projectFace::calcLambdas
85 (
86  const labelPair& n,
87  const pointField& points,
88  scalarField& lambdaI,
89  scalarField& lambdaJ
90 ) const
91 {
92  lambdaI.setSize(points.size());
93  lambdaI = 0.0;
94  lambdaJ.setSize(points.size());
95  lambdaJ = 0.0;
96 
97  for (label i = 1; i < n.first(); i++)
98  {
99  for (label j = 1; j < n.second(); j++)
100  {
101  label ij = index(n, labelPair(i, j));
102  label iMin1j = index(n, labelPair(i-1, j));
103  lambdaI[ij] = lambdaI[iMin1j] + mag(points[ij]-points[iMin1j]);
104 
105  label ijMin1 = index(n, labelPair(i, j-1));
106  lambdaJ[ij] = lambdaJ[ijMin1] + mag(points[ij]-points[ijMin1]);
107  }
108  }
109 
110  for (label i = 1; i < n.first(); i++)
111  {
112  label ijLast = index(n, labelPair(i, n.second()-1));
113  for (label j = 1; j < n.second(); j++)
114  {
115  label ij = index(n, labelPair(i, j));
116  lambdaJ[ij] /= lambdaJ[ijLast];
117  }
118  }
119  for (label j = 1; j < n.second(); j++)
120  {
121  label iLastj = index(n, labelPair(n.first()-1, j));
122  for (label i = 1; i < n.first(); i++)
123  {
124  label ij = index(n, labelPair(i, j));
125  lambdaI[ij] /= lambdaI[iLastj];
126  }
127  }
128 }
129 
130 
131 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
132 
133 Foam::blockFaces::projectFace::projectFace
134 (
135  const dictionary& dict,
136  const label index,
137  const searchableSurfaces& geometry,
138  Istream& is
139 )
140 :
141  blockFace(dict, index, is),
142  surface_(lookupSurface(geometry, is))
143 {}
144 
145 
146 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
147 
149 (
150  const blockDescriptor& desc,
151  const label blockFacei,
153 ) const
154 {
155  // For debugging to tag the output
156  static label fIter = 0;
157 
158  autoPtr<OBJstream> debugStr;
159  if (debug)
160  {
161  debugStr.reset
162  (
163  new OBJstream("projectFace_" + Foam::name(fIter++) + ".obj")
164  );
165  Info<< "Face:" << blockFacei << " on block:" << desc.blockShape()
166  << " with verts:" << desc.vertices()
167  << " writing lines from start points"
168  << " to projected points to " << debugStr().name() << endl;
169  }
170 
171 
172  // Find out range of vertices in face
173  labelPair n(-1, -1);
174  switch (blockFacei)
175  {
176  case 0:
177  case 1:
178  {
179  n.first() = desc.density().y() + 1;
180  n.second() = desc.density().z() + 1;
181  }
182  break;
183 
184  case 2:
185  case 3:
186  {
187  n.first() = desc.density().x() + 1;
188  n.second() = desc.density().z() + 1;
189  }
190  break;
191 
192  case 4:
193  case 5:
194  {
195  n.first() = desc.density().x() + 1;
196  n.second() = desc.density().y() + 1;
197  }
198  break;
199  }
200 
201 
202  // Calculate initial normalised edge lengths (= u,v coordinates)
203  scalarField lambdaI(points.size(), Zero);
204  scalarField lambdaJ(points.size(), Zero);
205  calcLambdas(n, points, lambdaI, lambdaJ);
206 
207 
208  // Upper limit for number of iterations
209  const label maxIter = 10;
210  // Residual tolerance
211  const scalar relTol = 0.1;
212 
213  scalar initialResidual = 0.0;
214  scalar iResidual = 0.0;
215  scalar jResidual = 0.0;
216 
217  for (label iter = 0; iter < maxIter; iter++)
218  {
219  // Do projection
220  {
221  List<pointIndexHit> hits;
222  scalarField nearestDistSqr
223  (
224  points.size(),
225  magSqr(points[0] - points[points.size()-1])
226  );
227  surface_.findNearest(points, nearestDistSqr, hits);
228 
229  forAll(hits, i)
230  {
231  if (hits[i].hit())
232  {
233  const point& hitPt = hits[i].hitPoint();
234  if (debugStr)
235  {
236  debugStr().write(linePointRef(points[i], hitPt));
237  }
238  points[i] = hitPt;
239  }
240  }
241  }
242 
243  if (debug)
244  {
245  Pout<< "Iter:" << iter << " initialResidual:" << initialResidual
246  << " iResidual+jResidual:" << iResidual+jResidual << endl;
247  }
248 
249 
250  if
251  (
252  iter > 0
253  && (
254  initialResidual < ROOTVSMALL
255  || ((iResidual+jResidual)/initialResidual < relTol)
256  )
257  )
258  {
259  break;
260  }
261 
262 
263  // Predict along i
264  vectorField residual(points.size(), Zero);
265 
266  // Work arrays for interpolation
267  labelList indices;
268  scalarField weights;
269  for (label j = 1; j < n.second()-1; j++)
270  {
271  // Calculate actual lamdba along constant j line
272  scalarField projLambdas(n.first());
273  projLambdas[0] = 0.0;
274  for (label i = 1; i < n.first(); i++)
275  {
276  label ij = index(n, labelPair(i, j));
277  label iMin1j = index(n, labelPair(i-1, j));
278  projLambdas[i] =
279  projLambdas[i-1]
280  +mag(points[ij]-points[iMin1j]);
281  }
282  projLambdas /= projLambdas.last();
283 
284  linearInterpolationWeights interpolator(projLambdas);
285 
286  for (label i = 1; i < n.first()-1; i++)
287  {
288  label ij = index(n, labelPair(i, j));
289 
290  interpolator.valueWeights(lambdaI[ij], indices, weights);
291 
292  point predicted(Zero);
293  forAll(indices, indexi)
294  {
295  label ptIndex = index(n, labelPair(indices[indexi], j));
296  predicted += weights[indexi]*points[ptIndex];
297  }
298  residual[ij] = predicted-points[ij];
299  }
300  }
301 
302  if (debugStr)
303  {
304  forAll(points, i)
305  {
306  const point predicted(points[i] + residual[i]);
307  debugStr().write(linePointRef(points[i], predicted));
308  }
309  }
310 
311  iResidual = sum(mag(residual));
312 
313  // Update points before doing j. Note: is this needed? Complicates
314  // residual checking.
315  points += residual;
316 
317 
318  // Predict along j
319  residual = vector::zero;
320  for (label i = 1; i < n.first()-1; i++)
321  {
322  // Calculate actual lamdba along constant i line
323  scalarField projLambdas(n.second());
324  projLambdas[0] = 0.0;
325  for (label j = 1; j < n.second(); j++)
326  {
327  label ij = index(n, labelPair(i, j));
328  label ijMin1 = index(n, labelPair(i, j-1));
329  projLambdas[j] =
330  projLambdas[j-1]
331  +mag(points[ij]-points[ijMin1]);
332  }
333 
334  projLambdas /= projLambdas.last();
335 
336  linearInterpolationWeights interpolator(projLambdas);
337 
338  for (label j = 1; j < n.second()-1; j++)
339  {
340  label ij = index(n, labelPair(i, j));
341 
342  interpolator.valueWeights(lambdaJ[ij], indices, weights);
343 
344  point predicted(Zero);
345  forAll(indices, indexi)
346  {
347  label ptIndex = index(n, labelPair(i, indices[indexi]));
348  predicted += weights[indexi]*points[ptIndex];
349  }
350  residual[ij] = predicted-points[ij];
351  }
352  }
353 
354  if (debugStr)
355  {
356  forAll(points, i)
357  {
358  const point predicted(points[i] + residual[i]);
359  debugStr().write(linePointRef(points[i], predicted));
360  }
361  }
362 
363  jResidual = sum(mag(residual));
364 
365  if (iter == 0)
366  {
367  initialResidual = iResidual + jResidual;
368  }
369 
370  points += residual;
371  }
372 }
373 
374 
375 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::Vector::x
const Cmpt & x() const
Access to the vector x component.
Definition: VectorI.H:73
Foam::OBJstream
OFstream that keeps track of vertices.
Definition: OBJstream.H:58
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
unitConversion.H
Unit conversion functions.
Foam::blockFace
Define a curved face.
Definition: blockFace.H:57
Foam::blockDescriptor::vertices
const pointField & vertices() const noexcept
Reference to point field defining the block mesh.
Definition: blockDescriptorI.H:32
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
blockDescriptor.H
Foam::Vector::z
const Cmpt & z() const
Access to the vector z component.
Definition: VectorI.H:85
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::magSqr
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
linearInterpolationWeights.H
Foam::labelPair
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:54
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::blockFaces::addToRunTimeSelectionTable
addToRunTimeSelectionTable(blockFace, projectFace, Istream)
Foam::Field< vector >
projectFace.H
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::blockDescriptor::density
const labelVector & density() const noexcept
The mesh density (number of cells) in the i,j,k directions.
Definition: blockDescriptorI.H:53
Foam::searchableSurface
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
Definition: searchableSurface.H:69
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::linearInterpolationWeights::valueWeights
virtual bool valueWeights(const scalar t, labelList &indices, scalarField &weights) const
Calculate weights and indices to calculate t from samples.
Definition: linearInterpolationWeights.C:89
Foam::linearInterpolationWeights
Definition: linearInterpolationWeights.H:50
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::blockFaces::defineTypeNameAndDebug
defineTypeNameAndDebug(projectFace, 0)
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::blockFaces::projectFace
Projects the given set of face points onto the selected surface of the geometry provided as a searcha...
Definition: projectFace.H:54
Foam::autoPtr::reset
void reset(autoPtr< T > &&other) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:117
Foam::blockFaces::projectFace::project
virtual void project(const blockDescriptor &, const label blockFacei, pointField &points) const
Project the given points onto the surface.
Definition: projectFace.C:149
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::Vector::y
const Cmpt & y() const
Access to the vector y component.
Definition: VectorI.H:79
Foam::linePointRef
line< point, const point & > linePointRef
A line using referred points.
Definition: linePointRef.H:47
Foam::Pair< label >
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: BitOps.H:63
Foam::searchableSurfaces
Container for searchableSurfaces. The collection is specified as a dictionary. For example,...
Definition: searchableSurfaces.H:92
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:327
Foam::blockDescriptor::blockShape
const cellShape & blockShape() const noexcept
Return the block shape.
Definition: blockDescriptorI.H:46
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::zero
static const Vector< scalar > zero
Definition: VectorSpace.H:115
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::blockDescriptor
Takes the description of the block and the list of curved edges and creates a list of points on edges...
Definition: blockDescriptor.H:78
OBJstream.H