1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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.
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
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "volPointInterpolation.H"
27 #include "volFields.H"
28 #include "pointFields.H"
29 #include "emptyFvPatch.H"
30 #include "mapDistribute.H"
31 #include "coupledPointPatchField.H"
32 #include "valuePointPatchField.H"
33 #include "transform.H"
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 template<class Type, class CombineOp>
43 void volPointInterpolation::syncUntransformedData
45 List<Type>& pointData,
49 // Transfer onto coupled patch
50 const globalMeshData& gmd = mesh().globalData();
51 const indirectPrimitivePatch& cpp = gmd.coupledPatch();
52 const labelList& meshPoints = cpp.meshPoints();
54 const mapDistribute& slavesMap = gmd.globalPointSlavesMap();
55 const labelListList& slaves = gmd.globalPointSlaves();
57 List<Type> elems(slavesMap.constructSize());
60 elems[i] = pointData[meshPoints[i]];
63 // Pull slave data onto master. No need to update transformed slots.
64 slavesMap.distribute(elems, false);
66 // Combine master data with slave data
69 Type& elem = elems[i];
71 const labelList& slavePoints = slaves[i];
73 // Combine master with untransformed slave data
74 forAll(slavePoints, j)
76 cop(elem, elems[slavePoints[j]]);
79 // Copy result back to slave slots
80 forAll(slavePoints, j)
82 elems[slavePoints[j]] = elem;
86 // Push slave-slot data back to slaves
87 slavesMap.reverseDistribute(elems.size(), elems, false);
89 // Extract back onto mesh
92 pointData[meshPoints[i]] = elems[i];
98 void volPointInterpolation::pushUntransformedData
100 List<Type>& pointData
103 // Transfer onto coupled patch
104 const globalMeshData& gmd = mesh().globalData();
105 const indirectPrimitivePatch& cpp = gmd.coupledPatch();
106 const labelList& meshPoints = cpp.meshPoints();
108 const mapDistribute& slavesMap = gmd.globalPointSlavesMap();
109 const labelListList& slaves = gmd.globalPointSlaves();
111 List<Type> elems(slavesMap.constructSize());
112 forAll(meshPoints, i)
114 elems[i] = pointData[meshPoints[i]];
117 // Combine master data with slave data
120 const labelList& slavePoints = slaves[i];
122 // Copy master data to slave slots
123 forAll(slavePoints, j)
125 elems[slavePoints[j]] = elems[i];
129 // Push slave-slot data back to slaves
130 slavesMap.reverseDistribute(elems.size(), elems, false);
132 // Extract back onto mesh
133 forAll(meshPoints, i)
135 pointData[meshPoints[i]] = elems[i];
141 void volPointInterpolation::addSeparated
143 GeometricField<Type, pointPatchField, pointMesh>& pf
148 Pout<< "volPointInterpolation::addSeparated" << endl;
151 forAll(pf.boundaryField(), patchI)
153 if (pf.boundaryField()[patchI].coupled())
155 refCast<coupledPointPatchField<Type> >
156 (pf.boundaryField()[patchI]).initSwapAddSeparated
158 Pstream::blocking, //Pstream::nonBlocking,
164 // Block for any outstanding requests
165 //Pstream::waitRequests();
167 forAll(pf.boundaryField(), patchI)
169 if (pf.boundaryField()[patchI].coupled())
171 refCast<coupledPointPatchField<Type> >
172 (pf.boundaryField()[patchI]).swapAddSeparated
174 Pstream::blocking, //Pstream::nonBlocking,
183 void volPointInterpolation::interpolateInternalField
185 const GeometricField<Type, fvPatchField, volMesh>& vf,
186 GeometricField<Type, pointPatchField, pointMesh>& pf
191 Pout<< "volPointInterpolation::interpolateInternalField("
192 << "const GeometricField<Type, fvPatchField, volMesh>&, "
193 << "GeometricField<Type, pointPatchField, pointMesh>&) : "
194 << "interpolating field from cells to points"
198 const labelListList& pointCells = vf.mesh().pointCells();
200 // Multiply volField by weighting factor matrix to create pointField
201 forAll(pointCells, pointi)
203 if (!isPatchPoint_[pointi])
205 const scalarList& pw = pointWeights_[pointi];
206 const labelList& ppc = pointCells[pointi];
208 pf[pointi] = pTraits<Type>::zero;
210 forAll(ppc, pointCelli)
212 pf[pointi] += pw[pointCelli]*vf[ppc[pointCelli]];
220 tmp<Field<Type> > volPointInterpolation::flatBoundaryField
222 const GeometricField<Type, fvPatchField, volMesh>& vf
225 const fvMesh& mesh = vf.mesh();
226 const fvBoundaryMesh& bm = mesh.boundary();
228 tmp<Field<Type> > tboundaryVals
230 new Field<Type>(mesh.nFaces()-mesh.nInternalFaces())
232 Field<Type>& boundaryVals = tboundaryVals();
234 forAll(vf.boundaryField(), patchI)
236 label bFaceI = bm[patchI].patch().start() - mesh.nInternalFaces();
238 if (!isA<emptyFvPatch>(bm[patchI]) && !bm[patchI].coupled())
243 vf.boundaryField()[patchI].size(),
245 ).assign(vf.boundaryField()[patchI]);
249 const polyPatch& pp = bm[patchI].patch();
253 boundaryVals[bFaceI++] = pTraits<Type>::zero;
258 return tboundaryVals;
263 void volPointInterpolation::interpolateBoundaryField
265 const GeometricField<Type, fvPatchField, volMesh>& vf,
266 GeometricField<Type, pointPatchField, pointMesh>& pf,
267 const bool overrideFixedValue
270 const primitivePatch& boundary = boundaryPtr_();
272 Field<Type>& pfi = pf.internalField();
274 // Get face data in flat list
275 tmp<Field<Type> > tboundaryVals(flatBoundaryField(vf));
276 const Field<Type>& boundaryVals = tboundaryVals();
279 // Do points on 'normal' patches from the surrounding patch faces
280 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
282 forAll(boundary.meshPoints(), i)
284 label pointI = boundary.meshPoints()[i];
286 if (isPatchPoint_[pointI])
288 const labelList& pFaces = boundary.pointFaces()[i];
289 const scalarList& pWeights = boundaryPointWeights_[i];
291 Type& val = pfi[pointI];
293 val = pTraits<Type>::zero;
296 if (boundaryIsPatchFace_[pFaces[j]])
298 val += pWeights[j]*boundaryVals[pFaces[j]];
304 // Sum collocated contributions
305 //mesh().globalData().syncPointData(pfi, plusEqOp<Type>());
306 syncUntransformedData(pfi, plusEqOp<Type>());
308 // And add separated contributions
311 // Push master data to slaves. It is possible (not sure how often) for
312 // a coupled point to have its master on a different patch so
313 // to make sure just push master data to slaves. Reuse the syncPointData
315 //mesh().globalData().syncPointData(pfi, nopEqOp<Type>());
316 pushUntransformedData(pfi);
320 if (overrideFixedValue)
322 forAll(pf.boundaryField(), patchI)
324 pointPatchField<Type>& ppf = pf.boundaryField()[patchI];
326 if (isA<valuePointPatchField<Type> >(ppf))
328 refCast<valuePointPatchField<Type> >(ppf) =
329 ppf.patchInternalField();
335 // Override constrained pointPatchField types with the constraint value.
336 // This relys on only constrained pointPatchField implementing the evaluate
338 pf.correctBoundaryConditions();
340 // Sync any dangling points
341 //mesh().globalData().syncPointData(pfi, nopEqOp<Type>());
342 pushUntransformedData(pfi);
344 // Apply multiple constraints on edge/corner points
345 applyCornerConstraints(pf);
350 void volPointInterpolation::applyCornerConstraints
352 GeometricField<Type, pointPatchField, pointMesh>& pf
355 forAll(patchPatchPointConstraintPoints_, pointi)
357 pf[patchPatchPointConstraintPoints_[pointi]] = transform
359 patchPatchPointConstraintTensors_[pointi],
360 pf[patchPatchPointConstraintPoints_[pointi]]
367 void volPointInterpolation::interpolate
369 const GeometricField<Type, fvPatchField, volMesh>& vf,
370 GeometricField<Type, pointPatchField, pointMesh>& pf
375 Pout<< "volPointInterpolation::interpolate("
376 << "const GeometricField<Type, fvPatchField, volMesh>&, "
377 << "GeometricField<Type, pointPatchField, pointMesh>&) : "
378 << "interpolating field from cells to points"
382 interpolateInternalField(vf, pf);
384 // Interpolate to the patches preserving fixed value BCs
385 interpolateBoundaryField(vf, pf, false);
390 tmp<GeometricField<Type, pointPatchField, pointMesh> >
391 volPointInterpolation::interpolate
393 const GeometricField<Type, fvPatchField, volMesh>& vf,
394 const wordList& patchFieldTypes
397 const pointMesh& pm = pointMesh::New(vf.mesh());
399 // Construct tmp<pointField>
400 tmp<GeometricField<Type, pointPatchField, pointMesh> > tpf
402 new GeometricField<Type, pointPatchField, pointMesh>
406 "volPointInterpolate(" + vf.name() + ')',
416 interpolateInternalField(vf, tpf());
418 // Interpolate to the patches overriding fixed value BCs
419 interpolateBoundaryField(vf, tpf(), true);
426 tmp<GeometricField<Type, pointPatchField, pointMesh> >
427 volPointInterpolation::interpolate
429 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tvf,
430 const wordList& patchFieldTypes
433 // Construct tmp<pointField>
434 tmp<GeometricField<Type, pointPatchField, pointMesh> > tpf =
435 interpolate(tvf(), patchFieldTypes);
442 tmp<GeometricField<Type, pointPatchField, pointMesh> >
443 volPointInterpolation::interpolate
445 const GeometricField<Type, fvPatchField, volMesh>& vf
448 const pointMesh& pm = pointMesh::New(vf.mesh());
450 tmp<GeometricField<Type, pointPatchField, pointMesh> > tpf
452 new GeometricField<Type, pointPatchField, pointMesh>
456 "volPointInterpolate(" + vf.name() + ')',
465 interpolateInternalField(vf, tpf());
466 interpolateBoundaryField(vf, tpf(), false);
473 tmp<GeometricField<Type, pointPatchField, pointMesh> >
474 volPointInterpolation::interpolate
476 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tvf
479 // Construct tmp<pointField>
480 tmp<GeometricField<Type, pointPatchField, pointMesh> > tpf =
487 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
489 } // End namespace Foam
491 // ************************************************************************* //