Go to the documentation of this file.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 <finiteVolume/fvMesh.H>
00027 #include <finiteVolume/volFields.H>
00028 #include <finiteVolume/surfaceFields.H>
00029 #include <OpenFOAM/demandDrivenData.H>
00030 #include <finiteVolume/coupledFvPatch.H>
00031 #include <OpenFOAM/mathematicalConstants.H>
00032
00033
00034
00035 namespace Foam
00036 {
00037 defineTypeNameAndDebug(surfaceInterpolation, 0);
00038 }
00039
00040
00041
00042 void Foam::surfaceInterpolation::clearOut()
00043 {
00044 deleteDemandDrivenData(weightingFactors_);
00045 deleteDemandDrivenData(differenceFactors_);
00046 deleteDemandDrivenData(correctionVectors_);
00047 }
00048
00049
00050
00051
00052 Foam::surfaceInterpolation::surfaceInterpolation(const fvMesh& fvm)
00053 :
00054 fvSchemes(static_cast<const objectRegistry&>(fvm)),
00055 fvSolution(static_cast<const objectRegistry&>(fvm)),
00056 mesh_(fvm),
00057 weightingFactors_(NULL),
00058 differenceFactors_(NULL),
00059 orthogonal_(false),
00060 correctionVectors_(NULL)
00061 {}
00062
00063
00064
00065
00066 Foam::surfaceInterpolation::~surfaceInterpolation()
00067 {
00068 clearOut();
00069 }
00070
00071
00072
00073
00074 const Foam::surfaceScalarField& Foam::surfaceInterpolation::weights() const
00075 {
00076 if (!weightingFactors_)
00077 {
00078 makeWeights();
00079 }
00080
00081 return (*weightingFactors_);
00082 }
00083
00084
00085 const Foam::surfaceScalarField& Foam::surfaceInterpolation::deltaCoeffs() const
00086 {
00087 if (!differenceFactors_)
00088 {
00089 makeDeltaCoeffs();
00090 }
00091
00092 return (*differenceFactors_);
00093 }
00094
00095
00096 bool Foam::surfaceInterpolation::orthogonal() const
00097 {
00098 if (orthogonal_ == false && !correctionVectors_)
00099 {
00100 makeCorrectionVectors();
00101 }
00102
00103 return orthogonal_;
00104 }
00105
00106
00107 const Foam::surfaceVectorField&
00108 Foam::surfaceInterpolation::correctionVectors() const
00109 {
00110 if (orthogonal())
00111 {
00112 FatalErrorIn("surfaceInterpolation::correctionVectors()")
00113 << "cannot return correctionVectors; mesh is orthogonal"
00114 << abort(FatalError);
00115 }
00116
00117 return (*correctionVectors_);
00118 }
00119
00120
00121 bool Foam::surfaceInterpolation::movePoints()
00122 {
00123 deleteDemandDrivenData(weightingFactors_);
00124 deleteDemandDrivenData(differenceFactors_);
00125
00126 orthogonal_ = false;
00127 deleteDemandDrivenData(correctionVectors_);
00128
00129 return true;
00130 }
00131
00132
00133 void Foam::surfaceInterpolation::makeWeights() const
00134 {
00135 if (debug)
00136 {
00137 Info<< "surfaceInterpolation::makeWeights() : "
00138 << "Constructing weighting factors for face interpolation"
00139 << endl;
00140 }
00141
00142
00143 weightingFactors_ = new surfaceScalarField
00144 (
00145 IOobject
00146 (
00147 "weightingFactors",
00148 mesh_.pointsInstance(),
00149 mesh_
00150 ),
00151 mesh_,
00152 dimless
00153 );
00154 surfaceScalarField& weightingFactors = *weightingFactors_;
00155
00156
00157
00158
00159
00160
00161 const unallocLabelList& owner = mesh_.owner();
00162 const unallocLabelList& neighbour = mesh_.neighbour();
00163
00164 const vectorField& Cf = mesh_.faceCentres();
00165 const vectorField& C = mesh_.cellCentres();
00166 const vectorField& Sf = mesh_.faceAreas();
00167
00168
00169 scalarField& w = weightingFactors.internalField();
00170
00171 forAll(owner, facei)
00172 {
00173
00174
00175
00176
00177
00178 scalar SfdOwn = mag(Sf[facei] & (Cf[facei] - C[owner[facei]]));
00179 scalar SfdNei = mag(Sf[facei] & (C[neighbour[facei]] - Cf[facei]));
00180 w[facei] = SfdNei/(SfdOwn + SfdNei);
00181 }
00182
00183 forAll(mesh_.boundary(), patchi)
00184 {
00185 mesh_.boundary()[patchi].makeWeights
00186 (
00187 weightingFactors.boundaryField()[patchi]
00188 );
00189 }
00190
00191
00192 if (debug)
00193 {
00194 Info<< "surfaceInterpolation::makeWeights() : "
00195 << "Finished constructing weighting factors for face interpolation"
00196 << endl;
00197 }
00198 }
00199
00200
00201 void Foam::surfaceInterpolation::makeDeltaCoeffs() const
00202 {
00203 if (debug)
00204 {
00205 Info<< "surfaceInterpolation::makeDeltaCoeffs() : "
00206 << "Constructing differencing factors array for face gradient"
00207 << endl;
00208 }
00209
00210
00211
00212 weights();
00213
00214 differenceFactors_ = new surfaceScalarField
00215 (
00216 IOobject
00217 (
00218 "differenceFactors_",
00219 mesh_.pointsInstance(),
00220 mesh_
00221 ),
00222 mesh_,
00223 dimless/dimLength
00224 );
00225 surfaceScalarField& DeltaCoeffs = *differenceFactors_;
00226
00227
00228
00229 const volVectorField& C = mesh_.C();
00230 const unallocLabelList& owner = mesh_.owner();
00231 const unallocLabelList& neighbour = mesh_.neighbour();
00232 const surfaceVectorField& Sf = mesh_.Sf();
00233 const surfaceScalarField& magSf = mesh_.magSf();
00234
00235 forAll(owner, facei)
00236 {
00237 vector delta = C[neighbour[facei]] - C[owner[facei]];
00238 vector unitArea = Sf[facei]/magSf[facei];
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 DeltaCoeffs[facei] = 1.0/max(unitArea & delta, 0.05*mag(delta));
00251 }
00252
00253 forAll(DeltaCoeffs.boundaryField(), patchi)
00254 {
00255 mesh_.boundary()[patchi].makeDeltaCoeffs
00256 (
00257 DeltaCoeffs.boundaryField()[patchi]
00258 );
00259 }
00260 }
00261
00262
00263 void Foam::surfaceInterpolation::makeCorrectionVectors() const
00264 {
00265 if (debug)
00266 {
00267 Info<< "surfaceInterpolation::makeCorrectionVectors() : "
00268 << "Constructing non-orthogonal correction vectors"
00269 << endl;
00270 }
00271
00272 correctionVectors_ = new surfaceVectorField
00273 (
00274 IOobject
00275 (
00276 "correctionVectors",
00277 mesh_.pointsInstance(),
00278 mesh_
00279 ),
00280 mesh_,
00281 dimless
00282 );
00283 surfaceVectorField& corrVecs = *correctionVectors_;
00284
00285
00286 const volVectorField& C = mesh_.C();
00287 const unallocLabelList& owner = mesh_.owner();
00288 const unallocLabelList& neighbour = mesh_.neighbour();
00289 const surfaceVectorField& Sf = mesh_.Sf();
00290 const surfaceScalarField& magSf = mesh_.magSf();
00291 const surfaceScalarField& DeltaCoeffs = deltaCoeffs();
00292
00293 forAll(owner, facei)
00294 {
00295 vector unitArea = Sf[facei]/magSf[facei];
00296 vector delta = C[neighbour[facei]] - C[owner[facei]];
00297
00298 corrVecs[facei] = unitArea - delta*DeltaCoeffs[facei];
00299 }
00300
00301
00302
00303
00304
00305 forAll(corrVecs.boundaryField(), patchi)
00306 {
00307 fvsPatchVectorField& patchcorrVecs = corrVecs.boundaryField()[patchi];
00308
00309 if (!patchcorrVecs.coupled())
00310 {
00311 patchcorrVecs = vector::zero;
00312 }
00313 else
00314 {
00315 const fvsPatchScalarField& patchDeltaCoeffs
00316 = DeltaCoeffs.boundaryField()[patchi];
00317
00318 const fvPatch& p = patchcorrVecs.patch();
00319
00320 vectorField patchDeltas = mesh_.boundary()[patchi].delta();
00321
00322 forAll(p, patchFacei)
00323 {
00324 vector unitArea =
00325 Sf.boundaryField()[patchi][patchFacei]
00326 /magSf.boundaryField()[patchi][patchFacei];
00327
00328 const vector& delta = patchDeltas[patchFacei];
00329
00330 patchcorrVecs[patchFacei] =
00331 unitArea - delta*patchDeltaCoeffs[patchFacei];
00332 }
00333 }
00334 }
00335
00336 scalar MaxNonOrthog = 0.0;
00337
00338
00339 if (returnReduce(magSf.size(), sumOp<label>()) > 0)
00340 {
00341 MaxNonOrthog =
00342 asin
00343 (
00344 min
00345 (
00346 max(mag(corrVecs)).value(),
00347 1.0
00348 )
00349 )*180.0/mathematicalConstant::pi;
00350 }
00351
00352 if (debug)
00353 {
00354 Info<< "surfaceInterpolation::makeCorrectionVectors() : "
00355 << "maximum non-orthogonality = " << MaxNonOrthog << " deg."
00356 << endl;
00357 }
00358
00359
00360
00361 if (MaxNonOrthog < 5)
00362 {
00363 orthogonal_ = true;
00364 deleteDemandDrivenData(correctionVectors_);
00365 }
00366 else
00367 {
00368 orthogonal_ = false;
00369 }
00370
00371 if (debug)
00372 {
00373 Info<< "surfaceInterpolation::makeCorrectionVectors() : "
00374 << "Finished constructing non-orthogonal correction vectors"
00375 << endl;
00376 }
00377 }
00378
00379
00380