示例#1
0
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;
    }
  }
示例#2
0
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);
    }
  
  };
示例#3
0
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;
  }
示例#4
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);
  }
示例#5
0
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));
    }
  };
示例#6
0
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);
  }
示例#7
0
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;
}
示例#8
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);
    }

  };
示例#9
0
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;
  };
示例#10
0
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);

  }
示例#11
0
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;
  };
示例#12
0
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());
  }
示例#13
0
  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;
  }
示例#14
0
//------------------------------------------------------------------------
//  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;
}
示例#15
0
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);
  };
示例#16
0
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;
  };
示例#17
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;
  }
示例#18
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;
  };
示例#19
0
	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;

	}
示例#20
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;
  };
示例#21
0
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]));
      };
    }
  };
示例#22
0
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);
  };
示例#23
0
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;
};
示例#24
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();
  }
示例#25
0
//==========================================================================
// 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();
  }
示例#26
0
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;
  };
示例#27
0
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;
//    };
  }
示例#28
0
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)));
    }
示例#29
0
文件: PSD.cpp 项目: abcweizhuo/Test3
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);
  }
}
示例#30
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;
  }