Exemplo n.º 1
0
void CEC_FinalConc::BuildDataDefn(DataDefnBlk & DDB)
  {
  Strng T;
  T.Set("Final Conc %s", m_Spc.m_Name());

  DDB.Text  (T());
  DDEF_Flags VFlags=DDB.GetVisibility();
  DDB.String("ExtentType",        "",        DC_,     "",      xid_RCTExtentType,          &Eq, SetOnChange|isParm, DDBExtentTypes);
  DDB.SetVisibility(VFlags);

  if (m_Spc.m_ReactTerm>=0 || m_Spc.m_ProdTerm>=0)
    {
    CCnvIndex dc;
    pchar pCnvTxt;
    SDB.AddSpCnv(DC_Conc, SDB[m_Spc.m_SpcId].SymOrTag(), "g/L", dc, pCnvTxt);
    Strng S,C("Rct"),R("Reqd");
    if (Valid(m_dRqdTemp))
      S.Set("@%.2f", K2C(m_dRqdTemp));
    else
      S="@FinalT";
    C+=S;
    R+=S;
    m_ddRqdConc.BuildDataDefn(DDB, "Conc_Rqd", "", dc, pCnvTxt, xid_RCTExtent, &Eq, C(), R());
    DDB.Double("Conc_MeasTemp",    "",          DC_T,     "C",  xid_RCTFinalConcT,  &Eq, isResult|noFile|noSnap|InitHidden);
    DDB.Double("Conc_EOStep",      "Conc_Act",  DC_,      "",   &m_dKEOStep,             &Eq, isResult);
    DDB.TagComment(S());
    DDB.Double("Conc_Final",       "",          DC_,      "",   &m_dKFinal,              &Eq, isResult|NAN_OK);
    DDB.TagComment(S());
    DDB.Double("ExtentError",      "",          DC_Frac,  "%",  xid_ExtentError, &Eq, isResult|noFile|noSnap|NAN_OK);
    }
  };
Exemplo n.º 2
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());
  }
Exemplo n.º 3
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;
  }
Exemplo n.º 4
0
double AirEnth(double T)
  {
  ASSERT_RDB(K2C(T)>-106.666666666666 && K2C(T)<70.0000001, "Temperature range problem!", __FILE__, __LINE__);
  const double Tc = Range(-106.666666666667, K2C(T), 70.0);
  if (Tc<-45.5555555555557)
    return 1.0086*Tc + 18.092; //y = 1.0086x + 18.092
  if (Tc<-23.3333333333334)
    return 0.0026*Tc*Tc + 1.2353*Tc + 23.016; //y = 0.0026x2 + 1.2353x + 23.016
  if (Tc<-12.2222222222223)
    return 0.0082*Tc*Tc + 1.4875*Tc + 25.788; //y = 0.0082x2 + 1.4875x + 25.788
  if (Tc<0.0000000001)
    return 0.0199*Tc*Tc + 1.7523*Tc + 27.309; //y = 0.0199x2 + 1.7523x + 27.309
  if (Tc<12.2222222222223)
    return exp(-0.0005*Tc*Tc + 0.0599*Tc + 3.3099); //y = exp(-0.0005x2 + 0.0599x + 3.3099)
  if (Tc<30.0000000001)
    return exp(-8E-05*Tc*Tc + 0.0487*Tc + 3.3802); //y = exp(-8E-05x2 + 0.0487x + 3.3802)
  if (Tc<50.0000001)
    return exp(-1.51312249 + 0.0000769787611*(Tc+255.676741)*(Tc+255.676741)); //y = exp(-1.51312249 + 0.0000769787611*(x+255.676741)^2)
  //if (Tc<70.0000001)
    return exp(3.30966428 + 0.00023039444*(Tc+51.4242508)*(Tc+51.4242508)); //y = exp(3.30966428 + 0.00023039444*(x+51.4242508)^2)
  }
Exemplo n.º 5
0
void CPrecipitator::AdjustT(MStream &Prod) 
{
  MVDouble EvapWater (Evap, spWaterVapor);
  EvapWater = x[3];
  double dHeatIn = Feed.totHz();
  dReactionHeat = x[iALUMINA]*GibbsiteHOR(K2C(Prod.T));
  double newTotDH = m_dOldTotDH*m_dDamping+(m_dTotThermalLoss-dReactionHeat)*(1-m_dDamping);
  if (iThermalLossMethod==THL_TempDrop) {  // Override all other heat loss calcs
    Prod.T = Feed.T - dTempDropRqd;
  } else {
    Prod.Set_totHz(dHeatIn - newTotDH);
  }
  
  m_dOldTotDH = newTotDH;
}
Exemplo n.º 6
0
void CEC_FinalConc::Parse(CRCTTokenFile &TF)
  {
  Clear();
  ParseExtent(TF);
  m_Spc.m_Name=TF.NextToken();
  TF.CheckToken("=");
  m_ddRqdConc.SetVal(GEZ(TF.DoubleToken()), &Eq);
  m_iFReactTerm=-1;
  m_iFProdTerm=-1;
  if (TF.TokenIs("At"))
    {
    m_dRqdTemp=GEZ(C2K(TF.DoubleToken()));
    if (TF.TokenIs("K"))
      m_dRqdTemp=K2C(m_dRqdTemp);
    }
  //ParseDynamic(TF);
  };
