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 "ConeInjectionMP.H"
00027 #include <lagrangianIntermediate/DataEntry.H>
00028 #include <OpenFOAM/mathematicalConstants.H>
00029
00030
00031
00032 template<class CloudType>
00033 Foam::label Foam::ConeInjectionMP<CloudType>::parcelsToInject
00034 (
00035 const scalar time0,
00036 const scalar time1
00037 ) const
00038 {
00039 if ((time0 >= 0.0) && (time0 < duration_))
00040 {
00041 const scalar targetVolume = volumeFlowRate_().integrate(0, time1);
00042
00043 const label targetParcels =
00044 parcelsPerInjector_*targetVolume/this->volumeTotal_;
00045
00046 const label nToInject = targetParcels - nInjected_;
00047
00048 nInjected_ += nToInject;
00049
00050 return positions_.size()*nToInject;
00051 }
00052 else
00053 {
00054 return 0;
00055 }
00056 }
00057
00058
00059 template<class CloudType>
00060 Foam::scalar Foam::ConeInjectionMP<CloudType>::volumeToInject
00061 (
00062 const scalar time0,
00063 const scalar time1
00064 ) const
00065 {
00066 if ((time0 >= 0.0) && (time0 < duration_))
00067 {
00068 return volumeFlowRate_().integrate(time0, time1);
00069 }
00070 else
00071 {
00072 return 0.0;
00073 }
00074 }
00075
00076
00077
00078
00079 template<class CloudType>
00080 Foam::ConeInjectionMP<CloudType>::ConeInjectionMP
00081 (
00082 const dictionary& dict,
00083 CloudType& owner
00084 )
00085 :
00086 InjectionModel<CloudType>(dict, owner, typeName),
00087 positionsFile_(this->coeffDict().lookup("positionsFile")),
00088 positions_
00089 (
00090 IOobject
00091 (
00092 positionsFile_,
00093 owner.db().time().constant(),
00094 owner.mesh(),
00095 IOobject::MUST_READ,
00096 IOobject::NO_WRITE
00097 )
00098 ),
00099 injectorCells_(positions_.size()),
00100 axesFile_(this->coeffDict().lookup("axesFile")),
00101 axes_
00102 (
00103 IOobject
00104 (
00105 axesFile_,
00106 owner.db().time().constant(),
00107 owner.mesh(),
00108 IOobject::MUST_READ,
00109 IOobject::NO_WRITE
00110 )
00111 ),
00112 duration_(readScalar(this->coeffDict().lookup("duration"))),
00113 parcelsPerInjector_
00114 (
00115 readScalar(this->coeffDict().lookup("parcelsPerInjector"))
00116 ),
00117 volumeFlowRate_
00118 (
00119 DataEntry<scalar>::New
00120 (
00121 "volumeFlowRate",
00122 this->coeffDict()
00123 )
00124 ),
00125 Umag_
00126 (
00127 DataEntry<scalar>::New
00128 (
00129 "Umag",
00130 this->coeffDict()
00131 )
00132 ),
00133 thetaInner_
00134 (
00135 DataEntry<scalar>::New
00136 (
00137 "thetaInner",
00138 this->coeffDict()
00139 )
00140 ),
00141 thetaOuter_
00142 (
00143 DataEntry<scalar>::New
00144 (
00145 "thetaOuter",
00146 this->coeffDict()
00147 )
00148 ),
00149 parcelPDF_
00150 (
00151 pdfs::pdf::New
00152 (
00153 this->coeffDict().subDict("parcelPDF"),
00154 owner.rndGen()
00155 )
00156 ),
00157 nInjected_(this->parcelsAddedTotal()),
00158 tanVec1_(positions_.size()),
00159 tanVec2_(positions_.size())
00160 {
00161
00162
00163 forAll(axes_, i)
00164 {
00165 axes_[i] /= mag(axes_[i]);
00166
00167 vector tangent = vector::zero;
00168 scalar magTangent = 0.0;
00169
00170 while (magTangent < SMALL)
00171 {
00172 vector v = this->owner().rndGen().vector01();
00173
00174 tangent = v - (v & axes_[i])*axes_[i];
00175 magTangent = mag(tangent);
00176 }
00177
00178 tanVec1_[i] = tangent/magTangent;
00179 tanVec2_[i] = axes_[i]^tanVec1_[i];
00180 }
00181
00182
00183 this->volumeTotal_ = volumeFlowRate_().integrate(0.0, duration_);
00184
00185
00186 forAll(positions_, i)
00187 {
00188 this->findCellAtPosition
00189 (
00190 injectorCells_[i],
00191 positions_[i]
00192 );
00193 }
00194 }
00195
00196
00197
00198
00199 template<class CloudType>
00200 Foam::ConeInjectionMP<CloudType>::~ConeInjectionMP()
00201 {}
00202
00203
00204
00205
00206 template<class CloudType>
00207 bool Foam::ConeInjectionMP<CloudType>::active() const
00208 {
00209 return true;
00210 }
00211
00212
00213 template<class CloudType>
00214 Foam::scalar Foam::ConeInjectionMP<CloudType>::timeEnd() const
00215 {
00216 return this->SOI_ + duration_;
00217 }
00218
00219
00220 template<class CloudType>
00221 void Foam::ConeInjectionMP<CloudType>::setPositionAndCell
00222 (
00223 const label parcelI,
00224 const label,
00225 const scalar,
00226 vector& position,
00227 label& cellOwner
00228 )
00229 {
00230 const label i = parcelI%positions_.size();
00231
00232 position = positions_[i];
00233 cellOwner = injectorCells_[i];
00234 }
00235
00236
00237 template<class CloudType>
00238 void Foam::ConeInjectionMP<CloudType>::setProperties
00239 (
00240 const label parcelI,
00241 const label,
00242 const scalar time,
00243 typename CloudType::parcelType& parcel
00244 )
00245 {
00246
00247 const label i = parcelI%positions_.size();
00248
00249 const scalar deg2Rad = mathematicalConstant::pi/180.0;
00250
00251 scalar t = time - this->SOI_;
00252 scalar ti = thetaInner_().value(t);
00253 scalar to = thetaOuter_().value(t);
00254 scalar coneAngle = this->owner().rndGen().scalar01()*(to - ti) + ti;
00255
00256 coneAngle *= deg2Rad;
00257 scalar alpha = sin(coneAngle);
00258 scalar dcorr = cos(coneAngle);
00259 scalar beta = mathematicalConstant::twoPi*this->owner().rndGen().scalar01();
00260
00261 vector normal = alpha*(tanVec1_[i]*cos(beta) + tanVec2_[i]*sin(beta));
00262 vector dirVec = dcorr*axes_[i];
00263 dirVec += normal;
00264
00265 dirVec /= mag(dirVec);
00266
00267 parcel.U() = Umag_().value(t)*dirVec;
00268
00269
00270 parcel.d() = parcelPDF_().sample();
00271 }
00272
00273
00274 template<class CloudType>
00275 bool Foam::ConeInjectionMP<CloudType>::fullyDescribed() const
00276 {
00277 return false;
00278 }
00279
00280
00281 template<class CloudType>
00282 bool Foam::ConeInjectionMP<CloudType>::validInjection(const label)
00283 {
00284 return true;
00285 }
00286
00287
00288