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 | Copyright (C) 2011-2015 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 "meshToMesh0.H"
27 #include "tetOverlapVolume.H"
28 
29 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30 
32 {
33  if (debug)
34  {
35  Info<< "meshToMesh0::calculateInverseDistanceWeights() : "
36  << "calculating inverse distance weighting factors" << endl;
37  }
38 
40  {
42  << "weighting factors already calculated"
43  << exit(FatalError);
44  }
45 
46  //- Initialise overlap volume to zero
47  V_ = 0.0;
48 
51 
52  // get reference to source mesh data
53  const labelListList& cc = fromMesh_.cellCells();
54  const vectorField& centreFrom = fromMesh_.C().internalField();
55  const vectorField& centreTo = toMesh_.C().internalField();
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 
134 {
135  if (debug)
136  {
137  Info<< "meshToMesh0::calculateInverseVolumeWeights() : "
138  << "calculating inverse volume weighting factors" << endl;
139  }
140 
141  if (inverseVolumeWeightsPtr_)
142  {
144  << "weighting factors already calculated"
145  << exit(FatalError);
146  }
147 
148  //- Initialise overlap volume to zero
149  V_ = 0.0;
150 
151  inverseVolumeWeightsPtr_ = new scalarListList(toMesh_.nCells());
152  scalarListList& invVolCoeffs = *inverseVolumeWeightsPtr_;
153 
154  const labelListList& cellToCell = cellToCellAddressing();
155 
156  tetOverlapVolume overlapEngine;
157 
158  forAll(cellToCell, celli)
159  {
160  const labelList& overlapCells = cellToCell[celli];
161 
162  if (overlapCells.size() > 0)
163  {
164  invVolCoeffs[celli].setSize(overlapCells.size());
165 
166  forAll(overlapCells, j)
167  {
168  label cellFrom = overlapCells[j];
169  treeBoundBox bbFromMesh
170  (
171  pointField
172  (
173  fromMesh_.points(),
174  fromMesh_.cellPoints()[cellFrom]
175  )
176  );
177 
178  scalar v = overlapEngine.cellCellOverlapVolumeMinDecomp
179  (
180  toMesh_,
181  celli,
182 
183  fromMesh_,
184  cellFrom,
185  bbFromMesh
186  );
187  invVolCoeffs[celli][j] = v/toMesh_.V()[celli];
188 
189  V_ += v;
190  }
191  }
192  }
193 }
194 
195 
197 {
198  if (debug)
199  {
200  Info<< "meshToMesh0::calculateCellToCellAddressing() : "
201  << "calculating cell to cell addressing" << endl;
202  }
203 
204  if (cellToCellAddressingPtr_)
205  {
207  << "addressing already calculated"
208  << exit(FatalError);
209  }
210 
211  //- Initialise overlap volume to zero
212  V_ = 0.0;
213 
214  tetOverlapVolume overlapEngine;
215 
216  cellToCellAddressingPtr_ = new labelListList(toMesh_.nCells());
217  labelListList& cellToCell = *cellToCellAddressingPtr_;
218 
219 
220  forAll(cellToCell, iTo)
221  {
222  const labelList overLapCells =
223  overlapEngine.overlappingCells(fromMesh_, toMesh_, iTo);
224  if (overLapCells.size() > 0)
225  {
226  //Info << "To " << iTo << endl;
227  //Info << "cellToCell " << overLapCells << endl;
228 
229  cellToCell[iTo].setSize(overLapCells.size());
230  forAll(overLapCells, j)
231  {
232  cellToCell[iTo][j] = overLapCells[j];
233  V_ += fromMesh_.V()[overLapCells[j]];
234  }
235  }
236  }
237 }
238 
239 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
240 
242 {
243  if (!inverseDistanceWeightsPtr_)
244  {
245  calculateInverseDistanceWeights();
246  }
247 
248  return *inverseDistanceWeightsPtr_;
249 }
250 
251 
253 {
254  if (!inverseVolumeWeightsPtr_)
255  {
256  calculateInverseVolumeWeights();
257  }
258 
259  return *inverseVolumeWeightsPtr_;
260 }
261 
262 
264 {
265  if (!cellToCellAddressingPtr_)
266  {
267  calculateCellToCellAddressing();
268  }
269 
270  return *cellToCellAddressingPtr_;
271 }
272 
273 
274 // ************************************************************************* //
Foam::meshToMesh0::cellAddressing_
labelList cellAddressing_
Cell addressing.
Definition: meshToMesh0.H:85
meshToMesh0.H
Foam::meshToMesh0::fromMesh_
const fvMesh & fromMesh_
Definition: meshToMesh0.H:69
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::tetOverlapVolume::cellCellOverlapVolumeMinDecomp
scalar cellCellOverlapVolumeMinDecomp(const primitiveMesh &meshA, const label cellAI, const primitiveMesh &meshB, const label cellBI, const treeBoundBox &cellBbB) const
Calculates the overlap volume.
Definition: tetOverlapVolume.C:103
Foam::treeBoundBox
Standard boundBox + extra functionality for use in octree.
Definition: treeBoundBox.H:75
Foam::meshToMesh0::inverseDistanceWeightsPtr_
scalarListList * inverseDistanceWeightsPtr_
Inverse-distance interpolation weights.
Definition: meshToMesh0.H:91
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::meshToMesh0::calculateInverseVolumeWeights
void calculateInverseVolumeWeights() const
Definition: calculateMeshToMesh0Weights.C:133
Foam::primitiveMesh::nCells
label nCells() const
Definition: primitiveMeshI.H:64
Foam::meshToMesh0::inverseVolumeWeights
const scalarListList & inverseVolumeWeights() const
Definition: calculateMeshToMesh0Weights.C:252
Foam::fvMesh::V
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
Definition: fvMeshGeometry.C:199
Foam::label
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
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::Info
messageStream Info
Foam::primitiveMesh::cellCells
const labelListList & cellCells() const
Definition: primitiveMeshCellCells.C:100
Foam::meshToMesh0::cellToCellAddressing
const labelListList & cellToCellAddressing() const
Definition: calculateMeshToMesh0Weights.C:263
Foam::tetOverlapVolume::overlappingCells
labelList overlappingCells(const polyMesh &meshA, const polyMesh &meshB, const label cellBI) const
Return a list of cells in meshA which overlaps with cellBI in.
Definition: tetOverlapVolume.C:154
Foam::GeometricField::internalField
InternalField & internalField()
Return internal field.
Definition: GeometricField.C:724
Foam::cellToCell
A topoSetSource to select the cells from another cellSet.
Definition: cellToCell.H:48
Foam::meshToMesh0::inverseDistanceWeights
const scalarListList & inverseDistanceWeights() const
Definition: calculateMeshToMesh0Weights.C:241
Foam::FatalError
error FatalError
Foam::meshToMesh0::toMesh_
const fvMesh & toMesh_
Definition: meshToMesh0.H:70
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
tetOverlapVolume.H
Foam::meshToMesh0::directHitTol
static const scalar directHitTol
Direct hit tolerance.
Definition: meshToMesh0.H:132
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::fvMesh::C
const volVectorField & C() const
Return cell centres as volVectorField.
Definition: fvMeshGeometry.C:369
Foam::Vector< scalar >
Foam::List< scalarList >
Foam::meshToMesh0::V_
scalar V_
Overlap volume.
Definition: meshToMesh0.H:100
Foam::meshToMesh0::calculateCellToCellAddressing
void calculateCellToCellAddressing() const
Definition: calculateMeshToMesh0Weights.C:196
Foam::meshToMesh0::calculateInverseDistanceWeights
void calculateInverseDistanceWeights() const
Definition: calculateMeshToMesh0Weights.C:31
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::scalarListList
List< scalarList > scalarListList
Definition: scalarList.H:51
Foam::tetOverlapVolume
Calculates the overlap volume of two cells using tetrahedral decomposition.
Definition: tetOverlapVolume.H:54