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 -------------------------------------------------------------------------------
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 "meshToMesh0.H"
30 #include "tetOverlapVolume.H"
31 
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 
34 void 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 
133 void 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  (
168  pointField
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 
193 void 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 
232 const Foam::scalarListList& Foam::meshToMesh0::inverseDistanceWeights() const
233 {
234  if (!inverseDistanceWeightsPtr_)
235  {
236  calculateInverseDistanceWeights();
237  }
238 
239  return *inverseDistanceWeightsPtr_;
240 }
241 
242 
243 const Foam::scalarListList& Foam::meshToMesh0::inverseVolumeWeights() const
244 {
245  if (!inverseVolumeWeightsPtr_)
246  {
247  calculateInverseVolumeWeights();
248  }
249 
250  return *inverseVolumeWeightsPtr_;
251 }
252 
253 
254 const Foam::labelListList& Foam::meshToMesh0::cellToCellAddressing() const
255 {
256  if (!cellToCellAddressingPtr_)
257  {
258  calculateCellToCellAddressing();
259  }
260 
261  return *cellToCellAddressingPtr_;
262 }
263 
264 
265 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::scalarListList
List< scalarList > scalarListList
A List of scalarList.
Definition: scalarList.H:66
meshToMesh0.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::primitiveMesh::nCells
label nCells() const noexcept
Number of mesh cells.
Definition: primitiveMeshI.H:96
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:388
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::primitiveMesh::cellCells
const labelListList & cellCells() const
Definition: primitiveMeshCellCells.C:102
Foam::fvMesh::C
const volVectorField & C() const
Return cell centres as volVectorField.
Definition: fvMeshGeometry.C:341
Foam::FatalError
error FatalError
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
tetOverlapVolume.H
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::List< scalarList >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::fvMesh::V
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
Definition: fvMeshGeometry.C:179