ガス分子を選択し(または分子直径を直接入力)、圧力、温度、代表寸法を入力すると平均自由行程とクヌーセン数をオンラインで計算してくれる JavaScript プログラムを ChatGPT に作ってもらいました。
—
—
—
今回ChatGPTに「WordPress上でオンライン計算ができるページの作り方」自体を聞くことからはじめています。当然 JavaScript を使ったこともなく、ChatGPT に指示するだけでコードは1文字も書いていません。ChatGPT が作ってくれたコードを WordPress のカスタムHTMLブロックに貼り付けて動作確認と検証を行い、レイアウトの修正なども全て ChatGPT への指示を繰り返して行いました。下にあるのが ChatGPT が書き出したコードで、これを埋め込んだものが上の計算ツールになります。作成時間は2,3時間、HTML + CSS + JavaScript の事前知識があればもっと短時間で済んだでしょう。改めて生成AIのすごさを実感しました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>平均自由行程とクヌーセン数計算機</title>
<style>
.mean-free-path-form {
max-width: 650px;
margin: auto;
padding: 1em;
border: 1px solid #ccc;
border-radius: 10px;
font-family: sans-serif;
}
.form-row {
display: flex;
align-items: center;
margin-top: 1em;
}
.form-row label {
flex: 0 0 30%;
font-weight: bold;
text-align: left;
}
.input-group {
display: flex;
flex: 1 0 70%;
align-items: center;
}
input.input-main,
select.unit-select {
padding: 0.5em;
font-size: 1em;
}
input.input-main {
flex: 1 0 50%;
}
select.unit-select {
flex: 0 0 20%;
margin-left: 0.5em;
}
.result-output {
flex: 1 0 50%;
padding: 0.5em;
font-size: 1em;
background: #f8f8f8;
border: 1px solid #ddd;
border-radius: 4px;
line-height: 1.2em;
text-align: left;
min-height: 38px;
box-sizing: border-box;
}
.knudsen-flow {
flex: 0 0 40%;
font-weight: bold;
padding-left: 1em;
}
</style>
</head>
<body>
<div class="mean-free-path-form">
<!-- ガス分子 -->
<div class="form-row">
<label for="gas">ガス分子</label>
<div class="input-group">
<select id="gas" class="input-main" onchange="setDiameter();">
<option value="" disabled selected style="color:blue;">Select</option>
<option value="H2">H₂</option>
<option value="He">He</option>
<option value="CH4">CH₄</option>
<option value="NH3">NH₃</option>
<option value="H2O">H₂O</option>
<option value="Ne">Ne</option>
<option value="C2H2">C₂H₂</option>
<option value="N2">N₂</option>
<option value="CO">CO</option>
<option value="C2H4">C₂H₄</option>
<option value="NO">NO</option>
<option value="O2">O₂</option>
<option value="H2S">H₂S</option>
<option value="HCl">HCl</option>
<option value="Ar">Ar</option>
<option value="C3H6">C₃H₆</option>
<option value="CO2">CO₂</option>
<option value="N2O">N₂O</option>
<option value="C3H8">C₃H₈</option>
<option value="SO2">SO₂</option>
<option value="Cl2">Cl₂</option>
<option value="C6H6">C₆H₆</option>
<option value="HBr">HBr</option>
<option value="Kr">Kr</option>
<option value="Xe">Xe</option>
<option value="SF6">SF₆</option>
<option value="CCl4">CCl₄</option>
<option value="Br2">Br₂</option>
</select>
<div class="unit-select"></div>
</div>
</div>
<!-- 分子直径 d -->
<div class="form-row">
<label>分子直径 d</label>
<div class="input-group">
<input type="number" id="diameter" class="input-main" step="0.1" value="">
<select class="unit-select" id="diameterUnit" onchange="convertInput('diameter')">
<option value="pm" selected>pm</option>
<option value="nm">nm</option>
<option value="um">μm</option>
<option value="mm">mm</option>
<option value="m">m</option>
</select>
</div>
</div>
<!-- 圧力 p -->
<div class="form-row">
<label>圧力 p</label>
<div class="input-group">
<input type="number" id="pressure" class="input-main" value="" step="1">
<select class="unit-select" id="pressureUnit" onchange="convertInput('pressure')">
<option value="Pa" selected>Pa</option>
<option value="atm">atm</option>
<option value="mTorr">mTorr</option>
</select>
</div>
</div>
<!-- 温度 T -->
<div class="form-row">
<label>温度 T</label>
<div class="input-group">
<input type="number" id="temperature" class="input-main" value="" step="0.1">
<select class="unit-select" id="temperatureUnit" onchange="convertInput('temperature')">
<option value="K" selected>K</option>
<option value="C">℃</option>
</select>
</div>
</div>
<!-- 平均自由行程 λ -->
<div class="form-row">
<label>平均自由行程 λ</label>
<div class="input-group">
<div id="result" class="result-output">---</div>
<select class="unit-select" id="resultUnit" onchange="calculate()">
<option value="pm">pm</option>
<option value="nm">nm</option>
<option value="um">μm</option>
<option value="mm" selected>mm</option>
<option value="m">m</option>
</select>
</div>
</div>
<!-- 代表寸法 L -->
<div class="form-row">
<label>代表寸法 L</label>
<div class="input-group">
<input type="number" id="characteristicLength" class="input-main" value="" step="0.001">
<select class="unit-select" id="lengthUnit" onchange="convertInput('length')">
<option value="pm">pm</option>
<option value="nm">nm</option>
<option value="um">μm</option>
<option value="mm" selected>mm</option>
<option value="m">m</option>
</select>
</div>
</div>
<!-- クヌーセン数 Kn + 区分 -->
<div class="form-row">
<label>クヌーセン数 Kn</label>
<div class="input-group">
<div id="knudsenResult" class="result-output" style="flex:1;">---</div>
<div id="flowRegime" class="knudsen-flow">---</div>
</div>
</div>
</div>
<script>
const diameters = {
H2: 289, He: 260, CH4: 380, NH3: 260, H2O: 265, Ne: 275, C2H2: 330, N2: 364, CO: 376, C2H4: 390,
NO: 317, O2: 346, H2S: 360, HCl: 320, Ar: 340, C3H6: 450, CO2: 330, N2O: 330, C3H8: 430, SO2: 360,
Cl2: 320, C6H6: 585, HBr: 350, Kr: 360, Xe: 396, SF6: 550, CCl4: 590, Br2: 350
};
const unitFactors = {
diameter: { pm: 1e-12, nm: 1e-9, um: 1e-6, mm: 1e-3, m: 1 },
pressure: { Pa: 1, atm: 101325, mTorr: 101325 / 760000 },
temperature: {
toK: (val, unit) => unit === 'K' ? val : val + 273.15,
fromK: (val, unit) => unit === 'K' ? val : val - 273.15
},
result: { pm: 1e12, nm: 1e9, um: 1e6, mm: 1e3, m: 1 },
length: { pm: 1e-12, nm: 1e-9, um: 1e-6, mm: 1e-3, m: 1 }
};
const previousUnits = {
diameter: 'pm', pressure: 'Pa', temperature: 'K', length: 'mm'
};
function setDiameter() {
const gasSelect = document.getElementById('gas');
const gas = gasSelect.value;
if (gas && diameters.hasOwnProperty(gas)) {
document.getElementById('diameter').value = diameters[gas];
document.getElementById('diameterUnit').value = 'pm';
previousUnits['diameter'] = 'pm';
} else {
document.getElementById('diameter').value = '';
}
calculate();
}
function convertInput(type) {
const input = document.getElementById(type === 'length' ? 'characteristicLength' : type);
const unitSelect = document.getElementById(type + 'Unit');
const oldUnit = previousUnits[type];
const newUnit = unitSelect.value;
let val = parseFloat(input.value);
if (isNaN(val)) return;
if (type === 'temperature') {
const valInK = unitFactors.temperature.toK(val, oldUnit);
const newVal = unitFactors.temperature.fromK(valInK, newUnit);
input.value = newVal.toFixed(2);
} else if (type === 'pressure') {
// 圧力単位変換は1 atm=101325 Pa=760000 mTorr を基準に換算
// 入力値を旧単位からPaに変換してから新単位に戻す
const valInPa = val * unitFactors.pressure[oldUnit];
const converted = valInPa / unitFactors.pressure[newUnit];
input.value = formatSmart(converted);
} else {
const base = val * unitFactors[type][oldUnit];
const converted = base / unitFactors[type][newUnit];
input.value = formatSmart(converted);
}
previousUnits[type] = newUnit;
calculate();
}
function formatSmart(val) {
if (val === 0) return '0';
const absVal = Math.abs(val);
if (absVal < 1e-4 || absVal >= 1e6) {
return val.toExponential(1);
} else {
return val.toFixed(6).replace(/\.?0+$/, '');
}
}
function calculate() {
const k = 1.380649e-23;
const pi = 3.141592653589793;
const d = parseFloat(document.getElementById('diameter').value) * unitFactors.diameter[document.getElementById('diameterUnit').value];
const P = parseFloat(document.getElementById('pressure').value) * unitFactors.pressure[document.getElementById('pressureUnit').value];
const T = unitFactors.temperature.toK(parseFloat(document.getElementById('temperature').value), document.getElementById('temperatureUnit').value);
const lengthInput = document.getElementById('characteristicLength').value;
const L = lengthInput ? parseFloat(lengthInput) * unitFactors.length[document.getElementById('lengthUnit').value] : null;
const resultUnit = document.getElementById('resultUnit').value;
if ([d, P, T].some(v => isNaN(v) || v <= 0)) {
document.getElementById('result').textContent = "---";
document.getElementById('knudsenResult').textContent = "---";
document.getElementById('flowRegime').textContent = "---";
return;
}
const lambda = k * T / (Math.sqrt(2) * pi * d * d * P);
const lambdaConv = lambda * unitFactors.result[resultUnit];
document.getElementById('result').textContent = formatSmart(lambdaConv);
if (!L || L <= 0) {
document.getElementById('knudsenResult').textContent = "---";
document.getElementById('flowRegime').textContent = "---";
return;
}
const Kn = lambda / L;
document.getElementById('knudsenResult').textContent = formatSmart(Kn);
const flowRegime = document.getElementById('flowRegime');
if (Kn < 0.01) {
flowRegime.textContent = "連続流";
flowRegime.style.color = "blue";
} else if (Kn < 0.1) {
flowRegime.textContent = "すべり流";
flowRegime.style.color = "green";
} else if (Kn < 10) {
flowRegime.textContent = "遷移流";
flowRegime.style.color = "brown";
} else {
flowRegime.textContent = "自由分子流";
flowRegime.style.color = "red";
}
}
document.querySelectorAll('input, select').forEach(el => {
if (el.id !== 'resultUnit') {
el.addEventListener('input', calculate);
el.addEventListener('change', () => {
if (el.tagName === 'SELECT') calculate();
});
}
});
window.addEventListener('DOMContentLoaded', () => {
setDiameter();
calculate();
});
</script>
</body>
</html>
コメント