<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Saturated Steam Properties Archives - Chemical Engineering Site</title>
	<atom:link href="https://chemicalengineeringsite.in/tag/saturated-steam-properties/feed/" rel="self" type="application/rss+xml" />
	<link>https://chemicalengineeringsite.in/tag/saturated-steam-properties/</link>
	<description>For Chemical Engineers</description>
	<lastBuildDate>Sat, 13 Sep 2025 14:25:18 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Saturated Steam Properties Calculator</title>
		<link>https://chemicalengineeringsite.in/saturated-steam-properties-calculator/</link>
		
		<dc:creator><![CDATA[chemicalengineeringsite]]></dc:creator>
		<pubDate>Sat, 13 Sep 2025 14:25:15 +0000</pubDate>
				<category><![CDATA[Calculators]]></category>
		<category><![CDATA[boiler calculations]]></category>
		<category><![CDATA[chemical engineering]]></category>
		<category><![CDATA[energy calculations]]></category>
		<category><![CDATA[engineering calculator]]></category>
		<category><![CDATA[latent heat]]></category>
		<category><![CDATA[online steam table]]></category>
		<category><![CDATA[Process engineering]]></category>
		<category><![CDATA[saturated steam]]></category>
		<category><![CDATA[Saturated Steam Enthalpy Calculator]]></category>
		<category><![CDATA[Saturated Steam Latent Heat Calculator]]></category>
		<category><![CDATA[Saturated Steam Properties]]></category>
		<category><![CDATA[saturated steam table]]></category>
		<category><![CDATA[saturation pressure]]></category>
		<category><![CDATA[specific enthalpy]]></category>
		<category><![CDATA[specific volume]]></category>
		<category><![CDATA[Steam]]></category>
		<category><![CDATA[steam calculator]]></category>
		<category><![CDATA[steam enthalpy]]></category>
		<category><![CDATA[steam pressure]]></category>
		<category><![CDATA[steam properties]]></category>
		<category><![CDATA[steam quality]]></category>
		<category><![CDATA[steam table]]></category>
		<category><![CDATA[steam temperature]]></category>
		<category><![CDATA[thermodynamic properties]]></category>
		<guid isPermaLink="false">https://chemicalengineeringsite.in/?p=4053</guid>

					<description><![CDATA[<p>Saturated Steam Properties Calculator Enter either Temperature or Pressure. Calculates saturation and properties: vg, ρg, vf, ρf, hf, hfg, hg, sf, sfg, sg. Export to Excel — changing inputs there updates outputs automatically. Input Mode By Temperature By Pressure Temperature °CK Valid range: 0–≈374 °C (273.15–647.096 K) Pressure bar(a)kPa(a)MPa(a) Valid range: 0.006–221 bar(a) Calculate &#x1f4ca; [&#8230;]</p>
<p>The post <a href="https://chemicalengineeringsite.in/saturated-steam-properties-calculator/">Saturated Steam Properties Calculator</a> appeared first on <a href="https://chemicalengineeringsite.in">Chemical Engineering Site</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<!-- Saturated Steam Properties Calculator + Excel Export (row-safe, HTML=Excel) -->
<div id="ssc" class="ssc-card" role="region" aria-label="Saturated Steam Properties Calculator">
  <div class="ssc-header">
    <h3 class="ssc-title">Saturated Steam Properties Calculator</h3>
    <p class="ssc-sub">Enter either Temperature or Pressure. Calculates saturation and properties: v<sub>g</sub>, ρ<sub>g</sub>, v<sub>f</sub>, ρ<sub>f</sub>, h<sub>f</sub>, h<sub>fg</sub>, h<sub>g</sub>, s<sub>f</sub>, s<sub>fg</sub>, s<sub>g</sub>. Export to Excel — changing inputs there updates outputs automatically.</p>
  </div>

  <form class="ssc-form" onsubmit="return false;">
    <fieldset class="ssc-fieldset">
      <legend>Input Mode</legend>
      <div class="ssc-inline">
        <label class="ssc-radio"><input type="radio" name="ssc-mode" value="T2P" checked /> <span>By Temperature</span></label>
        <label class="ssc-radio"><input type="radio" name="ssc-mode" value="P2T" /> <span>By Pressure</span></label>
      </div>
    </fieldset>

    <div class="ssc-grid" id="ssc-temp-box">
      <label class="ssc-field">
        <span>Temperature</span>
        <div class="ssc-inline">
          <input id="ssc-temp" type="number" step="any" placeholder="e.g., 150" />
          <select id="ssc-tunit" aria-label="Temperature unit">
            <option value="C">°C</option>
            <option value="K">K</option>
          </select>
        </div>
        <small class="ssc-hint">Valid range: 0–≈374 °C (273.15–647.096 K)</small>
      </label>
    </div>

    <div class="ssc-grid" id="ssc-press-box" style="display:none">
      <label class="ssc-field">
        <span>Pressure</span>
        <div class="ssc-inline">
          <input id="ssc-press" type="number" step="any" placeholder="e.g., 10" />
          <select id="ssc-punit" aria-label="Pressure unit">
            <option value="bar">bar(a)</option>
            <option value="kPa">kPa(a)</option>
            <option value="MPa">MPa(a)</option>
          </select>
        </div>
        <small class="ssc-hint">Valid range: 0.006–221 bar(a)</small>
      </label>
    </div>

    <div class="ssc-actions">
      <button type="button" id="ssc-calc" class="ssc-btn">Calculate</button>
      <button type="button" id="ssc-export" class="ssc-btn ssc-btn-ghost" title="Export Excel (dynamic)"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ca.png" alt="📊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Export Excel</button>
      <button type="button" id="ssc-reset" class="ssc-btn ssc-btn-ghost">Reset</button>
      <button type="button" id="ssc-copy" class="ssc-btn ssc-btn-ghost" title="Copy results">Copy</button>
    </div>
  </form>

  <div class="ssc-results" aria-live="polite">
    <div class="ssc-result"><div class="ssc-result-label">Saturation Temperature (T<sub>sat</sub>)</div><div class="ssc-result-value"><span id="ssc-oT">–</span></div></div>
    <div class="ssc-result"><div class="ssc-result-label">Saturation Pressure (P<sub>sat</sub>)</div><div class="ssc-result-value"><span id="ssc-oP">–</span></div></div>

    <div class="ssc-result"><div class="ssc-result-label">Specific Volume (Vapor) v<sub>g</sub> (m³/kg)</div><div class="ssc-result-value"><span id="ssc-ovg">–</span></div></div>
    <div class="ssc-result"><div class="ssc-result-label">Density (Vapor) ρ<sub>g</sub> (kg/m³)</div><div class="ssc-result-value"><span id="ssc-orhog">–</span></div></div>

    <div class="ssc-result"><div class="ssc-result-label">Specific Volume (Liquid) v<sub>f</sub> (m³/kg)</div><div class="ssc-result-value"><span id="ssc-ovf">–</span></div></div>
    <div class="ssc-result"><div class="ssc-result-label">Density (Liquid) ρ<sub>f</sub> (kg/m³)</div><div class="ssc-result-value"><span id="ssc-orhof">–</span></div></div>

    <div class="ssc-result"><div class="ssc-result-label">Enthalpy (Liquid) h<sub>f</sub> (kJ/kg)</div><div class="ssc-result-value"><span id="ssc-ohf">–</span></div></div>
    <div class="ssc-result"><div class="ssc-result-label">Latent Heat h<sub>fg</sub> (kJ/kg)</div><div class="ssc-result-value"><span id="ssc-ohfg">–</span></div></div>
    <div class="ssc-result"><div class="ssc-result-label">Enthalpy (Vapor) h<sub>g</sub> (kJ/kg)</div><div class="ssc-result-value"><span id="ssc-ohg">–</span></div></div>

    <div class="ssc-result"><div class="ssc-result-label">Entropy (Liquid) s<sub>f</sub> (kJ/kg·K)</div><div class="ssc-result-value"><span id="ssc-osf">–</span></div></div>
    <div class="ssc-result"><div class="ssc-result-label">Entropy of Vaporization s<sub>fg</sub> (kJ/kg·K)</div><div class="ssc-result-value"><span id="ssc-osfg">–</span></div></div>
    <div class="ssc-result"><div class="ssc-result-label">Entropy (Vapor) s<sub>g</sub> (kJ/kg·K)</div><div class="ssc-result-value"><span id="ssc-osg">–</span></div></div>

    <div id="ssc-note" class="ssc-note"></div>
  </div>

  <details class="ssc-details">
    <summary>Formula &#038; correlation notes</summary>
    <ul>
      <li><b>Wagner saturation (IAPWS):</b> ln(p/pc) = (Tc/T)·(a₁τ + a₂τ^1.5 + a₃τ³ + a₄τ^3.5 + a₅τ⁴ + a₆τ^7.5), τ = 1 − T/Tc</li>
      <li><b>Ideal gas for v<sub>g</sub>:</b> v<sub>g</sub> ≈ R·T/p; ρ<sub>g</sub> = 1/v<sub>g</sub></li>
      <li><b>Watson latent heat:</b> h<sub>fg</sub>(T) = h<sub>fg,ref</sub>·[(1−T/Tc)/(1−T<sub>ref</sub>/Tc)]^0.38</li>
      <li><b>h<sub>g</sub>:</b> h<sub>g</sub> ≈ c<sub>p,g</sub>·T + h₀ (2676 kJ/kg at 100 °C); h<sub>f</sub>=h<sub>g</sub>−h<sub>fg</sub></li>
      <li><b>s<sub>g</sub>:</b> s<sub>g</sub> ≈ c<sub>p,g</sub>·ln(T/T<sub>ref</sub>) − R·ln(p/p<sub>ref</sub>) + s<sub>g,ref</sub>; s<sub>fg</sub>=h<sub>fg</sub>/T; s<sub>f</sub>=s<sub>g</sub>−s<sub>fg</sub></li>
      <li><b>Liquid ρ<sub>f</sub>:</b> Kell (≤100 °C) + smooth fit above 100 °C; v<sub>f</sub>=1/ρ<sub>f</sub>.</li>
    </ul>
  </details>

  <footer class="ssc-footer">
    <small>Credit: <a href="https://chemicalengineeringsite.in/" target="_blank" rel="noopener">chemicalengineeringsite.in</a></small>
  </footer>
</div>

<style>
  .ssc-card{--b:#e6eef6;--t:#0f172a;--muted:#475569;--a:#2563eb;--bg:#ffffff;max-width:860px;margin:1.25rem auto;padding:1.25rem;border:1px solid var(--b);border-radius:16px;background:var(--bg);box-shadow:0 6px 20px rgba(2,6,23,.06)}
  .ssc-title{margin:.25rem 0;font-size:1.25rem;color:var(--t)}
  .ssc-sub{margin:0;color:var(--muted)}
  .ssc-form{margin-top:.75rem}
  .ssc-fieldset{border:1px dashed var(--b);border-radius:12px;padding:.6rem .7rem}
  .ssc-fieldset legend{color:var(--muted)}
  .ssc-radio{display:flex;align-items:center;gap:.45rem;margin-right:1rem;color:var(--t)}
  .ssc-grid{display:grid;grid-template-columns:repeat(1,minmax(0,1fr));gap:14px}
  .ssc-field{display:flex;flex-direction:column;gap:6px}
  .ssc-field span{font-weight:600;color:var(--t)}
  .ssc-inline{display:flex;gap:8px;align-items:center}
  .ssc-field input,.ssc-field select{width:100%;padding:.6rem .7rem;border:1px solid var(--b);border-radius:10px;background:#fff;color:var(--t)}
  .ssc-hint{color:var(--muted)}
  .ssc-actions{display:flex;gap:10px;margin-top:.75rem;flex-wrap:wrap}
  .ssc-btn{border:1px solid var(--a);background:var(--a);color:#fff;border-radius:999px;padding:.55rem .9rem;font-weight:600;cursor:pointer}
  .ssc-btn-ghost{background:#fff;color:var(--a)}
  .ssc-results{margin-top:1rem;border-top:1px dashed var(--b);padding-top:.9rem}
  .ssc-result{display:flex;justify-content:space-between;align-items:center;margin:.35rem 0}
  .ssc-result-label{color:var(--muted)}
  .ssc-result-value{font-size:1.1rem;font-weight:700;color:var(--t)}
  .ssc-note{margin-top:.4rem;color:#b45309}
  .ssc-details{margin-top:.6rem}
  .ssc-footer{margin-top:.6rem;color:var(--muted)}
</style>

<script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>

<script>
(function(){
  const $ = id => document.getElementById(id);

  // Elements
  const EL = {
    mode:  () => document.querySelector('input[name="ssc-mode"]:checked')?.value || 'T2P',
    tempBox: $('ssc-temp-box'),
    pressBox: $('ssc-press-box'),
    t: $('ssc-temp'), tUnit: $('ssc-tunit'),
    p: $('ssc-press'), pUnit: $('ssc-punit'),
    btnCalc: $('ssc-calc'), btnReset: $('ssc-reset'),
    btnCopy: $('ssc-copy'), btnExport: $('ssc-export'),
    oT: $('ssc-oT'), oP: $('ssc-oP'),
    ovg: $('ssc-ovg'), orhog: $('ssc-orhog'),
    ovf: $('ssc-ovf'), orhof: $('ssc-orhof'),
    ohf: $('ssc-ohf'), ohfg: $('ssc-ohfg'), ohg: $('ssc-ohg'),
    osf: $('ssc-osf'), osfg: $('ssc-osfg'), osg: $('ssc-osg'),
    note: $('ssc-note')
  };

  // Constants (match Excel)
  const Tc=647.096, pc_bar=220.64, R=0.461526, cp_g=1.996, Tref=373.15, pref_bar=1.01325, hfg_ref=2256.9, sg_ref=7.354;
  const a=[-7.85951783,1.84408259,-11.7866497,22.6807411,-15.9618719,1.80122502];

  const clamp=(x,min,max)=>Math.max(min,Math.min(max,x));
  const C2K=C=>C+273.15, K2C=K=>K-273.15;
  const round=(v,dp=3)=>Number.isFinite(v)?(Math.round(v*10**dp)/10**dp).toFixed(dp):'–';

  function psat(T){
    const tau=1-(T/Tc);
    const lnpr=(Tc/T)*(a[0]*tau + a[1]*tau**1.5 + a[2]*tau**3 + a[3]*tau**3.5 + a[4]*tau**4 + a[5]*tau**7.5);
    return Math.exp(lnpr)*pc_bar;
  }
  function Tsat(p){
    let T=clamp(273.15+100*(p/pref_bar)**0.25,273.15,Tc-0.01);
    for(let i=0;i<30;i++){
      const dT=0.005, f=psat(T)-p, dp=(psat(T+dT)-psat(T-dT))/(2*dT);
      if(!isFinite(dp)||Math.abs(dp)<1e-7) break;
      const step=f/dp; T=clamp(T-step,273.15,Tc-1e-6); if(Math.abs(step)<1e-6) break;
    }
    return T;
  }
  const vg=(T,P)=> (R*T)/(P*100);
  const hFG=T=> hfg_ref*((1-T/Tc)/(1-Tref/Tc))**0.38;
  const hG =T=> cp_g*T + (2676 - cp_g*Tref);
  const sG =(T,P)=> sg_ref + cp_g*Math.log(T/Tref) - R*Math.log(P/pref_bar);

  function rhoL(T){
    const t=K2C(T);
    if(t<=100){
      return 1000*(1 - ((t+288.9414)/(508929.2*(t+68.12963)))*(t-3.9863)*(t-3.9863));
    }else{
      const dt=t-100; return Math.max(322, 1000 - 1.2*dt - 0.002*dt*dt);
    }
  }

  // Toggle boxes
  Array.from(document.querySelectorAll('input[name="ssc-mode"]')).forEach(r=>{
    r.addEventListener('change', ()=>{
      if(EL.mode()==='T2P'){ EL.tempBox.style.display='grid'; EL.pressBox.style.display='none'; }
      else{ EL.tempBox.style.display='none'; EL.pressBox.style.display='grid'; }
      clearOut();
    });
  });

  function clearOut(){
    ['oT','oP','ovg','orhog','ovf','orhof','ohf','ohfg','ohg','osf','osfg','osg'].forEach(k=>EL[k].textContent='–');
    EL.note.textContent=''; window.__ssc_state=null;
  }

  function calculate(){
    const mode=EL.mode(); let T,P;
    if(mode==='T2P'){
      const t=Number(EL.t.value); if(!isFinite(t)){ EL.note.textContent='Enter a valid Temperature.'; return; }
      T=(EL.tUnit.value==='C')?C2K(t):t; if(T<273.15||T>=Tc){ EL.note.textContent='Temperature must be 273.15–647.096 K.'; return; }
      P=psat(T);
    }else{
      const p=Number(EL.p.value); if(!isFinite(p)||p<=0){ EL.note.textContent='Enter a valid Pressure.'; return; }
      P=(EL.pUnit.value==='bar')?p:(EL.pUnit.value==='kPa'?p/100:p*10); if(P<0.006||P>221){ EL.note.textContent='Pressure must be 0.006–221 bar(a).'; return; }
      T=Tsat(P);
    }

    const vg_v = vg(T,P), rhog = 1/vg_v;
    const rhof = rhoL(T), vf = 1/rhof;
    const hfgv=hFG(T), hgv=hG(T), hfv=hgv-hfgv;
    const sgv=sG(T,P), sfgv=hfgv/T, sfv=sgv-sfgv;

    EL.oT.textContent=`${round(K2C(T),3)} °C`;
    EL.oP.textContent=`${round(P,5)} bar`;
    EL.ovg.textContent=round(vg_v,6);
    EL.orhog.textContent=round(rhog,5);
    EL.ovf.textContent=round(vf,6);
    EL.orhof.textContent=round(rhof,3);
    EL.ohf.textContent=round(hfv,2);
    EL.ohfg.textContent=round(hfgv,2);
    EL.ohg.textContent=round(hgv,2);
    EL.osf.textContent=round(sfv,4);
    EL.osfg.textContent=round(sfgv,5);
    EL.osg.textContent=round(sgv,4);
    EL.note.textContent='';

    window.__ssc_state={mode, T_in_C:T-273.15, P_in_bar:P};
  }

  function copyResults(){
    const txt = `Saturated Steam Properties
--------------------------
Saturation Temperature (°C): ${EL.oT.textContent}
Saturation Pressure (bar): ${EL.oP.textContent}
Specific Volume (Vapor) v_g (m³/kg): ${EL.ovg.textContent}
Density (Vapor) ρ_g (kg/m³): ${EL.orhog.textContent}
Specific Volume (Liquid) v_f (m³/kg): ${EL.ovf.textContent}
Density (Liquid) ρ_f (kg/m³): ${EL.orhof.textContent}
Enthalpy (Liquid) h_f (kJ/kg): ${EL.ohf.textContent}
Latent Heat h_fg (kJ/kg): ${EL.ohfg.textContent}
Enthalpy (Vapor) h_g (kJ/kg): ${EL.ohg.textContent}
Entropy (Liquid) s_f (kJ/kg·K): ${EL.osf.textContent}
Entropy of Vaporization s_fg (kJ/kg·K): ${EL.osfg.textContent}
Entropy (Vapor) s_g (kJ/kg·K): ${EL.osg.textContent}`;
    navigator.clipboard?.writeText(txt).then(()=>{
      EL.note.style.color='#16a34a'; EL.note.textContent='Results copied.'; setTimeout(()=>{EL.note.textContent=''; EL.note.style.color='';},1400);
    }).catch(()=>{ EL.note.style.color='#b45309'; EL.note.textContent='Copy failed. Select and copy manually.'; });
  }

  // Excel export with row-safe formulas
  function exportExcel(){
    const s=window.__ssc_state; if(!s){ EL.note.style.color='#b45309'; EL.note.textContent='Calculate first.'; return; }

    const modeStr=s.mode||'T2P', T_in_C=+s.T_in_C.toFixed(6), P_in=+s.P_in_bar.toFixed(8);

    // Formula text (for the Formula column)
    const FT = {
      TmodeK: 'IF(Mode="T2P", T_in_C+273.15, T_from_P)',
      TmodeC: 'TmodeK-273.15',
      Pmode:  'IF(Mode="T2P", p_sat(TmodeK), P_in)',
      vg:     'R*TmodeK/(Pmode*100)',
      rhog:   '1/v_g',
      rhof:   'IF(T_C<=100, Kell(T_C), MAX(322, 1000-1.2*ΔT-0.002*ΔT^2))',
      vf:     '1/ρ_f',
      hfg:    'h_fg,ref * ((1 - TmodeK/Tc)/(1 - T_ref/Tc))^0.38',
      hg:     'cp_g*TmodeK + h0',
      hf:     'h_g - h_fg',
      sfg:    'h_fg / TmodeK',
      sg:     's_g,ref + cp_g*ln(TmodeK/T_ref) - R*ln(Pmode/p_ref)',
      sf:     's_g - s_fg'
    };

    // Build the sheet with labels; formulas will be patched by searching labels
    const A = [
      ['Saturated Steam Properties (dynamic Excel)','','',''],
      ['','','',''],
      ['Mode ("T2P" or "P2T")', modeStr,'',''],
      ['Temperature Input (°C)', T_in_C,'','Enter T for T2P'],
      ['Pressure Input (bar a)', P_in,'','Enter P for P2T'],
      ['','','',''],

      // Constants
      ['Constants','Value','Units',''],
      ['Critical Temperature (Tc)', 647.096, 'K',''],
      ['Critical Pressure (pc)', 220.64, 'bar',''],
      ['Gas Constant (steam, R)', 0.461526, 'kJ/(kg·K)',''],
      ['Vapor cp (cp_g)', 1.996, 'kJ/(kg·K)',''],
      ['Reference Temperature (T_ref)', 373.15, 'K',''],
      ['Reference Pressure (p_ref)', 1.01325, 'bar',''],
      ['Latent Heat at 100°C (h_fg,ref)', 2256.9, 'kJ/kg',''],
      ['Reference s_g at 100°C', 7.354, 'kJ/(kg·K)',''],
      ['h0 (for h_g calibration)', {t:'n', f:'2676 - B11*B12'}, 'kJ/kg',''],
      ['','','',''],

      // Mode mapping (+ forward p_sat(TmodeK))
      ['TmodeK (K)', '', 'K', FT.TmodeK],
      ['TmodeC (°C)', '', '°C', FT.TmodeC],
      ['Pmode (bar)', '', 'bar', FT.Pmode],
      ['τ = 1 - T/Tc', '', '', ''],
      ['ln(p/pc)', '', '', ''],
      ['p_sat(T) (bar)', '', 'bar', 'exp(ln(p/pc))*pc'],
      ['','','',''],

      // P->T Newton (T_from_P)
      ['ΔT = 0.005 K', 0.005,'K',''],
      ['P_in (bar)', {t:'n', f:'B5'}, 'bar',''],
      ['T0 (K) seed', '', 'K','MAX(273.15, MIN(Tc-0.01, 273.15+100*(P_in/p_ref)^0.25))'],
      ['p(T0) (bar)', '', 'bar',''],
      ['dp/dT @T0', '', 'bar/K',''],
      ['T1 (K)', '', 'K',''],
      ['p(T1) (bar)', '', 'bar',''],
      ['dp/dT @T1', '', 'bar/K',''],
      ['T2 (K)', '', 'K',''],
      ['p(T2) (bar)', '', 'bar',''],
      ['dp/dT @T2', '', 'bar/K',''],
      ['T3 (K)', '', 'K',''],
      ['p(T3) (bar)', '', 'bar',''],
      ['dp/dT @T3', '', 'bar/K',''],
      ['T4 (K)', '', 'K',''],
      ['p(T4) (bar)', '', 'bar',''],
      ['dp/dT @T4', '', 'bar/K',''],
      ['T_from_P (K)', '', 'K',''],
      ['','','',''],

      // Helpers for liquid density
      ['T_C (°C)', '', '°C','TmodeK - 273.15'],
      ['ΔT (°C) = max(T_C-100,0)', '', '°C','MAX(T_C-100,0)'],
      ['','','',''],

      // RESULTS
      ['Property','Value','Units','Formula'],
      ['Saturation Temperature (K)', '', 'K', FT.TmodeK],
      ['Saturation Temperature (°C)', '', '°C', FT.TmodeC],
      ['Saturation Pressure (bar)', '', 'bar', FT.Pmode],
      ['Specific Volume (Vapor) v_g', '', 'm³/kg', FT.vg],
      ['Density (Vapor) ρ_g', '', 'kg/m³', FT.rhog],
      ['Density (Liquid) ρ_f', '', 'kg/m³', FT.rhof],
      ['Specific Volume (Liquid) v_f', '', 'm³/kg', FT.vf],
      ['Latent Heat h_fg', '', 'kJ/kg', FT.hfg],
      ['Enthalpy (Vapor) h_g', '', 'kJ/kg', FT.hg],
      ['Enthalpy (Liquid) h_f', '', 'kJ/kg', FT.hf],
      ['Entropy of Vaporization s_fg', '', 'kJ/kg·K', FT.sfg],
      ['Entropy (Vapor) s_g', '', 'kJ/kg·K', FT.sg],
      ['Entropy (Liquid) s_f', '', 'kJ/kg·K', FT.sf],
      ['','','',''],
      ['Source: chemicalengineeringsite.in','','','']
    ];

    // Create sheet
    const ws = XLSX.utils.aoa_to_sheet(A);
    ws['!cols']=[{wch:44},{wch:22},{wch:14},{wch:46}];
    ws['!freeze']={xSplit:1,ySplit:7};

    // Helper to find row by left label
    function rowOf(label){
      for(const addr in ws){
        if(!/^[A-Z]+[0-9]+$/.test(addr)) continue;
        const c = ws[addr];
        if(c && c.v === label && addr.startsWith('A')) return parseInt(addr.replace(/^[A-Z]+/,''),10);
      }
      return null;
    }
    const setB = (row, f) => { ws['B'+row] = {t:'n', f}; };

    // Grab rows for constants
    const rTc=rowOf('Critical Temperature (Tc)'),
          rpc=rowOf('Critical Pressure (pc)'),
          rR=rowOf('Gas Constant (steam, R)'),
          rcp=rowOf('Vapor cp (cp_g)'),
          rTref=rowOf('Reference Temperature (T_ref)'),
          rPref=rowOf('Reference Pressure (p_ref)'),
          rhfgref=rowOf('Latent Heat at 100°C (h_fg,ref)'),
          rsgref=rowOf('Reference s_g at 100°C'),
          rh0=rowOf('h0 (for h_g calibration)');

    // Mode rows & Wagner forward
    const rTmodeK=rowOf('TmodeK (K)'),
          rTmodeC=rowOf('TmodeC (°C)'),
          rPmode=rowOf('Pmode (bar)'),
          rtau=rowOf('τ = 1 - T/Tc'),
          rln=rowOf('ln(p/pc)'),
          rpsat=rowOf('p_sat(T) (bar)');

    // Newton block (P→T)
    const rDelta=rowOf('ΔT = 0.005 K'),
          rPin=rowOf('P_in (bar)'),
          rT0=rowOf('T0 (K) seed'),
          rPT0=rowOf('p(T0) (bar)'),
          rdp0=rowOf('dp/dT @T0'),
          rT1=rowOf('T1 (K)'),
          rPT1=rowOf('p(T1) (bar)'),
          rdp1=rowOf('dp/dT @T1'),
          rT2=rowOf('T2 (K)'),
          rPT2=rowOf('p(T2) (bar)'),
          rdp2=rowOf('dp/dT @T2'),
          rT3=rowOf('T3 (K)'),
          rPT3=rowOf('p(T3) (bar)'),
          rdp3=rowOf('dp/dT @T3'),
          rT4=rowOf('T4 (K)'),
          rPT4=rowOf('p(T4) (bar)'),
          rdp4=rowOf('dp/dT @T4'),
          rTfromP=rowOf('T_from_P (K)');

    // Liquid helpers
    const rTC=rowOf('T_C (°C)'),
          rDT=rowOf('ΔT (°C) = max(T_C-100,0)');

    // Results rows
    const rResTK=rowOf('Saturation Temperature (K)'),
          rResTC=rowOf('Saturation Temperature (°C)'),
          rResP=rowOf('Saturation Pressure (bar)'),
          rVG=rowOf('Specific Volume (Vapor) v_g'),
          rRG=rowOf('Density (Vapor) ρ_g'),
          rRF=rowOf('Density (Liquid) ρ_f'),
          rVF=rowOf('Specific Volume (Liquid) v_f'),
          rHFG=rowOf('Latent Heat h_fg'),
          rHG=rowOf('Enthalpy (Vapor) h_g'),
          rHF=rowOf('Enthalpy (Liquid) h_f'),
          rSFG=rowOf('Entropy of Vaporization s_fg'),
          rSG=rowOf('Entropy (Vapor) s_g'),
          rSF=rowOf('Entropy (Liquid) s_f');

    // === Fill mode mapping ===
    setB(rTmodeK, `IF(B3="T2P", B4+273.15, B${rTfromP})`);
    setB(rTmodeC, `B${rTmodeK}-273.15`);
    setB(rPmode,  `IF(B3="T2P", B${rpsat}, B5)`);

    // Wagner forward at TmodeK
    setB(rtau, `1 - B${rTmodeK}/B${rTc}`);
    setB(rln,  `(B${rTc}/B${rTmodeK})*( -7.85951783*B${rtau} + 1.84408259*POWER(B${rtau},1.5) -11.7866497*POWER(B${rtau},3) +22.6807411*POWER(B${rtau},3.5) -15.9618719*POWER(B${rtau},4) +1.80122502*POWER(B${rtau},7.5) )`);
    setB(rpsat, `EXP(B${rln})*B${rpc}`);

    // Newton P→T (5 iterations, central derivative)
    setB(rT0,  `MAX(273.15, MIN(B${rTc}-0.01, 273.15 + 100*POWER(B${rPin}/B${rPref},0.25)))`);
    function p_of(rowT){ return `EXP((B${rTc}/B${rowT})*( -7.85951783*(1-B${rowT}/B${rTc}) + 1.84408259*POWER(1-B${rowT}/B${rTc},1.5) -11.7866497*POWER(1-B${rowT}/B${rTc},3) +22.6807411*POWER(1-B${rowT}/B${rTc},3.5) -15.9618719*POWER(1-B${rowT}/B${rTc},4) +1.80122502*POWER(1-B${rowT}/B${rTc},7.5) ))*B${rpc}`; }
    function dpdt(rowT){ return `( ${p_of(rowT+'+'+rDelta)} - ${p_of(rowT+'-'+rDelta)} )/(2*B${rDelta})`; }
    setB(rPT0, p_of(rT0)); setB(rdp0, dpdt(rT0)); setB(rT1, `MAX(273.15, MIN(B${rTc}-1E-6, B${rT0} - (B${rPT0} - B${rPin})/B${rdp0} ))`);
    setB(rPT1, p_of(rT1)); setB(rdp1, dpdt(rT1)); setB(rT2, `MAX(273.15, MIN(B${rTc}-1E-6, B${rT1} - (B${rPT1} - B${rPin})/B${rdp1} ))`);
    setB(rPT2, p_of(rT2)); setB(rdp2, dpdt(rT2)); setB(rT3, `MAX(273.15, MIN(B${rTc}-1E-6, B${rT2} - (B${rPT2} - B${rPin})/B${rdp2} ))`);
    setB(rPT3, p_of(rT3)); setB(rdp3, dpdt(rT3)); setB(rT4, `MAX(273.15, MIN(B${rTc}-1E-6, B${rT3} - (B${rPT3} - B${rPin})/B${rdp3} ))`);
    setB(rPT4, p_of(rT4)); setB(rdp4, dpdt(rT4)); setB(rTfromP, `MAX(273.15, MIN(B${rTc}-1E-6, B${rT4} - (B${rPT4} - B${rPin})/B${rdp4} ))`);

    // Liquid helpers
    setB(rTC, `B${rTmodeK}-273.15`);
    setB(rDT, `MAX(B${rTC}-100,0)`);

    // Results (all VALUE cells)
    setB(rResTK, `B${rTmodeK}`);
    setB(rResTC, `B${rTmodeC}`);
    setB(rResP,  `B${rPmode}`);
    setB(rVG,    `B${rR}*B${rTmodeK}/(B${rPmode}*100)`);
    setB(rRG,    `1/B${rVG}`);
    // ρ_f
    setB(rRF,    `IF(B${rTC}<=100, 1000*(1 - ((B${rTC}+288.9414)/(508929.2*(B${rTC}+68.12963)))*POWER(B${rTC}-3.9863,2)), MAX(322, 1000 - 1.2*B${rDT} - 0.002*POWER(B${rDT},2)))`);
    // v_f = 1/ρ_f
    setB(rVF,    `1/B${rRF}`);
    setB(rHFG,   `B${rhfgref}*POWER((1 - B${rTmodeK}/B${rTc})/(1 - B${rTref}/B${rTc}), 0.38)`);
    setB(rHG,    `B${rcp}*B${rTmodeK} + B${rh0}`);
    setB(rHF,    `B${rHG} - B${rHFG}`);
    setB(rSFG,   `B${rHFG} / B${rTmodeK}`);
    setB(rSG,    `B${rsgref} + B${rcp}*LN(B${rTmodeK}/B${rTref}) - B${rR}*LN(B${rPmode}/B${rPref})`);
    setB(rSF,    `B${rSG} - B${rSFG}`);

    // Make source clickable
    const lastRow = Math.max(...Object.keys(ws).filter(k=>/^[A-Z]+\d+$/.test(k)).map(k=>+k.replace(/^[A-Z]+/,'')));
    ws['A'+lastRow] = { t:'s', v:'Source: chemicalengineeringsite.in', l:{ Target:'https://chemicalengineeringsite.in/' } };

    const wb=XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'SatSteam');
    const ts=new Date().toISOString().slice(0,19).replace(/[:T]/g,'-');
    XLSX.writeFile(wb, `saturated_steam_dynamic_${ts}.xlsx`);
  }

  // Wire up
  EL.btnCalc.addEventListener('click', calculate);
  EL.btnReset.addEventListener('click', ()=>{ EL.t.value=''; EL.p.value=''; EL.tUnit.value='C'; EL.pUnit.value='bar'; clearOut(); });
  EL.btnCopy.addEventListener('click', copyResults);
  EL.btnExport.addEventListener('click', exportExcel);
  ['ssc-temp','ssc-press'].forEach(id=>$(id).addEventListener('keydown', e=>{ if(e.key==='Enter'){ e.preventDefault(); calculate(); }}));
})();
</script>
<!-- /Saturated Steam Properties Calculator + Excel Export -->

<p>The post <a href="https://chemicalengineeringsite.in/saturated-steam-properties-calculator/">Saturated Steam Properties Calculator</a> appeared first on <a href="https://chemicalengineeringsite.in">Chemical Engineering Site</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
