{ volScalarField& rDeltaT = trDeltaT.ref(); const dictionary& pimpleDict = pimple.dict(); // Maximum flow Courant number scalar maxCo(pimpleDict.lookup("maxCo")); // Maximum time scale scalar maxDeltaT(pimpleDict.lookupOrDefault("maxDeltaT", great)); // Smoothing parameter (0-1) when smoothing iterations > 0 scalar rDeltaTSmoothingCoeff ( pimpleDict.lookupOrDefault("rDeltaTSmoothingCoeff", 0.1) ); // Damping coefficient (1-0) scalar rDeltaTDampingCoeff ( pimpleDict.lookupOrDefault("rDeltaTDampingCoeff", 1.0) ); // Maximum change in cell temperature per iteration // (relative to previous value) scalar alphaTemp(pimpleDict.lookupOrDefault("alphaTemp", 0.05)); // Maximum change in cell concentration per iteration // (relative to reference value) scalar alphaY(pimpleDict.lookupOrDefault("alphaY", 1.0)); // Cache old reciprocal time scale field volScalarField rDeltaT0("rDeltaT0", rDeltaT); Info<< "Time scales min/max:" << endl; // Flow time scale { surfaceScalarField maxPhi("maxPhi", phi); forAll(phases, phasei) { maxPhi = max(maxPhi, mag(phases[phasei].phi())); } // Set the reciprocal time-step from the local Courant number and // limit the largest time scale rDeltaT.ref() = max ( 1/dimensionedScalar(dimTime, maxDeltaT), fvc::surfaceSum(maxPhi)()() /((2*maxCo)*mesh.V()) ); Info<< " Flow = " << gMin(1/rDeltaT.primitiveField()) << ", " << gMax(1/rDeltaT.primitiveField()) << endl; } // Heat release rate time scale if (alphaTemp < 1) { autoPtr heatTransferPtr(fluid.heatTransfer()); phaseSystem::heatTransferTable& heatTransfer = heatTransferPtr(); volScalarField::Internal rDeltaTT ( volScalarField::Internal::New ( "rDeltatTT", mesh, dimensionedScalar(rDeltaT.dimensions(), 0) ) ); forAll(fluid.anisothermalPhases(), anisothermalPhasei) { phaseModel& phase = fluid.anisothermalPhases()[anisothermalPhasei]; tmp rho = phase.rho(); tmp Cp = phase.thermo().Cp(); tmp T = phase.thermo().T(); // Heat release due to combustion is not included due to missing // access from the phaseModel rDeltaTT.field() = max ( rDeltaTT, ( mag(heatTransfer[phase.name()]->source()) + mag(fvModels.source(rho, phase.thermoRef().he())->source()) ) /(alphaTemp*rho*Cp*T*mesh.V()) ); } Info<< " Temperature = " << 1/(gMax(rDeltaTT.field()) + vSmall) << ", " << 1/(gMin(rDeltaTT.field()) + vSmall) << endl; rDeltaT.ref() = max(rDeltaT(), rDeltaTT); } // Reaction rate time scale if (alphaY < 1) { dictionary Yref(pimpleDict.subDict("Yref")); autoPtr specieTransferPtr(fluid.specieTransfer()); phaseSystem::specieTransferTable& specieTransfer(specieTransferPtr()); volScalarField::Internal rDeltaTY ( volScalarField::Internal::New ( "rDeltaTY", mesh, dimensionedScalar(rDeltaT.dimensions(), 0) ) ); bool foundY = false; forAll(fluid.multiComponentPhases(), multiComponentPhasei) { phaseModel& phase = fluid.anisothermalPhases()[multiComponentPhasei]; UPtrList& Y = phase.YActiveRef(); tmp rho = phase.rho(); forAll(Y, i) { volScalarField& Yi = Y[i]; if (Yref.found(Yi.member())) { foundY = true; scalar Yrefi = Yref.lookup(Yi.member()); rDeltaTY.field() = max ( rDeltaTY, ( mag(specieTransfer[Y[i].name()]->source()) + mag(phase.R(Yi)->source()) + mag(fvModels.source(rho, Y[i])->source()) ) /((Yrefi*alphaY)*(rho*mesh.V())) ); } } } if (foundY) { Info<< " Composition = " << 1/(gMax(rDeltaTY.field()) + vSmall) << ", " << 1/(gMin(rDeltaTY.field()) + vSmall) << endl; rDeltaT.ref() = max(rDeltaT(), rDeltaTY); } else { IOWarningIn(args.executable().c_str(), Yref) << "Cannot find any active species in Yref " << Yref << endl; } } // Update the boundary values of the reciprocal time-step rDeltaT.correctBoundaryConditions(); // Spatially smooth the time scale field if (rDeltaTSmoothingCoeff < 1) { fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff); } // Limit rate of change of time scale // - reduce as much as required // - only increase at a fraction of old time scale if ( rDeltaTDampingCoeff < 1 && runTime.timeIndex() > runTime.startTimeIndex() + 1 ) { rDeltaT = max ( rDeltaT, (scalar(1) - rDeltaTDampingCoeff)*rDeltaT0 ); } // Update the boundary values of the reciprocal time-step rDeltaT.correctBoundaryConditions(); Info<< " Overall = " << 1/gMax(rDeltaT.primitiveField()) << ", " << 1/gMin(rDeltaT.primitiveField()) << nl << endl; }