{"id":24963,"date":"2026-10-23T02:58:37","date_gmt":"2026-10-23T02:58:37","guid":{"rendered":"https:\/\/www.mechstream.com\/?p=24963"},"modified":"2026-10-23T02:58:42","modified_gmt":"2026-10-23T02:58:42","slug":"surface-roughness-factor-calculator","status":"publish","type":"post","link":"https:\/\/www.mechstream.com\/pt\/surface-roughness-factor-calculator\/","title":{"rendered":"Surface Roughness Factor Calculator"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The Surface Roughness Factor Calculator is a practical engineering tool designed to estimate the influence of surface finish and roughness on the fatigue strength of metallic components. Using empirical surface modification factor equations, this calculator helps engineers evaluate how different manufacturing processes, including grinding, machining, hot rolling, and forging, affect material endurance strength. By entering ultimate tensile strength and selecting a surface finish, users can calculate the estimated surface modification factor (ka), fatigue strength reduction, and surface-corrected endurance limit. Ideal for mechanical engineers, material scientists, and manufacturing professionals, the Surface Roughness Factor Calculator supports preliminary fatigue analysis, material selection, and mechanical component design optimization. Improve engineering efficiency and make informed decisions with reliable, formula-based surface finish evaluations.<\/p>\n\n\n\n<div id=\"srf-calculator\" class=\"srf-root\" data-srf-widget=\"surface-roughness-factor\">\n<style>\n#srf-calculator,#srf-calculator *,#srf-calculator *::before,#srf-calculator *::after{box-sizing:border-box}\n#srf-calculator{\n  --srf-bg:#f4f6f9;--srf-card:#ffffff;--srf-navy:#0f2342;--srf-text:#1f2b3b;--srf-muted:#55667c;--srf-soft:#7f8ea3;\n  --srf-line:#cdd6e1;--srf-line-soft:#e2e8f0;--srf-accent:#1d64c8;--srf-accent-dark:#154c9a;--srf-accent-soft:#e8f0fb;\n  --srf-err:#c4291c;--srf-err-soft:#fdecea;--srf-warn:#7a5200;--srf-warn-soft:#fff6e0;--srf-ok:#16704f;--srf-ok-soft:#eaf6f0;\n  --srf-s1:#2a78d6;--srf-s2:#eb6834;--srf-s3:#1baf7a;--srf-s4:#eda100;--srf-bar:#b7d3f6;--srf-grid:#e6ebf1;\n  display:block;width:100%;max-width:1120px;margin:24px auto;padding:32px;background:var(--srf-bg);color:var(--srf-text);\n  border-radius:22px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif;\n  font-size:16px;line-height:1.55;font-weight:400;letter-spacing:normal;text-transform:none;text-indent:0;word-spacing:normal;-webkit-font-smoothing:antialiased;text-align:left;position:relative\n}\n#srf-calculator .srf-wrap{container-type:inline-size;container-name:srf;width:100%}\n#srf-calculator h1,#srf-calculator h2,#srf-calculator h3,#srf-calculator h4,#srf-calculator p,#srf-calculator ul,#srf-calculator ol,#srf-calculator li,#srf-calculator figure,#srf-calculator figcaption,#srf-calculator table,#srf-calculator thead,#srf-calculator tbody,#srf-calculator tr,#srf-calculator th,#srf-calculator td,#srf-calculator details,#srf-calculator summary,#srf-calculator fieldset,#srf-calculator legend,#srf-calculator label,#srf-calculator header,#srf-calculator section,#srf-calculator article,#srf-calculator blockquote{\n  margin:0;padding:0;border:0;background:none;color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;font-style:normal;line-height:inherit;text-indent:0;text-transform:none;letter-spacing:normal;text-shadow:none;box-shadow:none;float:none;width:auto;max-width:none;text-align:left\n}\n#srf-calculator ul,#srf-calculator ol{list-style:none}\n#srf-calculator a{color:var(--srf-accent);text-decoration:underline}\n#srf-calculator sub,#srf-calculator sup{font-size:.72em;line-height:0;position:relative;vertical-align:baseline}\n#srf-calculator sub{bottom:-.25em}\n#srf-calculator sup{top:-.5em}\n#srf-calculator [hidden]{display:none!important}\n#srf-calculator .srf-vh{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;margin:-1px;padding:0;border:0}\n\/* ---------- cards \/ layout ---------- *\/\n#srf-calculator .srf-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;align-items:start}\n#srf-calculator .srf-card{background:var(--srf-card);border:1px solid var(--srf-line-soft);border-radius:18px;padding:22px;box-shadow:0 1px 2px rgba(15,35,66,.05),0 4px 14px rgba(15,35,66,.04);min-width:0}\n#srf-calculator .srf-card-title{margin:0 0 4px;color:var(--srf-navy);font-size:18px;font-weight:650;line-height:1.25;display:flex;align-items:center;gap:10px}\n#srf-calculator .srf-step{display:inline-flex;align-items:center;justify-content:center;flex:0 0 24px;width:24px;height:24px;border-radius:50%;background:var(--srf-accent-soft);color:var(--srf-accent);font-size:12.8px;font-weight:700}\n#srf-calculator .srf-card-note{color:var(--srf-muted);font-size:14.1px;margin:0 0 16px}\n#srf-calculator .srf-inputs{container-type:inline-size;container-name:srfin}\n#srf-calculator .srf-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:16px 18px}\n#srf-calculator .srf-field{min-width:0}\n#srf-calculator .srf-span{grid-column:1\/-1}\n#srf-calculator .srf-sub-title{grid-column:1\/-1;font-size:14.6px;font-weight:650;color:var(--srf-navy);padding-top:14px;border-top:1px solid var(--srf-line-soft)}\n\/* ---------- labels and tooltips ---------- *\/\n#srf-calculator .srf-labrow{position:relative;display:flex;align-items:center;gap:6px;margin:0 0 6px}\n#srf-calculator .srf-label{display:block;font-size:14.1px;font-weight:600;color:var(--srf-navy);line-height:1.3}\n#srf-calculator .srf-opt{color:var(--srf-soft);font-weight:400;font-size:12.8px;margin-left:4px}\n#srf-calculator .srf-q{-webkit-appearance:none;appearance:none;display:inline-flex;align-items:center;justify-content:center;flex:0 0 20px;width:20px;height:20px;min-height:0;min-width:0;margin:0;padding:0;border-radius:50%;border:1px solid var(--srf-line);background:#fff;color:var(--srf-muted);font:inherit;font-size:12px;font-weight:700;line-height:1;cursor:help;box-shadow:none;text-transform:none}\n#srf-calculator .srf-q:hover,#srf-calculator .srf-q:focus{border-color:var(--srf-accent);color:var(--srf-accent);outline:none}\n#srf-calculator .srf-q:focus-visible{box-shadow:0 0 0 3px rgba(29,100,200,.3)}\n#srf-calculator .srf-qtext{display:none;position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:20;padding:10px 12px;border-radius:10px;background:var(--srf-navy);color:#fff;font-size:13px;font-weight:400;line-height:1.45;box-shadow:0 6px 20px rgba(15,35,66,.25);max-width:420px}\n#srf-calculator .srf-q:hover+.srf-qtext,#srf-calculator .srf-q:focus+.srf-qtext{display:block}\n#srf-calculator .srf-hint{display:block;color:var(--srf-soft);font-size:12.7px;margin-top:5px;line-height:1.45}\n#srf-calculator .srf-hint:empty{display:none}\n#srf-calculator .srf-error{display:block;color:var(--srf-err);font-size:13px;margin-top:4px;line-height:1.4}\n#srf-calculator .srf-error:empty{display:none}\n\/* ---------- controls ---------- *\/\n#srf-calculator .srf-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:stretch}\n#srf-calculator .srf-row-sel{grid-template-columns:minmax(0,1fr) minmax(88px,auto)}\n#srf-calculator .srf-unit{display:inline-flex;align-items:center;justify-content:center;min-width:60px;min-height:46px;padding:0 12px;border-radius:12px;background:#eef2f7;color:var(--srf-muted);font-size:14.1px;font-weight:600;white-space:nowrap}\n#srf-calculator input[type=number],#srf-calculator select{\n  -webkit-appearance:none;appearance:none;display:block;width:100%;min-height:46px;height:auto;margin:0;padding:10px 14px;font:inherit;font-size:16px;line-height:1.3;\n  color:var(--srf-text);background-color:#fff;border:1px solid var(--srf-line);border-radius:12px;box-shadow:none;outline:none;max-width:none;transition:border-color .15s ease,box-shadow .15s ease\n}\n#srf-calculator select{padding-right:36px;background-image:linear-gradient(45deg,transparent 50%,#55667c 50%),linear-gradient(135deg,#55667c 50%,transparent 50%);background-position:calc(100% - 19px) 20px,calc(100% - 14px) 20px;background-size:5px 5px,5px 5px;background-repeat:no-repeat;cursor:pointer}\n#srf-calculator input[type=number]:focus,#srf-calculator select:focus{border-color:var(--srf-accent);box-shadow:0 0 0 4px rgba(29,100,200,.18)}\n#srf-calculator input[type=number]::placeholder{color:#a7b2c1;opacity:1}\n#srf-calculator .srf-invalid{border-color:var(--srf-err)!important;box-shadow:0 0 0 3px rgba(196,41,28,.12)!important}\n#srf-calculator .srf-seg{display:grid;grid-auto-columns:minmax(0,1fr);grid-auto-flow:column;min-width:0;width:100%;gap:4px;padding:4px;background:#e9eef4;border-radius:13px;border:0;margin:0;position:relative}\n#srf-calculator .srf-seg legend{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}\n#srf-calculator .srf-seg input{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}\n#srf-calculator .srf-seg label{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:40px;padding:6px;border-radius:10px;font-size:14.1px;font-weight:600;color:var(--srf-muted);cursor:pointer;text-align:center;line-height:1.2;transition:background .15s,color .15s,box-shadow .15s;margin:0}\n#srf-calculator .srf-seg label small{display:block;font-size:11.8px;font-weight:500;color:var(--srf-soft);margin-top:2px}\n#srf-calculator .srf-seg input:checked+label{background:#fff;color:var(--srf-navy);box-shadow:0 1px 3px rgba(15,35,66,.15)}\n#srf-calculator .srf-seg input:focus-visible+label{outline:3px solid rgba(29,100,200,.4);outline-offset:1px}\n#srf-calculator .srf-seg-mode label{min-height:56px}\n#srf-calculator .srf-seg-label{display:block;font-size:14.1px;font-weight:600;color:var(--srf-navy);margin:0 0 6px}\n#srf-calculator .srf-check{display:flex;gap:10px;align-items:flex-start;font-size:14.1px;font-weight:500;color:var(--srf-text);cursor:pointer;line-height:1.45}\n#srf-calculator .srf-check input{flex:0 0 18px;width:18px;height:18px;margin:2px 0 0;accent-color:var(--srf-accent);cursor:pointer}\n#srf-calculator .srf-check.srf-invalid-check{color:var(--srf-err)}\n#srf-calculator .srf-info{padding:12px 14px;border-radius:12px;background:#f7f9fc;border:1px solid var(--srf-line-soft);font-size:13.5px;color:var(--srf-muted);line-height:1.5}\n#srf-calculator .srf-info strong{color:var(--srf-navy);font-weight:600}\n#srf-calculator .srf-info-warn{background:var(--srf-warn-soft);border-color:#f0dca6;color:#5c4300}\n#srf-calculator .srf-info-warn strong{color:#4a3600}\n#srf-calculator .srf-info-err{background:var(--srf-err-soft);border-color:#f3c3be;color:#8a1d14}\n#srf-calculator .srf-info-err strong{color:#7a160e}\n\/* ---------- buttons ---------- *\/\n#srf-calculator .srf-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px;justify-content:center}\n#srf-calculator .srf-btn{-webkit-appearance:none;appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:46px;min-width:120px;margin:0;padding:10px 20px;border-radius:999px;border:1px solid var(--srf-line);background:#fff;color:var(--srf-navy);font:inherit;font-size:15px;font-weight:600;line-height:1.2;cursor:pointer;text-decoration:none;text-transform:none;letter-spacing:normal;box-shadow:none;width:auto;height:auto;transition:background .15s,border-color .15s,color .15s}\n#srf-calculator .srf-btn:hover{border-color:var(--srf-accent);color:var(--srf-accent)}\n#srf-calculator .srf-btn-primary{background:var(--srf-accent);border-color:var(--srf-accent);color:#fff;min-width:140px}\n#srf-calculator .srf-btn-primary:hover{background:var(--srf-accent-dark);border-color:var(--srf-accent-dark);color:#fff}\n#srf-calculator .srf-btn:focus-visible{outline:3px solid rgba(29,100,200,.4);outline-offset:2px}\n#srf-calculator .srf-btn-sm{min-height:40px;min-width:0;padding:8px 16px;font-size:14px}\n#srf-calculator .srf-form-msg{color:var(--srf-err);font-size:13.8px;margin-top:10px;min-height:1.3em}\n#srf-calculator .srf-copy-msg{font-size:13px;color:var(--srf-ok);align-self:center;min-height:1em}\n\/* ---------- results ---------- *\/\n#srf-calculator .srf-stale{margin:0 0 12px;padding:10px 13px;border-radius:10px;background:var(--srf-warn-soft);color:#5c4300;font-size:13.3px;border:1px solid #f0dca6}\n#srf-calculator .srf-is-stale .srf-dim{opacity:.45;transition:opacity .2s}\n#srf-calculator .srf-hero{border-radius:16px;padding:18px 20px;background:var(--srf-accent-soft);border:1px solid #c9dbf3}\n#srf-calculator .srf-hero.srf-hero-flag{background:var(--srf-err-soft);border-color:#f3c3be}\n#srf-calculator .srf-hero.srf-hero-na{background:#f7f9fc;border-color:var(--srf-line-soft)}\n#srf-calculator .srf-hero-label{font-size:13.5px;font-weight:600;color:var(--srf-muted)}\n#srf-calculator .srf-hero-value{font-size:clamp(36px,6vw,50px);font-weight:750;color:var(--srf-navy);letter-spacing:-.02em;line-height:1.1;margin-top:4px;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}\n#srf-calculator .srf-hero-na .srf-hero-value{font-size:24px;color:var(--srf-soft)}\n#srf-calculator .srf-hero-sub{font-size:13.3px;color:var(--srf-muted);margin-top:6px;line-height:1.45}\n#srf-calculator .srf-interp{margin-top:12px;font-size:14.4px;color:var(--srf-text);line-height:1.55}\n#srf-calculator .srf-sec{color:var(--srf-navy);font-size:15px;font-weight:650;margin:20px 0 10px}\n#srf-calculator .srf-kpis{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}\n#srf-calculator .srf-kpi{background:#f7f9fc;border:1px solid var(--srf-line-soft);border-radius:13px;padding:12px 14px;min-width:0}\n#srf-calculator .srf-kpi-label{font-size:12.8px;font-weight:600;color:var(--srf-muted);line-height:1.3}\n#srf-calculator .srf-kpi-value{font-size:clamp(17px,2.2vw,21px);font-weight:700;color:var(--srf-navy);letter-spacing:-.01em;margin-top:3px;line-height:1.25;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}\n#srf-calculator .srf-kpi-value.srf-na{color:var(--srf-soft);font-size:15.5px}\n#srf-calculator .srf-kpi-sub{font-size:12.3px;color:var(--srf-muted);margin-top:3px;line-height:1.4;overflow-wrap:anywhere}\n#srf-calculator .srf-formula{margin-top:12px;padding:11px 14px;border-radius:11px;background:#f7f9fc;border:1px dashed var(--srf-line);font-size:13.6px;color:var(--srf-text);overflow-wrap:anywhere;line-height:1.55;font-variant-numeric:tabular-nums}\n#srf-calculator .srf-notes{display:grid;gap:8px}\n#srf-calculator .srf-note{display:grid;grid-template-columns:auto minmax(0,1fr);gap:9px;align-items:start;padding:10px 12px;border-radius:11px;font-size:13.3px;line-height:1.5;border:1px solid var(--srf-line-soft);background:#f7f9fc;color:var(--srf-muted)}\n#srf-calculator .srf-note-ic{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;font-size:11.5px;font-weight:800;line-height:1;margin-top:1px;background:var(--srf-accent-soft);color:var(--srf-accent)}\n#srf-calculator .srf-note-w{background:var(--srf-warn-soft);border-color:#f0dca6;color:#5c4300}\n#srf-calculator .srf-note-w .srf-note-ic{background:#f7e2a8;color:#5c4300}\n#srf-calculator .srf-note-e{background:var(--srf-err-soft);border-color:#f3c3be;color:#7a160e}\n#srf-calculator .srf-note-e .srf-note-ic{background:#f6cdc8;color:#7a160e}\n#srf-calculator .srf-res-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}\n\/* ---------- responsive ---------- *\/\n@container srfin (min-width:460px){\n  #srf-calculator .srf-grid{grid-template-columns:repeat(2,minmax(0,1fr))}\n}\n@container srf (min-width:760px){\n  #srf-calculator .srf-kpis{grid-template-columns:repeat(4,minmax(0,1fr))}\n}\n@media (max-width:700px){\n  #srf-calculator{padding:18px 14px;border-radius:16px;margin:12px auto}\n  #srf-calculator .srf-card{padding:18px 15px;border-radius:16px}\n  #srf-calculator .srf-actions .srf-btn{flex:1 1 auto;min-width:0}\n  #srf-calculator .srf-seg label{font-size:13.1px;padding:6px 3px}\n}\n@media (max-width:380px){\n  #srf-calculator .srf-kpis{grid-template-columns:minmax(0,1fr)}\n}\n@media (prefers-reduced-motion:reduce){#srf-calculator *{transition:none!important}}\n@media print{#srf-calculator .srf-actions,#srf-calculator .srf-res-actions,#srf-calculator .srf-q{display:none!important}}\n<\/style>\n<div class=\"srf-wrap\">\n<div class=\"srf-layout\">\n<form class=\"srf-card srf-inputs\" id=\"srf-form\" novalidate onsubmit=\"return false;\" aria-labelledby=\"srf-h-in\">\n<h2 class=\"srf-card-title\" id=\"srf-h-in\"><span class=\"srf-step\" aria-hidden=\"true\">1<\/span>Input parameters<\/h2>\n<p class=\"srf-card-note\">Choose a calculation mode. The two modes are kept separate: the manufacturing-process coefficients in Mode A are not functions of Ra.<\/p>\n<span class=\"srf-seg-label\" aria-hidden=\"true\">Calculation mode<\/span>\n<fieldset class=\"srf-seg srf-seg-mode\">\n<legend>Calculation mode<\/legend>\n<input type=\"radio\" id=\"srf-m-a\" name=\"srf-mode\" value=\"A\" checked><label for=\"srf-m-a\">Mode A<small>Manufacturing process<\/small><\/label>\n<input type=\"radio\" id=\"srf-m-b\" name=\"srf-mode\" value=\"B\"><label for=\"srf-m-b\">Mode B<small>Custom Ra model<\/small><\/label>\n<\/fieldset>\n<div class=\"srf-info\" id=\"srf-mode-info\" style=\"margin-top:10px\" aria-live=\"polite\"><\/div>\n<div class=\"srf-grid\" style=\"margin-top:18px\">\n<div class=\"srf-field srf-span\">\n<span class=\"srf-seg-label\" aria-hidden=\"true\">Stress unit<\/span>\n<fieldset class=\"srf-seg\">\n<legend>Stress unit<\/legend>\n<input type=\"radio\" id=\"srf-u-mpa\" name=\"srf-unit\" value=\"MPa\" checked><label for=\"srf-u-mpa\">MPa<\/label>\n<input type=\"radio\" id=\"srf-u-pa\" name=\"srf-unit\" value=\"Pa\"><label for=\"srf-u-pa\">Pa<\/label>\n<input type=\"radio\" id=\"srf-u-psi\" name=\"srf-unit\" value=\"psi\"><label for=\"srf-u-psi\">psi<\/label>\n<input type=\"radio\" id=\"srf-u-ksi\" name=\"srf-unit\" value=\"ksi\"><label for=\"srf-u-ksi\">ksi<\/label>\n<\/fieldset>\n<span class=\"srf-hint\">Used for Sut and Se&#x2032;. Values are converted to MPa internally (1 ksi = 6.894757 MPa, 1 psi = 0.006894757 MPa). Switching converts the values already entered.<\/span>\n<\/div>\n<div class=\"srf-field srf-span\">\n<div class=\"srf-labrow\"><label class=\"srf-label\" for=\"srf-material\">Material type<\/label><button type=\"button\" class=\"srf-q\" aria-label=\"About material type\" aria-describedby=\"srf-tt-mat\">?<\/button><span class=\"srf-qtext\" role=\"tooltip\" id=\"srf-tt-mat\">The Mode A coefficients were fitted to steel test data. Other materials need a material-specific model, entered in Mode B.<\/span><\/div>\n<select id=\"srf-material\" name=\"material\">\n<option value=\"carbon\" selected>Carbon Steel<\/option>\n<option value=\"alloy\">Alloy Steel<\/option>\n<option value=\"stainless\">Stainless Steel<\/option>\n<option value=\"aluminum\">Aluminum Alloy<\/option>\n<option value=\"custom\">Custom Material<\/option>\n<\/select>\n<\/div>\n<div class=\"srf-info srf-span\" id=\"srf-mat-info\" aria-live=\"polite\"><\/div>\n<div class=\"srf-field srf-span\" id=\"srf-confirm-mat-field\" hidden>\n<label class=\"srf-check\" for=\"srf-confirm-mat\" id=\"srf-confirm-mat-label\"><input type=\"checkbox\" id=\"srf-confirm-mat\" name=\"confirmMat\"><span>I have confirmed from validated data that the steel surface-factor coefficients are applicable to this material.<\/span><\/label>\n<span class=\"srf-error\" id=\"srf-confirm-mat-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"srf-field\">\n<div class=\"srf-labrow\"><label class=\"srf-label\" for=\"srf-sut\">Ultimate Tensile Strength (S<sub>ut<\/sub>) <span class=\"srf-opt\" id=\"srf-sut-opt\"><\/span><\/label><button type=\"button\" class=\"srf-q\" aria-label=\"About ultimate tensile strength\" aria-describedby=\"srf-tt-sut\">?<\/button><span class=\"srf-qtext\" role=\"tooltip\" id=\"srf-tt-sut\">The tensile strength of the material in its final heat-treated condition. In Mode A, higher-strength steels are more sensitive to surface irregularities, so ka falls as Sut rises. Mode B does not use it in the formula.<\/span><\/div>\n<div class=\"srf-row\"><input id=\"srf-sut\" name=\"sut\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 600\" aria-describedby=\"srf-sut-err\"><span class=\"srf-unit srf-ulabel\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"srf-error\" id=\"srf-sut-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"srf-field\" id=\"srf-finish-field\">\n<div class=\"srf-labrow\"><label class=\"srf-label\" for=\"srf-finish\">Surface finish<\/label><button type=\"button\" class=\"srf-q\" aria-label=\"About surface finish\" aria-describedby=\"srf-tt-fin\">?<\/button><span class=\"srf-qtext\" role=\"tooltip\" id=\"srf-tt-fin\">The final manufacturing process at the critical location. Each finish has its own empirical a and b coefficients. Cold-drawn uses the machined coefficients.<\/span><\/div>\n<select id=\"srf-finish\" name=\"finish\" aria-describedby=\"srf-finish-hint\">\n<option value=\"ground\">Ground<\/option>\n<option value=\"machined\" selected>Machined<\/option>\n<option value=\"colddrawn\">Cold-Drawn<\/option>\n<option value=\"hotrolled\">Hot-Rolled<\/option>\n<option value=\"forged\">As-Forged<\/option>\n<\/select>\n<span class=\"srf-hint\" id=\"srf-finish-hint\"><\/span>\n<\/div>\n<div class=\"srf-field\">\n<div class=\"srf-labrow\"><label class=\"srf-label\" for=\"srf-ra\">Surface Roughness Ra <span class=\"srf-opt\" id=\"srf-ra-opt\">(optional)<\/span><\/label><button type=\"button\" class=\"srf-q\" aria-label=\"About surface roughness Ra\" aria-describedby=\"srf-tt-ra\">?<\/button><span class=\"srf-qtext\" role=\"tooltip\" id=\"srf-tt-ra\">The arithmetic mean deviation of the measured surface profile (for example per ISO 4287 or ISO 21920-2). In Mode A it is shown for reference only and does not change ka.<\/span><\/div>\n<div class=\"srf-row srf-row-sel\"><input id=\"srf-ra\" name=\"ra\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 1.6\" aria-describedby=\"srf-ra-err\"><select id=\"srf-ra-unit\" name=\"raUnit\" aria-label=\"Roughness unit\"><option value=\"um\" selected>&#x3bc;m<\/option><option value=\"uin\">&#x3bc;in<\/option><\/select><\/div>\n<span class=\"srf-error\" id=\"srf-ra-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"srf-field\">\n<div class=\"srf-labrow\"><label class=\"srf-label\" for=\"srf-sep\">Unmodified Endurance Limit (S<sub>e<\/sub>&#x2032;) <span class=\"srf-opt\">(optional)<\/span><\/label><button type=\"button\" class=\"srf-q\" aria-label=\"About unmodified endurance limit\" aria-describedby=\"srf-tt-sep\">?<\/button><span class=\"srf-qtext\" role=\"tooltip\" id=\"srf-tt-sep\">The endurance limit of polished, unnotched rotating-beam specimens, from test data or an accepted estimate. If you enter it, the calculator also gives the endurance limit corrected for surface finish only.<\/span><\/div>\n<div class=\"srf-row\"><input id=\"srf-sep\" name=\"sep\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 300\" aria-describedby=\"srf-sep-err\"><span class=\"srf-unit srf-ulabel\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"srf-error\" id=\"srf-sep-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<p class=\"srf-sub-title\" id=\"srf-b-title\" hidden>Custom empirical model: k<sub>a<\/sub> = C&#xb7;(R<sub>a<\/sub>\/R<sub>a,ref<\/sub>)<sup>m<\/sup><\/p>\n<div class=\"srf-field\" id=\"srf-raref-field\" hidden>\n<div class=\"srf-labrow\"><label class=\"srf-label\" for=\"srf-raref\">Reference Roughness (R<sub>a,ref<\/sub>)<\/label><button type=\"button\" class=\"srf-q\" aria-label=\"About reference roughness\" aria-describedby=\"srf-tt-ref\">?<\/button><span class=\"srf-qtext\" role=\"tooltip\" id=\"srf-tt-ref\">The roughness at which your model gives ka = C, usually the roughness of the reference test specimens. It must be greater than zero and in the same unit as Ra.<\/span><\/div>\n<div class=\"srf-row\"><input id=\"srf-raref\" name=\"raref\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 0.2\" aria-describedby=\"srf-raref-err\"><span class=\"srf-unit srf-ralabel\" aria-hidden=\"true\">&#x3bc;m<\/span><\/div>\n<span class=\"srf-error\" id=\"srf-raref-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"srf-field\" id=\"srf-c-field\" hidden>\n<div class=\"srf-labrow\"><label class=\"srf-label\" for=\"srf-c\">Custom Coefficient (C)<\/label><button type=\"button\" class=\"srf-q\" aria-label=\"About coefficient C\" aria-describedby=\"srf-tt-c\">?<\/button><span class=\"srf-qtext\" role=\"tooltip\" id=\"srf-tt-c\">A dimensionless coefficient fitted to fatigue tests on your material and process. It must be greater than zero and no more than 10.<\/span><\/div>\n<input id=\"srf-c\" name=\"c\" type=\"number\" inputmode=\"decimal\" step=\"any\" placeholder=\"from your data\" aria-describedby=\"srf-c-err\">\n<span class=\"srf-error\" id=\"srf-c-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"srf-field\" id=\"srf-mexp-field\" hidden>\n<div class=\"srf-labrow\"><label class=\"srf-label\" for=\"srf-mexp\">Custom Exponent (m)<\/label><button type=\"button\" class=\"srf-q\" aria-label=\"About exponent m\" aria-describedby=\"srf-tt-m\">?<\/button><span class=\"srf-qtext\" role=\"tooltip\" id=\"srf-tt-m\">An empirical exponent fitted to your data. A negative m means a rougher surface gives a lower ka. Allowed range: &#x2212;5 to 5.<\/span><\/div>\n<input id=\"srf-mexp\" name=\"mexp\" type=\"number\" inputmode=\"decimal\" step=\"any\" placeholder=\"from your data\" aria-describedby=\"srf-mexp-err\">\n<span class=\"srf-error\" id=\"srf-mexp-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"srf-field srf-span\" id=\"srf-confirm-model-field\" hidden>\n<label class=\"srf-check\" for=\"srf-confirm-model\" id=\"srf-confirm-model-label\"><input type=\"checkbox\" id=\"srf-confirm-model\" name=\"confirmModel\"><span>I confirm that C, m and R<sub>a,ref<\/sub> come from material-specific fatigue testing, validated literature or an applicable standard, and that the model applies to this material, process and roughness range.<\/span><\/label>\n<span class=\"srf-error\" id=\"srf-confirm-model-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<\/div>\n<div class=\"srf-actions\">\n<button type=\"button\" class=\"srf-btn srf-btn-primary\" id=\"srf-calc\">Calculate<\/button>\n<\/div>\n<p class=\"srf-form-msg\" id=\"srf-form-msg\" aria-live=\"polite\"><\/p>\n<\/form>\n<section class=\"srf-card\" id=\"srf-results\" aria-labelledby=\"srf-h-res\" tabindex=\"-1\" hidden>\n<h2 class=\"srf-card-title\" id=\"srf-h-res\"><span class=\"srf-step\" aria-hidden=\"true\">2<\/span>Calculation results<\/h2>\n<div id=\"srf-res-body\">\n<p class=\"srf-stale\" id=\"srf-stale\" role=\"status\" hidden>Some inputs are invalid. The results below are from the last valid calculation.<\/p>\n<div class=\"srf-dim\">\n<div class=\"srf-hero\" id=\"srf-hero\" style=\"margin-top:12px\">\n<div class=\"srf-hero-label\">Surface Modification Factor k<sub>a<\/sub><\/div>\n<div class=\"srf-hero-value\" id=\"srf-r-ka\"><\/div>\n<div class=\"srf-hero-sub\" id=\"srf-r-ka-sub\"><\/div>\n<\/div>\n<p class=\"srf-interp\" id=\"srf-r-interp\"><\/p>\n<h3 class=\"srf-sec\">Primary results<\/h3>\n<div class=\"srf-kpis\" id=\"srf-r-primary\"><\/div>\n<p class=\"srf-formula\" id=\"srf-r-formula\"><\/p>\n<h3 class=\"srf-sec\">Secondary results<\/h3>\n<div class=\"srf-kpis\" id=\"srf-r-secondary\"><\/div>\n<h3 class=\"srf-sec\">Engineering applicability notes<\/h3>\n<div class=\"srf-notes\" id=\"srf-r-notes\"><\/div>\n<\/div>\n<div class=\"srf-res-actions\">\n<button type=\"button\" class=\"srf-btn srf-btn-sm\" id=\"srf-copy\">Copy Results<\/button>\n<button type=\"button\" class=\"srf-btn srf-btn-sm\" id=\"srf-print\">Print Results<\/button>\n<span class=\"srf-copy-msg\" id=\"srf-copy-msg\" role=\"status\" aria-live=\"polite\"><\/span>\n<\/div>\n<\/div>\n<\/section>\n<\/div>\n<\/div>\n<script>\n(function () {\n  \"use strict\";\n  \/* =====================================================================\n     REFERENCE DATA\n     Marin surface factor ka = a * Sut^b with Sut in MPa.\n     Coefficients: Budynas and Nisbett, Shigley's Mechanical Engineering\n     Design, Table 6-2 (steels). Cold-drawn shares the machined set.\n     ===================================================================== *\/\n  var TO_MPA = { MPa: 1, Pa: 1e-6, psi: 0.006894757, ksi: 6.894757 };\n  var UIN_TO_UM = 0.0254; \/* 1 microinch = 0.0254 micrometre *\/\n  var FINISH = {\n    ground: { name: \"Ground\", a: 1.58, b: -0.085, group: \"ground\" },\n    machined: { name: \"Machined\", a: 4.51, b: -0.265, group: \"machined\" },\n    colddrawn: { name: \"Cold-Drawn\", a: 4.51, b: -0.265, group: \"machined\" },\n    hotrolled: { name: \"Hot-Rolled\", a: 57.7, b: -0.718, group: \"hotrolled\" },\n    forged: { name: \"As-Forged\", a: 272, b: -0.995, group: \"forged\" }\n  };\n  \/* Approximate tensile-strength range of the steel test data behind the fits\n     (about 60-240 ksi). Values outside are flagged as extrapolation. *\/\n  var RANGE = { lo: 400, hi: 1600 };\n  var MATS = {\n    carbon: { name: \"Carbon Steel\", modeA: \"ok\" },\n    alloy: { name: \"Alloy Steel\", modeA: \"ok\" },\n    stainless: { name: \"Stainless Steel\", modeA: \"caution\" },\n    aluminum: { name: \"Aluminum Alloy\", modeA: \"no\" },\n    custom: { name: \"Custom Material\", modeA: \"confirm\" }\n  };\n  var MAT_INFO = {\n    carbon: [\"Mode A applicable.\", \"The surface-finish coefficients were fitted to wrought steel data, including plain carbon steels.\"],\n    alloy: [\"Mode A applicable.\", \"The coefficients were fitted to wrought steel data. Case-hardened, nitrided or very high-strength alloy steels may behave differently; prefer test data for them.\"],\n    stainless: [\"Mode A applied with caution.\", \"The fits are based mainly on carbon and low-alloy steels. Stainless grades, especially austenitic ones, can deviate. Use validated data for critical parts.\"],\n    aluminum: [\"Mode A not applicable.\", \"The steel coefficients are not applied to aluminum alloys, which also have no true endurance limit. Use Mode B with coefficients from material-specific fatigue tests or validated literature.\"],\n    custom: [\"Mode A requires confirmation.\", \"The steel coefficients are applied to a custom material only after you confirm that validated data support them. Otherwise use Mode B with your own model.\"]\n  };\n  \/* =====================================================================\n     FORMATTING HELPERS\n     ===================================================================== *\/\n  function isNum(v) { return typeof v === \"number\" ? isFinite(v) : false; }\n  function fix(v, d) { var r = Number(v.toFixed(d)); return r === 0 ? 0 : r; }\n  function fmt(v, d) {\n    if (!isNum(v)) { return \"\\u2014\"; }\n    var r = fix(v, d);\n    return (r < 0 ? \"\\u2212\" : \"\") + Math.abs(r).toLocaleString(\"en-US\", { minimumFractionDigits: d, maximumFractionDigits: d });\n  }\n  function fmtTrim(v, d) {\n    if (!isNum(v)) { return \"\\u2014\"; }\n    var r = fix(v, d);\n    return (r < 0 ? \"\\u2212\" : \"\") + Math.abs(r).toLocaleString(\"en-US\", { minimumFractionDigits: 0, maximumFractionDigits: d });\n  }\n  var UDEC = { MPa: 1, Pa: 0, psi: 0, ksi: 2 };\n  function fmtS(mpa, u) { if (!isNum(mpa)) { return \"\\u2014\"; } return fmt(mpa \/ TO_MPA[u], UDEC[u]) + \" \" + u; }\n  function fmtMPa(mpa) { return fmt(mpa, 1) + \" MPa\"; }\n  function fmtKa(v) { return fmt(v, 4); }\n  function raLabel(u) { return u === \"uin\" ? \"\\u03bcin\" : \"\\u03bcm\"; }\n  function fmtRa(um, u) { if (!isNum(um)) { return \"\\u2014\"; } return u === \"uin\" ? fmtTrim(um \/ UIN_TO_UM, 1) + \" \\u03bcin\" : fmtTrim(um, 3) + \" \\u03bcm\"; }\n  \/* =====================================================================\n     ENGINE (pure functions, no DOM). Stresses in MPa, roughness in \\u03bcm.\n     ===================================================================== *\/\n  function marin(a, b, sutMPa) { return a * Math.pow(sutMPa, b); }\n  function sutAtUnity(a, b) { return Math.pow(a, -1 \/ b); } \/* Sut where a*Sut^b = 1 *\/\n  function computeA(inp) {\n    var m = MATS[inp.mat], r = { mode: \"A\", inp: inp, mat: m, notes: [] };\n    function N(level, text) { r.notes.push({ level: level, text: text }); }\n    var F = FINISH[inp.finish];\n    r.finish = F;\n    r.model = \"Marin surface factor for steel: ka = a\\u00b7Sut^b (Sut in MPa), coefficients from Shigley Table 6-2\";\n    if (m.modeA === \"no\") {\n      r.ka = null;\n      r.blocked = \"Not calculated: the steel surface-finish coefficients are not applied to \" + m.name + \". Switch to Mode B and enter coefficients from material-specific data.\";\n      N(\"e\", r.blocked);\n      return r;\n    }\n    r.a = F.a; r.b = F.b;\n    r.ka = marin(F.a, F.b, inp.sut);\n    r.reduction = (1 - r.ka) * 100;\n    r.seS = inp.sep === null ? null : r.ka * inp.sep;\n    var s1 = sutAtUnity(F.a, F.b);\n    if (r.ka > 1) {\n      N(\"e\", \"ka = \" + fmtKa(r.ka) + \" is greater than 1, outside the physically meaningful range of 0 to 1. For \" + F.name.toLowerCase() + \" steel the fit reaches 1.0 at about \" + fmtTrim(s1, 0) + \" MPa, so this result is an extrapolation below the data. It has not been capped; do not use it as a design value.\");\n    }\n    if (inp.sut < RANGE.lo) {\n      N(\"w\", \"Sut = \" + fmtMPa(inp.sut) + \" is below the approximate strength range of the underlying steel data (about \" + RANGE.lo + \" to \" + RANGE.hi + \" MPa). The result is extrapolated.\");\n    } else if (inp.sut > RANGE.hi) {\n      N(\"w\", \"Sut = \" + fmtMPa(inp.sut) + \" is above the approximate strength range of the underlying steel data (about \" + RANGE.lo + \" to \" + RANGE.hi + \" MPa). The result is extrapolated.\");\n    }\n    if (m.modeA === \"caution\") { N(\"w\", \"Stainless steel: the coefficients were fitted mainly to carbon and low-alloy steels. Austenitic grades in particular can deviate; confirm with validated data.\"); }\n    if (m.modeA === \"confirm\") { N(\"w\", \"Custom material: steel coefficients applied on the basis of your confirmation that validated data support them.\"); }\n    if (inp.finish === \"colddrawn\") { N(\"i\", \"Cold-drawn surfaces use the same coefficients as machined surfaces.\"); }\n    if (inp.finish === \"hotrolled\" ? true : inp.finish === \"forged\") { N(\"i\", \"Hot-rolled and as-forged factors include the effect of scale and surface decarburization typical of those processes.\"); }\n    if (inp.ra !== null) { N(\"i\", \"Ra is shown for reference only. Mode A coefficients depend on the manufacturing process category, not on the measured Ra value.\"); }\n    if (r.seS !== null) {\n      N(\"i\", \"Se,surface includes only the surface factor. A complete endurance limit also needs the size, load, temperature, reliability and miscellaneous factors, plus notch effects.\");\n      if (inp.sut !== null ? inp.sep > 0.5 * inp.sut : false) { N(\"w\", \"Se\\u2032 is above 0.5\\u00b7Sut, higher than the usual steel estimate. Check that it is a polished-specimen endurance limit in the selected unit.\"); }\n    }\n    N(\"i\", \"Residual stresses (from shot peening, rolling or grinding), coatings, plating and corrosion are not represented by ka.\");\n    return r;\n  }\n  function computeB(inp) {\n    var r = { mode: \"B\", inp: inp, mat: MATS[inp.mat], notes: [] };\n    function N(level, text) { r.notes.push({ level: level, text: text }); }\n    r.hasModel = inp.c !== null;\n    r.model = r.hasModel ? \"User-defined empirical model: ka = C\\u00b7(Ra\/Ra,ref)^m\" : \"No fatigue correction model supplied\";\n    if (!r.hasModel) {\n      r.ka = null;\n      r.blocked = \"No fatigue correction calculated. Ra is reported as a measured surface characteristic only. Enter validated C, m and Ra,ref and confirm the model to calculate ka.\";\n      N(\"i\", \"There is no universally accepted equation that converts Ra into a fatigue surface factor for every material and process, so none is assumed here.\");\n      return r;\n    }\n    r.C = inp.c; r.m = inp.mexp; r.ratio = inp.ra \/ inp.raref;\n    r.ka = inp.c * Math.pow(r.ratio, inp.mexp);\n    r.reduction = (1 - r.ka) * 100;\n    r.seS = inp.sep === null ? null : r.ka * inp.sep;\n    if (r.ka > 1) { N(\"e\", \"ka = \" + fmtKa(r.ka) + \" is greater than 1, outside the physically meaningful range of 0 to 1 for a surface reduction factor. It has not been capped; check C, m and Ra,ref, and whether Ra is outside the fitted range.\"); }\n    if (inp.mexp > 0) { N(\"w\", \"The exponent m is positive, so the model predicts a higher ka for rougher surfaces. Check that this matches your data.\"); }\n    if (inp.mexp === 0) { N(\"i\", \"m = 0: ka equals C for every roughness value.\"); }\n    N(\"i\", \"This is a configurable mathematical model, not a universally validated fatigue law. It is valid only for the material, process and Ra range of the data used to fit C and m.\");\n    if (r.ratio > 10 ? true : r.ratio < 0.1) { N(\"w\", \"Ra differs from Ra,ref by more than a factor of 10. Check that Ra is inside the range of the data used to fit the model.\"); }\n    if (r.seS !== null) { N(\"i\", \"Se,surface includes only the surface factor. Other Marin factors and notch effects are not included.\"); }\n    if (inp.sut !== null) { N(\"i\", \"Sut is recorded for reference; the custom model does not use it.\"); }\n    return r;\n  }\n  \/* =====================================================================\n     UI\n     ===================================================================== *\/\n  function init() {\n    var root = document.getElementById(\"srf-calculator\");\n    if (!root) { return; }\n    if (root.getAttribute(\"data-srf-init\") === \"1\") { return; }\n    root.setAttribute(\"data-srf-init\", \"1\");\n    root.srfEngine = { computeA: computeA, computeB: computeB, marin: marin };\n    function $(id) { return root.querySelector(\"#\" + id); }\n    function mk(tag, cls, text) { var n = document.createElement(tag); if (cls) { n.className = cls; } if (text !== undefined) { n.textContent = text; } return n; }\n    function clear(n) { while (n.firstChild) { n.removeChild(n.firstChild); } }\n    function radioVal(name) { var r = root.querySelector('input[name=\"' + name + '\"]:checked'); return r ? r.value : null; }\n    function setRadio(name, v) { var r = root.querySelector('input[name=\"' + name + '\"][value=\"' + v + '\"]'); if (r) { r.checked = true; } }\n    var el = {\n      form: $(\"srf-form\"), modeInfo: $(\"srf-mode-info\"), material: $(\"srf-material\"), matInfo: $(\"srf-mat-info\"),\n      confirmMatField: $(\"srf-confirm-mat-field\"), confirmMat: $(\"srf-confirm-mat\"), confirmMatLabel: $(\"srf-confirm-mat-label\"),\n      sut: $(\"srf-sut\"), sutOpt: $(\"srf-sut-opt\"), finish: $(\"srf-finish\"), finishField: $(\"srf-finish-field\"), finishHint: $(\"srf-finish-hint\"),\n      ra: $(\"srf-ra\"), raUnit: $(\"srf-ra-unit\"), raOpt: $(\"srf-ra-opt\"), sep: $(\"srf-sep\"),\n      bTitle: $(\"srf-b-title\"), raref: $(\"srf-raref\"), rarefField: $(\"srf-raref-field\"), c: $(\"srf-c\"), cField: $(\"srf-c-field\"),\n      mexp: $(\"srf-mexp\"), mexpField: $(\"srf-mexp-field\"), confirmModelField: $(\"srf-confirm-model-field\"), confirmModel: $(\"srf-confirm-model\"), confirmModelLabel: $(\"srf-confirm-model-label\"),\n      calc: $(\"srf-calc\"), formMsg: $(\"srf-form-msg\"),\n      results: $(\"srf-results\"), stale: $(\"srf-stale\"),\n      hero: $(\"srf-hero\"), ka: $(\"srf-r-ka\"), kaSub: $(\"srf-r-ka-sub\"), interp: $(\"srf-r-interp\"), primary: $(\"srf-r-primary\"), formula: $(\"srf-r-formula\"),\n      secondary: $(\"srf-r-secondary\"), notes: $(\"srf-r-notes\"), copy: $(\"srf-copy\"), print: $(\"srf-print\"), copyMsg: $(\"srf-copy-msg\")\n    };\n    var state = { live: false, last: null, timer: null, lastUnit: \"MPa\", lastRaUnit: \"um\" };\n    function mode() { return radioVal(\"srf-mode\") || \"A\"; }\n    function unit() { return radioVal(\"srf-unit\") || \"MPa\"; }\n    \/* ---------- reading numbers ---------- *\/\n    function readNum(input) {\n      var s = String(input.value).trim();\n      if (s === \"\") { return (input.validity ? input.validity.badInput : false) ? NaN : null; }\n      var v = Number(s);\n      return isFinite(v) ? v : NaN;\n    }\n    function nOrNull(input) { var v = readNum(input); return isNum(v) ? v : null; }\n    function setVal(input, v, d) { input.value = (v === null ? true : v === \"\") ? \"\" : String(fix(Number(v), d === undefined ? 6 : d)); }\n    \/* ---------- validation ---------- *\/\n    function setErr(input, msg) {\n      var e = $(input.id + \"-err\");\n      if (e) { e.textContent = msg || \"\"; }\n      if (msg) { input.classList.add(\"srf-invalid\"); input.setAttribute(\"aria-invalid\", \"true\"); }\n      else { input.classList.remove(\"srf-invalid\"); input.removeAttribute(\"aria-invalid\"); }\n      return !msg;\n    }\n    function setCheckErr(input, label, msg) {\n      var e = $(input.id + \"-err\");\n      if (e) { e.textContent = msg || \"\"; }\n      if (msg) { label.classList.add(\"srf-invalid-check\"); input.setAttribute(\"aria-invalid\", \"true\"); }\n      else { label.classList.remove(\"srf-invalid-check\"); input.removeAttribute(\"aria-invalid\"); }\n      return !msg;\n    }\n    function numCheck(input, opts) {\n      var v = readNum(input);\n      if (v === null) { return opts.optional ? setErr(input, \"\") : setErr(input, opts.req); }\n      if (isNaN(v)) { return setErr(input, \"Enter a valid number.\"); }\n      return setErr(input, opts.check(v) || \"\");\n    }\n    function uTxt(mpa) { return fmtS(mpa, unit()); }\n    function vSut() {\n      return numCheck(el.sut, { optional: mode() === \"B\", req: \"Enter the ultimate tensile strength.\", check: function (v) {\n        var mpa = v * TO_MPA[unit()];\n        if (mpa <= 0) { return \"Ultimate tensile strength must be greater than zero.\"; }\n        if (mpa > 3500) { return \"Sut above \" + uTxt(3500) + \" is outside the range of engineering metals. Check the stress unit.\"; }\n        return \"\";\n      } });\n    }\n    function vRa() {\n      return numCheck(el.ra, { optional: mode() === \"A\", req: \"Enter the measured surface roughness Ra.\", check: function (v) {\n        var um = el.raUnit.value === \"uin\" ? v * UIN_TO_UM : v;\n        if (v < 0) { return \"Surface roughness cannot be negative.\"; }\n        if (um > 1000) { return \"Ra above \" + fmtRa(1000, el.raUnit.value) + \" is outside the range of machined or formed surfaces. Check the unit.\"; }\n        if (mode() === \"B\" ? (v === 0 ? modelEntered() : false) : false) { return \"Ra must be greater than zero to evaluate the power-law model.\"; }\n        return \"\";\n      } });\n    }\n    function vSep() {\n      return numCheck(el.sep, { optional: true, check: function (v) {\n        if (v <= 0) { return \"The endurance limit must be greater than zero, or leave it blank.\"; }\n        var sut = readNum(el.sut);\n        if (isNum(sut) ? (sut > 0 ? v >= sut : false) : false) { return \"The endurance limit must be lower than the ultimate tensile strength.\"; }\n        return \"\";\n      } });\n    }\n    function modelEntered() { return [el.raref, el.c, el.mexp].some(function (i) { return String(i.value).trim() !== \"\"; }); }\n    function vRaref() {\n      if (mode() !== \"B\") { return setErr(el.raref, \"\"); }\n      return numCheck(el.raref, { optional: !modelEntered(), req: \"Enter a reference roughness greater than zero.\", check: function (v) {\n        if (v <= 0) { return \"The reference roughness must be greater than zero (it is a divisor).\"; }\n        var um = el.raUnit.value === \"uin\" ? v * UIN_TO_UM : v;\n        if (um > 1000) { return \"Reference roughness above \" + fmtRa(1000, el.raUnit.value) + \" is not plausible. Check the unit.\"; }\n        return \"\";\n      } });\n    }\n    function vC() {\n      if (mode() !== \"B\") { return setErr(el.c, \"\"); }\n      return numCheck(el.c, { optional: !modelEntered(), req: \"Enter the coefficient C from your validated model.\", check: function (v) {\n        if (v <= 0) { return \"C must be greater than zero.\"; }\n        if (v > 10) { return \"C must not exceed 10 for a dimensionless surface factor model.\"; }\n        return \"\";\n      } });\n    }\n    function vM() {\n      if (mode() !== \"B\") { return setErr(el.mexp, \"\"); }\n      return numCheck(el.mexp, { optional: !modelEntered(), req: \"Enter the exponent m from your validated model.\", check: function (v) {\n        if (v < -5 ? true : v > 5) { return \"m must be between \\u22125 and 5.\"; }\n        return \"\";\n      } });\n    }\n    function vConfirmModel() {\n      if (mode() !== \"B\" ? true : !modelEntered()) { return setCheckErr(el.confirmModel, el.confirmModelLabel, \"\"); }\n      return setCheckErr(el.confirmModel, el.confirmModelLabel, el.confirmModel.checked ? \"\" : \"Confirm that the model coefficients are validated for this material and application before ka is calculated.\");\n    }\n    function vConfirmMat() {\n      if (mode() !== \"A\" ? true : el.material.value !== \"custom\") { return setCheckErr(el.confirmMat, el.confirmMatLabel, \"\"); }\n      return setCheckErr(el.confirmMat, el.confirmMatLabel, el.confirmMat.checked ? \"\" : \"For a custom material, confirm that validated data support the steel coefficients, or use Mode B.\");\n    }\n    var VALIDATORS = {\n      \"srf-sut\": function () { vSut(); return vSep(); }, \"srf-ra\": vRa, \"srf-sep\": vSep,\n      \"srf-raref\": function () { vRaref(); vC(); vM(); vRa(); return vConfirmModel(); },\n      \"srf-c\": function () { vRaref(); vC(); vM(); vRa(); return vConfirmModel(); },\n      \"srf-mexp\": function () { vRaref(); vC(); vM(); vRa(); return vConfirmModel(); },\n      \"srf-confirm-model\": vConfirmModel, \"srf-confirm-mat\": vConfirmMat\n    };\n    function validateAll() {\n      var res = [vSut(), vRa(), vSep(), vRaref(), vC(), vM(), vConfirmModel(), vConfirmMat()];\n      return res.every(Boolean);\n    }\n    function readInput() {\n      var u = unit(), k = TO_MPA[u], ruf = el.raUnit.value === \"uin\" ? UIN_TO_UM : 1;\n      var sut = nOrNull(el.sut), sep = nOrNull(el.sep), ra = nOrNull(el.ra), raref = nOrNull(el.raref);\n      var B = mode() === \"B\", model = B ? modelEntered() : false;\n      return {\n        mode: mode(), unit: u, raUnit: el.raUnit.value, mat: el.material.value, finish: el.finish.value,\n        sut: sut === null ? null : sut * k, sep: sep === null ? null : sep * k, ra: ra === null ? null : ra * ruf,\n        raref: model ? raref * ruf : null, c: model ? nOrNull(el.c) : null, mexp: model ? nOrNull(el.mexp) : null\n      };\n    }\n    \/* ---------- dependent UI ---------- *\/\n    function updateModeUI() {\n      var B = mode() === \"B\", m = MATS[el.material.value], k = el.material.value;\n      clear(el.modeInfo);\n      var p = mk(\"p\");\n      if (B) {\n        p.appendChild(mk(\"strong\", \"\", \"Mode B: custom surface roughness correction. \"));\n        p.appendChild(document.createTextNode(\"There is no universal Ra-to-ka equation. ka is calculated only from a model you supply, with coefficients from material-specific fatigue tests, validated literature or an applicable standard. Without coefficients, Ra is reported as a measurement only.\"));\n      } else {\n        p.appendChild(mk(\"strong\", \"\", \"Mode A: surface finish factor from the manufacturing process. \"));\n        p.appendChild(document.createTextNode(\"ka = a\\u00b7Sut^b with empirical steel coefficients for each finish. Ra, if entered, is shown for reference and does not change ka.\"));\n      }\n      el.modeInfo.appendChild(p);\n      el.finishField.hidden = B;\n      [el.bTitle, el.rarefField, el.cField, el.mexpField, el.confirmModelField].forEach(function (n) { n.hidden = !B; });\n      el.sutOpt.textContent = B ? \"(optional)\" : \"\";\n      el.raOpt.textContent = B ? \"(required)\" : \"(optional)\";\n      el.confirmMatField.hidden = B ? true : k !== \"custom\";\n      clear(el.matInfo);\n      var info = MAT_INFO[k], p1 = mk(\"p\");\n      if (B) {\n        p1.appendChild(mk(\"strong\", \"\", m.name + \". \"));\n        p1.appendChild(document.createTextNode(\"Mode B coefficients must be specific to this material and its manufacturing process.\"));\n        el.matInfo.className = \"srf-info srf-span\";\n      } else {\n        p1.appendChild(mk(\"strong\", \"\", m.name + \": \" + info[0] + \" \"));\n        p1.appendChild(document.createTextNode(info[1]));\n        el.matInfo.className = \"srf-info srf-span\" + (m.modeA === \"ok\" ? \"\" : (m.modeA === \"no\" ? \" srf-info-err\" : \" srf-info-warn\"));\n      }\n      el.matInfo.appendChild(p1);\n      var F = FINISH[el.finish.value];\n      el.finishHint.textContent = \"a = \" + fmtTrim(F.a, 3) + \", b = \" + fmt(F.b, 3) + \" (Sut in MPa).\" + (el.finish.value === \"colddrawn\" ? \" Same coefficients as machined.\" : \"\");\n    }\n    function updateUnitLabels() {\n      var u = unit(), a = root.querySelectorAll(\".srf-ulabel\"), i;\n      for (i = 0; i < a.length; i++) { a[i].textContent = u; }\n      var b = root.querySelectorAll(\".srf-ralabel\");\n      for (i = 0; i < b.length; i++) { b[i].textContent = raLabel(el.raUnit.value); }\n      el.sut.placeholder = \"e.g. \" + fmtTrim(600 \/ TO_MPA[u], u === \"ksi\" ? 1 : 0).replace(\/,\/g, \"\");\n      el.sep.placeholder = \"e.g. \" + fmtTrim(300 \/ TO_MPA[u], u === \"ksi\" ? 1 : 0).replace(\/,\/g, \"\");\n      el.ra.placeholder = el.raUnit.value === \"uin\" ? \"e.g. 63\" : \"e.g. 1.6\";\n      el.raref.placeholder = el.raUnit.value === \"uin\" ? \"e.g. 8\" : \"e.g. 0.2\";\n    }\n    function onUnit() {\n      var u = unit(), prev = state.lastUnit;\n      if (u === prev) { return; }\n      [el.sut, el.sep].forEach(function (i) {\n        var v = readNum(i);\n        if (isNum(v)) { setVal(i, v * TO_MPA[prev] \/ TO_MPA[u], u === \"Pa\" ? 0 : (u === \"psi\" ? 1 : 4)); }\n      });\n      state.lastUnit = u;\n      updateUnitLabels();\n    }\n    function onRaUnit() {\n      var u = el.raUnit.value, prev = state.lastRaUnit;\n      if (u === prev) { return; }\n      [el.ra, el.raref].forEach(function (i) {\n        var v = readNum(i);\n        if (isNum(v)) { setVal(i, u === \"uin\" ? v \/ UIN_TO_UM : v * UIN_TO_UM, u === \"uin\" ? 2 : 4); }\n      });\n      state.lastRaUnit = u;\n      updateUnitLabels();\n    }\n    \/* =====================================================================\n       RENDER RESULTS\n       ===================================================================== *\/\n    function kpi(label, value, sub, na) {\n      var c = mk(\"div\", \"srf-kpi\");\n      c.appendChild(mk(\"div\", \"srf-kpi-label\", label));\n      c.appendChild(mk(\"div\", \"srf-kpi-value\" + (na ? \" srf-na\" : \"\"), value));\n      if (sub) { c.appendChild(mk(\"div\", \"srf-kpi-sub\", sub)); }\n      return c;\n    }\n    function inRange(ka) { return isNum(ka) ? (ka > 0 ? ka <= 1 : false) : false; }\n    function render(r, scroll) {\n      var inp = r.inp, u = inp.unit;\n      root.classList.remove(\"srf-is-stale\"); el.stale.hidden = true;\n      el.results.hidden = false;\n      \/* --- hero --- *\/\n      var has = r.ka !== null, ok = inRange(r.ka);\n      el.hero.className = \"srf-hero\" + (has ? (ok ? \"\" : \" srf-hero-flag\") : \" srf-hero-na\");\n      el.ka.textContent = has ? fmtKa(r.ka) : \"Not calculated\";\n      if (!has) { el.kaSub.textContent = r.blocked; }\n      else if (ok) { el.kaSub.textContent = \"Within the physically meaningful range 0 < ka \\u2264 1.\"; }\n      else { el.kaSub.textContent = \"Flagged: outside the physically meaningful range 0 < ka \\u2264 1. Shown unclipped; not a valid design value.\"; }\n      \/* --- interpretation, only when values support it --- *\/\n      if (ok) {\n        el.interp.textContent = \"A calculated surface factor of \" + fmtKa(r.ka) + \" indicates that the selected empirical model estimates an endurance limit approximately \" + fmt(r.reduction, 1) + \"% lower than the unmodified reference value due to the surface finish correction\" + (r.seS !== null ? \" (\" + fmtS(inp.sep, u) + \" to \" + fmtS(r.seS, u) + \").\" : \".\");\n        el.interp.hidden = false;\n      } else { el.interp.textContent = \"\"; el.interp.hidden = true; }\n      \/* --- primary --- *\/\n      clear(el.primary);\n      el.primary.appendChild(kpi(\"Estimated Surface-Related Endurance Reduction\", has ? (ok ? fmt(r.reduction, 1) + \"%\" : \"Not meaningful\") : \"Not available\", has ? (ok ? \"(1 \\u2212 ka) \\u00d7 100, relative to the reference endurance limit\" : \"ka is outside 0 to 1; computed value \" + fmt(r.reduction, 1) + \"%\") : \"\", !(has ? ok : false)));\n      el.primary.appendChild(kpi(\"Selected Manufacturing Surface Finish\", r.mode === \"A\" ? r.finish.name : \"Not used (Mode B)\", r.mode === \"A\" ? (inp.finish === \"colddrawn\" ? \"Uses machined coefficients\" : \"Mode A process category\") : \"Mode B uses measured Ra\", r.mode !== \"A\"));\n      el.primary.appendChild(kpi(\"Ultimate Tensile Strength\", inp.sut === null ? \"Not entered\" : fmtS(inp.sut, u), inp.sut === null ? \"Optional in Mode B\" : (u === \"MPa\" ? \"\" : \"= \" + fmtMPa(inp.sut) + \" (used internally)\"), inp.sut === null));\n      el.primary.appendChild(kpi(\"Applied Calculation Model\", r.mode === \"A\" ? \"Marin (steel), Mode A\" : (r.hasModel ? \"User-defined, Mode B\" : \"None (Ra only)\"), r.model, false));\n      \/* --- formula --- *\/\n      if (r.mode === \"A\" ? has : false) {\n        el.formula.textContent = \"ka = a \\u00b7 Sut^b = \" + fmtTrim(r.a, 3) + \" \\u00d7 \" + fmtTrim(inp.sut, 2) + \"^(\" + fmt(r.b, 3) + \") = \" + fmtKa(r.ka) + (r.seS !== null ? \"    \\u00b7    Se,surface = ka \\u00b7 Se\\u2032 = \" + fmtKa(r.ka) + \" \\u00d7 \" + fmtMPa(inp.sep) + \" = \" + fmtMPa(r.seS) : \"\");\n        el.formula.hidden = false;\n      } else if (r.mode === \"B\" ? has : false) {\n        el.formula.textContent = \"ka = C \\u00b7 (Ra \/ Ra,ref)^m = \" + fmtTrim(r.C, 4) + \" \\u00d7 (\" + fmtRa(inp.ra, inp.raUnit) + \" \/ \" + fmtRa(inp.raref, inp.raUnit) + \")^(\" + fmtTrim(r.m, 4) + \") = \" + fmtTrim(r.C, 4) + \" \\u00d7 \" + fmtTrim(r.ratio, 4) + \"^(\" + fmtTrim(r.m, 4) + \") = \" + fmtKa(r.ka) + (r.seS !== null ? \"    \\u00b7    Se,surface = \" + fmtKa(r.ka) + \" \\u00d7 \" + fmtS(inp.sep, u) + \" = \" + fmtS(r.seS, u) : \"\");\n        el.formula.hidden = false;\n      } else { el.formula.hidden = true; }\n      \/* --- secondary --- *\/\n      clear(el.secondary);\n      el.secondary.appendChild(kpi(\"Unmodified Endurance Limit Se\\u2032\", inp.sep === null ? \"Not entered\" : fmtS(inp.sep, u), inp.sep === null ? \"Optional input\" : (u === \"MPa\" ? \"Reference (polished specimen) value\" : \"= \" + fmtMPa(inp.sep)), inp.sep === null));\n      var seTxt = r.seS === null ? (inp.sep === null ? \"Not available\" : \"Not calculated\") : fmtS(r.seS, u);\n      var seSub = r.seS === null ? (inp.sep === null ? \"Enter Se\\u2032 to calculate\" : \"Requires a valid ka\") : (\"Surface factor only\" + (ok ? \"\" : \"; flagged, ka outside 0 to 1\"));\n      el.secondary.appendChild(kpi(\"Surface-Corrected Endurance Limit Se,surface\", seTxt, seSub, r.seS === null));\n      el.secondary.appendChild(kpi(\"Surface Roughness Ra\", inp.ra === null ? \"Not entered\" : fmtRa(inp.ra, inp.raUnit), inp.ra === null ? \"Optional in Mode A\" : (r.mode === \"A\" ? \"Reference only; not used for ka\" : (inp.raUnit === \"uin\" ? \"= \" + fmtRa(inp.ra, \"um\") : \"= \" + fmtRa(inp.ra, \"uin\"))), inp.ra === null));\n      var coef = \"\\u2014\", coefSub = \"\";\n      if (r.mode === \"A\") { if (r.a !== undefined) { coef = \"a = \" + fmtTrim(r.a, 3) + \", b = \" + fmt(r.b, 3); coefSub = \"Shigley Table 6-2, Sut in MPa\"; } else { coefSub = \"Not applied to this material\"; } }\n      else if (r.hasModel) { coef = \"C = \" + fmtTrim(r.C, 4) + \", m = \" + fmtTrim(r.m, 4); coefSub = \"Ra,ref = \" + fmtRa(inp.raref, inp.raUnit) + \" (user-supplied)\"; }\n      else { coefSub = \"No model coefficients supplied\"; }\n      el.secondary.appendChild(kpi(\"Empirical Coefficients Used\", coef, coefSub, coef === \"\\u2014\"));\n      \/* --- notes --- *\/\n      clear(el.notes);\n      var order = { e: 0, w: 1, i: 2 }, ic = { e: \"!\", w: \"!\", i: \"i\" };\n      r.notes.slice().sort(function (x, y) { return order[x.level] - order[y.level]; }).forEach(function (n) {\n        var d = mk(\"div\", \"srf-note srf-note-\" + n.level);\n        d.appendChild(mk(\"span\", \"srf-note-ic\", ic[n.level])).setAttribute(\"aria-hidden\", \"true\");\n        var t = mk(\"span\", \"\", \"\"); t.appendChild(mk(\"span\", \"srf-vh\", n.level === \"e\" ? \"Error: \" : (n.level === \"w\" ? \"Warning: \" : \"Note: \"))); t.appendChild(document.createTextNode(n.text));\n        d.appendChild(t); el.notes.appendChild(d);\n      });\n      if (scroll) { focusResults(); }\n    }\n    function focusResults() {\n      try { el.results.focus({ preventScroll: true }); } catch (e) { \/* ignore *\/ }\n      var rect = el.results.getBoundingClientRect(), vh = window.innerHeight || document.documentElement.clientHeight;\n      if (rect.top < 0 ? true : rect.top > vh * 0.6) { if (el.results.scrollIntoView) { el.results.scrollIntoView({ behavior: \"smooth\", block: \"start\" }); } }\n    }\n    \/* =====================================================================\n       COPY AND PRINT\n       ===================================================================== *\/\n    function reportLines(r) {\n      var inp = r.inp, u = inp.unit, L = [], ok = inRange(r.ka);\n      L.push(\"Surface Roughness Factor Calculator \\u2014 results\");\n      L.push(\"\");\n      L.push(\"Mode: \" + (r.mode === \"A\" ? \"A, surface finish factor from manufacturing process\" : \"B, custom surface roughness correction\"));\n      L.push(\"Material: \" + r.mat.name);\n      L.push(\"Surface modification factor ka: \" + (r.ka === null ? \"not calculated\" : fmtKa(r.ka) + (ok ? \"\" : \" (FLAGGED: outside 0 to 1)\")));\n      L.push(\"Estimated surface-related endurance reduction: \" + (r.ka === null ? \"not available\" : (ok ? fmt(r.reduction, 1) + \"%\" : \"not meaningful (ka outside 0 to 1)\")));\n      L.push(\"Selected manufacturing surface finish: \" + (r.mode === \"A\" ? r.finish.name : \"not used\"));\n      L.push(\"Ultimate tensile strength: \" + (inp.sut === null ? \"not entered\" : fmtS(inp.sut, u) + (u === \"MPa\" ? \"\" : \" (\" + fmtMPa(inp.sut) + \")\")));\n      L.push(\"Applied calculation model: \" + r.model);\n      if (r.mode === \"A\" ? r.a !== undefined : false) { L.push(\"Empirical coefficients: a = \" + fmtTrim(r.a, 3) + \", b = \" + fmt(r.b, 3) + \" (Sut in MPa)\"); }\n      if (r.mode === \"B\" ? r.hasModel : false) { L.push(\"Model coefficients: C = \" + fmtTrim(r.C, 4) + \", m = \" + fmtTrim(r.m, 4) + \", Ra,ref = \" + fmtRa(inp.raref, inp.raUnit)); }\n      L.push(\"Surface roughness Ra: \" + (inp.ra === null ? \"not entered\" : fmtRa(inp.ra, inp.raUnit) + (r.mode === \"A\" ? \" (reference only)\" : \"\")));\n      L.push(\"Unmodified endurance limit Se\\u2032: \" + (inp.sep === null ? \"not entered\" : fmtS(inp.sep, u)));\n      L.push(\"Surface-corrected endurance limit Se,surface: \" + (r.seS === null ? \"not available\" : fmtS(r.seS, u) + \" (surface factor only)\"));\n      if (ok) { L.push(\"\"); L.push(el.interp.textContent); }\n      L.push(\"\"); L.push(\"Notes:\");\n      r.notes.forEach(function (n) { L.push(\"- \" + (n.level === \"e\" ? \"[Flag] \" : (n.level === \"w\" ? \"[Warning] \" : \"\")) + n.text); });\n      L.push(\"\");\n      L.push(\"Disclaimer: Approximate empirical values for preliminary engineering evaluation and educational purposes. Critical applications require validated material data and appropriate fatigue analysis.\");\n      return L;\n    }\n    function flash(msg) { el.copyMsg.textContent = msg; clearTimeout(state.ct); state.ct = setTimeout(function () { el.copyMsg.textContent = \"\"; }, 2600); }\n    function fallbackCopy(s) {\n      var ta = document.createElement(\"textarea\");\n      ta.value = s; ta.setAttribute(\"readonly\", \"\"); ta.style.position = \"fixed\"; ta.style.top = \"-1000px\"; ta.style.opacity = \"0\";\n      document.body.appendChild(ta); ta.select();\n      var ok = false; try { ok = document.execCommand(\"copy\"); } catch (e) { ok = false; }\n      document.body.removeChild(ta);\n      flash(ok ? \"Results copied.\" : \"Copy failed. Select and copy the results manually.\");\n    }\n    function copyResults() {\n      if (!state.last) { return; }\n      var s = reportLines(state.last).join(\"\\n\");\n      if (navigator.clipboard ? window.isSecureContext : false) {\n        navigator.clipboard.writeText(s).then(function () { flash(\"Results copied.\"); }, function () { fallbackCopy(s); });\n      } else { fallbackCopy(s); }\n    }\n    function printResults() {\n      if (!state.last) { return; }\n      var r = state.last, frame = document.createElement(\"iframe\");\n      frame.setAttribute(\"aria-hidden\", \"true\"); frame.setAttribute(\"tabindex\", \"-1\");\n      frame.style.position = \"fixed\"; frame.style.right = \"0\"; frame.style.bottom = \"0\"; frame.style.width = \"0\"; frame.style.height = \"0\"; frame.style.border = \"0\";\n      document.body.appendChild(frame);\n      var doc = frame.contentDocument || frame.contentWindow.document;\n      doc.open(); doc.write(\"<!doctype html><html><head><meta charset=\\\"utf-8\\\"><title>Surface Roughness Factor Results<\/title><\/head><body><\/body><\/html>\"); doc.close();\n      var st = doc.createElement(\"style\");\n      st.textContent = \"body{font-family:-apple-system,Segoe UI,Roboto,Arial,sans-serif;color:#1f2b3b;margin:24px;font-size:13px;line-height:1.5}h1{font-size:20px;color:#0f2342;margin:0 0 4px}p{margin:0 0 4px}.big{font-size:30px;font-weight:700;color:#0f2342;margin:8px 0}.sec{margin-top:14px;font-weight:700;color:#0f2342}.small{color:#55667c;font-size:11.5px;margin-top:14px}\";\n      doc.head.appendChild(st);\n      var lines = reportLines(r);\n      var h = doc.createElement(\"h1\"); h.textContent = lines[0]; doc.body.appendChild(h);\n      var big = doc.createElement(\"p\"); big.className = \"big\"; big.textContent = \"ka = \" + (r.ka === null ? \"not calculated\" : fmtKa(r.ka)); doc.body.appendChild(big);\n      lines.slice(1).forEach(function (s) { var p = doc.createElement(\"p\"); p.textContent = s; if (s === \"Notes:\") { p.className = \"sec\"; } doc.body.appendChild(p); });\n      var dis = doc.createElement(\"p\"); dis.className = \"small\"; dis.textContent = \"Printed \" + new Date().toLocaleString(); doc.body.appendChild(dis);\n      var win = frame.contentWindow;\n      setTimeout(function () {\n        try { win.focus(); win.print(); } catch (e) { window.print(); }\n        setTimeout(function () { if (frame.parentNode) { frame.parentNode.removeChild(frame); } }, 1500);\n      }, 60);\n    }\n    \/* =====================================================================\n       CALCULATE \/ LIVE UPDATE\n       ===================================================================== *\/\n    function finite(r) {\n      if (r.ka !== null ? !isNum(r.ka) : false) { return false; }\n      if (r.seS !== undefined ? (r.seS !== null ? !isNum(r.seS) : false) : false) { return false; }\n      return true;\n    }\n    function run(fromButton) {\n      if (fromButton) { el.formMsg.textContent = \"\"; }\n      var ok = validateAll();\n      if (!ok) {\n        if (fromButton) {\n          el.formMsg.textContent = \"Please correct the highlighted fields.\";\n          var first = root.querySelector(\".srf-invalid, [aria-invalid=true]\");\n          if (first) { first.focus(); }\n        }\n        if (state.last) { root.classList.add(\"srf-is-stale\"); el.stale.hidden = false; }\n        return;\n      }\n      var inp = readInput();\n      var r = inp.mode === \"A\" ? computeA(inp) : computeB(inp);\n      if (!finite(r)) {\n        el.formMsg.textContent = \"The inputs produce an undefined or non-finite result. Check the values and units.\";\n        if (state.last) { root.classList.add(\"srf-is-stale\"); el.stale.hidden = false; }\n        return;\n      }\n      state.last = r; state.live = true; el.formMsg.textContent = \"\";\n      render(r, fromButton);\n    }\n    function schedule() { clearTimeout(state.timer); state.timer = setTimeout(function () { if (state.live) { run(false); } }, 150); }\n    function clearErrors() {\n      var all = root.querySelectorAll(\".srf-invalid\"), i;\n      for (i = 0; i < all.length; i++) { all[i].classList.remove(\"srf-invalid\"); all[i].removeAttribute(\"aria-invalid\"); }\n      var ch = root.querySelectorAll(\".srf-invalid-check\");\n      for (i = 0; i < ch.length; i++) { ch[i].classList.remove(\"srf-invalid-check\"); }\n      [el.confirmMat, el.confirmModel].forEach(function (c) { c.removeAttribute(\"aria-invalid\"); });\n      var errs = root.querySelectorAll(\".srf-error\");\n      for (i = 0; i < errs.length; i++) { errs[i].textContent = \"\"; }\n      el.formMsg.textContent = \"\";\n    }\n    function fill(D) {\n      setRadio(\"srf-mode\", D.mode); setRadio(\"srf-unit\", D.unit); state.lastUnit = D.unit;\n      el.material.value = D.material; el.finish.value = D.finish; el.raUnit.value = D.raUnit; state.lastRaUnit = D.raUnit;\n      setVal(el.sut, D.sut); setVal(el.ra, D.ra); setVal(el.sep, D.sep); setVal(el.raref, D.raref); setVal(el.c, D.c); setVal(el.mexp, D.mexp);\n      el.confirmMat.checked = false; el.confirmModel.checked = false;\n      clearErrors(); updateUnitLabels(); updateModeUI();\n    }\n    function resetAll() {\n      fill({ mode: \"A\", unit: \"MPa\", material: \"carbon\", sut: \"\", finish: \"machined\", ra: \"\", raUnit: \"um\", sep: \"\", raref: \"\", c: \"\", mexp: \"\" });\n      state.last = null; state.live = false;\n      root.classList.remove(\"srf-is-stale\"); el.stale.hidden = true;\n      el.results.hidden = true;\n    }\n    \/* ---------- events (bound once) ---------- *\/\n    function onFieldEvent(e) {\n      var t = e.target;\n      if (!t ? true : !(t.id || t.name)) { return; }\n      if (t.name === \"srf-unit\") { onUnit(); vSut(); vSep(); }\n      if (t.id === \"srf-ra-unit\") { onRaUnit(); vRa(); vRaref(); }\n      if (t.name === \"srf-mode\") { clearErrors(); updateModeUI(); }\n      if (t.id === \"srf-material\" ? true : t.id === \"srf-finish\") { updateModeUI(); vConfirmMat(); }\n      if (VALIDATORS[t.id]) { VALIDATORS[t.id](); }\n      schedule();\n    }\n    function isChoice(t) { return !t ? false : (t.tagName === \"SELECT\" ? true : (t.type === \"radio\" ? true : t.type === \"checkbox\")); }\n    el.form.addEventListener(\"input\", function (e) { if (!isChoice(e.target)) { onFieldEvent(e); } });\n    el.form.addEventListener(\"change\", function (e) { if (isChoice(e.target)) { onFieldEvent(e); } });\n    el.form.addEventListener(\"keydown\", function (e) { if (e.key === \"Enter\" ? (e.target ? e.target.tagName === \"INPUT\" : false) : false) { e.preventDefault(); run(true); } });\n    root.addEventListener(\"keydown\", function (e) { if (e.key === \"Escape\" ? (document.activeElement ? document.activeElement.classList.contains(\"srf-q\") : false) : false) { document.activeElement.blur(); } });\n    el.calc.addEventListener(\"click\", function () { run(true); });\n    el.copy.addEventListener(\"click\", copyResults);\n    el.print.addEventListener(\"click\", printResults);\n    \/* initial state: empty inputs, results hidden until Calculate is pressed *\/\n    resetAll();\n  }\n  if (document.getElementById(\"srf-calculator\")) { init(); }\n  else if (document.readyState === \"loading\") { document.addEventListener(\"DOMContentLoaded\", init); }\n  else { init(); }\n})();\n<\/script>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The Surface Roughness Factor Calculator is a practical engineering tool designed to estimate the influence of surface finish and roughness on the fatigue strength of&#8230;<\/p>","protected":false},"author":2,"featured_media":24964,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"pmpro_default_level":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[8647],"tags":[8764,3526,8761,8762,8763],"class_list":["post-24963","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-materials-science-and-properties","tag-fatigue-strength-analysis","tag-mechanical-engineering-tools","tag-surface-finish-calculator","tag-surface-modification-factor","tag-surface-roughness-factor","pmpro-has-access"],"acf":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/www.mechstream.com\/wp-content\/uploads\/2026\/10\/Surface-Roughness-Factor-Calculator.png","_links":{"self":[{"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/posts\/24963","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/comments?post=24963"}],"version-history":[{"count":1,"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/posts\/24963\/revisions"}],"predecessor-version":[{"id":24965,"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/posts\/24963\/revisions\/24965"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/media\/24964"}],"wp:attachment":[{"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/media?parent=24963"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/categories?post=24963"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mechstream.com\/pt\/wp-json\/wp\/v2\/tags?post=24963"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}