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 "supersonicFreestreamFvPatchVectorField.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <finiteVolume/fvPatchFieldMapper.H>
00029 #include <finiteVolume/volFields.H>
00030
00031
00032
00033 namespace Foam
00034 {
00035
00036
00037
00038 supersonicFreestreamFvPatchVectorField::supersonicFreestreamFvPatchVectorField
00039 (
00040 const fvPatch& p,
00041 const DimensionedField<vector, volMesh>& iF
00042 )
00043 :
00044 mixedFvPatchVectorField(p, iF),
00045 UInf_(vector::zero),
00046 pInf_(0),
00047 TInf_(0),
00048 gamma_(0)
00049 {
00050 refValue() = patchInternalField();
00051 refGrad() = vector::zero;
00052 valueFraction() = 1;
00053 }
00054
00055
00056 supersonicFreestreamFvPatchVectorField::supersonicFreestreamFvPatchVectorField
00057 (
00058 const supersonicFreestreamFvPatchVectorField& ptf,
00059 const fvPatch& p,
00060 const DimensionedField<vector, volMesh>& iF,
00061 const fvPatchFieldMapper& mapper
00062 )
00063 :
00064 mixedFvPatchVectorField(ptf, p, iF, mapper),
00065 UInf_(ptf.UInf_),
00066 pInf_(ptf.pInf_),
00067 TInf_(ptf.TInf_),
00068 gamma_(ptf.gamma_)
00069 {}
00070
00071
00072 supersonicFreestreamFvPatchVectorField::supersonicFreestreamFvPatchVectorField
00073 (
00074 const fvPatch& p,
00075 const DimensionedField<vector, volMesh>& iF,
00076 const dictionary& dict
00077 )
00078 :
00079 mixedFvPatchVectorField(p, iF),
00080 UInf_(dict.lookup("UInf")),
00081 pInf_(readScalar(dict.lookup("pInf"))),
00082 TInf_(readScalar(dict.lookup("TInf"))),
00083 gamma_(readScalar(dict.lookup("gamma")))
00084 {
00085 if (dict.found("value"))
00086 {
00087 fvPatchField<vector>::operator=
00088 (
00089 vectorField("value", dict, p.size())
00090 );
00091 }
00092 else
00093 {
00094 fvPatchField<vector>::operator=(patchInternalField());
00095 }
00096
00097 refValue() = *this;
00098 refGrad() = vector::zero;
00099 valueFraction() = 1;
00100
00101 if (pInf_ < SMALL)
00102 {
00103 FatalIOErrorIn
00104 (
00105 "supersonicFreestreamFvPatchVectorField::"
00106 "supersonicFreestreamFvPatchVectorField"
00107 "(const fvPatch&, const vectorField&, const dictionary&)",
00108 dict
00109 ) << " unphysical pInf specified (pInf <= 0.0)"
00110 << "\n on patch " << this->patch().name()
00111 << " of field " << this->dimensionedInternalField().name()
00112 << " in file " << this->dimensionedInternalField().objectPath()
00113 << exit(FatalIOError);
00114 }
00115 }
00116
00117
00118 supersonicFreestreamFvPatchVectorField::supersonicFreestreamFvPatchVectorField
00119 (
00120 const supersonicFreestreamFvPatchVectorField& sfspvf
00121 )
00122 :
00123 mixedFvPatchVectorField(sfspvf),
00124 UInf_(sfspvf.UInf_),
00125 pInf_(sfspvf.pInf_),
00126 TInf_(sfspvf.TInf_),
00127 gamma_(sfspvf.gamma_)
00128 {}
00129
00130
00131 supersonicFreestreamFvPatchVectorField::supersonicFreestreamFvPatchVectorField
00132 (
00133 const supersonicFreestreamFvPatchVectorField& sfspvf,
00134 const DimensionedField<vector, volMesh>& iF
00135 )
00136 :
00137 mixedFvPatchVectorField(sfspvf, iF),
00138 UInf_(sfspvf.UInf_),
00139 pInf_(sfspvf.pInf_),
00140 TInf_(sfspvf.TInf_),
00141 gamma_(sfspvf.gamma_)
00142 {}
00143
00144
00145
00146
00147 void supersonicFreestreamFvPatchVectorField::updateCoeffs()
00148 {
00149 if (!size() || updated())
00150 {
00151 return;
00152 }
00153
00154 const fvPatchField<scalar>& pT =
00155 patch().lookupPatchField<volScalarField, scalar>("T");
00156
00157 const fvPatchField<scalar>& pp =
00158 patch().lookupPatchField<volScalarField, scalar>("p");
00159
00160 const fvPatchField<scalar>& ppsi =
00161 patch().lookupPatchField<volScalarField, scalar>("psi");
00162
00163
00164
00165 scalar R = 1.0/(ppsi[0]*pT[0]);
00166
00167 scalar MachInf = mag(UInf_)/sqrt(gamma_*R*TInf_);
00168
00169 if (MachInf < 1.0)
00170 {
00171 FatalErrorIn
00172 (
00173 "supersonicFreestreamFvPatchVectorField::updateCoeffs()"
00174 ) << " MachInf < 1.0, free stream must be supersonic"
00175 << "\n on patch " << this->patch().name()
00176 << " of field " << this->dimensionedInternalField().name()
00177 << " in file " << this->dimensionedInternalField().objectPath()
00178 << exit(FatalError);
00179 }
00180
00181 vectorField& Up = refValue();
00182 valueFraction() = 1;
00183
00184
00185 vectorField U = patchInternalField();
00186
00187
00188
00189
00190
00191
00192 vector UInfHat = UInf_/mag(UInf_);
00193
00194
00195 vectorField nnInfHat = UInfHat ^ patch().nf();
00196
00197
00198
00199
00200
00201
00202
00203
00204 vectorField nHatInf = nnInfHat ^ UInfHat;
00205
00206
00207
00208 vectorField Un = nHatInf*(nHatInf & U);
00209
00210
00211 vectorField Ut = U - Un;
00212
00213
00214 scalar nuMachInf =
00215 sqrt((gamma_ + 1)/(gamma_ - 1))
00216 *atan(sqrt((gamma_ - 1)/(gamma_ + 1)*(sqr(MachInf) - 1)))
00217 - atan(sqr(MachInf) - 1);
00218
00219
00220
00221
00222
00223 forAll(Up, facei)
00224 {
00225 if (pp[facei] >= pInf_)
00226 {
00227
00228
00229
00230 scalar fpp =
00231 sqrt(sqr(MachInf) - 1)
00232 /(gamma_*sqr(MachInf))*mag(Ut[facei])*log(pp[facei]/pInf_);
00233
00234 Up[facei] = Ut[facei] + fpp*nHatInf[facei];
00235
00236
00237 scalar Mach = mag(Up[facei])/sqrt(gamma_/ppsi[facei]);
00238
00239 if (Mach <= 1)
00240 {
00241
00242
00243 Up[facei] = U[facei];
00244 valueFraction()[facei] = 0;
00245 }
00246 }
00247 else
00248 {
00249
00250
00251
00252 scalar Mach =
00253 sqrt
00254 (
00255 (2/(gamma_ - 1))*(1 + ((gamma_ - 1)/2)*sqr(MachInf))
00256 *pow(pp[facei]/pInf_, (1 - gamma_)/gamma_)
00257 - 2/(gamma_ - 1)
00258 );
00259
00260 if (Mach > 1)
00261 {
00262
00263
00264
00265 scalar nuMachf =
00266 sqrt((gamma_ + 1)/(gamma_ - 1))
00267 *atan(sqrt((gamma_ - 1)/(gamma_ + 1)*(sqr(Mach) - 1)))
00268 - atan(sqr(Mach) - 1);
00269
00270 scalar fpp = (nuMachInf - nuMachf)*mag(Ut[facei]);
00271
00272 Up[facei] = Ut[facei] + fpp*nHatInf[facei];
00273 }
00274 else
00275 {
00276 FatalErrorIn
00277 (
00278 "supersonicFreestreamFvPatchVectorField::updateCoeffs()"
00279 ) << "unphysical subsonic inflow has been generated"
00280 << "\n on patch " << this->patch().name()
00281 << " of field " << this->dimensionedInternalField().name()
00282 << " in file "
00283 << this->dimensionedInternalField().objectPath()
00284 << exit(FatalError);
00285 }
00286 }
00287 }
00288
00289 mixedFvPatchVectorField::updateCoeffs();
00290 }
00291
00292
00293 void supersonicFreestreamFvPatchVectorField::write(Ostream& os) const
00294 {
00295 fvPatchVectorField::write(os);
00296 os.writeKeyword("UInf") << UInf_ << token::END_STATEMENT << nl;
00297 os.writeKeyword("pInf") << pInf_ << token::END_STATEMENT << nl;
00298 os.writeKeyword("TInf") << TInf_ << token::END_STATEMENT << nl;
00299 os.writeKeyword("gamma") << gamma_ << token::END_STATEMENT << nl;
00300 writeEntry("value", os);
00301 }
00302
00303
00304
00305
00306 makePatchTypeField
00307 (
00308 fvPatchVectorField,
00309 supersonicFreestreamFvPatchVectorField
00310 );
00311
00312
00313
00314 }
00315
00316