int degree_k2c(u16 k) {
	return (K2C(k));
}
Exemplo n.º 8
0
bool BatchPrecip::PrecipBatch(double dTime, MVector & Prod, double CurLevel, bool AgglomON )
  {
  long m;
  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 ProdSSurf, ProdNNtl;

  //adjusting the PSD from 1 gpl to real conc....
  for (m=0; m<NIntervals; m++)
    ProdHyPsd[m]= gpl1 * ProdHyPsd[m];

  #if ForceOptimizeOff
  for (m=0; m<NIntervals; m++)
    if (ProdHyPsd[m]<0.0)
      SetStopRequired("Phone Denis, negative PSD!");
  #endif
  CalcSSurgNNtl(SizeClass, ProdHyPsd, NIntervals, ProdSSurf, ProdNNtl);

  //initialise deltaPSD
  for (m=0; m<NIntervals; m++)
    dPSD[m]=0.0;

  //variation of Particles due to Agglomeration by Collision
  const double GRate2 = ProdB.GrowthRate();
  if (AgglomON )
	ApplyAgglom(GRate2, dTime, m_dKvFac, ProdNNtl);

  //variation due to Nucleation in the Smallest Classes ONLY
  const double NRate = get_NucleationRate(m_eNuclModel, Prod, ProdSSurf, m_eShearRate);
  dPSD[0] += NRate*dTime;

  // variation due to Growth Only
  const double GRate3 = ProdB.GrowthRate();
  const double Const_boucle3 = GRate3*dTime/HPDSize;
  dPSD[0] += Const_boucle3*( ProdHyPsd[0]-ProdHyPsd[2] )/2.0;
  for (m=1; m<NIntervals-1; m++)
    dPSD[m] += Const_boucle3*(ProdHyPsd[m-1]-ProdHyPsd[m+1])/2.0;

  // Finally Substr. or Adding Particles to the Each Classes
  for (m=0; m<NIntervals; m++)
    {
    ProdHyPsd[m] += dPSD[m];
    ProdHyPsd[m] = Max(0.0, ProdHyPsd[m]);
    }

  CalcSSurgNNtl(SizeClass, ProdHyPsd, NIntervals, ProdSSurf, ProdNNtl); //Update ProdSSurf and ProdNNtl

  double gpl1x=gpl1;
  gpl1=0.0;
  for (m=0; m<NIntervals; m++)            
    {
    gpl1=gpl1 + ProdHyPsd[m]*pow(SizeClass[m],3)/6E12;
    }
  gpl1 = gpl1 * PI * 2.42;// *ProdVolFlow;

  //readjusting the PSD to 1 gpl...
  for (m=0; m<NIntervals; m++)
    ProdHyPsd[m] = ProdHyPsd[m] / gpl1;

  //=== 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

  bool CErr;
  const double Na2OFac = get_Na2OFactor(Prod);

  PerformAluminaSolubility(Prod, dNAN, dNAN, gpl1, 0/*NoPerSec2*/, 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
 //    mfshydPrev:=mfshyd;
//     mfshyd:=flowtotal*gpl1 -mfsSoda -mfsOxal -mfsSio2 ;the way it was done in HYPROD.. it is WRONG though

  HeatBalance(Prod, SolidsVariation, enthIn, dTime, CurLevel);  // Éliminé pour vérifier la temp ?
  
  return true;
  }
Exemplo n.º 9
0
//---------------------------------------------------------------------------
// All the precipitation rate calcs are done in this routine 
// Takes the product composition and calculates rates from this
// Rates (in kg/s) are put into global x
//---------------------------------------------------------------------------
void CPrecipitator::EvalPrecipRates(MStream & Prod, double T) 
{
  T = Prod.T;   // May want to do the rate calculation at other temperature
  
  MIBayer & ProdB=Prod.IF<MIBayer>(false);
  MISSA & ProdSSA = Prod.IF<MISSA>(false);
  dResidenceTime = dTankVol/GTZ(Prod.Volume(MP_SL));
  for (int i=0; i<nPRECIPCOMPS; i++)
    xo[i]=x[i];   // Save old values for convergence test, damping
  double SAL = ProdSSA.SpecificSurfaceAreaVol();
  double SSA = ProdSSA.SpecificSurfaceAreaMass();
  double dSSat;
  if (ProdB.CausticConc(T) > 0)
    dSSat = (ProdB.AluminaConc(T)-ProdB.AluminaConcSat(T))/ProdB.CausticConc(T);
  else
    dSSat = 0.0; 
  if (dSSat < 0) dSSat=0.0;
  
  // Supersaturation...

  switch (iGrowthRateMethod) {
    
  case GRM_Fixed:
    x[iALUMINA] = dGrowthRate;
    x[1] = x[iBOUND_ORGANICS] = 0.0;
    break;
  case GRM_White: 
    {
      MIBayer & FeedB = Feed.IF<MIBayer>(false);
      double Ain = FeedB.AluminaConc(T);
      double Aout = ProdB.AluminaConc(T);
      dGrowthRateFactor = gF_White*K_White*Exps(-ER_White/T);
      dGrowthRate = dGrowthRateFactor*Sqr(dSSat);
      x[iALUMINA] = dGrowthRate*SAL*dTankVol/1000.;
      double sodaRate = m_dK_Soda*Sqr(dSSat)*Exps(m_dE_Soda/T)*(Aout - Ain)*dTankVol/1000.;
      if (sodaRate <0.0) sodaRate = 0.0;
      x[iBOUND_SODA] = sodaRate*(1.0-m_dBndOrgSoda);
      x[iBOUND_ORGANICS] = sodaRate*m_dBndOrgSoda;
      
			   
    }
    
    break;
  case GRM_TTTest: 
    { // Alumina Precipitation.... as per QPRECIPD.cpp
      MIBayer & FeedB = Feed.IF<MIBayer>(false);
      double C  = ProdB.CausticConc(T);
      double C25 = ProdB.CausticConc(C2K(25));
      double CtoS = ProdB.CtoS();
      double S_out = C25/CtoS;
      //      double FC = ProdB.FreeCaustic(T);
      double FC = ProdB.FreeCaustic(C2K(25));
      double ACeq = ProdB.AluminaConcSat(T)/C25;   
      double TOOC=ProdB.TOC(C2K(25))*MW_Na2CO3/MW_C;
      double a=Exps(-m_dActivationEnergy/T);
      double b=Exps(-TOOC*m_dk_TOC);
      double c=Pow(GTZ(S_out), m_dn_s);
      double d=Pow(GTZ(FC), m_dn_fc);
      double e=Pow(GTZ(ACeq), m_dn_eq);

      double K = m_dK0*a*b*c*d*e;
      double ACout = ProdB.AtoC();
      double VLiq = Prod.Volume()*3600.;
      double MSolids     = Prod.MassVector[spTHA]*3600.0/1000.0;
      double Sol = MSolids*1000.0/GTZ(VLiq);
      double deltaAC = K * dResidenceTime/3600 *
	Pow(GTZ(ACout-ACeq),m_dn_) * Pow(GTZ(Sol),m_dn_sol) * Pow(GTZ(m_dSSA),m_dn_ssa);
      double ACoutEst = dACin - deltaAC;
      double VolOut = Prod.Volume(MP_Liq, C2K(25.0));
      double xx = deltaAC*C25*VolOut*2*MW_Alumina/MW_Al2O3;
      if (xx<0.0) xx=0.0;
      x[iALUMINA] = xx;
      
      // Bound Soda calculations... slurped from QAL file
      double k1x = m_dK1 * (0.000598*C25 - 0.00036*K2C(T) + 0.019568*TOOC/C) * (1.0 - 0.758*CtoS);
      double BoundSoda = k1x * Sqr(ACoutEst-ACeq);
      
      if (x[iALUMINA]>=0.0) {
	double BndSoda    = BoundSoda*(x[iALUMINA]*MW_Al2O3/(2.0*MW_THA))*(1.0-m_dBndOrgSoda)*((2.0*MW_NaOH)/MW_Na2O);
	double BndOrgSoda = BoundSoda*(x[iALUMINA]*MW_Al2O3/(2.0*MW_THA))*(m_dBndOrgSoda)*(MW_OrganicSoda/MW_Na2O);
	/*  If represented as Na2O
	    double BndSoda    = BoundSoda*GibbsRate*dBndOrgSoda;
	    double BndOrgSoda = BoundSoda*GibbsRate*(1.0-dBndOrgSoda);
	*/	
	x[iBOUND_SODA] = BndSoda;
	x[iBOUND_ORGANICS] = BndOrgSoda;

      }
      

    }
    
    break;
  }

  return;
}