38 Foam::pressurePIDControlInletVelocityFvPatchVectorField::facePressure()
const
42 const word pfName(pName_ +
"f");
44 if (!db().foundObject<surfaceScalarField>(pfName))
58 db().lookupObject<surfaceScalarField>(pfName)
73 Foam::pressurePIDControlInletVelocityFvPatchVectorField::
74 pressurePIDControlInletVelocityFvPatchVectorField
77 const DimensionedField<vector, volMesh>& iF
80 fixedValueFvPatchField<
vector>(
p, iF),
81 upstreamName_(word::null),
82 downstreamName_(word::null),
91 Q_(-
gSum(*this & patch().Sf())),
101 Foam::pressurePIDControlInletVelocityFvPatchVectorField::
102 pressurePIDControlInletVelocityFvPatchVectorField
104 const pressurePIDControlInletVelocityFvPatchVectorField& ptf,
106 const DimensionedField<vector, volMesh>& iF,
107 const fvPatchFieldMapper& mapper
110 fixedValueFvPatchField<
vector>(ptf,
p, iF, mapper),
111 upstreamName_(ptf.upstreamName_),
112 downstreamName_(ptf.downstreamName_),
113 deltaP_(ptf.deltaP_),
114 shapeFactor_(ptf.shapeFactor_),
116 phiName_(ptf.phiName_),
117 rhoName_(ptf.rhoName_),
123 errorIntegral_(ptf.errorIntegral_),
125 oldError_(ptf.oldError_),
126 oldErrorIntegral_(ptf.oldErrorIntegral_),
127 timeIndex_(ptf.timeIndex_)
131 Foam::pressurePIDControlInletVelocityFvPatchVectorField::
132 pressurePIDControlInletVelocityFvPatchVectorField
135 const DimensionedField<vector, volMesh>& iF,
136 const dictionary&
dict
143 shapeFactor_(
dict.lookupOrDefault<scalar>(
"shapeFactor", 0)),
144 pName_(
dict.lookupOrDefault<word>(
"p",
"p")),
145 phiName_(
dict.lookupOrDefault<word>(
"phi",
"phi")),
146 rhoName_(
dict.lookupOrDefault<word>(
"rho",
"none")),
150 Q_(-
gSum(*this & patch().Sf())),
151 error_(
dict.lookupOrDefault<scalar>(
"error", 0)),
152 errorIntegral_(
dict.lookupOrDefault<scalar>(
"errorIntegral", 0)),
155 oldErrorIntegral_(0),
160 Foam::pressurePIDControlInletVelocityFvPatchVectorField::
161 pressurePIDControlInletVelocityFvPatchVectorField
163 const pressurePIDControlInletVelocityFvPatchVectorField& ptf
166 fixedValueFvPatchField<
vector>(ptf),
167 upstreamName_(ptf.upstreamName_),
168 downstreamName_(ptf.downstreamName_),
169 deltaP_(ptf.deltaP_),
170 shapeFactor_(ptf.shapeFactor_),
172 phiName_(ptf.phiName_),
173 rhoName_(ptf.rhoName_),
179 errorIntegral_(ptf.errorIntegral_),
181 oldError_(ptf.oldError_),
182 oldErrorIntegral_(ptf.oldErrorIntegral_),
183 timeIndex_(ptf.timeIndex_)
187 Foam::pressurePIDControlInletVelocityFvPatchVectorField::
188 pressurePIDControlInletVelocityFvPatchVectorField
190 const pressurePIDControlInletVelocityFvPatchVectorField& ptf,
191 const DimensionedField<vector, volMesh>& iF
194 fixedValueFvPatchField<
vector>(ptf, iF),
195 upstreamName_(ptf.upstreamName_),
196 downstreamName_(ptf.downstreamName_),
197 deltaP_(ptf.deltaP_),
198 shapeFactor_(ptf.shapeFactor_),
200 phiName_(ptf.phiName_),
201 rhoName_(ptf.rhoName_),
207 errorIntegral_(ptf.errorIntegral_),
209 oldError_(ptf.oldError_),
210 oldErrorIntegral_(ptf.oldErrorIntegral_),
211 timeIndex_(ptf.timeIndex_)
217 void Foam::pressurePIDControlInletVelocityFvPatchVectorField::updateCoeffs()
225 const fvMesh&
mesh(patch().boundaryMesh().
mesh());
228 const scalar deltaT(db().time().deltaTValue());
233 db().lookupObject<surfaceScalarField>(phiName_)
237 if (timeIndex_ != db().time().
timeIndex())
239 timeIndex_ = db().time().timeIndex();
242 oldErrorIntegral_ = errorIntegral_;
253 const fvPatchField<scalar>& rhoField =
256 rho =
gSum(rhoField*patch().magSf())/
gSum(patch().magSf());
261 <<
"The dimensions of the field " << phiName_
262 <<
"are not recognised. The dimensions are " <<
phi.dimensions()
264 <<
" for an incompressible case, or "
270 const scalar patchA =
gSum(patch().magSf());
271 Q_ = -
gSum(*
this & patch().Sf());
276 faceZoneAverage(upstreamName_,
mesh.
Cf(), Aa, xa);
277 faceZoneAverage(downstreamName_,
mesh.
Cf(), Ab, xb);
278 const scalar L =
mag(xa - xb);
279 const scalar LbyALinear = L/(Aa - Ab)*
log(Aa/Ab);
280 const scalar LbyAStep = L/2*(1/Aa + 1/Ab);
281 const scalar LbyA = (1 - shapeFactor_)*LbyALinear + shapeFactor_*LbyAStep;
287 scalar deltaP = deltaP_;
291 faceZoneAverage(upstreamName_, facePressure(), Aa, pa);
292 faceZoneAverage(downstreamName_, facePressure(), Ab, pb);
298 <<
"The pressure field name, \"pName\", is \"" << pName_ <<
"\", "
299 <<
"but a field of that name was not found. The inlet velocity "
300 <<
"will be set to an analytical value calculated from the "
301 <<
"specified pressure drop. No PID control will be done and "
302 <<
"transient effects will be ignored. This behaviour is designed "
303 <<
"to be appropriate for potentialFoam solutions. If you are "
304 <<
"getting this warning from another solver, you have probably "
305 <<
"specified an incorrect pressure name."
310 scalar QTarget, QMeasured;
311 const scalar a = (1/
sqr(Ab) - 1/
sqr(Aa))/(2*
rho);
314 const scalar
b = LbyA/deltaT;
315 const scalar
c = - LbyA/deltaT*oldQ_ ;
316 QTarget = (-
b +
sqrt(
sqr(
b) - 4*a*(
c - deltaP_)))/(2*a);
317 QMeasured = (-
b +
sqrt(
sqr(
b) - 4*a*(
c - deltaP)))/(2*a);
321 QTarget =
sqrt(deltaP_/a);
322 QMeasured =
sqrt(deltaP/a);
326 error_ = QTarget - QMeasured;
327 errorIntegral_ = oldErrorIntegral_ + 0.5*(error_ + oldError_);
328 const scalar errorDifferential = oldError_ - error_;
338 + D_*errorDifferential
346 const scalar error = deltaP/deltaP_ - 1;
347 const scalar newQ = -
gSum(*
this & patch().Sf());
348 Info<<
"pressurePIDControlInletVelocityFvPatchField " << patch().name()
353 <<
" (" <<
mag(error)*100 <<
"\% "
354 << (error < 0 ?
"below" :
"above") <<
" the target)" <<
endl;
370 os.writeKeyword(
"downstream")
372 os.writeKeyword(
"shapeFactor") << shapeFactor_
374 writeEntryIfDifferent<word>(os,
"p",
"p", pName_);
375 writeEntryIfDifferent<word>(os,
"rho",
"none", rhoName_);
380 os.writeKeyword(
"errorIntegral")
383 writeEntry(
"value", os);
394 pressurePIDControlInletVelocityFvPatchVectorField