calculateMeshToMesh0Weights.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) 2020 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 "meshToMesh0.H"
30#include "tetOverlapVolume.H"
31
32// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33
34void Foam::meshToMesh0::calculateInverseDistanceWeights() const
35{
37 << "Calculating inverse distance weighting factors" << nl;
38
39 if (inverseDistanceWeightsPtr_)
40 {
42 << "weighting factors already calculated"
43 << exit(FatalError);
44 }
45
46 //- Initialise overlap volume to zero
47 V_ = 0;
48
49 inverseDistanceWeightsPtr_.reset(new scalarListList(toMesh_.nCells()));
50 auto& invDistCoeffs = *inverseDistanceWeightsPtr_;
51
52 // get reference to source mesh data
53 const labelListList& cc = fromMesh_.cellCells();
54 const vectorField& centreFrom = fromMesh_.C();
55 const vectorField& centreTo = toMesh_.C();
56
57 forAll(cellAddressing_, celli)
58 {
59 if (cellAddressing_[celli] != -1)
60 {
61 const vector& target = centreTo[celli];
62 scalar m = mag(target - centreFrom[cellAddressing_[celli]]);
63
64 const labelList& neighbours = cc[cellAddressing_[celli]];
65
66 // if the nearest cell is a boundary cell or there is a direct hit,
67 // pick up the value
68 label directCelli = -1;
69 if (m < directHitTol || neighbours.empty())
70 {
71 directCelli = celli;
72 }
73 else
74 {
75 forAll(neighbours, ni)
76 {
77 scalar nm = mag(target - centreFrom[neighbours[ni]]);
78 if (nm < directHitTol)
79 {
80 directCelli = neighbours[ni];
81 break;
82 }
83 }
84 }
85
86
87 if (directCelli != -1)
88 {
89 // Direct hit
90 invDistCoeffs[directCelli].setSize(1);
91 invDistCoeffs[directCelli][0] = 1.0;
92 V_ += fromMesh_.V()[cellAddressing_[directCelli]];
93 }
94 else
95 {
96 invDistCoeffs[celli].setSize(neighbours.size() + 1);
97
98 // The first coefficient corresponds to the centre cell.
99 // The rest is ordered in the same way as the cellCells list.
100 scalar invDist = 1.0/m;
101 invDistCoeffs[celli][0] = invDist;
102 scalar sumInvDist = invDist;
103
104 // now add the neighbours
105 forAll(neighbours, ni)
106 {
107 invDist = 1.0/mag(target - centreFrom[neighbours[ni]]);
108 invDistCoeffs[celli][ni + 1] = invDist;
109 sumInvDist += invDist;
110 }
111
112 // divide by the total inverse-distance
113 forAll(invDistCoeffs[celli], i)
114 {
115 invDistCoeffs[celli][i] /= sumInvDist;
116 }
117
118
119 V_ +=
120 invDistCoeffs[celli][0]
121 *fromMesh_.V()[cellAddressing_[celli]];
122 for (label i = 1; i < invDistCoeffs[celli].size(); i++)
123 {
124 V_ +=
125 invDistCoeffs[celli][i]*fromMesh_.V()[neighbours[i-1]];
126 }
127 }
128 }
129 }
130}
131
132
133void Foam::meshToMesh0::calculateInverseVolumeWeights() const
134{
136 << "Calculating inverse volume weighting factors" << endl;
137
138 if (inverseVolumeWeightsPtr_)
139 {
141 << "weighting factors already calculated"
142 << exit(FatalError);
143 }
144
145 //- Initialise overlap volume to zero
146 V_ = 0;
147
148 inverseVolumeWeightsPtr_.reset(new scalarListList(toMesh_.nCells()));
149 auto& invVolCoeffs = *inverseVolumeWeightsPtr_;
150
151 const labelListList& cellToCell = cellToCellAddressing();
152
153 tetOverlapVolume overlapEngine;
154
155 forAll(cellToCell, celli)
156 {
157 const labelList& overlapCells = cellToCell[celli];
158
159 if (overlapCells.size() > 0)
160 {
161 invVolCoeffs[celli].setSize(overlapCells.size());
162
163 forAll(overlapCells, j)
164 {
165 label cellFrom = overlapCells[j];
166 treeBoundBox bbFromMesh
167 (
169 (
170 fromMesh_.points(),
171 fromMesh_.cellPoints()[cellFrom]
172 )
173 );
174
175 scalar v = overlapEngine.cellCellOverlapVolumeMinDecomp
176 (
177 toMesh_,
178 celli,
179
180 fromMesh_,
181 cellFrom,
182 bbFromMesh
183 );
184 invVolCoeffs[celli][j] = v/toMesh_.V()[celli];
185
186 V_ += v;
187 }
188 }
189 }
190}
191
192
193void Foam::meshToMesh0::calculateCellToCellAddressing() const
194{
196 << "Calculating cell to cell addressing" << endl;
197
198 if (cellToCellAddressingPtr_)
199 {
201 << "addressing already calculated"
202 << exit(FatalError);
203 }
204
205 //- Initialise overlap volume to zero
206 V_ = 0;
207
208 tetOverlapVolume overlapEngine;
209
210 cellToCellAddressingPtr_.reset(new labelListList(toMesh_.nCells()));
211 auto& cellToCell = *cellToCellAddressingPtr_;
212
213
214 forAll(cellToCell, iTo)
215 {
216 const labelList overLapCells =
217 overlapEngine.overlappingCells(fromMesh_, toMesh_, iTo);
218 if (overLapCells.size() > 0)
219 {
220 cellToCell[iTo].setSize(overLapCells.size());
221 forAll(overLapCells, j)
222 {
223 cellToCell[iTo][j] = overLapCells[j];
224 V_ += fromMesh_.V()[overLapCells[j]];
225 }
226 }
227 }
228}
229
230// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
231
232const Foam::scalarListList& Foam::meshToMesh0::inverseDistanceWeights() const
233{
234 if (!inverseDistanceWeightsPtr_)
235 {
236 calculateInverseDistanceWeights();
237 }
238
239 return *inverseDistanceWeightsPtr_;
240}
241
242
243const Foam::scalarListList& Foam::meshToMesh0::inverseVolumeWeights() const
244{
245 if (!inverseVolumeWeightsPtr_)
246 {
247 calculateInverseVolumeWeights();
248 }
249
250 return *inverseVolumeWeightsPtr_;
251}
252
253
254const Foam::labelListList& Foam::meshToMesh0::cellToCellAddressing() const
255{
256 if (!cellToCellAddressingPtr_)
257 {
258 calculateCellToCellAddressing();
259 }
260
261 return *cellToCellAddressingPtr_;
262}
263
264
265// ************************************************************************* //
void setSize(const label n)
Alias for resize()
Definition: List.H:218
const volVectorField & C() const
Return cell centres as volVectorField.
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
const labelListList & cellCells() const
label nCells() const noexcept
Number of mesh cells.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
#define DebugInFunction
Report an information message using Foam::Info.
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
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
Field< vector > vectorField
Specialisation of Field<T> for vector.
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
List< scalarList > scalarListList
A List of scalarList.
Definition: scalarList.H:66
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333