matchPoints.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-2026 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 "matchPoints.H"
27 #include "SortableList.H"
28 #include "ListOps.H"
29 
30 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
31 
33 (
34  const Field<point>& pts0,
35  const Field<point>& pts1,
36  const Field<scalar>& matchDistances,
37  const bool verbose,
38  labelList& from0To1,
39  const point& origin
40 )
41 {
42  from0To1.setSize(pts0.size());
43  from0To1 = -1;
44 
45  bool fullMatch = true;
46 
47  point compareOrigin = origin;
48 
49  if (origin == point(vGreat, vGreat, vGreat))
50  {
51  if (pts1.size())
52  {
53  compareOrigin = sum(pts1)/pts1.size();
54  }
55  }
56 
57  SortableList<scalar> pts0MagSqr(magSqr(pts0 - compareOrigin));
58  SortableList<scalar> pts1MagSqr(magSqr(pts1 - compareOrigin));
59 
60  forAll(pts0MagSqr, i)
61  {
62  scalar dist0 = pts0MagSqr[i];
63 
64  label face0I = pts0MagSqr.indices()[i];
65 
66  scalar matchDist = matchDistances[face0I];
67 
68  label startI = findLower(pts1MagSqr, 0.99999*dist0 - 2*matchDist);
69 
70  if (startI == -1)
71  {
72  startI = 0;
73  }
74 
75 
76  // Go through range of equal mag and find nearest vector.
77  scalar minDistSqr = vGreat;
78  label minFacei = -1;
79 
80  for
81  (
82  label j = startI;
83  (
84  (j < pts1MagSqr.size())
85  && (pts1MagSqr[j] < 1.00001*dist0 + 2*matchDist)
86  );
87  j++
88  )
89  {
90  label facei = pts1MagSqr.indices()[j];
91  // Compare actual vectors
92  scalar distSqr = magSqr(pts0[face0I] - pts1[facei]);
93 
94  if (distSqr <= sqr(matchDist) && distSqr < minDistSqr)
95  {
96  minDistSqr = distSqr;
97  minFacei = facei;
98  }
99  }
100 
101  if (minFacei == -1)
102  {
103  fullMatch = false;
104 
105  if (verbose)
106  {
107  Pout<< "Cannot find point in pts1 matching point " << face0I
108  << " coord:" << pts0[face0I]
109  << " in pts0 when using tolerance " << matchDist << endl;
110 
111  // Go through range of equal mag and find equal vector.
112  Pout<< "Searching started from:" << startI << " in pts1"
113  << endl;
114  for
115  (
116  label j = startI;
117  (
118  (j < pts1MagSqr.size())
119  && (pts1MagSqr[j] < 1.00001*dist0 + 2*matchDist)
120  );
121  j++
122  )
123  {
124  label facei = pts1MagSqr.indices()[j];
125 
126  Pout<< " Compared coord: " << pts1[facei]
127  << " at index " << j
128  << " with difference to point "
129  << mag(pts1[facei] - pts0[face0I]) << endl;
130  }
131  }
132  }
133 
134  from0To1[face0I] = minFacei;
135  }
136 
137  return fullMatch;
138 }
139 
140 
142 (
143  const Field<point>& pts0,
144  const Field<point>& pts1,
145  const Field<point>& pts0Dir,
146  const Field<point>& pts1Dir,
147  const Field<scalar>& matchDistances,
148  const bool verbose,
149  labelList& from0To1,
150  const point& origin
151 )
152 {
153  from0To1.setSize(pts0.size());
154  from0To1 = -1;
155 
156  bool fullMatch = true;
157 
158  point compareOrigin = origin;
159 
160  if (origin == point(vGreat, vGreat, vGreat))
161  {
162  if (pts1.size())
163  {
164  compareOrigin = sum(pts1)/pts1.size();
165  }
166  }
167 
168  SortableList<scalar> pts0MagSqr(magSqr(pts0 - compareOrigin));
169  SortableList<scalar> pts1MagSqr(magSqr(pts1 - compareOrigin));
170 
171  forAll(pts0MagSqr, i)
172  {
173  scalar dist0 = pts0MagSqr[i];
174 
175  label face0I = pts0MagSqr.indices()[i];
176 
177  scalar matchDist = matchDistances[face0I];
178 
179  label startI = findLower(pts1MagSqr, 0.99999*dist0 - 2*matchDist);
180 
181  if (startI == -1)
182  {
183  startI = 0;
184  }
185 
186  // Go through range of equal mag and find nearest vector.
187  scalar minDistSqr = vGreat;
188  scalar minDistNorm = 0;
189  label minFacei = -1;
190 
191  for
192  (
193  label j = startI;
194  (
195  (j < pts1MagSqr.size())
196  && (pts1MagSqr[j] < 1.00001*dist0 + 2*matchDist)
197  );
198  j++
199  )
200  {
201  label facei = pts1MagSqr.indices()[j];
202  // Compare actual vectors
203  scalar distSqr = magSqr(pts0[face0I] - pts1[facei]);
204 
205  scalar distNorm = (pts0Dir[face0I] & pts1Dir[facei]);
206 
207  if
208  (
209  magSqr(pts0Dir[face0I]) < sqr(small)
210  && magSqr(pts1Dir[facei]) < sqr(small)
211  )
212  {
213  distNorm = -1;
214  }
215 
216  if (distSqr <= sqr(matchDist) && distSqr < minDistSqr)
217  {
218  // Check that the normals point in equal and opposite directions
219  if (distNorm < minDistNorm)
220  {
221  minDistNorm = distNorm;
222  minDistSqr = distSqr;
223  minFacei = facei;
224  }
225  }
226  }
227 
228  if (minFacei == -1)
229  {
230  fullMatch = false;
231 
232  if (verbose)
233  {
234  Pout<< "Cannot find point in pts1 matching point " << face0I
235  << " coord:" << pts0[face0I]
236  << " in pts0 when using tolerance " << matchDist << endl;
237 
238  // Go through range of equal mag and find equal vector.
239  Pout<< "Searching started from:" << startI << " in pts1"
240  << endl;
241  for
242  (
243  label j = startI;
244  (
245  (j < pts1MagSqr.size())
246  && (pts1MagSqr[j] < 1.00001*dist0 + 2*matchDist)
247  );
248  j++
249  )
250  {
251  label facei = pts1MagSqr.indices()[j];
252 
253  Pout<< " Compared coord: " << pts1[facei]
254  << " at index " << j
255  << " with difference to point "
256  << mag(pts1[facei] - pts0[face0I]) << endl;
257  }
258  }
259  }
260 
261  from0To1[face0I] = minFacei;
262  }
263 
264  return fullMatch;
265 }
266 
267 
268 // ************************************************************************* //
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Pre-declare SubField and related Field type.
Definition: Field.H:83
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 that is sorted upon construction or when explicitly requested with the sort() method.
Definition: SortableList.H:55
const labelList & indices() const
Return the list of sorted indices. Updated every sort.
Definition: SortableList.H:96
Determine correspondence between points. See below.
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
label findLower(const ListType &, typename ListType::const_reference, const label stary, const BinaryOp &bop)
Find last element < given value in sorted list and return index,.
vector point
Point is a vector.
Definition: point.H:41
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
bool matchPoints(const Field< point > &pts0, const Field< point > &pts1, const Field< scalar > &matchDistance, const bool verbose, labelList &from0To1, const point &origin=point::zero)
Determine correspondence between pointFields. Gets passed.
Definition: matchPoints.C:33
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)