findRefCells.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) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2016 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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 "findRefCell.H"
30#include "regionSplit.H"
31
32// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
33
35(
36 const volScalarField& field,
37 const volScalarField& fieldRef,
38 const dictionary& dict,
39 boolList& regionNeedReference,
40 labelList& regionRefCells,
41 scalarField& regionRefValues,
42 const bool forceReference
43)
44{
45 const regionSplit& regions = regionSplit::New(field.mesh());
46
47 regionNeedReference.setSize(regions.nRegions(), true);
48 regionRefCells.setSize(regions.nRegions(), -1);
49 regionRefValues.setSize(regions.nRegions(), 0);
50
51 if (!forceReference)
52 {
53 const volScalarField::GeometricBoundaryField& bfld =
54 fieldRef.boundaryField();
55
56 forAll(bfld, patchI)
57 {
58 if (bfld[patchI].fixesValue())
59 {
60 // Unmark all regions
61
62 const labelUList& fc = bfld[patchI].patch().patch().faceCells();
63
64 forAll(fc, faceI)
65 {
66 regionNeedReference[regions[fc[faceI]]] = false;
67 }
68 }
69 }
70
71 Pstream::listCombineAllGather(regionNeedReference, orEqOp<bool>());
72 }
73
74
75 label nRefs = 0;
76 forAll(regionNeedReference, regionI)
77 {
78 if (regionNeedReference[regionI])
79 {
80 nRefs++;
81 }
82 }
83
84 if (nRefs == 0)
85 {
86 return;
87 }
88
89 // Get the reference cells for all the regions
90
91 word refCellName = field.name() + "RefCells";
92 word refPointName = field.name() + "RefPoints";
93 word refValueName = field.name() + "RefValues";
94
95
96 // (per region!) does region have reference cell?
97 labelList hasRef(regionNeedReference.size(), Zero);
98
99
100 const labelList refValues(dict.lookup(refValueName));
101
102
103 if (dict.found(refCellName))
104 {
105 // Have specified reference cells (on master!)
106
107 if (Pstream::master())
108 {
109 labelList refCells(dict.lookup(refCellName));
110
111 if (refCells.size() != regionNeedReference.size())
112 {
114 << "Number of refCells " << refCells.size()
115 << " does not correspond to number of regions "
116 << regionNeedReference.size()
117 << exit(FatalIOError);
118 }
119
120 forAll(refCells, i)
121 {
122 label regionI = regions[refCells[i]];
123
124 if (regionNeedReference[regionI])
125 {
126 regionRefCells[regionI] = refCells[i];
127 regionRefValues[regionI] = refValues[i];
128 }
129 }
130
131
132 forAll(regionNeedReference, regionI)
133 {
134 if
135 (
136 regionNeedReference[regionI]
137 && regionRefCells[regionI] == -1
138 )
139 {
141 << "Have no reference cell for region " << regionI
142 << nl
143 << "Overall per-region reference cells "
144 << regionRefCells
145 << exit(FatalIOError);
146 }
147 }
148 }
149 }
150 else if (dict.found(refPointName))
151 {
152 pointField refPoints(dict.lookup(refPointName));
153
154 if (refPoints.size() != regionNeedReference.size())
155 {
157 << "Number of refPoints " << refPoints.size()
158 << " does not correspond to number of regions "
159 << regionNeedReference.size()
160 << exit(FatalIOError);
161 }
162
163 labelList hasRef(refPoints.size(), Zero);
164
165 forAll(refPoints, i)
166 {
167 // Note: find reference cell using facePlanes to avoid constructing
168 // face decomposition structure. Most likely the reference
169 // cell is an undistorted one so this should not be a
170 // problem.
171
172 label celli = field.mesh().findCell
173 (
174 refPoints[i],
175 polyMesh::FACEPLANES
176 );
177
178 if (celli >= 0)
179 {
180 Pout<< "Found point " << refPoints[i]
181 << " in reference cell " << celli
182 << " at " << field.mesh().cellCentres()[celli]
183 << " for region " << regions[celli]
184 << endl;
185
186 regionRefCells[regions[celli]] = celli;
187 hasRef[regions[celli]] = 1;
188 }
189 }
190
191 Pstream::listCombineAllGather(hasRef, plusEqOp<label>());
192
193 forAll(hasRef, regionI)
194 {
195 if (hasRef[regionI] != 1)
196 {
198 << "Unable to set reference cell for field " << field.name()
199 << nl
200 << " Reference points " << refPointName
201 << " " << refPoints
202 << nl << " For region " << regionI
203 << " found on " << hasRef[regionI]
204 << " domains (should be one)"
205 << nl << exit(FatalIOError);
206 }
207 }
208 }
209 else
210 {
212 << "Unable to set reference cell for field " << field.name()
213 << nl
214 << " Please supply either " << refCellName
215 << " or " << refPointName << nl << exit(FatalIOError);
216 }
217}
218
219
220// ************************************************************************* //
rDeltaTY field()
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Find the reference cell nearest (in index) to the given cell but which is not on a cyclic,...
void setRefCells(const volScalarField &field, const volScalarField &fieldRef, const dictionary &dict, const label refCelli, const scalar refValue, boolList &needReference, labelList &refCells, scalarField &refValues, const bool forceReference=false)
Set reference cells for multi-region domains. Returns per region:
List< label > labelList
A List of labels.
Definition: List.H:66
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333