00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "meshToMesh.H"
00027 #include <finiteVolume/volFields.H>
00028 #include <finiteVolume/interpolationCellPoint.H>
00029 #include <OpenFOAM/SubField.H>
00030 #include <finiteVolume/mixedFvPatchField.H>
00031
00032
00033
00034 namespace Foam
00035 {
00036
00037
00038
00039 template<class Type>
00040 void meshToMesh::mapField
00041 (
00042 Field<Type>& toF,
00043 const Field<Type>& fromVf,
00044 const labelList& adr
00045 ) const
00046 {
00047
00048
00049 forAll(toF, celli)
00050 {
00051 if (adr[celli] != -1)
00052 {
00053 toF[celli] = fromVf[adr[celli]];
00054 }
00055 }
00056
00057
00058 }
00059
00060
00061 template<class Type>
00062 void meshToMesh::interpolateField
00063 (
00064 Field<Type>& toF,
00065 const GeometricField<Type, fvPatchField, volMesh>& fromVf,
00066 const labelList& adr,
00067 const scalarListList& weights
00068 ) const
00069 {
00070
00071
00072
00073 const labelListList& cc = fromMesh_.cellCells();
00074
00075 forAll (toF, celli)
00076 {
00077 if (adr[celli] != -1)
00078 {
00079 const labelList& neighbours = cc[adr[celli]];
00080 const scalarList& w = weights[celli];
00081
00082 toF[celli] = fromVf[adr[celli]]*w[0];
00083
00084 for (label ni = 1; ni < w.size(); ni++)
00085 {
00086 toF[celli] += fromVf[neighbours[ni - 1]]*w[ni];
00087 }
00088 }
00089 }
00090 }
00091
00092
00093 template<class Type>
00094 void meshToMesh::interpolateField
00095 (
00096 Field<Type>& toF,
00097 const GeometricField<Type, fvPatchField, volMesh>& fromVf,
00098 const labelList& adr,
00099 const vectorField& centres
00100 ) const
00101 {
00102
00103 interpolationCellPoint<Type> interpolator(fromVf);
00104
00105 forAll (toF, celli)
00106 {
00107 if (adr[celli] != -1)
00108 {
00109 toF[celli] = interpolator.interpolate
00110 (
00111 centres[celli],
00112 adr[celli]
00113 );
00114 }
00115 }
00116 }
00117
00118
00119 template<class Type>
00120 void meshToMesh::interpolateInternalField
00121 (
00122 Field<Type>& toF,
00123 const GeometricField<Type, fvPatchField, volMesh>& fromVf,
00124 meshToMesh::order ord
00125 ) const
00126 {
00127 if (fromVf.mesh() != fromMesh_)
00128 {
00129 FatalErrorIn
00130 (
00131 "meshToMesh::interpolateInternalField(Field<Type>& toF, "
00132 "const GeometricField<Type, fvPatchField, volMesh>& fromVf, "
00133 "meshToMesh::order ord) const"
00134 ) << "the argument field does not correspond to the right mesh. "
00135 << "Field size: " << fromVf.size()
00136 << " mesh size: " << fromMesh_.nCells()
00137 << exit(FatalError);
00138 }
00139
00140 if (toF.size() != toMesh_.nCells())
00141 {
00142 FatalErrorIn
00143 (
00144 "meshToMesh::interpolateInternalField(Field<Type>& toF, "
00145 "const GeometricField<Type, fvPatchField, volMesh>& fromVf, "
00146 "meshToMesh::order ord) const"
00147 ) << "the argument field does not correspond to the right mesh. "
00148 << "Field size: " << toF.size()
00149 << " mesh size: " << toMesh_.nCells()
00150 << exit(FatalError);
00151 }
00152
00153 switch(ord)
00154 {
00155 case MAP:
00156 mapField(toF, fromVf, cellAddressing_);
00157 break;
00158
00159 case INTERPOLATE:
00160 interpolateField
00161 (
00162 toF,
00163 fromVf,
00164 cellAddressing_,
00165 inverseDistanceWeights()
00166 );
00167 break;
00168
00169 case CELL_POINT_INTERPOLATE:
00170 interpolateField
00171 (
00172 toF,
00173 fromVf,
00174 cellAddressing_,
00175 toMesh_.cellCentres()
00176 );
00177 break;
00178
00179 default:
00180 FatalErrorIn
00181 (
00182 "meshToMesh::interpolateInternalField(Field<Type>& toF, "
00183 "const GeometricField<Type, fvPatchField, volMesh>& fromVf, "
00184 "meshToMesh::order ord) const"
00185 ) << "unknown interpolation scheme " << ord
00186 << exit(FatalError);
00187 }
00188 }
00189
00190
00191 template<class Type>
00192 void meshToMesh::interpolateInternalField
00193 (
00194 Field<Type>& toF,
00195 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
00196 meshToMesh::order ord
00197 ) const
00198 {
00199 interpolateInternalField(toF, tfromVf(), ord);
00200 tfromVf.clear();
00201 }
00202
00203
00204 template<class Type>
00205 void meshToMesh::interpolate
00206 (
00207 GeometricField<Type, fvPatchField, volMesh>& toVf,
00208 const GeometricField<Type, fvPatchField, volMesh>& fromVf,
00209 meshToMesh::order ord
00210 ) const
00211 {
00212 interpolateInternalField(toVf, fromVf, ord);
00213
00214 forAll (toMesh_.boundaryMesh(), patchi)
00215 {
00216 const fvPatch& toPatch = toMesh_.boundary()[patchi];
00217
00218 if (cuttingPatches_.found(toPatch.name()))
00219 {
00220 switch(ord)
00221 {
00222 case MAP:
00223 mapField
00224 (
00225 toVf.boundaryField()[patchi],
00226 fromVf,
00227 boundaryAddressing_[patchi]
00228 );
00229 break;
00230
00231 case INTERPOLATE:
00232 interpolateField
00233 (
00234 toVf.boundaryField()[patchi],
00235 fromVf,
00236 boundaryAddressing_[patchi],
00237 toPatch.Cf()
00238 );
00239 break;
00240
00241 case CELL_POINT_INTERPOLATE:
00242 interpolateField
00243 (
00244 toVf.boundaryField()[patchi],
00245 fromVf,
00246 boundaryAddressing_[patchi],
00247 toPatch.Cf()
00248 );
00249 break;
00250
00251 default:
00252 FatalErrorIn
00253 (
00254 "meshToMesh::interpolate("
00255 "GeometricField<Type, fvPatchField, volMesh>& toVf, "
00256 "const GeometricField<Type, fvPatchField, volMesh>& "
00257 "fromVf, meshToMesh::order ord) const"
00258 ) << "unknown interpolation scheme " << ord
00259 << exit(FatalError);
00260 }
00261
00262 if (isA<mixedFvPatchField<Type> >(toVf.boundaryField()[patchi]))
00263 {
00264 refCast<mixedFvPatchField<Type> >
00265 (
00266 toVf.boundaryField()[patchi]
00267 ).refValue() = toVf.boundaryField()[patchi];
00268 }
00269 }
00270 else if
00271 (
00272 patchMap_.found(toPatch.name())
00273 && fromMeshPatches_.found(patchMap_.find(toPatch.name())())
00274 )
00275 {
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 mapField
00288 (
00289 toVf.boundaryField()[patchi],
00290 fromVf.boundaryField()
00291 [
00292 fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
00293 ],
00294 boundaryAddressing_[patchi]
00295 );
00296 }
00297 }
00298 }
00299
00300
00301 template<class Type>
00302 void meshToMesh::interpolate
00303 (
00304 GeometricField<Type, fvPatchField, volMesh>& toVf,
00305 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
00306 meshToMesh::order ord
00307 ) const
00308 {
00309 interpolate(toVf, tfromVf(), ord);
00310 tfromVf.clear();
00311 }
00312
00313
00314 template<class Type>
00315 tmp<GeometricField<Type, fvPatchField, volMesh> > meshToMesh::interpolate
00316 (
00317 const GeometricField<Type, fvPatchField, volMesh>& fromVf,
00318 meshToMesh::order ord
00319 ) const
00320 {
00321
00322 Field<Type> internalField(toMesh_.nCells());
00323 interpolateInternalField(internalField, fromVf, ord);
00324
00325
00326
00327 if (fromMesh_.boundary().size() != toMesh_.boundary().size())
00328 {
00329 FatalErrorIn
00330 (
00331 "meshToMesh::interpolate"
00332 "(const GeometricField<Type, fvPatchField, volMesh>& fromVf,"
00333 "meshToMesh::order ord) const"
00334 ) << "Incompatible meshes: different number of boundaries, "
00335 "only internal field may be interpolated"
00336 << exit(FatalError);
00337 }
00338
00339
00340 PtrList<fvPatchField<Type> > patchFields
00341 (
00342 boundaryAddressing_.size()
00343 );
00344
00345 forAll (boundaryAddressing_, patchI)
00346 {
00347 patchFields.set
00348 (
00349 patchI,
00350 fvPatchField<Type>::New
00351 (
00352 fromVf.boundaryField()[patchI],
00353 toMesh_.boundary()[patchI],
00354 DimensionedField<Type, volMesh>::null(),
00355 patchFieldInterpolator
00356 (
00357 boundaryAddressing_[patchI]
00358 )
00359 )
00360 );
00361 }
00362
00363
00364
00365 tmp<GeometricField<Type, fvPatchField, volMesh> > ttoF
00366 (
00367 new GeometricField<Type, fvPatchField, volMesh>
00368 (
00369 IOobject
00370 (
00371 "interpolated(" + fromVf.name() + ')',
00372 toMesh_.time().timeName(),
00373 toMesh_,
00374 IOobject::NO_READ,
00375 IOobject::NO_WRITE
00376 ),
00377 toMesh_,
00378 fromVf.dimensions(),
00379 internalField,
00380 patchFields
00381 )
00382 );
00383
00384 return ttoF;
00385 }
00386
00387
00388 template<class Type>
00389 tmp<GeometricField<Type, fvPatchField, volMesh> > meshToMesh::interpolate
00390 (
00391 const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
00392 meshToMesh::order ord
00393 ) const
00394 {
00395 tmp<GeometricField<Type, fvPatchField, volMesh> > tint =
00396 interpolate(tfromVf(), ord);
00397 tfromVf.clear();
00398
00399 return tint;
00400 }
00401
00402
00403
00404
00405 }
00406
00407