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 "cellMDLimitedGrad.H"
00027 #include <finiteVolume/gaussGrad.H>
00028 #include <finiteVolume/fvMesh.H>
00029 #include <finiteVolume/volMesh.H>
00030 #include <finiteVolume/surfaceMesh.H>
00031 #include <finiteVolume/volFields.H>
00032 #include <finiteVolume/fixedValueFvPatchFields.H>
00033
00034
00035
00036 namespace Foam
00037 {
00038
00039
00040
00041 namespace fv
00042 {
00043
00044
00045
00046 makeFvGradScheme(cellMDLimitedGrad)
00047
00048
00049
00050 template<>
00051 tmp<volVectorField> cellMDLimitedGrad<scalar>::grad
00052 (
00053 const volScalarField& vsf
00054 ) const
00055 {
00056 const fvMesh& mesh = vsf.mesh();
00057
00058 tmp<volVectorField> tGrad = basicGradScheme_().grad(vsf);
00059
00060 if (k_ < SMALL)
00061 {
00062 return tGrad;
00063 }
00064
00065 volVectorField& g = tGrad();
00066
00067 const unallocLabelList& owner = mesh.owner();
00068 const unallocLabelList& neighbour = mesh.neighbour();
00069
00070 const volVectorField& C = mesh.C();
00071 const surfaceVectorField& Cf = mesh.Cf();
00072
00073 scalarField maxVsf(vsf.internalField());
00074 scalarField minVsf(vsf.internalField());
00075
00076 forAll(owner, facei)
00077 {
00078 label own = owner[facei];
00079 label nei = neighbour[facei];
00080
00081 scalar vsfOwn = vsf[own];
00082 scalar vsfNei = vsf[nei];
00083
00084 maxVsf[own] = max(maxVsf[own], vsfNei);
00085 minVsf[own] = min(minVsf[own], vsfNei);
00086
00087 maxVsf[nei] = max(maxVsf[nei], vsfOwn);
00088 minVsf[nei] = min(minVsf[nei], vsfOwn);
00089 }
00090
00091
00092 const volScalarField::GeometricBoundaryField& bsf = vsf.boundaryField();
00093
00094 forAll(bsf, patchi)
00095 {
00096 const fvPatchScalarField& psf = bsf[patchi];
00097
00098 const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
00099
00100 if (psf.coupled())
00101 {
00102 scalarField psfNei = psf.patchNeighbourField();
00103
00104 forAll(pOwner, pFacei)
00105 {
00106 label own = pOwner[pFacei];
00107 scalar vsfNei = psfNei[pFacei];
00108
00109 maxVsf[own] = max(maxVsf[own], vsfNei);
00110 minVsf[own] = min(minVsf[own], vsfNei);
00111 }
00112 }
00113 else
00114 {
00115 forAll(pOwner, pFacei)
00116 {
00117 label own = pOwner[pFacei];
00118 scalar vsfNei = psf[pFacei];
00119
00120 maxVsf[own] = max(maxVsf[own], vsfNei);
00121 minVsf[own] = min(minVsf[own], vsfNei);
00122 }
00123 }
00124 }
00125
00126 maxVsf -= vsf;
00127 minVsf -= vsf;
00128
00129 if (k_ < 1.0)
00130 {
00131 scalarField maxMinVsf = (1.0/k_ - 1.0)*(maxVsf - minVsf);
00132 maxVsf += maxMinVsf;
00133 minVsf -= maxMinVsf;
00134
00135
00136
00137 }
00138
00139
00140 forAll(owner, facei)
00141 {
00142 label own = owner[facei];
00143 label nei = neighbour[facei];
00144
00145
00146 limitFace
00147 (
00148 g[own],
00149 maxVsf[own],
00150 minVsf[own],
00151 Cf[facei] - C[own]
00152 );
00153
00154
00155 limitFace
00156 (
00157 g[nei],
00158 maxVsf[nei],
00159 minVsf[nei],
00160 Cf[facei] - C[nei]
00161 );
00162 }
00163
00164
00165 forAll(bsf, patchi)
00166 {
00167 const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
00168 const vectorField& pCf = Cf.boundaryField()[patchi];
00169
00170 forAll(pOwner, pFacei)
00171 {
00172 label own = pOwner[pFacei];
00173
00174 limitFace
00175 (
00176 g[own],
00177 maxVsf[own],
00178 minVsf[own],
00179 pCf[pFacei] - C[own]
00180 );
00181 }
00182 }
00183
00184 g.correctBoundaryConditions();
00185 gaussGrad<scalar>::correctBoundaryConditions(vsf, g);
00186
00187 return tGrad;
00188 }
00189
00190
00191 template<>
00192 tmp<volTensorField> cellMDLimitedGrad<vector>::grad
00193 (
00194 const volVectorField& vsf
00195 ) const
00196 {
00197 const fvMesh& mesh = vsf.mesh();
00198
00199 tmp<volTensorField> tGrad = basicGradScheme_().grad(vsf);
00200
00201 if (k_ < SMALL)
00202 {
00203 return tGrad;
00204 }
00205
00206 volTensorField& g = tGrad();
00207
00208 const unallocLabelList& owner = mesh.owner();
00209 const unallocLabelList& neighbour = mesh.neighbour();
00210
00211 const volVectorField& C = mesh.C();
00212 const surfaceVectorField& Cf = mesh.Cf();
00213
00214 vectorField maxVsf(vsf.internalField());
00215 vectorField minVsf(vsf.internalField());
00216
00217 forAll(owner, facei)
00218 {
00219 label own = owner[facei];
00220 label nei = neighbour[facei];
00221
00222 const vector& vsfOwn = vsf[own];
00223 const vector& vsfNei = vsf[nei];
00224
00225 maxVsf[own] = max(maxVsf[own], vsfNei);
00226 minVsf[own] = min(minVsf[own], vsfNei);
00227
00228 maxVsf[nei] = max(maxVsf[nei], vsfOwn);
00229 minVsf[nei] = min(minVsf[nei], vsfOwn);
00230 }
00231
00232
00233 const volVectorField::GeometricBoundaryField& bsf = vsf.boundaryField();
00234
00235 forAll(bsf, patchi)
00236 {
00237 const fvPatchVectorField& psf = bsf[patchi];
00238 const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
00239
00240 if (psf.coupled())
00241 {
00242 vectorField psfNei = psf.patchNeighbourField();
00243
00244 forAll(pOwner, pFacei)
00245 {
00246 label own = pOwner[pFacei];
00247 const vector& vsfNei = psfNei[pFacei];
00248
00249 maxVsf[own] = max(maxVsf[own], vsfNei);
00250 minVsf[own] = min(minVsf[own], vsfNei);
00251 }
00252 }
00253 else
00254 {
00255 forAll(pOwner, pFacei)
00256 {
00257 label own = pOwner[pFacei];
00258 const vector& vsfNei = psf[pFacei];
00259
00260 maxVsf[own] = max(maxVsf[own], vsfNei);
00261 minVsf[own] = min(minVsf[own], vsfNei);
00262 }
00263 }
00264 }
00265
00266 maxVsf -= vsf;
00267 minVsf -= vsf;
00268
00269 if (k_ < 1.0)
00270 {
00271 vectorField maxMinVsf = (1.0/k_ - 1.0)*(maxVsf - minVsf);
00272 maxVsf += maxMinVsf;
00273 minVsf -= maxMinVsf;
00274
00275
00276
00277 }
00278
00279
00280 forAll(owner, facei)
00281 {
00282 label own = owner[facei];
00283 label nei = neighbour[facei];
00284
00285
00286 limitFace
00287 (
00288 g[own],
00289 maxVsf[own],
00290 minVsf[own],
00291 Cf[facei] - C[own]
00292 );
00293
00294
00295 limitFace
00296 (
00297 g[nei],
00298 maxVsf[nei],
00299 minVsf[nei],
00300 Cf[facei] - C[nei]
00301 );
00302 }
00303
00304
00305 forAll(bsf, patchi)
00306 {
00307 const unallocLabelList& pOwner = mesh.boundary()[patchi].faceCells();
00308 const vectorField& pCf = Cf.boundaryField()[patchi];
00309
00310 forAll(pOwner, pFacei)
00311 {
00312 label own = pOwner[pFacei];
00313
00314 limitFace
00315 (
00316 g[own],
00317 maxVsf[own],
00318 minVsf[own],
00319 pCf[pFacei] - C[own]
00320 );
00321 }
00322 }
00323
00324 g.correctBoundaryConditions();
00325 gaussGrad<vector>::correctBoundaryConditions(vsf, g);
00326
00327 return tGrad;
00328 }
00329
00330
00331
00332
00333 }
00334
00335
00336
00337 }
00338
00339