FreeFOAM The Cross-Platform CFD Toolkit
patchProbes.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 | Copyright (C) 2010-2011 OpenCFD Ltd.
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 "patchProbes.H"
27 #include <finiteVolume/volFields.H>
28 #include <OpenFOAM/IOmanip.H>
29 // For 'nearInfo' helper class only
31 #include <meshTools/meshSearch.H>
32 #include <meshTools/treeBoundBox.H>
33 #include <meshTools/treeDataFace.H>
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39  defineTypeNameAndDebug(patchProbes, 0);
40 }
41 
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 
45 {
46 
47  const polyBoundaryMesh& bm = mesh.boundaryMesh();
48 
49  label patchI = bm.findPatchID(patchName_);
50 
51  if (patchI == -1)
52  {
54  (
55  " Foam::patchProbes::findElements(const fvMesh&)"
56  ) << " Unknown patch name "
57  << patchName_ << endl
58  << exit(FatalError);
59  }
60 
61 
62  // All the info for nearest. Construct to miss
64 
65  const polyPatch& pp = bm[patchI];
66 
67  if (pp.size() > 0)
68  {
69  labelList bndFaces(pp.size());
70  forAll(bndFaces, i)
71  {
72  bndFaces[i] = pp.start() + i;
73  }
74 
75  treeBoundBox overallBb(pp.points());
76  Random rndGen(123456);
77  overallBb = overallBb.extend(rndGen, 1E-4);
78  overallBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
79  overallBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
80 
81  const indexedOctree<treeDataFace> boundaryTree
82  (
83  treeDataFace // all information needed to search faces
84  (
85  false, // do not cache bb
86  mesh,
87  bndFaces // patch faces only
88  ),
89  overallBb, // overall search domain
90  8, // maxLevel
91  10, // leafsize
92  3.0 // duplicity
93  );
94 
95 
96  if (elementList_.empty())
97  {
99 
100  // Octree based search engine
101  //meshSearch meshSearchEngine(mesh, false);
102 
103  forAll(probeLocations_, probeI)
104  {
105  const point sample = probeLocations_[probeI];
106 
107  scalar span = boundaryTree.bb().mag();
108 
109  pointIndexHit info = boundaryTree.findNearest
110  (
111  sample,
112  Foam::sqr(span)
113  );
114 
115  if (!info.hit())
116  {
117  info = boundaryTree.findNearest
118  (
119  sample,
120  Foam::sqr(GREAT)
121  );
122  }
123 
124  label faceI = boundaryTree.shapes().faceLabels()[info.index()];
125 
126  const label patchi = bm.whichPatch(faceI);
127 
128  if (isA<emptyPolyPatch>(bm[patchi]))
129  {
130  WarningIn
131  (
132  " Foam::patchProbes::findElements(const fvMesh&)"
133  )
134  << " The sample point: " << sample
135  << " belongs to " << patchi
136  << " which is an empty patch. This is not permitted. "
137  << " This sample will not be included "
138  << endl;
139  }
140  else
141  {
142  const point& fc = mesh.faceCentres()[faceI];
143 
145 
146  sampleInfo.first() = pointIndexHit
147  (
148  true,
149  fc,
150  faceI
151  );
152 
153  sampleInfo.second().first() = magSqr(fc-sample);
154  sampleInfo.second().second() = Pstream::myProcNo();
155 
156  nearest[probeI]= sampleInfo;
157  }
158  }
159  }
160  }
161  // Find nearest.
164 
165  if (debug)
166  {
167  Info<< "patchProbes::findElements" << " : " << endl;
168  forAll(nearest, sampleI)
169  {
170  label procI = nearest[sampleI].second().second();
171  label localI = nearest[sampleI].first().index();
172 
173  Info<< " " << sampleI << " coord:"<< probeLocations_[sampleI]
174  << " found on processor:" << procI
175  << " in local cell/face:" << localI
176  << " with cc:" << nearest[sampleI].first().rawPoint()
177  << " in patch : "<< pp.name() << endl;
178  }
179  }
180 
181  // Check if all patchProbes have been found.
182  forAll(probeLocations_, sampleI)
183  {
184  label localI = -1;
185  if (nearest[sampleI].second().second() == Pstream::myProcNo())
186  {
187  localI = nearest[sampleI].first().index();
188  }
189 
190  if (elementList_.empty())
191  {
193  }
194 
195  elementList_[sampleI] = localI;
196  }
197 }
198 
199 
200 
201 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
202 
203 Foam::patchProbes::patchProbes
204 (
205  const word& name,
206  const objectRegistry& obr,
207  const dictionary& dict,
208  const bool loadFromFiles
209 )
210 :
211  probes(name, obr, dict, loadFromFiles)
212 {
213  read(dict);
214 }
215 
216 
217 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
218 
220 {}
221 
222 
224 {
225  if (probeLocations_.size() && checkFieldTypes())
226  {
227  sampleAndWrite(scalarFields_);
228  sampleAndWrite(vectorFields_);
229  sampleAndWrite(sphericalTensorFields_);
230  sampleAndWrite(symmTensorFields_);
231  sampleAndWrite(tensorFields_);
232  }
233 }
234 
236 {
237  dict.lookup("patchName") >> patchName_;
238  probes::read(dict);
239 }
240 
241 
242 // ************************ vim: set sw=4 sts=4 et: ************************ //