void kinematicSingleLayer::continuityCheck() { const volScalarField deltaRho0(deltaRho_); solveContinuity(); if (debug) { const volScalarField mass(deltaRho_*magSf()); const dimensionedScalar totalMass = fvc::domainIntegrate(mass) + dimensionedScalar("SMALL", dimMass*dimVolume, ROOTVSMALL); const scalar sumLocalContErr = ( fvc::domainIntegrate(mag(mass - magSf()*deltaRho0))/totalMass ).value(); const scalar globalContErr = ( fvc::domainIntegrate(mass - magSf()*deltaRho0)/totalMass ).value(); cumulativeContErr_ += globalContErr; InfoInFunction << "Surface film: " << type() << nl << " time step continuity errors: sum local = " << sumLocalContErr << ", global = " << globalContErr << ", cumulative = " << cumulativeContErr_ << endl; } }
void thermoSingleLayer::evolveRegion() { if (debug) { tabAdd(); Info<<tab.c_str()<< "thermoSingleLayer::evolveRegion()" << endl; } //kvm, if updateSubmodels occurs after solveContinuity, then vaporization and separation don't get called until after deltaRho_ has been calculated, resulting in errors updateSubmodels(); // Solve continuity for deltaRho_ solveContinuity(); for (int oCorr=0; oCorr<nOuterCorr_; oCorr++) { // Explicit pressure source contribution tmp<volScalarField> tpu(this->pu()); // Implicit pressure source coefficient tmp<volScalarField> tpp(this->pp()); // Solve for momentum for U_ tmp<fvVectorMatrix> UEqn = solveMomentum(tpu(), tpp()); // Solve energy for hs_ - also updates thermo solveEnergy(); // Film thickness correction loop for (int corr=1; corr<=nCorr_; corr++) { // Solve thickness for delta_ solveThickness(tpu(), tpp(), UEqn()); } } T_ == T(hs_); #include "diagnostics.H" // Update deltaRho_ with new delta_ deltaRho_ == delta_*rho_; // Update film wall and surface velocities updateSurfaceVelocities(); // Update film wall and surface temperatures // only need to call once? // updateSurfaceTemperatures(); // Reset source terms for next time integration resetPrimaryRegionSourceTerms(); if (debug) { Info<<tab.c_str()<< "leaving thermoSingleLayer::evolveRegion()" << endl; tabSubtract(); } }
void kinematicSingleLayer::evolveRegion() { if (debug) { InfoInFunction << endl; } // Update film coverage indicator correctAlpha(); // Update film wall and surface velocities updateSurfaceVelocities(); // Update sub-models to provide updated source contributions updateSubmodels(); // Solve continuity for deltaRho_ solveContinuity(); // Implicit pressure source coefficient - constant tmp<volScalarField> tpp(this->pp()); for (int oCorr=1; oCorr<=nOuterCorr_; oCorr++) { // Explicit pressure source contribution - varies with delta_ tmp<volScalarField> tpu(this->pu()); // Solve for momentum for U_ tmp<fvVectorMatrix> UEqn = solveMomentum(tpu(), tpp()); // Film thickness correction loop for (int corr=1; corr<=nCorr_; corr++) { // Solve thickness for delta_ solveThickness(tpu(), tpp(), UEqn()); } } // Update deltaRho_ with new delta_ deltaRho_ == delta_*rho_; // Reset source terms for next time integration resetPrimaryRegionSourceTerms(); }
int kinwave_execute(int j, double* qinflow, double* qoutflow, double tStep) // // Input: j = link index // qinflow = inflow at current time (cfs) // tStep = time step (sec) // Output: qoutflow = outflow at current time (cfs), // returns number of iterations used // Purpose: finds outflow over time step tStep given flow entering a // conduit using Kinematic Wave flow routing. // // t // | qin, ain |-------------------| qout, aout // | | Flow ---> | // |----> x q1, a1 |-------------------| q2, a2 // // { int k; int result = 1; double dxdt, dq; double ain, aout; double qin, qout; double a1, a2, q1, q2; // --- no routing for non-conduit link (*qoutflow) = (*qinflow); if ( Link[j].type != CONDUIT ) return result; // --- no routing for dummy xsection if ( Link[j].xsect.type == DUMMY ) return result; // --- assign module-level variables pXsect = &Link[j].xsect; Qfull = Link[j].qFull; Afull = Link[j].xsect.aFull; k = Link[j].subIndex; Beta1 = Conduit[k].beta / Qfull; // --- normalize flows and areas q1 = Conduit[k].q1 / Qfull; q2 = Conduit[k].q2 / Qfull; a1 = Conduit[k].a1 / Afull; a2 = Conduit[k].a2 / Afull; qin = (*qinflow) / Conduit[k].barrels / Qfull; // --- use full area when inlet flow >= full flow //(5.0.012 - LR) if ( qin >= 1.0 ) ain = 1.0; //(5.0.012 - LR) // --- get normalized inlet area corresponding to inlet flow else ain = xsect_getAofS(pXsect, qin/Beta1) / Afull; // --- check for no flow if ( qin <= TINY && q2 <= TINY ) { qout = 0.0; aout = 0.0; } // --- otherwise solve finite difference form of continuity eqn. else { // --- compute constant factors dxdt = link_getLength(j) / tStep * Afull / Qfull; dq = q2 - q1; C1 = dxdt * WT / WX; C2 = (1.0 - WT) * (ain - a1); C2 = C2 - WT * a2; C2 = C2 * dxdt / WX; C2 = C2 + (1.0 - WX) / WX * dq - qin; // --- starting guess for aout is value from previous time step aout = a2; // --- solve continuity equation for aout result = solveContinuity(qin, ain, &aout); // --- report error if continuity eqn. not solved if ( result == -1 ) { report_writeErrorMsg(ERR_KINWAVE, Link[j].ID); return 1; } if ( result <= 0 ) result = 1; // --- compute normalized outlet flow from outlet area qout = Beta1 * xsect_getSofA(pXsect, aout*Afull); if ( qin > 1.0 ) qin = 1.0; } // --- save new flows and areas Conduit[k].q1 = qin * Qfull; Conduit[k].a1 = ain * Afull; Conduit[k].q2 = qout * Qfull; Conduit[k].a2 = aout * Afull; (*qinflow) = Conduit[k].q1 * Conduit[k].barrels; (*qoutflow) = Conduit[k].q2 * Conduit[k].barrels; return result; }