double CCWashMixEffFnd::Function(double x) {//x is fraction of wash to overflow //1) All solids go to underflow //2) Try meet user requirements for UF conc/liqFrac by adjusting wash fraction to overflow //3) Of the liquids reporting to the UF, we want (100%-RqdMixEff%) of liquids to retain mud liquids composition, // the rest is the wash liquids. Qu.QSetF(Qm, som_Sol, 1.0, POut); Qu.QAddF(Qw, som_Sol, 1.0); const double WashLiqToUF = (1.0 - x)*QwLiq; const double RqdMudLiqToUF = WashLiqToUF*(1.0/GTZ(RqdMixEff)-1.0); const double RqdMudFracToUF = Min(1.0, RqdMudLiqToUF/GTZ(QmLiq)); Qu.QAddF(Qm, som_Liq, RqdMudFracToUF); Qu.QAddF(Qw, som_Liq, (1.0 - x)); Qo.QSetF(Qm, som_Liq, (1.0-RqdMudFracToUF), POut); Qo.QAddF(Qw, som_Liq, x); if (1) {// Correct Enthalpy... Qu.SetTemp(FT); Qo.SetTemp(FT); double P = POut; double H = Qu.totHf()+Qo.totHf(); double dT = 0.0, H0, T0; for (int Hiter=0; Hiter<10; Hiter++) { if (ConvergedVV(HTot, H, 1.0e-12, 1.0e-12)) break; if (dT!=0.0) dT = (HTot-H)*(FT-T0)/NZ(H-H0); else dT = 0.1; T0 = FT; H0 = H; FT += dT; H = Qu.totHf(som_ALL, FT, P)+Qo.totHf(som_ALL, FT, P); } Qu.SetTemp(FT); Qo.SetTemp(FT); } if (SA) // Solids expressed as g/L. { double SolConc25 = Qu.PhaseConc(C_2_K(25.0), som_Sol, som_ALL); return SolConc25; } else // Solids expressed as % w/w. { double solid = Qu.QMass(som_Sol); double Totmass = Max(1e-6, Qu.QMass(som_ALL)); double SolUF = solid/Totmass; return SolUF; } }
void PL_SoftStSp::EvalCtrlActions(FlwNode* pFNode) { DoRunning(); double dReqdSpd, dDiffSpd; switch (iFwdRev) { case PLSS_FwdOnly: m_dSpeedReqd=Range(0.0, m_dSpeedReqd, 1.0); dReqdSpd=m_dSpeedReqd; if (Valid(m_dManualSpeed)) m_dManualSpeed=Range(0.0, m_dManualSpeed, 1.0); break; case PLSS_FwdRevLogic: m_dSpeedReqd=Range(0.0, m_dSpeedReqd, 1.0); dReqdSpd=m_dSpeedReqd*(bRunRev ? -1 : 1); if (Valid(m_dManualSpeed)) m_dManualSpeed=Range(0.0, m_dManualSpeed, 1.0); break; case PLSS_FwdRevRegulation: m_dSpeedReqd=Range(-1.0, m_dSpeedReqd, 1.0); dReqdSpd=m_dSpeedReqd; if (Valid(m_dManualSpeed)) m_dManualSpeed=Range(-1.0, m_dManualSpeed, 1.0); break; } // Decide the required position if (!bRunning) dReqdSpd=0.0; // the difference dDiffSpd = dReqdSpd-m_dSpeed; // limit the diff by the stroketime if (fabs(m_dSpeed+dDiffSpd*0.01)>fabs(m_dSpeed)) dDiffSpd = Sign(dDiffSpd)*Min(fabs(dDiffSpd), ICGetTimeInc()/GTZ(dStartTime)); else dDiffSpd = -Sign(dDiffSpd)*Max(-fabs(dDiffSpd),-ICGetTimeInc()/GTZ(dStopTime)); // apply it; m_dSpeed+=dDiffSpd; m_dSpeed=Range(-1.0, m_dSpeed, 1.0); if (!bRunning) m_dMapSpeed=0.0; else { if (Valid(m_dManualSpeed)) m_dMapSpeed=m_dManualSpeed; else m_dMapSpeed=m_dSpeed; m_dMapSpeed=dMapLo+m_dMapSpeed*(dMapHi-dMapLo); } };
void CSzSSA::SetSAMFromFlow(double THAFlow, double NoPerSec) { if (THAFlow>1.0e-6) { double Dens=SolidsDens(); double D=Pow(6.*THAFlow/GTZ(PI*Dens*NoPerSec), 1./3.); m_dSAM=3.0/GTZ(500.*Dens*D); double xD=PartDiamFromSAM(); } else m_dSAM=0.0; }
void CSzSSA::SetSAMfromPSD(long npts, double x[], double psd[]) { double Dens=SolidsDens(); double TotMass=0.0; double TotArea=0.0; for (int i=0; i<npts; i++) { double D=x[i]*1.0e-6; double SAMAtD=3.0/GTZ(500.*Dens*D); TotMass+=psd[i]; TotArea+=SAMAtD*psd[i]; } m_dSAM=TotArea/GTZ(TotMass); }
void HydroCyclone::EvalJoinFlows(int JoinNo) { double QmVIn = 0.0, QmSIn = 0.0; for (int i=0; i<NoFlwIOs() && IOId_Self(i)==ioidFeed ; i++) if (IO_In(i)) { pSpConduit p=IOConduit(i); QmVIn += p->QMass(som_Liq); QmSIn += p->QMass(som_Sol); } dbgpln("Hydrocyclone to be sorted out Liquids not done"); long Failed = 0; double Passing=0; int nIn1=IOWithId_Self(ioidFeed); if (nIn1 >= 0) { pSQSzDist1 pSz; pSz=SQSzDist1::Ptr(IOConduit(nIn1)->Model()); Ore2Grit=pSz->GritsFraction(PartCrv, 0.0, ByePass2Grits); GritFlowRatio=(Ore2Grit*QmSIn)/GTZ(QmVIn + (1.0-Ore2Grit)*QmSIn); Joins[0].SetQm_QmRatio(Max(1.0e-6, GritFlowRatio)); } };
double CDemoSM::get_Density(long Phases, double T, double P, MArray *pMA) { MArray MA(pMA ? *pMA : this); double MSol=0; double MLiq=0; double MGas=0; long SpecieCount=gs_MVDefn.Count(); //double * M=MassVector; for (int i=0; i<SpecieCount; i++) { long Ph=gs_MVDefn[i].Phase(); if (Ph & MP_Sol) MSol+=MA[i]; else if (Ph & MP_Liq) MLiq+=MA[i]; else MGas+=MA[i]; } double DSol=2000; double DLiq=1000; double DGas=1; return (MSol+MLiq+MGas)/GTZ(MSol/DSol+ MLiq/DLiq+ MGas/DGas); }
double CDArray::ToCumulative(double ConstInteg, double Total, flag Inverse, flag Shift) { if (GetSize()==0) return False; const long N = GetSize(); double Yt; m_pData[0]+=ConstInteg; for (long i=1; i<N; i++) m_pData[i] += m_pData[i-1];//*(X[i]-X[i-1]); Yt = m_pData[N-1]; if (Shift) { for (long i=N-1; i>0; i--) m_pData[i] = m_pData[i-1];//*(X[i]-X[i-1]); m_pData[i]=ConstInteg; } if (Inverse) { for (long i=0; i<N; i++) m_pData[i] = Yt-m_pData[i]; } if (Valid(Total)) { double Scale=Total/GTZ(Yt); if (Scale >= 1.0e-10 && Scale <=1.0e10) OpMult(Scale); return Scale; } return 1.0; }
void PL_SoftStart::EvalCtrlActions(FlwNode* pFNode) { DoRunning(); double dReqdSpd, dDiffSpd; // Decide the required position if (bRunning) dReqdSpd=m_dSpeedReqd; else dReqdSpd=0.0; // the difference dDiffSpd = dReqdSpd-m_dSpeed; // limit the diff by the stroketime dDiffSpd = Sign(dDiffSpd)*Min(fabs(dDiffSpd),(ICGetTimeInc()/GTZ(dStartTime))); // apply it; m_dSpeed+=dDiffSpd; m_dSpeed=Range(0.0, m_dSpeed, 1.0); if (!bRunning) m_dMapSpeed=0.0; else { if (Valid(m_dManualSpeed)) m_dMapSpeed=Range(0.0, m_dManualSpeed, 1.0); else m_dMapSpeed=m_dSpeed; m_dMapSpeed=dMapLo+m_dMapSpeed*(dMapHi-dMapLo); } };
flag PE_VolFlow::EvaluateFlwEqn(eScdFlwEqnTasks Task, CSpPropInfo *pProps, CFlwBlkBase & FE, bool On, double Regulation, CFBPhysData *pPhD0, CFBPhysData *pPhD1) { double dPq1, dPq2; if (Valid(OpVol)) { double Rho=Max(0.1, FE.MeanRho(pProps)); double K=fabs(OpDP)/Pow(fabs(OpVol), PwrLaw); double Vol1 = FE.SetQvMeasRange(Rho, 1.0); double dQm = FE.DQmMeas(1.001); double Vol2 = FE.QvMeas(1.001); dPq1 = -FE.QmSign()*K*Pow(Vol1,PwrLaw); dPq2 = -FE.QmSign()*K*Pow(Vol2,PwrLaw); FE.SetDPq(dPq1, (dPq2 - dPq1)/dQm); } else { double NRho=Max(0.1, FE.MeanRho(pProps)*Norm_P/GTZ(FE.MeanPress())*FE.MeanTemp(pProps)/Norm_T); double K=fabs(OpDP)/Pow(fabs(OpNVol), PwrLaw); double NVol1 = FE.SetQvMeasRange(NRho, 1.0); double dQm = FE.DQmMeas(1.001); double NVol2 = FE.QvMeas(1.001); dPq1 = -FE.QmSign()*K*Pow(NVol1,PwrLaw); dPq2 = -FE.QmSign()*K*Pow(NVol2,PwrLaw); FE.SetDPq(dPq1, (dPq2 - dPq1)/dQm); } m_dDP=fabs(dPq1); FE.SetFunctOfPress(); return True; };
void VLL_Sep::EvalProducts() { Contents.ZeroDeriv(); QFeed().QZero(); SigmaQIn(QFeed(), 0xffffffff); double TQvIn=0.0; double QvIn=0.0; for (int i=0; i<NoFlwIOs(); i++) if (IO_In(i)) { QvIn=IOConduit(i)->QVolume(som_SL); TQvIn+=QvIn; } double TQvInX=QFeed().QVolume(som_SL); /* hss I have included a variable to define the % of water removed in the boot. Previously it was 100%, which Andre Vogel says is incorrect. The user now has the ability to set the efficiency at a lower value and hence allow some of the water to leave with the condensate. 20/01/97 12/01/2000 hss I have included MEG in the boot contents, as it is also removed from the system via the boot. */ SpMArray OutImg, BootImg; OutImg = Contents.MArray(); OutImg[Water()] -= H2oSettled; OutImg[MEG()] -= MEGSettled; SetProdMakeup(PMU_IOId | PMU_Image, VLLIO_out, OutImg, Contents.Temp(), Contents.Press(), Contents.Model()); // The Boot BootImg = Contents.MArray(); double LoBLFScl=1.0e-6; double BootLiqFrac=(BootImg[Water()]+BootImg[MEG()])/GTZ(BootImg.Mass(som_SL)); double BootLiqScl=1; // @BootLiqFrac==0 then this =1 double OthrLiqScl=Range(0.0, 0.0+2*(LoBLFScl-BootLiqFrac)/LoBLFScl, 1.0); for (i=0; i<SDB.No(); i++) if (SDB[i].IsVap()) BootImg[i] = 0; else if (i==Water() || i==MEG()) BootImg[i] *= BootLiqScl; else BootImg[i] *= OthrLiqScl; SetProdMakeup(PMU_IOId | PMU_Image, VLLIO_boot, BootImg, Contents.Temp(), Contents.Press(), Contents.Model()); /* OLD BootImg = Contents.MArray(); BootImg[Water()] = 0.0; BootImg[MEG()] = 0.0; SetProdMakeup(PMU_IOId | PMU_Blocking, VLLIO_boot, BootImg, Contents.Temp(), Contents.Press(), Contents.Model()); */ EvalProducts_SurgeLevel(ContentHgtOrd); }
double CEC_FinalConc::ExtentActual(double ProdMoles) { SpMArray NewMoles; NewMoles=RB.Moles; CR_EqnControl::ApplyChanges(ProdMoles, NewMoles); RB.AdjustForSrcSnks(NewMoles); double M=NewMoles[m_Spc.m_SpcId]; double MW=SDB[m_Spc.m_SpcId].MoleWt(); double V=RB.VolWithLockup(som_Liq, NewMoles, Valid(m_dRqdTemp)?m_dRqdTemp:RB.EstFinalT(), RB.m_Press); double C; if (m_Spc.m_ReactTerm>=0) { C=(M*MW)/GTZ(V); } else if (m_Spc.m_ProdTerm>=0) { C=(M*MW)/GTZ(V); } else C=0.0; if (0) { if (1) dbgp("FinalConc:Actual: Prod:%14.8g Act:%14.8f Rqd:%14.8f %10.4f %10.4f|", ProdMoles, C, ExtentReqd(), M, V); else dbgp("FinalConc:Actual: %14.8f %14.8f %10.4f %10.4f %10.4f %10.4f %10.4f %10.4f|", ProdMoles, C, ExtentReqd(), M, MW, V, Valid(m_dRqdTemp)?m_dRqdTemp:RB.EstFinalT(), RB.m_Press); for (int i=0; i<SVSpcCount();i++) if (RB.Moles[i]>0.0 || NewMoles[i]>0) dbgp(" %10.6f", RB.Moles[i]); dbgpln(""); if (1) dbgp(" %14s %14s %14s %10s %10s|", "", "", "", "", "", "", "", ""); else dbgp(" %14s %14s %10s %10s %10s %10s %10s %10s|", "", "", "", "", "", "", "", ""); for (int i=0; i<SVSpcCount();i++) if (RB.Moles[i]>0.0 || NewMoles[i]>0) dbgp(" %10.6f", NewMoles[i]); dbgpln(""); } return C; };
void MN_Xfer::DumpDerivs() { dbgpln("--Xfr %-12s", FullObjTag()); for (int i = 0; i < NoFlwIOs(); i++) if (IO_In(i)) dbgpln(" In >> :[%14.6g][%14.6g]|[%14.6g] %14.6g %14.3fC %s", IOConduit(i)->QMass(som_SL), IOConduit(i)->QMass(som_Gas) , IOConduit(i)->msHz(), IOConduit(i)->totHf()/GTZ(IOConduit(i)->QMass(som_ALL)), K2C(IOConduit(i)->Temp()), Nd_Rmt(i)->FullObjTag()); for (i = 0; i < NoFlwIOs(); i++) if (IO_Out(i)) dbgpln(" Out << :[%14.6g][%14.6g]|[%14.6g] %14.6g %14.3fC %s", IOConduit(i)->QMass(som_SL), IOConduit(i)->QMass(som_Gas) , IOConduit(i)->msHz(), IOConduit(i)->totHf()/GTZ(IOConduit(i)->QMass(som_ALL)), K2C(IOConduit(i)->Temp()), Nd_Rmt(i)->FullObjTag()); }
bool BatchPrecip::PrecipBatchSS(double dTime, MVector & Prod, double CurLevel) { MIBayer & ProdB = *Prod.GetIF<MIBayer>(); MIPSD & ProdSz = *Prod.FindIF<MIPSD>(); MISSA & ProdSSA = *Prod.FindIF<MISSA>(); double TProd = Prod.getT(); double gpl1 = ProdB.SolidsConc(TProd); double ProdVolFlow = Prod.Volume(MP_All); double SolidsInitial = Prod.Mass(MP_Sol); double Sx; if (!sm_bCompletePopulation && sm_bUsePrevPSD) { MISSA & PrevSSA=*m_QProd.FindIF<MISSA>();// this is the SSA of the last Popul run to use in "NO POpul mode" if (IsNothing(PrevSSA)) { m_bPrevPSDUsed = 0; Sx=ProdSSA.SpecificSurfaceAreaMass(); //m^2/g//PROBLEM!!! Prev does not have SSA, use feed } else { m_bPrevPSDUsed = 1; Sx=PrevSSA.SpecificSurfaceAreaMass(); //m^2/g } } else { m_bPrevPSDUsed = 0; Sx = m_dInTankSSA ; // the SSA value manually entered by the user in m^2/g } Sx=Range(0.020, Sx, 0.085); //=== mass balance === double T0 = Prod.T; double Ain2 = ProdB.AluminaConc(C2K(25.0)); double Cin2 = ProdB.CausticConc(C2K(25.0)); double ASat2 = ProdB.AluminaConcSat(T0); double SSat2 = (Ain2-ASat2)/GTZ(Cin2); double NoPerSec2 = ProdSSA.PartNumPerSec(); double enthIn = Prod.totCp(MP_All) * K2C(T0); // Enthalpie IN double PrecipRate1 = get_PrecipRate(Prod, Sx); gpl1 = gpl1 - PrecipRate1 * dTime*156/102 ; bool CErr; const double Na2OFac = get_Na2OFactor(Prod); PerformAluminaSolubility(Prod, dNAN, dNAN, gpl1, 0, Na2OFac, SSat2, CErr); double T1 = Prod.T; double SolidsVariation = (Prod.Mass(MP_Sol) - SolidsInitial); //* 0.97 ;// 0.97 is to compensate for the HYPROD error HeatBalance(Prod, SolidsVariation, enthIn, dTime, CurLevel); // Éliminé pour vérifier la temp ? return true; }
//------------------------------------------------------------------------ // Check for convergence of the iteration // // //------------------------------------------------------------------------ bool CPrecipitator::ConvergenceTest() { double xmag = (x[0]*x[0]+x[1]*x[1]+x[2]*x[2]); double err = (Sqr(x[0]-xo[0]) + Sqr(x[1]-xo[1]) +Sqr(x[2]-xo[2]))/GTZ(xmag); if (err < m_dConvergenceLimit) return true; else return false; }
void CLimnStream::ConvertToFracForm(MVector & M, bool ApplyScale) { if (!m_bIsMassForm) return; if (DoDbgCvt) Dump("ConvertToFracForm:Before", DoDbgCvt); MArrayI Tot; // Current Total for (int ii=0; ii<gs_DWCfg.m_SeqIndex.GetCount(); ii++) { int i=gs_DWCfg.m_SeqIndex[ii]; Tot[gs_DWCfg.m_SpIds[i]] += m_Data[i]; }; if (ApplyScale) { for (int id=0; id<gs_MVDefn.Count(); id++) { M.M[id]=Tot[id]/gs_DWCfg.m_MassFactor[id]; Tot[id]=GTZ(Tot[id]); } M.MarkStateChanged(); } else { for (int id=0; id<gs_MVDefn.Count(); id++) { M.M[id]=Tot[id]; Tot[id]=GTZ(Tot[id]); } M.MarkStateChanged(); } for (int ii=0; ii<gs_DWCfg.m_SeqIndex.GetCount(); ii++) { int i = gs_DWCfg.m_SeqIndex[ii]; m_Data[i] = m_Data[i]/Tot[gs_DWCfg.m_SpIds[i]]; }; m_bIsMassForm = false; if (DoDbgCvt) Dump("ConvertToFracForm:After", DoDbgCvt); };
void CSzSSA::SetSAMFromPartDiam(double D) { //dbgpln("SSA:%4d(%d) SetSAMFromPartDiam(%g)", ID, m_bAllowSet, D); if (D>1.0e-12) { double Dens=SolidsDens(); m_dSAM=3.0/GTZ(500.*Dens*D); } else m_dSAM=0.0; };
flag CODESolver::StepSizeOK_2() { if (m_ErrMax <= 1.0) { if (m_ErrMax < GrowLimit) { // rIC.m_TimeIncNext = rIC.m_TimeInc*Grow; // rIC.m_TimeIncNext = rIC.m_TimeInc*Grow *Min(1.0+0.25*log(GrowLimit/GTZ(ErrMax)), 2.0); // rIC.m_TimeIncNext = rIC.m_TimeInc*Grow*Min(1.0+0.10*log(GrowLimit/GTZ(ErrMax)), 2.0); rIC.m_TimeIncNext = rIC.m_TimeInc*(1.0+0.10*log(GrowLimit/GTZ(m_ErrMax))); rIC.m_TimeIncNext = Min(rIC.m_TimeIncNext, Min(rIC.m_TimeInc*2.0, rIC.m_TimeIncMx)); #if dbgODESolve if (dbgStepsNext()) dbgpln("NextStep:Grow Err:%11.5g dT:%8.5f > %8.5f",m_ErrMax,rIC.m_TimeInc,rIC.m_TimeIncNext); #endif } else if (m_ErrMax > OKShrinkLimit) { // rIC.m_TimeIncNext = rIC.m_TimeInc*OKShrink; rIC.m_TimeIncNext = rIC.m_TimeInc*(1.0+(1.0-OKShrink)*(m_ErrMax - OKShrinkLimit)/(1.0 - OKShrinkLimit)); #if dbgODESolve if (dbgStepsNext()) dbgpln("NextStep:Shrink Err:%11.5g dT:%8.5f < %8.5f",m_ErrMax,rIC.m_TimeInc,rIC.m_TimeIncNext); #endif } else { rIC.m_TimeIncNext = rIC.m_TimeInc; #if dbgODESolve if (dbgStepsNext()) dbgpln("NextStep:Hold Err:%11.5g dT: %8.5f",m_ErrMax,rIC.m_TimeInc); #endif } CODEDataBlock ODB(this); ODB.Set(eStateAdvance, -1, CODEDataBlock::Correct2, pODEBase); return 1; } double ndt = rIC.m_TimeInc*BADShrink /(1.0+Min(0.25*log(m_ErrMax), 1.0)); #if dbgODESolve if (dbgStepsNext()) dbgpln("NextStep:Redo Err:%11.5g dT:%8.5f @ %8.5f",m_ErrMax,rIC.m_TimeInc,ndt); #endif rIC.m_TimeIncRestart = ndt; fStepSizeTooSmall = (rIC.m_TimeInc < rIC.m_TimeIncMn);//MINSTEPSIZE); return 0; }
double CEC_MLFinalFrac::ExtentActual(double ProdMoles) { SpMArray NewMoles; NewMoles=RB.Moles; CR_EqnControl::ApplyChanges(ProdMoles, NewMoles); RB.AdjustForSrcSnks(NewMoles); double F; if (m_Spc.m_ReactTerm>=0 || m_Spc.m_ProdTerm>=0) F=(NewMoles[m_Spc.m_SpcId])/GTZ(NewMoles.Mass(m_AsTotal ? som_ALL : SDB[m_Spc.m_SpcId].m_OccMsk)); else F=0.0; if (0) dbgpln("FinalPhaseFrac:Actual: %14.8f %14.8f |", ProdMoles, F, ExtentReqd()); return F; };
void CSeperator_EfficiencyCurve::CalculateEfficiencyCurve( MIPSD &in_PSD , double in_D50 , double in_Alpha, double in_Beta, double in_C, double &inout_BetaStar, CArray <double, double&> &out_Eu ) { long l_SizeCount = in_PSD.getSizeCount(); long l_PSDVectorCount = in_PSD.getPSDVectorCount(); // // Calculate BetaStar // inout_BetaStar = CalcBetaStar(in_Alpha, in_Beta ); // // Build probability passing from specified d50, Alpha parameters and PSD size // interval data // out_Eu.SetSize(l_SizeCount); for( int lSzIndex=0; lSzIndex < l_SizeCount; lSzIndex++ ) { const double NominalSize = in_PSD.getDefn().getGeometricMean(lSzIndex); //use geometrical mean const double d = in_Alpha*inout_BetaStar*NominalSize/in_D50; if (d>230.0)//limit of exp() out_Eu[lSzIndex] = 1.0; else { //out_Eu[lSzIndex] = (exp(d)-1.0) / (exp(d) + exp(in_Alpha) - 2.0); //out_Eu[lSzIndex] = 1.0 - in_C*(exp(in_Alpha)-1.0) / (exp(d) + exp(in_Alpha) - 2.0); double num = (1.0+in_Beta*inout_BetaStar*NominalSize/in_D50)*(exp(in_Alpha)-1.0 ); double den = exp(d) + exp(in_Alpha) - 2.0; out_Eu[lSzIndex] = 1.0 - in_C*num/GTZ(den); if (out_Eu[lSzIndex]>1.0) out_Eu[lSzIndex] = 1.0; if (out_Eu[lSzIndex]<0.0) out_Eu[lSzIndex] = 0.0; } } //out_Eu[0] = 0.0; }
//==================================================================================== // Actions bool Splitter::GetModelAction(CMdlActionArray & Acts) { int IOCnt = FlwIOs.getCount(); if (IOCnt==3) { Acts.SetSize(0); Acts.Add(CMdlAction(0, MAT_State, true, "Mass Split", 0)); Acts.Add(CMdlAction(1, MAT_State, true, "Phase Split", 1)); if (!bDoPhaseSplit) { double M1=FlwIOs[1].Stream.MassFlow(); double M2=FlwIOs[2].Stream.MassFlow(); double Split=(M1)/GTZ(M1+M2); Acts.Add(CMdlAction(2, MAT_Value, !bDoPhaseSplit, "Split (%)", true, dRqdFracSplit*100, 0.0, 100.0, Split*100)); } return true; } return false; };
void CLimnStream::AddDiscrete(MVector &V2, MSpQualityBase * pQual2, double Sgn_, double DeltaTime) { CLimnStream * pQ2=dynamic_cast<CLimnStream*>(pQual2); if (Sgn_>0.0) { MVector M1=Vector; // MArrayI m1; MArrayI m2; for (int id=0; id<gs_MVDefn.Count(); id++) { m1[id] = M1.M[id]; m2[id] = V2.M[id]*DeltaTime; } for (int ii=0; ii<gs_DWCfg.m_SeqIndex.GetCount(); ii++) { int i = gs_DWCfg.m_SeqIndex[ii]; int id = gs_DWCfg.m_SpIds[i]; m_Data[i] = (m_Data[i]*m1[id] + pQ2->m_Data[i]*m2[id])/(GTZ(m1[id]+m2[id])); }; } };
void CLimnStream::AddMassF(MSpQualityBase * QualAdd, MArray & MAdd) { ASSERT_ALWAYS(!m_bIsMassForm, "Mass Format not Expected", __FILE__, __LINE__); CLimnStream * pQualAdd=dynamic_cast<CLimnStream*>(QualAdd); // These numbers are always Fractional MVector M1=Vector; // MArrayI MFrac1; for (int id=0; id<gs_MVDefn.Count(); id++) MFrac1[id] = M1.M[id]/GTZ(M1.M[id]+MAdd[id]); for (int ii=0; ii<gs_DWCfg.m_SeqIndex.GetCount(); ii++) { int i = gs_DWCfg.m_SeqIndex[ii]; int id = gs_DWCfg.m_SpIds[i]; m_Data[i] = m_Data[i]*MFrac1[id] + pQualAdd->m_Data[i]*(1.0-MFrac1[id]); }; if (DoDbg) Dump("AddMassF", 0x7); };
double CDArray::LinearInterpolate(double XValue, CDArray & X, flag Extrapolate) { const long len = GetSize(); double * Y=m_pData; switch (len) { case 0 : return 0.0; case 1 : return Y[0]; default : { for (long i=0; (i<len-2) && (XValue>=X[i+1]); i++) { }; int xx=0; if (!Extrapolate) XValue=Range(X[0], XValue, X[len-1]); return Y[i]+(Y[i+1] - Y[i]) * (XValue - X[i]) / GTZ(X[i+1] - X[i]); } } return 0.0; };
CCWashMixEffFnd::CCWashMixEffFnd ( SpConduit &Qm_, SpConduit &Qw_, SpConduit &Qu_, SpConduit &Qo_, SpConduit &Qt_, double RqdMixEff_, byte SA_, double POut_): MRootFinderBase("CCWasher2", s_Tol),//1.0e-8), Qm(Qm_), Qw(Qw_), Qu(Qu_), Qo(Qo_), Qt(Qt_) { RqdMixEff = RqdMixEff_; SA = SA_; POut = POut_; QmLiq = Qm.QMass(som_Liq); QwLiq = Qw.QMass(som_Liq); Qt.QSetF(Qm, som_ALL, 1.0, Std_P); Qt.QAddF(Qw, som_ALL, 1.0); //limit is where 100% of mud liq reports to uf... const double xlim = (RqdMixEff*(QmLiq/GTZ(QwLiq) + 1.0) - 1.0) / NZ(RqdMixEff - 1.0); LoLimit = Range(0.0, xlim, 0.99999); FT = Qt.Temp(); HTot = Qm.totHf()+Qw.totHf(); }
//========================================================================== // never checked mhm double DewPt(rSpContainer Contents, rSpConduit Qi, double P) { // Y0 lb/MMscf // OpPres kPa abs // IF (OpPres > RZero) AND (Y0 > RZero) THEN // IF ((27.248 - 0.8446 * LN (OpPres) - LN (Y0)) <> RZero) THEN // GasOutletDP := (5214.4 - 38.34 * LN (OpPres)) / // (27.248 - 0.8446 * LN (OpPres) - LN (Y0)); double VolFlw=Qi.QMass(som_ALL)*Qi.NRho(som_Vap);//44Qi); // m^3/s double H2oMassFlw=Qi.Qm(Water())+Qi.Qm(Steam()); // kg/s double Y0=kg_2_lb(H2oMassFlw)/GTZ(Nm3_2_MMscf(VolFlw)); if ((P > 1.0) && (Y0 > 1.0e-10)) { double Den= 27.248 - 0.8446 * log(P) - log(Y0); if (fabs(Den) > 1.0e-10) return (5214.4 - 38.34 * log(P)) / Den; } return dNAN(); }
bool CTrompCurve::OperateModelGraphic(CMdlGraphicWnd & Wnd, CMdlGraphic & Grf) { const COLORREF White = COLORREF(RGB(255,255,255)); const COLORREF Black = COLORREF(RGB(0,0,0)); const COLORREF Blue = COLORREF(RGB(0,0,255)); const COLORREF Cyan = COLORREF(RGB(0,255,255)); const COLORREF Red = COLORREF(RGB(255,0,0)); const COLORREF Green = COLORREF(RGB(0,255,0)); switch (Wnd.m_eTask) { case MGT_Create: break; case MGT_Size: break; case MGT_Move: break; case MGT_EraseBkgnd: // Use Wnd.m_pDC; Wnd.m_bReturn = 0;// 1 if erased else 0 break; case MGT_Paint: { double Total=0; int IOCnt = FlwIOs.getCount(); if (IOCnt==3) { double M1=FlwIOs[1].Stream.MassFlow(); double M2=FlwIOs[2].Stream.MassFlow(); double Split=(M1)/GTZ(M1+M2); int charwide = Wnd.m_TextSize.x; int y0 = Wnd.m_ClientRect.top; int y1 = Wnd.m_TextSize.y+1; int y2 = Wnd.m_ClientRect.bottom; int x0 = Wnd.m_ClientRect.left; int xSplit = (int)(Split*Wnd.m_ClientRect.right); int x2 = Wnd.m_ClientRect.right; int y3 = 0; if (1)//!bDoPhaseSplit) { y3=y1; y1+=Wnd.m_TextSize.y; } Wnd.m_pPaintDC->FillSolidRect(CRect(x0,y1,xSplit,y2), Blue); Wnd.m_pPaintDC->FillSolidRect(CRect(xSplit,y1,x2,y2), Cyan); Wnd.m_pPaintDC->FillSolidRect(CRect(x0,y0,x2,y1), Black); Wnd.m_pPaintDC->SetTextColor(Green); CString S; //if (/*!bDoPhaseSplit &&*/ fabs(Split-dRqdFracSplit)>0.001) // S.Format("%.1f %% (Rqd:%.1f %%)", Split*100.0, dRqdFracSplit*100.0); //else S.Format("%.1f %%", Split*100.0); Wnd.m_pPaintDC->TextOut(x0,y0,S); //if (!bDoPhaseSplit) // { // CPen penWhite(PS_SOLID, 0, White); // CPen * oldPen=Wnd.m_pPaintDC->SelectObject(&penWhite); // CBrush brushRed(Red); // CBrush * oldBrush=Wnd.m_pPaintDC->SelectObject(&brushRed); // int xSplitRqd = (int)(dRqdFracSplit*Wnd.m_ClientRect.right); // POINT Arrow[] = // { // {xSplitRqd, y1}, // {xSplitRqd-charwide/2, y3}, // {xSplitRqd+charwide/2, y3}, // {xSplitRqd, y1}, // }; // Wnd.m_pPaintDC->Polygon(Arrow, sizeof(Arrow)/sizeof(Arrow[0])); // Wnd.m_pPaintDC->SelectObject(oldPen); // Wnd.m_pPaintDC->SelectObject(oldBrush); // } } else { int y0 = Wnd.m_ClientRect.top; int y2 = Wnd.m_ClientRect.bottom; int x0 = Wnd.m_ClientRect.left; int x2 = Wnd.m_ClientRect.right; Wnd.m_pPaintDC->FillSolidRect(CRect(x0,y0,x2,y2), Black); Wnd.m_pPaintDC->SetTextColor(Green); CString S; S.Format("Not Connected"); Wnd.m_pPaintDC->TextOut(x0,y0,S); } break; } case MGT_MouseMove: m_LBtnDn=(Wnd.m_MouseFlags & MK_LBUTTON); //if (m_LBtnDn && !bDoPhaseSplit) // { // m_MousePt=Wnd.m_MousePt; // dRqdFracSplit = (double)m_MousePt.x/Wnd.m_ClientRect.right; // Wnd.m_pWnd->RedrawWindow(0, 0, RDW_INVALIDATE|RDW_UPDATENOW); // } break; case MGT_LButtonDown: m_LBtnDn=true; //if (!bDoPhaseSplit) // { // m_MousePt=Wnd.m_MousePt; // dRqdFracSplit = (double)m_MousePt.x/Wnd.m_ClientRect.right; // Wnd.m_pWnd->RedrawWindow(0, 0, RDW_INVALIDATE|RDW_UPDATENOW); // } break; case MGT_LButtonUp: m_LBtnDn=false; break; case MGT_RButtonDown: m_RBtnDn=true; break; case MGT_RButtonUp: m_RBtnDn=false; break; } return true; };
void CActuatorBlk::ExecIns(double dT) { // double temp_rvalue, target_value, min_p, max_f, period, dt, max_time // double frequency_tolerance double Value; Value = m_dReqdValue; // switch (m_Flt.m_iType) // { // case Flt_FirstOrder: // Value = tx_First_Order_Filter (m_Flt.m_dPrevValue, Range((double)m_dMinValue, Value, (double)m_dMaxValue), m_Flt.m_dTau, dT); // break; // default:; // } // if ((m_Fail.m_iType & Fail_Type)!=0) m_Fail.m_dPrevValue=Value; switch (m_Fail.m_iType & Fail_Type) { case Fail_MinVal: Value = m_dMinValue; break; case Fail_MaxVal: Value = m_dMaxValue; break; case Fail_LoVal: Value = m_Fail.m_dLoValue; break; case Fail_HiVal: Value = m_Fail.m_dHiValue; break; case Fail_Hold: Value = m_Fail.m_dPrevValue; break; } if (m_Fail.m_iType & Fail_Ramp) { double MaxChg=(m_dMaxValue-m_dMinValue)*dT/GTZ(m_Fail.m_dSlewTime); Value = m_dValue + Range(-MaxChg, Value-m_dValue, MaxChg); Value = Range((double)m_dMinValue, Value, (double)m_dMaxValue); } switch (m_Xform.m_iType) { case XF_Linear: Value = (Value - m_Xform.m_dBias)/m_Xform.m_dFactor; break; case XF_Sqr: Value=Value*Value; Value = (Value - m_Xform.m_dBias)/m_Xform.m_dFactor; break; case XF_Sqrt: Value=Sqrt(GEZ(Value)); Value = (Value - m_Xform.m_dBias)/m_Xform.m_dFactor; break; default:; } m_dOutputValue = Value; // calculate switches m_bLo=(m_dOutputValue <= m_dLoLimit); m_bHi=(m_dOutputValue >= m_dHiLimit); if (m_bLoInvert) m_bLo=!m_bLo; if (m_bHiInvert) m_bHi=!m_bHi; // // calculate raw value // switch (m_RawXform.m_iType) // { // case XL_Linear: // m_dOutputValue = tx_Bounded_Linear_Interpolate (m_dValue, m_dMinValue, m_RawXform.m_dMinValue, // m_dMaxValue, m_RawXform.m_dMaxValue, // m_RawXform.m_dMinValue, m_RawXform.m_dMaxValue); // break; // case XL_AtoD: // m_dOutputValue = tx_Bounded_Linear_Interpolate (m_dValue, m_dMinValue, m_RawXform.m_dMinValue, // m_dMaxValue, m_RawXform.m_dMaxValue, // m_RawXform.m_dMinValue, m_RawXform.m_dMaxValue); // m_dOutputValue = Range((long)m_RawXform.m_dMinValue, (long)m_dOutputValue, (long)m_RawXform.m_dMaxValue); // break; // case XL_PulseEncode: // /* // if (maximum_frequency > 0) // dt = DeltaTime() // frequency_tolerance = 1e-10 // min_p = 2*dt // max_f = 1 / min_p // minimum_frequency = max(minimum_frequency,0) // maximum_frequency = min(maximum_frequency, max_f) // frequency = tx_Bounded_Linear_Interpolate (value, minimum_value, minimum_frequency, // maximum_value, maximum_frequency, // minimum_frequency, maximum_frequency) // if (frequency < frequency_tolerance) // frequency = 0 // endif // if (frequency > 0) // period = 1 / frequency // max_time = period / 2 // timer = timer + dt // if (timer >= max_time) // timer = 0 // pulse = not(pulse) // endif // else // timer = 0 // pulse = 0 // endif // else // pulse = 0 // endif // pulse_inverse = not(pulse) // */ // m_dOutputValue = m_dValue; // break; // default: // m_dOutputValue = m_dValue; // }; }
STDMETHODIMP CScdSpVector::get_Concentration(long SpecieIndex, long Phases, VARIANT TdK, VARIANT PkPa, double *pVal) { dllSCD_COMENTRYGET(long, pVal) { *pVal=m_pOwn->Model()->m_M[SpecieIndex]/GTZ(m_pOwn->Model()->Volume(Phases,TFromT(TdK),PFromP(PkPa))); }
double CPSDTestData::TestDataPercentPassingRR(double x) { long NPass; double xmax = 0.0; double xmin = 0.0; double logx1 = 0.0; double logx2 = 0.0; double logx = 0.0; double loglogy1 = 0.0; double loglogy2 = 0.0; Sort(); if ( x <= 0.0 ) return(0.0); if (m_eTestDataType == eTest_WeightPercent ) { // Data has been entered as Weight Percent (Size Fractions) // Make sure data has been converted to percent passing WeightToPassing(); NPass = m_lNTestData-1; } else { // Data is entered as % Passing NPass = m_lNTestData; } // Intervals are smallest to largest // Code assumes xi > xi+1 // Need to add code that makes sure data is sorted as such for (int i = 0 ; i < (NPass-1) ; i++ ) { double x1 = m_Size_Wt_Passing[i]; double x2 = m_Size_Wt_Passing[i + 1]; double y1 = m_Wt_Passing[i]*100.0; double y2 = m_Wt_Passing[i + 1]*100.0; if (x1 <= 0.0) x1 = 0.00000001; if (x2 <= 0.0) x2 = 0.00000001; if (y1 >= 99.999999) y1 = 99.999999; if (y2 >= 99.999999) y2 = 99.999999; if (y1 <= 0.000001) y1 = 0.000001; if (y2 <= 0.000001) y2 = 0.000001; // Record min and max data xmax = max(xmax,x1); xmax = max(xmax,x2); xmin = min(xmin,x1); xmin = min(xmin,x2); if (x1 == x) { // Exactly equal to existing size return(y1/100.0); } else if ( //(((x1 > x) && (x2 < x))) (((x1 <= x) && (x2 >= x))) ) { // Located between two existing sizes // Construct RR interpolation (x1-x2) -> PassingData if (y1 == y2) { return(y1/100.0); } else { logx1 = log(x1); logx = log(x); logx2 = log(x2); loglogy1 = log(-log(y1 / 100)); loglogy2 = log(-log(y2 / 100)); double slope = (loglogy2 - loglogy1) / GTZ(logx2 - logx1); double y = loglogy1 + (logx - logx1) * slope; double passing = 100 * exp(-exp(y)); return(passing/100.0); } } else { ; } } // Outside of test data range if (x >= xmax) { // Size is greater than largest size in sample data // Interpolate from last two know largest points double x1 = m_Size_Wt_Passing[NPass-2]; double x2 = m_Size_Wt_Passing[NPass-1]; double y1 = m_Wt_Passing[NPass-2]*100.0; double y2 = m_Wt_Passing[NPass-1]*100.0; if (x1 <= 0.0) x1 = 0.00000001; if (x2 <= 0.0) x2 = 0.00000001; if (y1 >= 99.999999) y1 = 99.999999; if (y2 >= 99.999999) y2 = 99.999999; if (y1 <= 0.000001) y1 = 0.000001; if (y2 <= 0.000001) y2 = 0.000001; logx1 = log(x1); logx = log(x); logx2 = log(x2); loglogy1 = log(-log(y1 / 100)); loglogy2 = log(-log(y2 / 100)); double slope = (loglogy2 - loglogy1) / GTZ(logx2 - logx1); double y = loglogy1 + (logx - logx1) * slope; double passing = 100 * exp(-exp(y)); if (passing > 100.0) passing = 100.0; return(passing/100.0); //return(1.0); } else { // Size is smaller than smallest size in sample data // Interpolate from smallest two points double x1 = m_Size_Wt_Passing[0]; double x2 = m_Size_Wt_Passing[1]; double y1 = m_Wt_Passing[0]*100.0; double y2 = m_Wt_Passing[1]*100.0; if (x1 <= 0.0) x1 = 0.00000001; if (x2 <= 0.0) x2 = 0.00000001; if (y1 >= 99.999999) y1 = 99.999999; if (y2 >= 99.999999) y2 = 99.999999; if (y1 <= 0.000001) y1 = 0.000001; if (y2 <= 0.000001) y2 = 0.000001; logx1 = log(x1); logx = log(x); logx2 = log(x2); loglogy1 = log(-log(y1 / 100)); loglogy2 = log(-log(y2 / 100)); double slope = (loglogy2 - loglogy1) / GTZ(logx2 - logx1); double y = loglogy1 + (logx - logx1) * slope; double passing = 100 * exp(-exp(y)); if (passing < 0.0) passing = 0.0; return(passing/100.0); //return(0.0); } }
flag BeltCnv::DataXchg(DataChangeBlk & DCB) { if (MdlNode::DataXchg(DCB)) return 1; if (m_BeltSB.DataXchg(DCB)) return 1; if (m_Pwr.DataXchg(DCB)) return 1; switch (DCB.lHandle) { case xidBeltLength: if (DCB.rD) m_Q.SetLength(*DCB.rD); DCB.D=m_Q.Length(); return 1; case xidBeltSpeed: DCB.D=m_MaxVelocity*Range(-1.0, m_BeltSB.Speed(this), 1.0); return 1; case xidTotSpilt: if (DCB.rD) { double Scl=*DCB.rD/GTZ(m_Q.TotalSpiltMass()); m_Q.SetTotalSpilt(*DCB.rD, Scl*m_Q.TotalSpiltHf(), Scl*m_Q.TotalSpiltHs(), Scl*m_Q.TotalSpiltHz()); } DCB.D=m_Q.TotalSpiltMass(); return 1; case xidTotVented: if (DCB.rD) { double Scl=*DCB.rD/GTZ(m_Q.TotalVentedMass()); m_Q.SetTotalVented(*DCB.rD, Scl*m_Q.TotalVentedHf(), Scl*m_Q.TotalVentedHs(), Scl*m_Q.TotalVentedHz()); } DCB.D=m_Q.TotalVentedMass(); return 1; case xidNWtMtrs: if (DCB.rL) { m_WtMtrPos.SetSize(*DCB.rL); StructureChanged(this); } DCB.L=m_WtMtrPos.GetSize(); return 1; case xidShowProf: if (DCB.rB) { m_fShowProfile=*DCB.rB; if (m_fShowProfile) m_Q.SetShowProfileType(m_ProfDispType); else m_Q.SetShowProfileType(QPT_None); StructureChanged(this); } DCB.B=m_fShowProfile; return 1; case xidProfDispType: if (DCB.rL) { m_ProfDispType=*DCB.rL; if (m_fShowProfile) { m_Q.SetShowProfileType(m_ProfDispType); if (m_ProfDispType==QPT_FixedPts) m_Q.SetProfileLen(m_ProfPts); StructureChanged(this); } } DCB.L=m_ProfDispType; return 1; case xidProfPts: if (DCB.rL) { m_ProfPts = Range(0L, *DCB.rL, 124L); m_Q.SetProfileLen(m_ProfPts); StructureChanged(this); } DCB.L=m_ProfPts; return 1; case xidNSections: DCB.L=m_Q.NSections(); return 1; case xidTotalMass: DCB.D=m_Q.TotalMass(); return 1; case xidAvgLoading: DCB.D=m_Q.AverageLoading(); return 1; default: { int i=DCB.lHandle-xidFeedPos0; if (i>=0 && i<m_Q.NFeeds()) { if (DCB.rD) m_Q.m_Feed[i].SetPosition(*DCB.rD); DCB.D=m_Q.m_Feed[i].Position(); return 1; } i=DCB.lHandle-xidFeedQm0; if (i>=0 && i<m_Q.NFeeds()) { DCB.D=m_Q.m_Feed[i].QmAct(); return 1; } i=DCB.lHandle-xidFeedLimited0; if (i>=0 && i<m_Q.NFeeds()) { if (DCB.rB) m_Q.m_Feed[i].SetFeedLimited(*DCB.rB); DCB.B=m_Q.m_Feed[i].FeedLimited(); return 1; } i=DCB.lHandle-xidFeedCapFrac0; if (i>=0 && i<m_Q.NFeeds()) { if (DCB.rD) m_Q.m_Feed[i].SetFeedCapFrac(*DCB.rD); DCB.D=m_Q.m_Feed[i].FeedCapFrac(); return 1; } i=DCB.lHandle-xidProdPos0; if (i>=0 && i<m_Q.NProds()) { if (DCB.rD) m_Q.m_Prod[i].SetPosition(*DCB.rD); DCB.D=m_Q.m_Prod[i].Position(); return 1; } i=DCB.lHandle-xidProdRemove0; if (i>=0 && i<m_Q.NProds()) { if (DCB.rD) m_Q.m_Prod[i].SetRemoval(*DCB.rD); DCB.D=m_Q.m_Prod[i].Removal(); return 1; } i=DCB.lHandle-xidProdQm0; if (i>=0 && i<m_Q.NProds()) { DCB.D=m_Q.m_Prod[i].QmAct(); return 1; } i=DCB.lHandle-xidProdLoss0; if (i>=0 && i<m_Q.NProds()) { DCB.D=m_Q.m_Prod[i].Loss(); return 1; } i=DCB.lHandle-xidWtrMtrPos0; if (i>=0 && i<m_WtMtrPos.GetSize()) { if (DCB.rD) m_WtMtrPos[i]=*DCB.rD; DCB.D=m_WtMtrPos[i]; return 1; } i=DCB.lHandle-xidWtrMtrLd0; if (i>=0 && i<m_WtMtrPos.GetSize()) { DCB.D=m_Q.Loading(m_WtMtrPos[i]); return 1; } i=DCB.lHandle-xidWtrMtrRate0; if (i>=0 && i<m_WtMtrPos.GetSize()) { DCB.D=m_Q.Loading(m_WtMtrPos[i])*m_MaxVelocity*Range(-1.0, m_BeltSB.Speed(this), 1.0); return 1; } } } return 0; }