<?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>단열설계 &#8211; MyEngNote</title>
	<atom:link href="https://myengnote.com/tag/%eb%8b%a8%ec%97%b4%ec%84%a4%ea%b3%84/feed/" rel="self" type="application/rss+xml" />
	<link>https://myengnote.com</link>
	<description></description>
	<lastBuildDate>Wed, 08 Jul 2026 04:42:32 +0000</lastBuildDate>
	<language>ko-KR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.2</generator>
	<item>
		<title>열전달 계산기 &#038; 시뮬레이터</title>
		<link>https://myengnote.com/heat-transfer-conduction-calculator/</link>
					<comments>https://myengnote.com/heat-transfer-conduction-calculator/#respond</comments>
		
		<dc:creator><![CDATA[동동]]></dc:creator>
		<pubDate>Tue, 09 Jun 2026 22:00:09 +0000</pubDate>
				<category><![CDATA[공학계산기]]></category>
		<category><![CDATA[단열설계]]></category>
		<category><![CDATA[대류전열]]></category>
		<category><![CDATA[복합벽]]></category>
		<category><![CDATA[열전달]]></category>
		<category><![CDATA[열전도율]]></category>
		<guid isPermaLink="false">https://myengnote.com/heat-transfer-conduction-calculator/</guid>

					<description><![CDATA[전도, 대류 및 단열재 3중 복합 벽체 구조를 통과하는 열유동을 실시간 유한차분 모델링으로 해석하여 온도 구배 선도와 총 열손실을 정밀하게 계산하는 공학 시뮬레이터입니다.]]></description>
										<content:encoded><![CDATA[
<h2 style="font-size: 1.6em; font-weight: 800; color: #0c0e25; border-bottom: 2px solid #00f2fe; padding-bottom: 8px; margin-bottom: 20px;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 열전달 계산기 &#038; 시뮬레이터</h2>


<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&#038;family=Outfit:wght@400;500;600;700;800&#038;display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
/* Scoped & Isolated Styles for heattransfer-calculator-wrapper */
        /* Modern Reset and Design Tokens */
        .heattransfer-calculator-wrapper *, .heattransfer-calculator-wrapper *::before, .heattransfer-calculator-wrapper *::after {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        .heattransfer-calculator-wrapper {
            --color-bg-dark: #f8f9fd;
            --color-bg-deep: #ffffff;
            --color-panel-bg: rgba(255, 255, 255, 0.85);
            --color-border: rgba(0, 0, 0, 0.06);
            --color-border-hover: rgba(0, 0, 0, 0.12);
            --color-text-main: #1e293b;
            --color-text-muted: #475569;
            --color-text-dark: #94a3b8;
            --color-cyan: #0284c7;
            --color-cyan-glow: rgba(2, 132, 199, 0.15);
            --color-magenta: #db2777;
            --color-magenta-glow: rgba(219, 39, 119, 0.15);
            --color-purple: #7c3aed;
            --color-purple-glow: rgba(124, 58, 237, 0.12);
            --color-success: #10b981;
            --gradient-primary: linear-gradient(135deg, var(--color-cyan) 0%, var(--color-purple) 100%);
            --gradient-accent: linear-gradient(135deg, var(--color-magenta) 0%, var(--color-purple) 100%);
            --gradient-panel: linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(248, 250, 252, 0.95) 100%);
            --font-heading: 'Outfit', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
            --shadow-neon-cyan: 0 0 15px var(--color-cyan-glow);
            --shadow-neon-magenta: 0 0 15px var(--color-magenta-glow);
            --shadow-card: 0 8px 32px 0 rgba(15, 23, 42, 0.05);
            --blur-glass: blur(16px);
        }
        .heattransfer-calculator-wrapper {
            background-color: var(--color-bg-dark);
            color: var(--color-text-main);
            font-family: var(--font-body);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            overflow-x: hidden;
            position: relative;
        }
        .app-background-glow {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
            overflow: hidden;
            pointer-events: none;
        }
        .app-background-glow::before, 
        .app-background-glow::after {
            content: '';
            position: absolute;
            width: 600px;
            height: 600px;
            border-radius: 50%;
            filter: blur(140px);
            opacity: 0.12;
        }
        .app-background-glow::before {
            background: var(--color-cyan);
            top: -10%;
            right: -5%;
            animation: pulse-slow 15s infinite alternate;
        }
        .app-background-glow::after {
            background: var(--color-purple);
            bottom: -10%;
            left: -5%;
            animation: pulse-slow 20s infinite alternate-reverse;
        }
        @keyframes pulse-slow {
            0% { transform: scale(1) translate(0, 0); opacity: 0.1; }
            100% { transform: scale(1.18) translate(40px, 40px); opacity: 0.18; }
        }
        .app-container {
            width: 100%;
            max-width: 1440px;
            padding: 24px;
            display: flex;
            flex-direction: column;
            gap: 24px;
        }
        .app-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 20px 24px;
            background: var(--color-panel-bg);
            backdrop-filter: var(--blur-glass);
            border: 1px solid var(--color-border);
            border-radius: 16px;
            box-shadow: var(--shadow-card);
        }
        .logo-area {
            display: flex;
            align-items: center;
            gap: 16px;
        }
        .logo-icon {
            font-size: 32px;
            background: linear-gradient(135deg, var(--color-cyan), var(--color-magenta));
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .logo-area h1 {
            font-family: var(--font-heading);
            font-weight: 800;
            font-size: 24px;
            letter-spacing: 1.5px;
            background: linear-gradient(90deg, var(--color-text-main), var(--color-text-muted));
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        .logo-area .subtitle {
            font-size: 12px;
            color: var(--color-text-muted);
            font-weight: 500;
            letter-spacing: 0.5px;
        }
        .header-badge {
            display: flex;
            align-items: center;
            gap: 10px;
            background: rgba(16, 185, 129, 0.1);
            border: 1px solid rgba(16, 185, 129, 0.2);
            padding: 6px 14px;
            border-radius: 20px;
        }
        .pulse-dot {
            width: 8px;
            height: 8px;
            background-color: var(--color-success);
            border-radius: 50%;
            box-shadow: 0 0 10px var(--color-success);
            animation: pulse-dot-anim 1.5s infinite;
        }
        @keyframes pulse-dot-anim {
            0% { transform: scale(0.9); opacity: 0.6; }
            50% { transform: scale(1.2); opacity: 1; }
            100% { transform: scale(0.9); opacity: 0.6; }
        }
        .badge-text {
            font-size: 11px;
            font-weight: 600;
            color: var(--color-success);
            letter-spacing: 0.5px;
        }
        .app-main-grid {
            display: grid;
            grid-template-columns: 340px 1fr 340px;
            gap: 24px;
            align-items: start;
        }
        .panel {
            background: var(--gradient-panel);
            backdrop-filter: var(--blur-glass);
            border: 1px solid var(--color-border);
            border-radius: 20px;
            padding: 24px;
            box-shadow: var(--shadow-card);
            display: flex;
            flex-direction: column;
            gap: 20px;
            transition: border-color 0.3s ease, box-shadow 0.3s ease;
        }
        .panel:hover {
            border-color: var(--color-border-hover);
        }
        .panel-header {
            display: flex;
            align-items: center;
            gap: 12px;
            border-bottom: 1px solid var(--color-border);
            padding-bottom: 14px;
        }
        .panel-header i {
            font-size: 18px;
        }
        .panel-header h2 {
            font-family: var(--font-heading);
            font-size: 18px;
            font-weight: 600;
            letter-spacing: 0.5px;
        }
        .text-cyan { color: #0284c7; }
        .text-magenta { color: #db2777; }
        .text-purple { color: var(--color-purple); }
        .control-panel {
            grid-column: 1;
            max-height: 90vh;
            overflow-y: auto;
            scrollbar-width: thin;
        }
        .input-group {
            display: flex;
            flex-direction: column;
            gap: 8px;
        }
        .input-label-row {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .input-label-row label {
            font-size: 13px;
            font-weight: 600;
            color: var(--color-text-main);
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .range-helper {
            font-size: 10px;
            color: var(--color-text-muted);
            font-weight: 500;
        }
                .number-input-wrapper {
            display: flex;
            position: relative;
            border-radius: 8px;
            overflow: hidden;
            border: 1px solid var(--color-border);
            background: #ffffff;
            transition: all 0.2s ease;
        }
        .number-input-wrapper:focus-within {
            border-color: var(--color-cyan);
            box-shadow: 0 0 10px var(--color-cyan-glow);
        }
        .number-input-wrapper:focus-within {
            border-color: #0284c7;
            box-shadow: 0 0 10px var(--color-cyan-glow);
        }
        .custom-select {
            width: 100%;
            background: #f8fafc;
            border: 1px solid var(--color-border);
            outline: none;
            color: #0f172a;
            padding: 8px 12px;
            font-family: var(--font-body);
            font-size: 13px;
            font-weight: 600;
            border-radius: 8px;
            cursor: pointer;
        }
                .custom-number-input {
            flex: 1;
            width: 0;
            min-width: 0;
            background: #f8fafc !important;
            border: none !important;
            outline: none !important;
            color: #0f172a !important;
            padding: 10px 14px !important;
            font-family: var(--font-body) !important;
            font-size: 15px !important;
            font-weight: 700 !important;
            text-align: right !important;
            box-shadow: none !important;
            -webkit-appearance: none !important;
            -moz-appearance: textfield !important;
        }
        .custom-number-input::-webkit-outer-spin-button,
        .custom-number-input::-webkit-inner-spin-button {
            -webkit-appearance: none;
            margin: 0;
        }
                .unit-badge {
            background: rgba(0, 0, 0, 0.03);
            color: var(--color-text-muted);
            font-size: 11px;
            font-weight: 700;
            padding: 0 14px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-left: 1px solid var(--color-border);
            pointer-events: none;
            flex-shrink: 0;
        }
        .custom-slider {
            -webkit-appearance: none;
            width: 100%;
            height: 6px;
            border-radius: 3px;
            background: rgba(0, 0, 0, 0.05);
            outline: none;
            margin: 6px 0;
        }
        .custom-slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 18px;
            height: 18px;
            border-radius: 50%;
            cursor: pointer;
            background: var(--color-cyan);
            box-shadow: 0 0 10px var(--color-cyan);
        }
        .presets-section {
            border-top: 1px solid var(--color-border);
            padding-top: 18px;
            display: flex;
            flex-direction: column;
            gap: 12px;
        }
        .presets-section h3 {
            font-size: 13px;
            font-weight: 700;
            color: var(--color-text-main);
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .presets-grid {
            display: grid;
            grid-template-columns: 1fr;
            gap: 8px;
        }
        .preset-btn {
            background: rgba(0, 0, 0, 0.015);
            border: 1px solid var(--color-border);
            border-radius: 10px;
            padding: 8px 12px;
            cursor: pointer;
            color: var(--color-text-main);
            display: flex;
            align-items: center;
            gap: 12px;
            text-align: left;
            transition: all 0.2s ease;
        }
        .preset-btn:hover {
            background: rgba(0, 0, 0, 0.05);
            transform: translateX(4px);
        }
        .preset-btn.active {
            background: linear-gradient(90deg, var(--color-cyan-glow), var(--color-magenta-glow));
            border-color: #0284c7;
            box-shadow: 0 0 10px var(--color-cyan-glow);
        }
        .preset-icon {
            width: 28px;
            height: 28px;
            background: rgba(0, 0, 0, 0.02);
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 12px;
            color: #0284c7;
        }
        .preset-btn:hover .preset-icon, .preset-btn.active .preset-icon {
            background: var(--gradient-primary);
            color: #fff;
        }
        .preset-name {
            font-size: 12px;
            font-weight: 600;
        }
        .simulation-panel {
            grid-column: 2;
            align-self: start;
        }
        .simulation-panel .panel-header {
            justify-content: space-between;
        }
        .canvas-scale-indicator {
            font-size: 11px;
            color: var(--color-text-muted);
            background: rgba(0, 0, 0, 0.02);
            padding: 4px 10px;
            border-radius: 6px;
            border: 1px solid var(--color-border);
        }
        .canvas-wrapper {
            position: relative;
            width: 100%;
            background: radial-gradient(circle at center, #ffffff 0%, #f1f5f9 100%);
            border: 1px solid rgba(0, 0, 0, 0.06);
            border-radius: 16px;
            overflow: hidden;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        #physics-canvas {
            display: block;
            width: 100%;
            height: auto;
            aspect-ratio: 16 / 9;
        }
        .results-panel {
            grid-column: 3;
        }
        .ratio-readout-box {
            background: linear-gradient(135deg, rgba(2, 132, 199, 0.08) 0%, rgba(124, 58, 237, 0.03) 100%);
            border: 1px solid rgba(2, 132, 199, 0.25);
            border-radius: 16px;
            padding: 20px;
            text-align: center;
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 6px;
        }
        .ratio-title {
            font-size: 11px;
            font-weight: 700;
            color: #0284c7;
            letter-spacing: 1px;
            text-transform: uppercase;
        }
        .ratio-value {
            font-family: var(--font-heading);
            font-weight: 800;
            font-size: 28px;
            background: linear-gradient(90deg, var(--color-text-main), var(--color-cyan));
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        .results-grid {
            display: flex;
            flex-direction: column;
            gap: 12px;
        }
        .result-card {
            background: rgba(255, 255, 255, 0.85);
            border: 1px solid var(--color-border);
            border-radius: 12px;
            padding: 12px 16px;
            display: flex;
            align-items: center;
            gap: 16px;
            transition: all 0.2s ease;
        }
        .result-card:hover {
            transform: translateY(-2px);
            border-color: rgba(2, 132, 199, 0.2);
            background: rgba(2, 132, 199, 0.03);
        }
        .card-icon {
            width: 38px;
            height: 38px;
            background: rgba(0, 0, 0, 0.015);
            border: 1px solid var(--color-border);
            border-radius: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            color: var(--color-text-muted);
        }
        .result-card:hover .card-icon {
            color: #0284c7;
            border-color: rgba(2, 132, 199, 0.3);
            background: rgba(2, 132, 199, 0.1);
        }
        .card-content {
            display: flex;
            flex-direction: column;
            gap: 2px;
        }
        .card-unit {
            font-size: 10px;
            font-weight: 600;
            color: var(--color-text-muted);
            text-transform: uppercase;
        }
        .card-value {
            font-family: var(--font-heading);
            font-weight: 700;
            font-size: 15px;
            color: var(--color-text-main);
        }
        .formula-card {
            background: rgba(0, 0, 0, 0.01);
            border: 1px solid var(--color-border);
            border-radius: 12px;
            padding: 16px;
            display: flex;
            flex-direction: column;
            gap: 8px;
            font-size: 12px;
        }
        .formula-card h4 {
            font-weight: 700;
            color: var(--color-text-main);
        }
        .formula-equation {
            font-family: monospace;
            color: #0284c7;
            font-size: 13px;
            background: #f8fafc;
            padding: 6px 10px;
            border-radius: 6px;
            border: 1px solid var(--color-border);
            text-align: center;
        }
        @container transfer-container (max-width: 1024px) {
            .app-main-grid {
                grid-template-columns: 1fr;
            }
            .control-panel {
                grid-column: 1;
                max-height: none;
            }
            .simulation-panel {
                grid-column: 1;
                order: -1;
            }
            .results-panel {
                grid-column: 1;
            }
        }
        .preset-details {
            display: flex;
            flex-direction: column;
            gap: 2px;
            align-items: flex-start;
            text-align: left;
        }
        .preset-spec {
            font-size: 11px;
            color: var(--color-text-muted);
            font-weight: 500;
        }
        .preset-name {
            font-size: 13px !important;
        }
/* ━━ WordPress 레이아웃 Override: 디자인 1 (2열 컴팩트 대칭 레이아웃) ━━ */
.heattransfer-calculator-wrapper .app-main-grid,
.heattransfer-calculator-wrapper .main-grid,
.heattransfer-calculator-wrapper .sim-grid {
    display: grid !important;
    grid-template-columns: 340px 1fr !important;
    gap: 24px !important;
    align-items: start !important;
}
/* 3열 레이아웃을 2열 레이아웃으로 변경하는 특화 스타일 */
.heattransfer-calculator-wrapper .right-column {
    display: flex !important;
    flex-direction: column !important;
    gap: 24px !important;
    min-width: 0 !important;
    grid-column: 2 !important;
}
.heattransfer-calculator-wrapper .simulation-panel,
.heattransfer-calculator-wrapper .canvas-panel,
.heattransfer-calculator-wrapper .sim-panel {
    grid-column: auto !important;
    order: 1 !important;
    align-self: stretch !important;
}
.heattransfer-calculator-wrapper .control-panel {
    grid-column: 1 !important;
}
/* 2열 통합 결과 분석 영역 레이아웃 */
.heattransfer-calculator-wrapper .simulation-results-section {
    display: grid !important;
    grid-template-columns: 1.1fr 1.3fr !important;
    gap: 20px !important;
    border-top: 1px solid var(--color-border) !important;
    padding-top: 20px !important;
    margin-top: 10px !important;
    align-items: stretch !important;
}
/* Readout Box 스타일 */
.heattransfer-calculator-wrapper .simulation-results-section .ratio-readout-box,
.heattransfer-calculator-wrapper .simulation-results-section .re-readout-box,
.heattransfer-calculator-wrapper .simulation-results-section .status-readout-box,
.heattransfer-calculator-wrapper .simulation-results-section .gauge-container {
    grid-column: 1 !important;
    grid-row: 1 !important;
    margin: 0 !important;
    height: auto !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
}
.heattransfer-calculator-wrapper .simulation-results-section .results-grid {
    grid-column: 2 !important;
    grid-row: 1 / span 2 !important;
    display: flex !important;
    flex-direction: column !important;
    gap: 12px !important;
    justify-content: flex-start !important;
}
.heattransfer-calculator-wrapper .simulation-results-section .results-grid .result-card {
    flex: none !important;
    display: flex !important;
    align-items: center !important;
    min-height: 72px !important;
    height: auto !important;
    padding: 12px 16px !important;
}
.heattransfer-calculator-wrapper .simulation-results-section .formula-card {
    grid-column: 1 !important;
    grid-row: 2 !important;
}
/* 모바일/반응형 (800px 이하) ── 항상 세로형(1열) 정렬 및 시뮬레이터 캔버스 최상단 배치 */
@media (max-width: 800px) {
    .heattransfer-calculator-wrapper .app-main-grid,
    .heattransfer-calculator-wrapper .main-grid,
    .heattransfer-calculator-wrapper .sim-grid {
        grid-template-columns: 1fr !important;
        display: flex !important;
        flex-direction: column !important;
    }
    .heattransfer-calculator-wrapper .control-panel {
        order: 2 !important;
        width: 100% !important;
    }
    .heattransfer-calculator-wrapper .right-column {
        order: 1 !important;
        width: 100% !important;
        display: flex !important;
        flex-direction: column !important;
    }
    .heattransfer-calculator-wrapper .simulation-panel,
    .heattransfer-calculator-wrapper .canvas-panel,
    .heattransfer-calculator-wrapper .sim-panel,
    .heattransfer-calculator-wrapper .canvas-section {
        order: -1 !important;
    }
    .heattransfer-calculator-wrapper .simulation-results-section {
        grid-template-columns: 1fr !important;
    }
    .heattransfer-calculator-wrapper .simulation-results-section .ratio-readout-box,
    .heattransfer-calculator-wrapper .simulation-results-section .re-readout-box,
    .heattransfer-calculator-wrapper .simulation-results-section .status-readout-box,
    .heattransfer-calculator-wrapper .simulation-results-section .gauge-container {
        grid-column: 1 !important;
        grid-row: auto !important;
        height: auto !important;
    }
    .heattransfer-calculator-wrapper .simulation-results-section .results-grid {
        grid-column: 1 !important;
        grid-row: auto !important;
    }
    .heattransfer-calculator-wrapper .simulation-results-section .formula-card {
        grid-column: 1 !important;
        grid-row: auto !important;
    }
}
.heattransfer-calculator-wrapper .app-container,
.heattransfer-calculator-wrapper .main-container {
    max-width: 100% !important;
    padding: 12px !important;
}
/* Premium Advice/Formula Card & Typography Overrides */
.heattransfer-calculator-wrapper .simulation-results-section .formula-card,
.heattransfer-calculator-wrapper .results-panel .formula-card {
    background: #ffffff !important;
    border: 1px solid var(--color-border) !important;
    border-radius: 12px !important;
    padding: 16px !important;
    box-shadow: var(--shadow-card) !important;
    transition: all 0.2s ease !important;
    display: flex !important;
    flex-direction: column !important;
    gap: 8px !important;
}
.heattransfer-calculator-wrapper .simulation-results-section .formula-card h4,
.heattransfer-calculator-wrapper .results-panel .formula-card h4 {
    font-weight: 700 !important;
    color: var(--color-text-main) !important;
}
.heattransfer-calculator-wrapper #text-judgment {
    font-size: 12px !important;
    font-weight: 500 !important;
    color: var(--color-text-muted) !important;
    line-height: 1.6 !important;
    word-break: keep-all !important;
}
</style>
<div class="heattransfer-calculator-wrapper" style="position: relative; width: 100%; box-sizing: border-box; overflow: hidden; margin: 30px auto; border-radius: 20px;">
    <div class="app-background-glow" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; overflow: hidden;"></div>
    <div style="position: relative; z-index: 2; width: 100%;">
    <div class="app-container">
        <!-- Header -->
        <header class="app-header">
            <div class="logo-area">
                <div class="logo-icon"><i class="fa-solid fa-arrows-left-right-to-line"></i></div>
                <div>
                    <h1>HEAT TRANSFER</h1>
                    <div class="subtitle">다층 복합벽 전열 계산기 &#038; 실시간 1D 열전달 시뮬레이터</div>
                </div>
            </div>
            <div class="header-badge">
                <div class="pulse-dot"></div>
                <div class="badge-text">전열 수치해석 실시간 계산중</div>
            </div>
        </header>
        <div class="app-main-grid">
            <!-- Left Column: Controls -->
            <div class="panel control-panel">
                <div class="panel-header">
                    <i class="fa-solid fa-sliders text-cyan"></i>
                    <h2>벽체 및 경계인자 제어</h2>
                </div>
                <div class="input-group">
                    <div class="input-label-row">
                        <label><i class="fa-solid fa-temperature-arrow-up text-magenta"></i> 고온 유체 온도 (T_f,h)</label>
                        <span class="range-helper">Min: 50°C / Max: 600°C</span>
                    </div>
                    <div class="number-input-wrapper">
                        <input type="number" id="input-tfh" class="custom-number-input" value="400" step="1" min="50" max="600">
                        <span class="unit-badge">°C</span>
                    </div>
                    <input type="range" id="slider-tfh" class="custom-slider" value="400" min="50" max="600" step="1">
                </div>
                <div class="input-group">
                    <div class="input-label-row">
                        <label><i class="fa-solid fa-temperature-arrow-down text-cyan"></i> 저온 유체 온도 (T_f,c)</label>
                        <span class="range-helper">Min: -20°C / Max: 50°C</span>
                    </div>
                    <div class="number-input-wrapper">
                        <input type="number" id="input-tfc" class="custom-number-input" value="15" step="1" min="-20" max="50">
                        <span class="unit-badge">°C</span>
                    </div>
                    <input type="range" id="slider-tfc" class="custom-slider" value="15" min="-20" max="50" step="1">
                </div>
                <!-- Layer 1 -->
                <div class="input-group">
                    <div class="input-label-row">
                        <label>Layer 1 (고온측 재질/두께)</label>
                    </div>
                    <select id="select-k1" class="custom-select">
                        <option value="brick" selected>적벽돌 (Brick &#8211; 0.7 W/m·K)</option>
                        <option value="steel">강철 (Steel &#8211; 50.0 W/m·K)</option>
                        <option value="concrete">콘크리트 (Concrete &#8211; 1.4 W/m·K)</option>
                        <option value="glasswool">글라스울 (Glasswool &#8211; 0.04 W/m·K)</option>
                    </select>
                    <div class="number-input-wrapper" style="margin-top: 4px;">
                        <input type="number" id="input-l1" class="custom-number-input" value="120" step="10" min="10" max="300">
                        <span class="unit-badge">mm</span>
                    </div>
                    <input type="range" id="slider-l1" class="custom-slider" value="120" min="10" max="300" step="10">
                </div>
                <!-- Layer 2 -->
                <div class="input-group">
                    <div class="input-label-row">
                        <label>Layer 2 (중간층 재질/두께)</label>
                    </div>
                    <select id="select-k2" class="custom-select">
                        <option value="glasswool" selected>글라스울 (Glasswool &#8211; 0.04 W/m·K)</option>
                        <option value="steel">강철 (Steel &#8211; 50.0 W/m·K)</option>
                        <option value="concrete">콘크리트 (Concrete &#8211; 1.4 W/m·K)</option>
                        <option value="brick">적벽돌 (Brick &#8211; 0.7 W/m·K)</option>
                    </select>
                    <div class="number-input-wrapper" style="margin-top: 4px;">
                        <input type="number" id="input-l2" class="custom-number-input" value="50" step="10" min="10" max="300">
                        <span class="unit-badge">mm</span>
                    </div>
                    <input type="range" id="slider-l2" class="custom-slider" value="50" min="10" max="300" step="10">
                </div>
                <!-- Layer 3 -->
                <div class="input-group">
                    <div class="input-label-row">
                        <label>Layer 3 (저온측 재질/두께)</label>
                    </div>
                    <select id="select-k3" class="custom-select">
                        <option value="concrete" selected>콘크리트 (Concrete &#8211; 1.4 W/m·K)</option>
                        <option value="steel">강철 (Steel &#8211; 50.0 W/m·K)</option>
                        <option value="brick">적벽돌 (Brick &#8211; 0.7 W/m·K)</option>
                        <option value="glasswool">글라스울 (Glasswool &#8211; 0.04 W/m·K)</option>
                    </select>
                    <div class="number-input-wrapper" style="margin-top: 4px;">
                        <input type="number" id="input-l3" class="custom-number-input" value="120" step="10" min="10" max="300">
                        <span class="unit-badge">mm</span>
                    </div>
                    <input type="range" id="slider-l3" class="custom-slider" value="120" min="10" max="300" step="10">
                </div>
                <div class="presets-section">
                    <h3><i class="fa-solid fa-hotel text-purple"></i> 벽체 구성 프리셋</h3>
                    <div class="presets-grid">
                        <button class="preset-btn" data-preset="insulated">
                            <div class="preset-icon"><i class="fa-solid fa-shield-halved"></i></div>
                            <div class="preset-details"><span class="preset-name">고성능 표준 단열벽 시나리오</div>
                        </button>
                        <button class="preset-btn" data-preset="non_insulated">
                            <div class="preset-icon"><i class="fa-solid fa-triangle-exclamation"></i></div>
                            <div class="preset-name">미단열 콘크리트벽</span><span class="preset-spec">열교현상</span></div>
                        </button>
                        <button class="preset-btn" data-preset="extreme">
                            <div class="preset-icon"><i class="fa-solid fa-snowflake"></i></div>
                            <div class="preset-details"><span class="preset-name">극저온 혹한 외부 노출 전열</div>
                        </button>
                    </div>
                </div>
            </div>
            <!-- Auto Injected Right Column wrapper for Design 1 -->
            <div class="right-column">
                <div class="panel simulation-panel">
                                <div class="panel-header">
                                    <div>
                                        <i class="fa-solid fa-chart-line text-cyan"></i>
                                        <h2>실시간 다층벽 온도 구배 (Temperature Gradient Line)</h2>
                                    </div>
                                </div>
                                <div class="canvas-wrapper">
                                    <canvas id="physics-canvas"></canvas>
                                </div>
                            <div class="simulation-results-section">
                                <div class="ratio-readout-box">
                                    <div class="ratio-title">통과 열유속</span><span class="preset-spec">Heat Flux &#8211; q&#8221;</span></div>
                                    <div id="txt-heat-flux" class="ratio-value">256.4 W/m²</div>
                                </div>
                                <div class="results-grid">
                                    <div class="result-card">
                                        <div class="card-icon"><i class="fa-solid fa-wave-square"></i></div>
                                        <div class="card-content">
                                            <div class="card-unit">총 열저항 (R_tot)</div>
                                            <div id="txt-rtot" class="card-value">1.500 m²·K/W</div>
                                        </div>
                                    </div>
                                    <div class="result-card">
                                        <div class="card-icon"><i class="fa-solid fa-bolt"></i></div>
                                        <div class="card-content">
                                            <div class="card-unit">총괄 열전달 계수 (U-Value)</div>
                                            <div id="txt-uvalue" class="card-value">0.667 W/m²·K</div>
                                        </div>
                                    </div>
                                    <div class="result-card">
                                        <div class="card-icon"><i class="fa-solid fa-circle-down"></i></div>
                                        <div class="card-content">
                                            <div class="card-unit">내부 표면 온도 (T_s,c)</div>
                                            <div id="txt-tsc" class="card-value">20.4 °C</div>
                                        </div>
                                    </div>
                                    <div class="result-card">
                                        <div class="card-icon"><i class="fa-solid fa-circle-up"></i></div>
                                        <div class="card-content">
                                            <div class="card-unit">외부 표면 온도 (T_s,h)</div>
                                            <div id="txt-tsh" class="card-value">374.5 °C</div>
                                        </div>
                                    </div>
                                </div>
                                <div class="formula-card">
                                    <h4>다층 벽체 총 열저항 식</h4>
                                    <div class="formula-equation">R = 1/h_h + Σ(L_i/k_i) + 1/h_c</div>
                                </div>
                            </div>
                </div>
            </div>
        </div>
        <!-- Disclaimer Footer -->
        <footer class="app-disclaimer" style="margin-top: 20px; padding: 12px 16px; background: rgba(0, 0, 0, 0.015); border: 1px solid var(--color-border); border-radius: 12px; font-size: 11px; color: var(--color-text-muted); line-height: 1.5; text-align: left; display: flex; gap: 10px; align-items: flex-start; clear: both;">
            <i class="fa-solid fa-circle-info" style="color: var(--color-cyan); font-size: 14px; margin-top: 2px; flex-shrink: 0;"></i>
            <span><strong>면책 조항 (Disclaimer):</strong> 본 시뮬레이터의 계산 결과는 교육 및 참고용으로만 제공되며, 실제 제품 설계나 제작 시에는 반드시 최신 공학 규격 및 공식 표준 설계 기준을 재확인하시기 바랍니다. 계산 값의 무결성을 보장하지 않으며, 이로 인해 발생하는 직접적/간접적 손해에 대해 제작자 및 본 블로그는 어떠한 책임을 지지 않습니다.</span>
        </footer>
</div>
    <!-- JavaScript Core Simulator Engine -->
    </div>
</div>
<script>
        (function() {
            let isInit = false;
            function initSimulator() {
                if (isInit) return;
                const canvas = document.getElementById('physics-canvas');
                if (!canvas) return;
                const ctx = canvas.getContext('2d');
                if (!ctx) return;
                isInit = true;
                window.__heattransfer_initialized = true;
                // DOM controls
                const sliderTfh = document.getElementById('slider-tfh');
                const inputTfh = document.getElementById('input-tfh');
                const sliderTfc = document.getElementById('slider-tfc');
                const inputTfc = document.getElementById('input-tfc');
                const selectK1 = document.getElementById('select-k1');
                const sliderL1 = document.getElementById('slider-l1');
                const inputL1 = document.getElementById('input-l1');
                const selectK2 = document.getElementById('select-k2');
                const sliderL2 = document.getElementById('slider-l2');
                const inputL2 = document.getElementById('input-l2');
                const selectK3 = document.getElementById('select-k3');
                const sliderL3 = document.getElementById('slider-l3');
                const inputL3 = document.getElementById('input-l3');
                const presetBtns = document.querySelectorAll('.preset-btn');
                // Readouts
                const txtHeatFlux = document.getElementById('txt-heat-flux');
                const txtRtot = document.getElementById('txt-rtot');
                const txtUvalue = document.getElementById('txt-uvalue');
                const txtTsc = document.getElementById('txt-tsc');
                const txtTsh = document.getElementById('txt-tsh');
                // Material conductivity table [W/m·K]
                const conductivities = {
                    brick: 0.7,
                    steel: 50.0,
                    concrete: 1.4,
                    glasswool: 0.04
                };
                // State
                const state = {
                    tfh: 400.0,
                    tfc: 15.0,
                    l1: 0.12,  // in meters
                    l2: 0.05,
                    l3: 0.12,
                    k1: 0.7,   // brick
                    k2: 0.04,  // glasswool
                    k3: 1.4,   // concrete
                    hh: 100.0, // convection hot W/m2K
                    hc: 25.0,  // convection cold W/m2K
                    particles: [],
                    fluxOffset: 0
                };
                function resizeCanvas() {
                    const rect = canvas.getBoundingClientRect();
                    const dpr = window.devicePixelRatio || 1;
                    canvas.width = rect.width * dpr;
                    canvas.height = rect.height * dpr;
                    ctx.scale(dpr, dpr);
                    state.particles = [];
                }
                resizeCanvas();
                window.addEventListener('resize', resizeCanvas);
                setTimeout(resizeCanvas, 300);
                // Input Synchronization with strict "clamping on change only"
                function syncTfhFromSlider() {
                    state.tfh = parseFloat(sliderTfh.value);
                    inputTfh.value = Math.round(state.tfh);
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncTfhFromInput() {
                    let val = parseFloat(inputTfh.value);
                    if (isNaN(val)) {
                        val = 400;
                    }
                    if (val < 50) {
                        val = 50;
                    }
                    if (val > 600) {
                        val = 600;
                    }
                    inputTfh.value = Math.round(val);
                    sliderTfh.value = val;
                    state.tfh = val;
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncTfcFromSlider() {
                    state.tfc = parseFloat(sliderTfc.value);
                    inputTfc.value = Math.round(state.tfc);
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncTfcFromInput() {
                    let val = parseFloat(inputTfc.value);
                    if (isNaN(val)) {
                        val = 15;
                    }
                    if (val < -20) {
                        val = -20;
                    }
                    if (val > 50) {
                        val = 50;
                    }
                    inputTfc.value = Math.round(val);
                    sliderTfc.value = val;
                    state.tfc = val;
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncL1FromSlider() {
                    state.l1 = parseFloat(sliderL1.value) / 1000;
                    inputL1.value = Math.round(sliderL1.value);
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncL1FromInput() {
                    let val = parseFloat(inputL1.value);
                    if (isNaN(val)) {
                        val = 120;
                    }
                    if (val < 10) {
                        val = 10;
                    }
                    if (val > 300) {
                        val = 300;
                    }
                    inputL1.value = Math.round(val);
                    sliderL1.value = val;
                    state.l1 = val / 1000;
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncL2FromSlider() {
                    state.l2 = parseFloat(sliderL2.value) / 1000;
                    inputL2.value = Math.round(sliderL2.value);
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncL2FromInput() {
                    let val = parseFloat(inputL2.value);
                    if (isNaN(val)) {
                        val = 50;
                    }
                    if (val < 10) {
                        val = 10;
                    }
                    if (val > 300) {
                        val = 300;
                    }
                    inputL2.value = Math.round(val);
                    sliderL2.value = val;
                    state.l2 = val / 1000;
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncL3FromSlider() {
                    state.l3 = parseFloat(sliderL3.value) / 1000;
                    inputL3.value = Math.round(sliderL3.value);
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncL3FromInput() {
                    let val = parseFloat(inputL3.value);
                    if (isNaN(val)) {
                        val = 120;
                    }
                    if (val < 10) {
                        val = 10;
                    }
                    if (val > 300) {
                        val = 300;
                    }
                    inputL3.value = Math.round(val);
                    sliderL3.value = val;
                    state.l3 = val / 1000;
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncSelectK1() {
                    state.k1 = conductivities[selectK1.value];
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncSelectK2() {
                    state.k2 = conductivities[selectK2.value];
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                function syncSelectK3() {
                    state.k3 = conductivities[selectK3.value];
                    clearPresets();
                    updateHeatTransferCalculations();
                }
                // Preset scripts
                function loadPreset(key) {
                    clearPresets();
                    presetBtns.forEach(btn => {
                        if (btn.dataset.preset === key) {
                            btn.classList.add('active');
                        }
                    });
                    if (key === 'insulated') {
                        state.tfh = 450;
                        state.tfc = 15;
                        state.l1 = 0.12;
                        state.l2 = 0.08;
                        state.l3 = 0.12;
                        selectK1.value = 'brick';
                        selectK2.value = 'glasswool';
                        selectK3.value = 'concrete';
                    }
                    if (key === 'non_insulated') {
                        state.tfh = 300;
                        state.tfc = 15;
                        state.l1 = 0.10;
                        state.l2 = 0.15;
                        state.l3 = 0.10;
                        selectK1.value = 'concrete';
                        selectK2.value = 'steel';
                        selectK3.value = 'concrete';
                    }
                    if (key === 'extreme') {
                        state.tfh = 550;
                        state.tfc = -20;
                        state.l1 = 0.15;
                        state.l2 = 0.12;
                        state.l3 = 0.08;
                        selectK1.value = 'brick';
                        selectK2.value = 'glasswool';
                        selectK3.value = 'brick';
                    }
                    state.k1 = conductivities[selectK1.value];
                    state.k2 = conductivities[selectK2.value];
                    state.k3 = conductivities[selectK3.value];
                    sliderTfh.value = state.tfh;
                    inputTfh.value = state.tfh;
                    sliderTfc.value = state.tfc;
                    inputTfc.value = state.tfc;
                    sliderL1.value = state.l1 * 1000;
                    inputL1.value = state.l1 * 1000;
                    sliderL2.value = state.l2 * 1000;
                    inputL2.value = state.l2 * 1000;
                    sliderL3.value = state.l3 * 1000;
                    inputL3.value = state.l3 * 1000;
                    updateHeatTransferCalculations();
                }
                function clearPresets() {
                    presetBtns.forEach(btn => btn.classList.remove('active'));
                }
                // Math Engine
                const nodalTemps = {
                    tfh: 0,
                    tsh: 0,
                    t12: 0,
                    t23: 0,
                    tsc: 0,
                    tfc: 0,
                    heatFlux: 0
                };
                function updateHeatTransferCalculations() {
                    // Thermal resistances
                    const r_conv_h = 1.0 / state.hh;
                    const r_cond_1 = state.l1 / state.k1;
                    const r_cond_2 = state.l2 / state.k2;
                    const r_cond_3 = state.l3 / state.k3;
                    const r_conv_c = 1.0 / state.hc;
                    const R_tot = r_conv_h + r_cond_1 + r_cond_2 + r_cond_3 + r_conv_c;
                    const uValue = 1.0 / R_tot;
                    const heatFlux = (state.tfh - state.tfc) / R_tot; // W/m²
                    // Calculate nodal interface temperatures
                    nodalTemps.tfh = state.tfh;
                    nodalTemps.tsh = state.tfh - heatFlux * r_conv_h;
                    nodalTemps.t12 = nodalTemps.tsh - heatFlux * r_cond_1;
                    nodalTemps.t23 = nodalTemps.t12 - heatFlux * r_cond_2;
                    nodalTemps.tsc = nodalTemps.t23 - heatFlux * r_cond_3;
                    nodalTemps.tfc = state.tfc;
                    nodalTemps.heatFlux = heatFlux;
                    // Update DOM metrics display
                    txtHeatFlux.innerText = `${heatFlux.toFixed(1)} W/m²`;
                    txtRtot.innerText = `${R_tot.toFixed(4)} m²·K/W`;
                    txtUvalue.innerText = `${uValue.toFixed(3)} W/m²·K`;
                    txtTsh.innerText = `${nodalTemps.tsh.toFixed(1)} °C`;
                    txtTsc.innerText = `${nodalTemps.tsc.toFixed(1)} °C`;
                }
                // Fluid Flow Animation Particle
                class FluidFlowParticle {
                    constructor(xRange, type) {
                        this.xMin = xRange[0];
                        this.xMax = xRange[1];
                        this.x = this.xMin + Math.random() * (this.xMax - this.xMin);
                        this.y = 0; // Will be initialized by dynamic setupY
                        this.type = type; // 'hot' or 'cold'
                        this.size = Math.random() * 3 + 1.5;
                        this.vy = (Math.random() - 0.5) * 0.8;
                        this.vx = (Math.random() - 0.5) * 0.4;
                        if (type === 'hot') {
                            this.color = `rgba(239, 68, 68, ${Math.random() * 0.4 + 0.25})`;
                        }
                        if (type === 'cold') {
                            this.color = `rgba(56, 189, 248, ${Math.random() * 0.4 + 0.25})`;
                        }
                    }
                    setupY(wY, wH) {
                        this.y = wY + Math.random() * wH;
                    }
                    update(wY, wH) {
                        this.x += this.vx;
                        this.y += this.vy;
                        // Boundary bounds check
                        if (this.x < this.xMin) {
                            this.x = this.xMax;
                        }
                        if (this.x > this.xMax) {
                            this.x = this.xMin;
                        }
                        if (this.y < wY) {
                            this.y = wY + wH;
                        }
                        if (this.y > wY + wH) {
                            this.y = wY;
                        }
                    }
                    draw(c) {
                        c.save();
                        c.fillStyle = this.color;
                        c.beginPath();
                        c.arc(this.x, this.y, this.size, 0, Math.PI * 2);
                        c.fill();
                        c.restore();
                    }
                }
                // Populate particles
                function initParticles(width, wY, wH) {
                    state.particles = [];
                    // Hot fluid left
                    for (let i = 0; i < 40; i++) {
                        const p = new FluidFlowParticle([10, 100], 'hot');
                        p.setupY(wY, wH);
                        state.particles.push(p);
                    }
                    // Cold fluid right
                    for (let i = 0; i < 40; i++) {
                        const p = new FluidFlowParticle([width - 100, width - 10], 'cold');
                        p.setupY(wY, wH);
                        state.particles.push(p);
                    }
                }
                // Animation main loop
                function animate(timestamp) {
                    requestAnimationFrame(animate);
                    // Check and auto-fit canvas resolution to layout changes (prevents vertical stretch &#038; empty gaps)
                    const dpr = window.devicePixelRatio || 1;
                    const rect = canvas.getBoundingClientRect();
                    if (Math.abs(canvas.width - rect.width * dpr) > 1.5 || Math.abs(canvas.height - rect.height * dpr) > 1.5) {
                        resizeCanvas();
                    }
                    const width = canvas.width / dpr;
                    const height = canvas.height / dpr;
                    ctx.clearRect(0, 0, width, height);
                    // Blueprint grid
                    ctx.save();
                    ctx.strokeStyle = 'rgba(2, 132, 199, 0.05)';
                    ctx.lineWidth = 1;
                    for (let x = 0; x < width; x += 24) {
                        ctx.beginPath();
                        ctx.moveTo(x, 0);
                        ctx.lineTo(x, height);
                        ctx.stroke();
                    }
                    for (let y = 0; y < height; y += 24) {
                        ctx.beginPath();
                        ctx.moveTo(0, y);
                        ctx.lineTo(width, y);
                        ctx.stroke();
                    }
                    ctx.restore();
                    // Wall Drawing Layout Coordinates
                    const wallLeftX = 115;
                    const wallRightX = width - 115;
                    const wallWidth = wallRightX - wallLeftX;
                    const wallHeight = Math.max(100, Math.min(150, height * 0.42));
                    // Golden Vertical Centering: mathematically centers the composite walls and graph lines
                    // Shift wall slightly up by 15px to give more room at the bottom for labels
                    const wallY = (height - wallHeight) / 2 - 15;
                    // Initialize particles on canvas resize
                    if (state.particles.length === 0) {
                        initParticles(width, wallY, wallHeight);
                    }
                    // Thickness proportions in pixels
                    const totalL = state.l1 + state.l2 + state.l3;
                    const w1 = (state.l1 / totalL) * wallWidth;
                    const w2 = (state.l2 / totalL) * wallWidth;
                    const w3 = (state.l3 / totalL) * wallWidth;
                    const x0 = wallLeftX;
                    const x1 = x0 + w1;
                    const x2 = x1 + w2;
                    const x3 = x2 + w3;
                    // Draw fluids on left/right edges
                    // Hot Fluid Left Block
                    ctx.fillStyle = 'rgba(239, 68, 68, 0.03)';
                    ctx.fillRect(10, wallY, wallLeftX - 10, wallHeight);
                    // Cold Fluid Right Block
                    ctx.fillStyle = 'rgba(56, 189, 248, 0.03)';
                    ctx.fillRect(wallRightX, wallY, width - wallRightX - 10, wallHeight);
                    // Update &#038; draw fluid flows
                    state.particles.forEach(p => {
                        p.update(wallY, wallHeight);
                        p.draw(ctx);
                    });
                    // Draw Composite Wall Layers
                    // Layer 1
                    ctx.save();
                    drawLayerBox(x0, wallY, w1, wallHeight, selectK1.value);
                    // Layer 2
                    drawLayerBox(x1, wallY, w2, wallHeight, selectK2.value);
                    // Layer 3
                    drawLayerBox(x2, wallY, w3, wallHeight, selectK3.value);
                    ctx.restore();
                    // Temperature axis y-mapping
                    // Maps temperature from state.tfh to state.tfc onto wall height [wallY+20, wallY+wallHeight-20]
                    const maxTemp = Math.max(state.tfh, 100);
                    const minTemp = Math.min(state.tfc, 0);
                    const tempSpan = maxTemp - minTemp;
                    function mapTempToY(temp) {
                        const ratio = (temp - minTemp) / tempSpan;
                        // Invert so high temperatures are at the top, leaving a comfortable 20px padding at the borders
                        return wallY + wallHeight - 20 - ratio * (wallHeight - 40);
                    }
                    // Compute node mapping positions on x-axis
                    const px_fh = 70;
                    const px_sh = x0;
                    const px_12 = x1;
                    const px_23 = x2;
                    const px_sc = x3;
                    const px_fc = width - 70;
                    const py_fh = mapTempToY(nodalTemps.tfh);
                    const py_sh = mapTempToY(nodalTemps.tsh);
                    const py_12 = mapTempToY(nodalTemps.t12);
                    const py_23 = mapTempToY(nodalTemps.t23);
                    const py_sc = mapTempToY(nodalTemps.tsc);
                    const py_fc = mapTempToY(nodalTemps.tfc);
                    // Draw Temperature Gradient Line Curve
                    ctx.save();
                    ctx.strokeStyle = '#db2777';
                    ctx.lineWidth = 4.5;
                    ctx.shadowBlur = 10;
                    ctx.shadowColor = 'rgba(219, 39, 119, 0.4)';
                    ctx.lineCap = 'round';
                    ctx.lineJoin = 'round';
                    ctx.beginPath();
                    ctx.moveTo(px_fh, py_fh);
                    ctx.lineTo(px_sh, py_sh);
                    ctx.lineTo(px_12, py_12);
                    ctx.lineTo(px_23, py_23);
                    ctx.lineTo(px_sc, py_sc);
                    ctx.lineTo(px_fc, py_fc);
                    ctx.stroke();
                    ctx.shadowBlur = 0;
                    ctx.restore();
                    // Draw connection points (circles) & labels
                    const nodes = [
                        { x: px_fh, y: py_fh, label: `T_fh: ${Math.round(nodalTemps.tfh)}°C`, col: '#ef4444', align: 'right', ox: -8, oy: -10 },
                        { x: px_sh, y: py_sh, label: `T_sh: ${nodalTemps.tsh.toFixed(1)}°C`, col: '#ea580c', align: 'left', ox: 8, oy: -10 },
                        { x: px_12, y: py_12, label: `${nodalTemps.t12.toFixed(1)}°C`, col: '#7c3aed', align: 'center', ox: 0, oy: -10 },
                        { x: px_23, y: py_23, label: `${nodalTemps.t23.toFixed(1)}°C`, col: '#7c3aed', align: 'center', ox: 0, oy: -10 },
                        { x: px_sc, y: py_sc, label: `T_sc: ${nodalTemps.tsc.toFixed(1)}°C`, col: '#2563eb', align: 'right', ox: -8, oy: -10 },
                        { x: px_fc, y: py_fc, label: `T_fc: ${Math.round(nodalTemps.tfc)}°C`, col: '#0284c7', align: 'left', ox: 8, oy: -10 }
                    ];
                    nodes.forEach(node => {
                        ctx.beginPath();
                        ctx.arc(node.x, node.y, 5, 0, Math.PI * 2);
                        ctx.fillStyle = '#ffffff';
                        ctx.fill();
                        ctx.strokeStyle = node.col;
                        ctx.lineWidth = 2.5;
                        ctx.stroke();
                        ctx.fillStyle = '#0f172a';
                        ctx.font = 'bold 9.5px sans-serif';
                        ctx.textAlign = node.align;
                        ctx.fillText(node.label, node.x + node.ox, node.y + node.oy);
                    });
                    // Draw convective film layers visually
                    ctx.save();
                    ctx.strokeStyle = 'rgba(239, 68, 68, 0.25)';
                    ctx.lineWidth = 2;
                    ctx.setLineDash([3, 3]);
                    ctx.beginPath();
                    ctx.moveTo(x0 - 15, wallY);
                    ctx.lineTo(x0 - 15, wallY + wallHeight);
                    ctx.stroke();
                    ctx.strokeStyle = 'rgba(56, 189, 248, 0.25)';
                    ctx.beginPath();
                    ctx.moveTo(x3 + 15, wallY);
                    ctx.lineTo(x3 + 15, wallY + wallHeight);
                    ctx.stroke();
                    ctx.restore();
                    // Heat Flux Flow indicator Arrow at bottom
                    ctx.save();
                    const arrowY = height - 25;
                    ctx.fillStyle = '#e2e8f0';
                    ctx.fillRect(wallLeftX - 10, arrowY - 6, wallWidth + 20, 12);
                    const arrowGrad = ctx.createLinearGradient(wallLeftX - 10, 0, wallRightX + 10, 0);
                    arrowGrad.addColorStop(0, '#f97316');
                    arrowGrad.addColorStop(1, '#0284c7');
                    ctx.fillStyle = arrowGrad;
                    const normalizedFluxSize = Math.min(nodalTemps.heatFlux / 1200, 1.0);
                    const flowBarHeight = Math.max(normalizedFluxSize * 10, 2);
                    ctx.fillRect(wallLeftX - 10, arrowY - flowBarHeight / 2, wallWidth + 20, flowBarHeight);
                    // Moving energy packets along heat path
                    state.fluxOffset += nodalTemps.heatFlux * 0.003;
                    if (state.fluxOffset > 40) {
                        state.fluxOffset = 0;
                    }
                    ctx.fillStyle = '#ffffff';
                    for (let ax = wallLeftX + state.fluxOffset; ax < wallRightX; ax += 30) {
                        ctx.beginPath();
                        ctx.arc(ax, arrowY, 2.5, 0, Math.PI * 2);
                        ctx.fill();
                    }
                    ctx.fillStyle = '#475569';
                    ctx.font = 'bold 10px Outfit';
                    ctx.fillText('전송 열에너지 흐름 방향 (Heat Energy Flux Path)', wallLeftX, arrowY - 14);
                    ctx.restore();
                    // Add material names below layers
                    ctx.save();
                    ctx.fillStyle = '#475569';
                    ctx.font = 'bold 9.5px sans-serif';
                    ctx.textAlign = 'center';
                    ctx.fillText(getMaterialLabel(selectK1.value) + ` (${Math.round(state.l1 * 1000)}mm)`, x0 + w1 / 2, wallY + wallHeight + 16);
                    ctx.fillText(getMaterialLabel(selectK2.value) + ` (${Math.round(state.l2 * 1000)}mm)`, x1 + w2 / 2, wallY + wallHeight + 16);
                    ctx.fillText(getMaterialLabel(selectK3.value) + ` (${Math.round(state.l3 * 1000)}mm)`, x2 + w3 / 2, wallY + wallHeight + 16);
                    ctx.restore();
                }
                // Helper to color/pattern wall materials
                function drawLayerBox(x, y, w, h, mat) {
                    if (mat === 'steel') {
                        const g = ctx.createLinearGradient(x, y, x + w, y);
                        g.addColorStop(0, '#cbd5e1');
                        g.addColorStop(1, '#94a3b8');
                        ctx.fillStyle = g;
                        ctx.fillRect(x, y, w, h);
                        ctx.strokeStyle = '#475569';
                        ctx.strokeRect(x, y, w, h);
                    }
                    if (mat === 'concrete') {
                        ctx.fillStyle = '#e2e8f0';
                        ctx.fillRect(x, y, w, h);
                        // Speckles (constrained inside boundaries with 2px padding)
                        ctx.fillStyle = 'rgba(0,0,0,0.15)';
                        for (let s = 0; s < 12; s++) {
                            const sx = x + 2 + (Math.sin(s * 10) * 0.5 + 0.5) * (w - 4);
                            const sy = y + 2 + (Math.cos(s * 7) * 0.5 + 0.5) * (h - 4);
                            ctx.fillRect(sx, sy, 2, 2);
                        }
                        ctx.strokeStyle = '#64748b';
                        ctx.strokeRect(x, y, w, h);
                    }
                    if (mat === 'brick') {
                        ctx.fillStyle = '#fca5a5';
                        ctx.fillRect(x, y, w, h);
                        // Brick joints lines
                        ctx.strokeStyle = 'rgba(255,255,255,0.45)';
                        ctx.lineWidth = 1.5;
                        for (let bx = x + 10; bx < x + w; bx += 14) {
                            ctx.beginPath();
                            ctx.moveTo(bx, y);
                            ctx.lineTo(bx, y + h);
                            ctx.stroke();
                        }
                        for (let by = y + 15; by < y + h; by += 20) {
                            ctx.beginPath();
                            ctx.moveTo(x, by);
                            ctx.lineTo(x + w, by);
                            ctx.stroke();
                        }
                        ctx.strokeStyle = '#b91c1c';
                        ctx.strokeRect(x, y, w, h);
                    }
                    if (mat === 'glasswool') {
                        ctx.fillStyle = '#fef08a';
                        ctx.fillRect(x, y, w, h);
                        // Swirls fibers (dynamically spaced and bound to box height h)
                        ctx.strokeStyle = '#eab308';
                        ctx.lineWidth = 1;
                        const spacing = 24;
                        const r = Math.min(w * 0.35, 10);
                        const startY = y + r + 5;
                        const maxY = y + h - r - 5;
                        let f = 0;
                        while (true) {
                            const cy = startY + f * spacing;
                            if (cy > maxY) {
                                break;
                            }
                            ctx.beginPath();
                            ctx.arc(x + w / 2, cy, r, 0, Math.PI, f % 2 === 0);
                            ctx.stroke();
                            f++;
                        }
                        ctx.strokeStyle = '#ca8a04';
                        ctx.strokeRect(x, y, w, h);
                    }
                }
                function getMaterialLabel(mat) {
                    if (mat === 'brick') return '적벽돌';
                    if (mat === 'steel') return '강철';
                    if (mat === 'concrete') return '콘크리트';
                    if (mat === 'glasswool') return '글라스울';
                    return '';
                }
                // Event Listeners Mapping
                sliderTfh.addEventListener('input', syncTfhFromSlider);
                inputTfh.addEventListener('change', syncTfhFromInput);
                sliderTfc.addEventListener('input', syncTfcFromSlider);
                inputTfc.addEventListener('change', syncTfcFromInput);
                sliderL1.addEventListener('input', syncL1FromSlider);
                inputL1.addEventListener('change', syncL1FromInput);
                sliderL2.addEventListener('input', syncL2FromSlider);
                inputL2.addEventListener('change', syncL2FromInput);
                sliderL3.addEventListener('input', syncL3FromSlider);
                inputL3.addEventListener('change', syncL3FromInput);
                selectK1.addEventListener('change', syncSelectK1);
                selectK2.addEventListener('change', syncSelectK2);
                selectK3.addEventListener('change', syncSelectK3);
                presetBtns.forEach(btn => {
                    btn.addEventListener('click', function() {
                        loadPreset(btn.dataset.preset);
                    });
                });
                // Load Initial configuration
                loadPreset('insulated');
                requestAnimationFrame(animate);
                // Anti-copying / Context protection code
                document.addEventListener('contextmenu', function(e) {
                    e.preventDefault();
                    alert("이 시뮬레이터 프로그램의 지식재산권은 보호받고 있습니다.");
                    return false;
                }, { capture: true });
                document.addEventListener('selectstart', function(e) {
                    e.preventDefault();
                    return false;
                }, { capture: true });
            }
            // Retry loader sequence
            let loadAttempts = 0;
            function tryLoad() {
                loadAttempts++;
                initSimulator();
                if (!window.__heattransfer_initialized) {
                    if (loadAttempts < 50) {
                        setTimeout(tryLoad, 100);
                    }
                }
            }
            if (document.readyState === 'complete' || document.readyState === 'interactive') {
                tryLoad();
            } else {
                document.addEventListener('DOMContentLoaded', tryLoad);
                window.addEventListener('load', tryLoad);
            }
        })();
</script>


<div style="background: linear-gradient(135deg, rgba(0,242,254,0.03), rgba(138,43,226,0.03)); border: 1px solid rgba(0,242,254,0.15); border-radius: 12px; padding: 18px 24px; margin: 25px auto 35px auto; font-size: 0.95em; color: #4b5563; line-height: 1.7; font-family: sans-serif;">
    <strong style="color: #1f2937; font-size: 1.05em; display: flex; align-items: center; gap: 8px;">
        <span style="font-size: 1.2em;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span> 간편 사용 설명서
    </strong>
    <ol style="margin: 10px 0 0 0; padding-left: 20px;">
        <li style="margin-bottom: 6px;"><strong>유체 경계 온도 설정: 고온측 유체 온도(Tf,h)와 저온측 유체 온도(Tf,c)를 설정합니다.</strong></li>
<li style="margin-bottom: 6px;">벽체 레이어 설계: 복합벽을 구성하는 3개 레이어의 재질(강철, 콘크리트, 적벽돌, 글라스울 단열재 등)과 각각의 두께(L)를 입력합니다.</li>
<li style="margin-bottom: 6px;">대류 열전달 계수 조절: 좌측 고온측과 우측 저온측의 대류 경계막 계수(h)를 설정하여 대류 저항을 모델링합니다.</li>
<li style="margin-bottom: 6px;">온도 구배 선도 분석: 대류막 및 고체 벽체 내부의 온도 강하 경사도(기울기)를 통해 어떤 지층에서 열 저항이 지배적으로 작용하는지 가시적으로 모니터링합니다.</li>
    </ol>
</div>


<details class="premium-seo-accordion" style="border: 1px solid rgba(0,0,0,0.08); border-radius: 12px; background: #fbfbfc; padding: 0; margin: 30px auto; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.01); font-family: sans-serif;">
    <summary style="display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; font-size: 1.1em; font-weight: 700; color: #1f2937; cursor: pointer; user-select: none; outline: none; list-style: none;">
        <span><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4da.png" alt="📚" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 다층 벽체 전도 및 대류 열저항 이론 식 확인하기</span>
        <span class="accordion-arrow" style="font-size: 0.9em; color: #9ca3af; transition: transform 0.2s ease;">▼</span>
    </summary>
    <div style="padding: 0 24px 24px 24px; border-top: 1px solid rgba(0,0,0,0.04); background: #ffffff; border-radius: 0 0 12px 12px; font-size: 0.98em; color: #374151; line-height: 1.8;">
        <div style="margin-top: 20px;">
            <h3>1. 1차원 정상상태 열전달 (Steady-State Heat Transfer)의 이론</h3>
<p>공학적 단열 설계나 보일러 벽체, 열교환기 튜브 등은 다층 구조의 고체를 통과하는 1차원 열유동으로 열적 거동을 근사할 수 있습니다. 정상상태(Steady-State) 조건이란 시간에 따라 모든 지점의 온도가 변하지 않는 가상의 평형 상태를 뜻하며, 이 상태에서는 고온 유체에서 벽체 내부를 거쳐 저온 유체로 흐르는 열량(Heat Rate)이 전 구간에서 보존됩니다.</p><ul><li><strong>대류 열전달 (Convective Heat Transfer):</strong> 유체와 인접한 고체 계면 사이에서 분자 진동과 거시적 유체 유동의 복합 작용으로 열이 전달되는 메커니즘입니다 (Q = h·A·ΔT).</li><li><strong>전도 열전달 (Conductive Heat Transfer):</strong> 유체의 이동 없이 물질 내부의 원자/전자의 격자 진동에 의해 열이 순차적으로 전달됩니다 (푸리에 법칙: q'' = -k·dT/dx).</li></ul>
<h3>2. 열회로망(Thermal Network) 분석 및 총괄 전열계수</h3>
<p>복합적인 전도와 대류가 직렬로 연계된 경우, 전기 회로의 저항 개념을 도입하여 **열저항망(Thermal Resistance Network)**으로 손쉽게 해석할 수 있습니다.</p><p><strong>① 개별 열저항 계산 공식 (Area A = 1 m² 기준):</strong></p><ul><li>대류 경계 열저항: <code>R_conv = 1 / h</code> &nbsp;[K/W]</li><li>고체 전도 열저항: <code>R_cond = L / k</code> &nbsp;[K/W] (L: 두께 m, k: 열전도율 W/m·K)</li></ul><p><strong>② 총 열저항 및 열유속 (Heat Flux, q''):</strong></p><p style="text-align: center; font-weight: bold; background: #f3f4f6; padding: 12px; border-radius: 8px;">R_tot = (1 / h_h) + (L1 / k1) + (L2 / k2) + (L3 / k3) + (1 / h_c) &nbsp;[m²·K/W]</p><p style="text-align: center; font-weight: bold; background: #f3f4f6; padding: 12px; border-radius: 8px;">q'' = Q / A = (T_f,h - T_f,c) / R_tot &nbsp;[W/m²]</p><p><strong>③ 노드별 표면 온도 강하 계산:</strong> 열저항을 통과할 때마다 전위차와 같이 온도 강하가 정비례하여 일어납니다:</p><p style="text-align: center; font-weight: bold; background: #e0f2fe; padding: 16px; border-radius: 8px; font-size: 1.05em; color: #0369a1;">T_s,h = T_f,h - q'' × (1 / h_h) &nbsp;[°C]</p><p style="text-align: center; font-weight: bold; background: #e0f2fe; padding: 16px; border-radius: 8px; font-size: 1.05em; color: #0369a1;">T_12 = T_s,h - q'' × (L1 / k1) &nbsp;[°C]</p><p>이 공식을 통해 복합 벽체의 계면 온도들을 구하여 재료가 열적으로 견딜 수 있는 안전 한계를 모니터링할 수 있습니다.</p>
<h3>3. 주요 공학 단열재의 특징 및 열전도성</h3>
<p>효율적인 열 관리를 위해 벽체 중간층에 열전도율이 대단히 낮은 단열재를 배치합니다.</p><ul><li><strong>글라스울/미네랄울 (Glass/Mineral Wool):</strong> 대략 k ≈ 0.035~0.045 W/m·K 로 고온 단열 성능이 탁월하며 미세 기공 내 공기의 열전도를 최소화합니다.</li><li><strong>붉은 벽돌 (Brick):</strong> k ≈ 0.7~0.8 W/m·K 로 구조적 내구성은 있으나 열손실 차단 성능은 단열재 대비 20배 이하로 떨어집니다.</li><li><strong>콘크리트 (Concrete):</strong> k ≈ 1.3~1.5 W/m·K 로 매우 높은 열전도를 가져 겨울철 결로 및 열교(Thermal Bridge) 현상의 주원인이 됩니다.</li></ul>
        </div>
    </div>
</details>
<style>
details.premium-seo-accordion[open] summary .accordion-arrow { transform: rotate(180deg); color: #00f2fe; }
details.premium-seo-accordion summary::-webkit-details-marker { display: none; }
details.premium-seo-accordion:hover { border-color: rgba(0,242,254,0.3); }
</style>

]]></content:encoded>
					
					<wfw:commentRss>https://myengnote.com/heat-transfer-conduction-calculator/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
