Merge remote-tracking branch 'origin/nr/multiSolverFix' into nextRelease
[foam-extend-3.2.git] / src / sampling / meshToMeshInterpolation / meshToMesh / meshToMeshInterpolate.C
blob56583d9ee90a6bb40d8786dd7195cbd3d9e5f48d
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "meshToMesh.H"
28 #include "volFields.H"
29 #include "interpolationCellPoint.H"
30 #include "SubField.H"
31 #include "mixedFvPatchField.H"
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 namespace Foam
38 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
40 template<class Type>
41 void meshToMesh::mapField
43     Field<Type>& toF,
44     const Field<Type>& fromVf,
45     const labelList& adr
46 ) const
48     // Direct mapping of nearest-cell values
50     forAll(toF, celli)
51     {
52         if (adr[celli] != -1)
53         {
54             toF[celli] = fromVf[adr[celli]];
55         }
56     }
58     //toF.map(fromVf, adr);
62 template<class Type>
63 void meshToMesh::interpolateField
65     Field<Type>& toF,
66     const GeometricField<Type, fvPatchField, volMesh>& fromVf,
67     const labelList& adr,
68     const scalarListList& weights
69 ) const
71     // Inverse distance weighted interpolation
73     // get reference to cellCells
74     const labelListList& cc = fromMesh_.cellCells();
76     forAll (toF, celli)
77     {
78         if (adr[celli] != -1)
79         {
80             const labelList& neighbours = cc[adr[celli]];
81             const scalarList& w = weights[celli];
83             toF[celli] = fromVf[adr[celli]]*w[0];
85             for (label ni = 1; ni < w.size(); ni++)
86             {
87                 toF[celli] += fromVf[neighbours[ni - 1]]*w[ni];
88             }
89         }
90     }
94 template<class Type>
95 void meshToMesh::interpolateField
97     Field<Type>& toF,
98     const GeometricField<Type, fvPatchField, volMesh>& fromVf,
99     const labelList& adr,
100     const vectorField& centres
101 ) const
103     // Cell-Point interpolation
104     interpolationCellPoint<Type> interpolator(fromVf);
106     forAll (toF, celli)
107     {
108         if (adr[celli] != -1)
109         {
110             toF[celli] = interpolator.interpolate
111             (
112                 centres[celli],
113                 adr[celli]
114             );
115         }
116     }
120 template<class Type>
121 void meshToMesh::interpolateInternalField
123     Field<Type>& toF,
124     const GeometricField<Type, fvPatchField, volMesh>& fromVf,
125     meshToMesh::order ord
126 ) const
128     if (fromVf.mesh() != fromMesh_)
129     {
130         FatalErrorIn
131         (
132             "meshToMesh::interpolateInternalField(Field<Type>& toF, "
133             "const GeometricField<Type, fvPatchField, volMesh>& fromVf, "
134             "meshToMesh::order ord) const"
135         )   << "the argument field does not correspond to the right mesh. "
136             << "Field size: " << fromVf.size()
137             << " mesh size: " << fromMesh_.nCells()
138             << exit(FatalError);
139     }
141     if (toF.size() != toMesh_.nCells())
142     {
143         FatalErrorIn
144         (
145             "meshToMesh::interpolateInternalField(Field<Type>& toF, "
146             "const GeometricField<Type, fvPatchField, volMesh>& fromVf, "
147             "meshToMesh::order ord) const"
148         )   << "the argument field does not correspond to the right mesh. "
149             << "Field size: " << toF.size()
150             << " mesh size: " << toMesh_.nCells()
151             << exit(FatalError);
152     }
154     switch(ord)
155     {
156         case MAP:
157             mapField(toF, fromVf, cellAddressing_);
158         break;
160         case INTERPOLATE:
161             interpolateField
162             (
163                 toF,
164                 fromVf,
165                 cellAddressing_,
166                 inverseDistanceWeights()
167             );
168         break;
170         case CELL_POINT_INTERPOLATE:
171             interpolateField
172             (
173                 toF,
174                 fromVf,
175                 cellAddressing_,
176                 toMesh_.cellCentres()
177             );
178         break;
180         default:
181             FatalErrorIn
182             (
183                 "meshToMesh::interpolateInternalField(Field<Type>& toF, "
184                 "const GeometricField<Type, fvPatchField, volMesh>& fromVf, "
185                 "meshToMesh::order ord) const"
186             )   << "unknown interpolation scheme " << ord
187                 << exit(FatalError);
188     }
192 template<class Type>
193 void meshToMesh::interpolateInternalField
195     Field<Type>& toF,
196     const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
197     meshToMesh::order ord
198 ) const
200     interpolateInternalField(toF, tfromVf(), ord);
201     tfromVf.clear();
205 template<class Type>
206 void meshToMesh::interpolate
208     GeometricField<Type, fvPatchField, volMesh>& toVf,
209     const GeometricField<Type, fvPatchField, volMesh>& fromVf,
210     meshToMesh::order ord
211 ) const
213     interpolateInternalField(toVf, fromVf, ord);
215     forAll (toMesh_.boundaryMesh(), patchi)
216     {
217         const fvPatch& toPatch = toMesh_.boundary()[patchi];
219         if (cuttingPatches_.found(toPatch.name()))
220         {
221             switch(ord)
222             {
223                 case MAP:
224                     mapField
225                     (
226                         toVf.boundaryField()[patchi],
227                         fromVf,
228                         boundaryAddressing_[patchi]
229                     );
230                 break;
232                 case INTERPOLATE:
233                     interpolateField
234                     (
235                         toVf.boundaryField()[patchi],
236                         fromVf,
237                         boundaryAddressing_[patchi],
238                         toPatch.Cf()
239                     );
240                 break;
242                 case CELL_POINT_INTERPOLATE:
243                     interpolateField
244                     (
245                         toVf.boundaryField()[patchi],
246                         fromVf,
247                         boundaryAddressing_[patchi],
248                         toPatch.Cf()
249                     );
250                 break;
252                 default:
253                     FatalErrorIn
254                     (
255                         "meshToMesh::interpolate("
256                         "GeometricField<Type, fvPatchField, volMesh>& toVf, "
257                         "const GeometricField<Type, fvPatchField, volMesh>& "
258                         "fromVf, meshToMesh::order ord) const"
259                     )   << "unknown interpolation scheme " << ord
260                         << exit(FatalError);
261             }
263             if (isA<mixedFvPatchField<Type> >(toVf.boundaryField()[patchi]))
264             {
265                 refCast<mixedFvPatchField<Type> >
266                 (
267                     toVf.boundaryField()[patchi]
268                 ).refValue() = toVf.boundaryField()[patchi];
269             }
270         }
271         else if
272         (
273             patchMap_.found(toPatch.name())
274          && fromMeshPatches_.found(patchMap_.find(toPatch.name())())
275         )
276         {
277             /*
278             toVf.boundaryField()[patchi].map
279             (
280                 fromVf.boundaryField()
281                 [
282                     fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
283                 ],
284                 boundaryAddressing_[patchi]
285             );
286             */
288             mapField
289             (
290                 toVf.boundaryField()[patchi],
291                 fromVf.boundaryField()
292                 [
293                     fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
294                 ],
295                 boundaryAddressing_[patchi]
296             );
297         }
298     }
302 template<class Type>
303 void meshToMesh::interpolate
305     GeometricField<Type, fvPatchField, volMesh>& toVf,
306     const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
307     meshToMesh::order ord
308 ) const
310     interpolate(toVf, tfromVf(), ord);
311     tfromVf.clear();
315 template<class Type>
316 tmp<GeometricField<Type, fvPatchField, volMesh> > meshToMesh::interpolate
318     const GeometricField<Type, fvPatchField, volMesh>& fromVf,
319     meshToMesh::order ord
320 ) const
322     // Create and map the internal-field values
323     Field<Type> internalField(toMesh_.nCells());
324     interpolateInternalField(internalField, fromVf, ord);
326     // check whether both meshes have got the same number
327     // of boundary patches
328     if (fromMesh_.boundary().size() != toMesh_.boundary().size())
329     {
330         FatalErrorIn
331         (
332             "meshToMesh::interpolate"
333             "(const GeometricField<Type, fvPatchField, volMesh>& fromVf,"
334             "meshToMesh::order ord) const"
335         )   << "Incompatible meshes: different number of boundaries, "
336                "only internal field may be interpolated"
337             << exit(FatalError);
338     }
340     // Create and map the patch field values
341     PtrList<fvPatchField<Type> > patchFields
342     (
343         boundaryAddressing_.size()
344     );
346     forAll (boundaryAddressing_, patchI)
347     {
348         patchFields.set
349         (
350             patchI,
351             fvPatchField<Type>::New
352             (
353                 fromVf.boundaryField()[patchI],
354                 toMesh_.boundary()[patchI],
355                 DimensionedField<Type, volMesh>::null(),
356                 patchFieldInterpolator
357                 (
358                     boundaryAddressing_[patchI]
359                 )
360             )
361         );
362     }
365     // Create the complete field from the pieces
366     tmp<GeometricField<Type, fvPatchField, volMesh> > ttoF
367     (
368         new GeometricField<Type, fvPatchField, volMesh>
369         (
370             IOobject
371             (
372                 "interpolated(" + fromVf.name() + ')',
373                 toMesh_.time().timeName(),
374                 toMesh_,
375                 IOobject::NO_READ,
376                 IOobject::NO_WRITE
377             ),
378             toMesh_,
379             fromVf.dimensions(),
380             internalField,
381             patchFields
382         )
383     );
385     return ttoF;
389 template<class Type>
390 tmp<GeometricField<Type, fvPatchField, volMesh> > meshToMesh::interpolate
392     const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
393     meshToMesh::order ord
394 ) const
396     tmp<GeometricField<Type, fvPatchField, volMesh> > tint =
397         interpolate(tfromVf(), ord);
398     tfromVf.clear();
400     return tint;
404 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
406 } // End namespace Foam
408 // ************************************************************************* //