Use this to calculate how much natural uranium and separative work you need to get
a given amount of enriched uranium at a certain enrichment, and so on. Learn more about [isotopes here]({% link isotopes.md %}).
Tails assay (wt %)
Feed assay (wt %)
Product Enrichment (wt %)
Choose Enrichment Preset
Natural Uranium (0.711%)
LEU (4%)
HALEU (20%)
Weapons-grade (90%)
LEU
Compute product mass from given feed mass
Compute feed mass from given product mass
Feed mass (kg or tonne)
Product mass (kg or tonne)
Tails mass (kg or tonne)
SWU (kg-SWU or tonne-SWU)
Copy
current settings to clipboard
<script src='
https://cdn.plot.ly/plotly-2.16.1.min.js'></script>
<script>
let range=document.getElementById("enrich");
let number=document.getElementById('enrich-text')
let select=document.getElementById('enrich-select')
let tails_assay=document.getElementById('tails-assay')
let feed_assay=document.getElementById('feed-assay')
let feed_mass=document.getElementById('feed-mass')
let product_mass=document.getElementById('product-mass')
let tails_mass=document.getElementById('tails-mass')
let swu=document.getElementById('swu-mass')
let mode=document.getElementById('mode')
let prod_const=document.getElementById('productConstant')
let save=document.getElementById('save')
tails_assay.addEventListener("input",(e)=>{
computeFeed();
})
feed_assay.addEventListener("input",(e)=>{
computeFeed();
})
product_mass.addEventListener("input",(e)=>{
computeFeed();
})
feed_mass.addEventListener("input",(e)=>{
computeFeed();
})
range.addEventListener("input",(e)=>{
let val = parseFloat(e.target.value);
if (val{
range.value=e.target.value;
select.value=""
setRange(e.target.value);
computeFeed();
})
select.addEventListener("change",(e)=>{
if (!e.target.value) {
return;
}
number.value=e.target.value;
range.value=e.target.value;
setRange(e.target.value);
computeFeed();
})
save.addEventListener("click", (e) => {
copySettingsToClipboard();
})
function setRange(val) {
let label=document.getElementById("enrich-label");
if (val>=0.0 && val<0.7) {
label.innerHTML="Depleted";
}
else if (val==0.7) {
label.innerHTML="Natural";
}
else if (val>0.7 && val<=5) {
label.innerHTML="LEU";
}
else if (val>5 && val<=20.0) {
label.innerHTML="HALEU";
}
else if (val>20.0 && val<=99.0) {
label.innerHTML="HEU";
}
else if (val>99.0 && val<=100.0) {
label.innerHTML="😲";
}
else {
label.innerHTML="Impossible";
}
}
function computeFeed() {
// Compute feed and SWU given desired product and enrichment
// compute MF/MP = feed factor
let mode = document.querySelector('input[name="mode"]:checked').value
let feed_factor = (number.value - tails_assay.value)/(feed_assay.value-tails_assay.value)
feed_factor= feed_factor;
if (mode=="1") {
feed_mass.value = (feed_factor * product_mass.value).toFixed(3);
}
else {
product_mass.value = (feed_mass.value/feed_factor).toFixed(3);
}
// swufactor= SWU/MP
let vxt = vx(tails_assay.value)
let swu_factor=(vx(number.value) - vxt) - feed_factor*(vx(feed_assay.value)-vxt)
swu.value = (swu_factor * product_mass.value).toFixed(3);
tails_mass.value = (feed_mass.value - product_mass.value).toFixed(3);
// update plot data
let u238 = {
x: ['Feed', 'Product', 'Tails'],
y: [feed_mass.value*(1-feed_assay.value/100.0),
product_mass.value*(1-number.value/100.0),
tails_mass.value*(1-tails_assay.value/100.0)
],
name: 'U238',
type: 'bar'
};
let u235 = {
x: ['Feed', 'Product', 'Tails'],
y: [feed_mass.value*(feed_assay.value/100.0),
product_mass.value*(number.value/100.0),
tails_mass.value*(tails_assay.value/100.0)
],
name: 'U235',
type: 'bar'
};
var data=[u238, u235];
Plotly.react('plot', data, layout);
}
function vx(x) {
// value function: gotta convert percentages to fraction
let xn = Number(x/100.0);
return (1.0-2*xn) * Math.log((1.0-xn)/xn);
}
function setInputVals() {
// These can all be passed in as query params
const input = new URLSearchParams(window.location.search);
tails_assay.value = input.get("tails-assay") || 0.25;
feed_assay.value = input.get("feed-assay") || 0.711;
number.value = input.get("enrich") || 4.0;
range.value=number.value;
feed_mass.value = input.get("feed-mass") || 0;
product_mass.value = input.get("product-mass") || 1;
feed_mass.value = input.get("feed-mass") || 1;
if (input.get("mode") == "0") {
// check a checkbox
prod_const.checked=true
};
}
function copySettingsToClipboard() {
let params = new URLSearchParams([
["tails-assay", tails_assay.value],
["feed-assay", feed_assay.value],
["enrich", number.value],
["feed-mass", feed_mass.value],
["product-mass", product_mass.value],
["mode", prod_const.checked ? "0" : "1"],
]);
let text = new URL(`${location.protocol + '//' + location.host + location.pathname}?${params}`);
navigator.clipboard.writeText(text);
}
var trace1 = {
x: ['Feed', 'Product', 'Tails'],
y: [20, 14, 23],
name: 'U238',
type: 'bar'
};
var trace2 = {
x: ['Feed', 'Product', 'Tails'],
y: [12, 18, 29],
name: 'U235',
type: 'bar'
};
var data = [trace1, trace2];
var layout = {barmode: 'stack', yaxis: {
type: 'log', autorange: true,
},
autosize: true,
margin: {
t: 0
},
};
Plotly.newPlot('plot', data, layout);
window.onresize = function() {
Plotly.relayout('plot', {})
}
// compute initial values
setInputVals();
computeFeed();
</script>