diff --git a/bun.lockb b/bun.lockb index 65f7ad0..655a1c0 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 003ff92..d640cc1 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ }, "dependencies": { "@tailwindcss/forms": "^0.5.10", + "katex": "^0.16.22", "lucide-svelte": "^0.471.0" }, "private": true diff --git a/src/lib/components/Dropdown.svelte b/src/lib/components/Dropdown.svelte new file mode 100644 index 0000000..a8e873b --- /dev/null +++ b/src/lib/components/Dropdown.svelte @@ -0,0 +1,49 @@ + + + + + diff --git a/src/lib/components/Latex.svelte b/src/lib/components/Latex.svelte new file mode 100644 index 0000000..27e6413 --- /dev/null +++ b/src/lib/components/Latex.svelte @@ -0,0 +1,25 @@ + + + + + + + + {@html katexString} + diff --git a/src/lib/components/NavigationFooter.svelte b/src/lib/components/NavigationFooter.svelte index f484d4c..e7ec52b 100644 --- a/src/lib/components/NavigationFooter.svelte +++ b/src/lib/components/NavigationFooter.svelte @@ -68,6 +68,12 @@ hotkey="d" redirectFunc={navigation.toRepository} /> + import "$lib/styles/NavigationHeader.scss"; + import Dropdown from "$lib/components/Dropdown.svelte"; import Button from "$lib/components/Button.svelte"; import Link from "$lib/components/Link.svelte"; @@ -13,6 +14,11 @@ export let display_logo = true; import { navigation } from "$lib/navigation"; + + const dataItems = [ + { text: "Repository", redirectFunc: navigation.toRepository, hotkey: "dr" }, + { text: "Methodology", redirectFunc: navigation.toMethodology, hotkey: "dm" }, + ];
@@ -26,12 +32,7 @@ redirectFunc={navigation.toHome} /> {/if} - + { window.location.href = "https://invenio.am-d-model.eu/"; }, + toMethodology: () => goto("/methodology"), to404: () => { throw error(404, "Page not found"); }, diff --git a/src/lib/styles/Dropdown.scss b/src/lib/styles/Dropdown.scss new file mode 100644 index 0000000..a131bfe --- /dev/null +++ b/src/lib/styles/Dropdown.scss @@ -0,0 +1,47 @@ +.dropdown { + position: relative; + display: inline-block; +} + +.dropdown-toggle { + background-color: transparent; + border: none; + cursor: pointer; + display: flex; + align-items: center; + gap: 5px; + padding: 0px 8px 0px 8px; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + background-color: white; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + min-width: 150px; + z-index: 10; + padding: 8px; +} + +.dropdown-item-wrapper { + display: block; + padding: 8px; +} + +:global(.dropdown-item) { + display: block; + padding: 8px 16px; + width: 100%; + text-align: left; +} + +:global(.dropdown-item:hover) { + background-color: #f5f5f5; +} + +.dropdown-arrow { + font-size: 0.7em; +} diff --git a/src/lib/styles/styles.css b/src/lib/styles/styles.css index 4dafd7d..4256af0 100644 --- a/src/lib/styles/styles.css +++ b/src/lib/styles/styles.css @@ -18,9 +18,31 @@ h5, -webkit-font-smoothing: antialiased; } +table { + font-size: 24pt; + border-collapse: collapse; + width: 100%; +} + +th, +td { + border: 1px solid #ddd; + padding: 8px; + text-align: center; +} + +th { + background-color: #f2f2f2; +} + +tr:nth-child(even) { + background-color: #f9f9f9; +} + menu, ol, -ul { +ul, +dl { list-style-type: none; list-style-position: inside; margin: 0; @@ -67,6 +89,12 @@ p { padding-bottom: 24px; } +@media (max-width: 620px) { + table { + font-size: 18pt; + } +} + @media (max-width: 620px) { h1 { font-size: 54pt; @@ -82,7 +110,8 @@ p { } ol, - ul { + ul, + dl { font-size: 16pt; } } @@ -101,13 +130,19 @@ p { font-size: 16pt; } + table, ol, - ul { + ul, + dl { font-size: 14pt; } } @media (max-width: 380px) { + table { + font-size: 16pt; + } + h1 { font-size: 36pt; } @@ -121,8 +156,10 @@ p { font-size: 16pt; } + table, ol, - ul { + ul, + dl { font-size: 14pt; } } diff --git a/src/routes/NavigationHeader.scss b/src/routes/NavigationHeader.scss index f8b0746..728e7bb 100644 --- a/src/routes/NavigationHeader.scss +++ b/src/routes/NavigationHeader.scss @@ -1,47 +1,47 @@ .splash-navigation-header { + position: relative; + height: 128px; + width: 100%; + padding-bottom: 120px; + + .navigation-header-items { + gap: 48px; + align-items: center; position: relative; - height: 128px; - width: 100%; - padding-bottom: 120px; + padding-top: 28px; + padding-right: 96px; + } - .navigation-header-items { - gap: 48px; - align-items: center; - position: relative; - padding-top: 28px; - padding-right: 96px; - } + .navigation-header-link { + color: var(--cpalettelight); + font-family: var(--navigation-header-font-family); + text-align: left; + font-size: var(--navigation-header-font-size); + font-weight: var(--navigation-header-font-weight); + border-bottom: 1px solid currentColor; // instead of an underline + position: relative; + display: flex; + align-items: center; + justify-content: flex-start; + } - .navigation-header-link { - color: var(--cpalettelight); - font-family: var(--navigation-header-font-family); - text-align: left; - font-size: var(--navigation-header-font-size); - font-weight: var(--navigation-header-font-weight); - text-decoration: underline; - position: relative; - display: flex; - align-items: center; - justify-content: flex-start; - } + .navigation-header-button { + background: var(--cpalettelight); + border-radius: 8px; + padding: 14px 24px 14px 24px; + display: flex; + flex-direction: row; + gap: 8px; + align-items: center; + justify-content: center; + flex-shrink: 0; + position: relative; + box-shadow: var(--button-shadow-box-shadow, 0px 1px 2px 0px rgba(0, 0, 0, 0.05)); + } - .navigation-header-button { - background: var(--cpalettelight); - border-radius: 8px; - padding: 14px 24px 14px 24px; - display: flex; - flex-direction: row; - gap: 8px; - align-items: center; - justify-content: center; - flex-shrink: 0; - position: relative; - box-shadow: var(--button-shadow-box-shadow, 0px 1px 2px 0px rgba(0, 0, 0, 0.05)); - } - - .navigation-header-button-text { - @extend .navigation-header-link; - color: var(--background); - text-decoration: none; - } + .navigation-header-button-text { + @extend .navigation-header-link; + color: var(--background); + text-decoration: none; + } } diff --git a/src/routes/methodology/+page.svelte b/src/routes/methodology/+page.svelte new file mode 100644 index 0000000..adfa132 --- /dev/null +++ b/src/routes/methodology/+page.svelte @@ -0,0 +1,361 @@ + + +
+ +
+
+

Methodology

+

+ This page describes the methodology being used for sample fabrication and in-situ IR + pyrometry being used by the AM-D-Model project. Data contributions to the project + should follow a similar methodology to this, to ensure data consistency in the + resulting benchmark. As part of our commitment to openness and transparency, we + encourage collaborators and interested parties to review our methodology and engage + with our team. We welcome any and all suggestions for potential improvements and + discussions on how we can ensure that this project produces a valuable benchmark + dataset that can drive the future development of metal AM. +

+
+ +
+
+

Component Geometry and Specification

+
+
+

+ The geometry of the test AM components (samples) shown in Figure 1 + consist of a 7mm × 7mm × 7.2mm (L x B x H) cuboid, complemented with a + tapered support structure of height, 2.85 mm. Additionally, sample + numbers with a height of 300 µm were incorporated into the top of the + cuboid geometry, resulting in a total sample dimension of 7mm × 7mm × + 10.35 mm. This geometry, along with the support structure design, was + specifically chosen to enable straightforward sample removal using a wet + abrasive cutter equipped with 2.8 mm thick blades, while also ensuring + easy handling during characterization. +

+
+
+
+ A CAD model projection of one of the samples produced. +
+ Figure 1. CAD representations of the sample geometry: + (a) + isometric view, and (b) front view. +
+
+
+
+
+
+ +
+
+

AM Pilot Line and Process Parameters

+

+ The samples were fabricated using the AM pilot line at Dublin City University + (DCU). This pilot line is the AconityMINI® 3D powder bed fusion-laser system. + It is equipped with a 200 W, 1068 nm Yb- fiber laser. This system supports laser + scanning speeds of up to 2000 mm/s and features a minimum laser beam diameter of + 32 µm. High-purity argon gas (99.99999% purity) was used as shielding gas, and + the "Skywriting" feature was enabled during the fabrication process. A + comprehensive PBF-LB process parameter window was defined through a + full-factorial experimental design. This approach systematically explores the + effects of key process parameters by varying four factors at four levels each (4 + factors × 4 levels = 44), resulting in a total of 256 unique + parameter combinations. The factors and their corresponding levels are as + follows: +

+
+
+ {#each laser_params as param} +
+
{@html param.name}:
+
[ {@html param.values.join(", ")} ] {@html param.unit}
+
+ {/each} +
+
+

+ The range of energy densities calculated from these parameters spans the + following: +

+
+
+ {#each ved_params as param} +
+
{@html param.name}:
+
+ [ {@html param.min} to {@html param.max} ] {@html param.unit} +
+
+ {/each} +
+
+

+ The metal powder feedstock used was the PowderRange® 316L stainless steel + powder supplied by Carpenter Additive®. The particle size of the powder + feedstock ranged between 15 and 45 µm. For this reason, the layer thickness (L) + parameter was maintained at a constant value of 50 µm. At this layer thickness, + each sample with dimensions of 7 mm × 7 mm × 10.3 mm required 206 layers to + complete fabrication. A bidirectional scanning strategy was applied, starting + with a layer angle of 45 degrees, followed by a 90° rotation for each subsequent + layer. +

+
+
+

+ Two sets of the 256 unique parameter combinations were fabricated, + yielding a total of 512 samples. Figure 2 shows representative pictures + of the first 100 samples produced. During the final print session, 56 + remaining samples from the first set were combined with 56 remaining + samples from the second set, creating a final print batch with 112 + samples. This method was implemented to maintain consistent interlayer + printing times and achieve thermal distribution uniformity across all + samples, comparable to the other print batches of 100 samples. +

+
+
+
+ 2 photographs of a PBF buildplate featuring 100 samples. +
+ Figure 2. Exemplar pictures of 100 fabricated samples still + attached to the build plate (a) top view and (b) angled + view. +
+
+
+
+

+ Volumetric Energy Density (VED) is a derived thermodynamic metric widely used in + AM industry and reported in metal AM research. It is typically expressed as + either the spot size variant (VEDf) or the hatch spacing + variant (VEDH), calculated using the below equations, + respectively: +

+
+ +
+
+ +
+

+ However, these two VED variants are not directly comparable, as neither + exclusively captures the full complexity of melt pool physics. This includes + melt pool formation and propagation, solidification geometry (width and depth), + and the intricate mass and heat transfer between the melt pool and the + surrounding material. Given these limitations, both VEDf and + VEDH are included as PBF-LB process-based features. The inclusion + of these two distinct measures of volumetric energy density, further enriches the + experimental space, enabling a nuanced exploration of the relevance of energy distribution + to the ML model performance. +

+
+ +
+

Infrared (IR) Pyrometry

+

+ IR pyrometry measures thermal radiation from the melt pools during the PBF-LB + process, enabling real-time recording of temperature distributions. This helps + identify issues such as overheating, insufficient melting, or thermal gradients + that may cause defects or residual stresses. +

+
+
+
+ 2 photographs of a PBF buildplate featuring 100 samples. +
+ Figure 3. Installed in-situ monitoring modules in the + (a) + AconityMINI PBF-LB machine + at DCU; (b) two + Kleiber® KG 740-LO pyrometers + in-line with the laser beam path; (c) + AMiquam W1 ECM module + with two channels; and (d) one + Avisoft-Bioacoustics® CM16/CMPA ultrasonic microphone. +
+
+
+
+

+ In-situ temporal IR monitoring was performed using two + Kleiber® KG 740-LO pyrometers + fitted to our AconityMINI machine (Figure 3a). The optical path of both pyrometers + was configured to be in line with the laser beam path (see Figure 3b). This + enabled the capturing of the meltpool positions (x, y) with the corresponding + relative temperature of the meltpool (T) of all samples being fabricated. + The pyrometers were calibrated to a black-body standard to the same temperature + range, and features: +

+
+
+ +
+
+
+ {#each pyrometry_params as param} +
+
{@html param.name}:
+
{@html param.desc}
+
+ {/each} +
+
+
+
+
+

Relative Density

+

+ The target material property is the observed relative density (RD) of the test + samples, expressed as a percentage of the theoretical density of a perfectly + dense specimen. The RD of each sample was determined using Archimedes’ + principle, following the ASTM B962-23 standard. Ethanol served as the immersion + fluid for the measurements, and the assumed theoretical density of 316L -SS was + to be 8000 kg/m3 for these calculations. +

+
+
+

Sensor Data

+

+ The collected data from the sensors form a comprehensive dataset designed to + capture various aspects of the PBF-LB process. This dataset integrates + measurements from multiple sources, ensuring a detailed representation of the + process parameters and their influence on the target material property + prediction. +

+
+
+

Infrared Pyrometry (IR) Data

+

+ IR data is stored as layer-by-layer .pcd files, where the filename represents + the layer thickness (e.g., 5.24.pcd corresponds to IR data at a 5.24 mm layer + thickness). Each file contains meltpool coordinates (x, y) and relative meltpool + temperature (in degrees Celsius) from the two pyrometers, as illustrated in + Table 1. +

+
+
+ Table 1: Raw IR data structure +
+ + + + {#each ir_table.headers as header} + + {/each} + + + + {#each ir_table.data as row} + + {#each ir_table.headers as header} + + {/each} + + {/each} + +
{header}
{row[header]}
+
+
+
+
+ +
diff --git a/src/routes/methodology/Methodology.scss b/src/routes/methodology/Methodology.scss new file mode 100644 index 0000000..1d638e5 --- /dev/null +++ b/src/routes/methodology/Methodology.scss @@ -0,0 +1,190 @@ +main { + padding: 5% 5% 5% 5%; +} + +p { + text-align: justify; +} + +figcaption { + text-align: center; + padding: 4px 0 4px 0; +} + +.methodology, +.methodology * { + box-sizing: border-box; +} + +.methodology { + background: var(--cpalettecomplimentary); + width: 100vw; + min-width: 250px; + position: absolute; + display: flex; + flex-direction: column; +} + +.copy { + padding: 0 8px 0 8px; +} + +.copy-with-figure { + @apply grid grid-cols-1 gap-8; + + @media (min-width: 768px) { + @apply grid-cols-2 + } + + div { + padding: 0; + display: flex; + align-items: center; + justify-content: center; + } +} + +.param-list { + display: flex; + align-items: center; + justify-content: center; + padding-bottom: 24px; + + dl { + @apply space-y-2; + + div { + @apply items-start; + + display: flex; + align-items: center; + } + } + + dl, + dt, + dd { + font-size: 24pt; + + @media (max-width: 820px) { + font-size: 18pt; + } + + @media (max-width: 620px) { + font-size: 14pt; + } + + @media (max-width: 420px) { + font-size: 12pt; + } + + @media (max-width: 380px) { + font-size: 10pt; + } + } + + dt { + @apply font-semibold text-gray-700; + } + + dd { + @apply flex-1 text-gray-500; + } +} + +.laser-param-list { + @extend .param-list; + + dt { + width: 416px; + + @media (max-width: 820px) { + width: 256px; + } + + @media (max-width: 620px) { + width: 184px; + } + + @media (max-width: 420px) { + width: 142px; + } + + @media (max-width: 380px) { + width: 112px; + } + } +} + +.ved-param-list { + @extend .param-list; + + dt { + width: 832px; + + @media (max-width: 1280px) { + width: 532px; + padding-bottom: 16px + } + + @media (max-width: 1024px) { + width: 410px; + } + + @media (max-width: 820px) { + width: 256px; + } + + @media (max-width: 514px) { + width: 128px; + } + } +} + +.equation-container { + padding: 8px 0 8px 0; +} + +.equation { + font-size: 36px; + + @media (max-width: 720px) { + font-size: 24px; + } + + @media (max-width: 480px) { + font-size: 18px; + } + + @media (max-width: 370px) { + font-size: 16px; + } + + @media (max-width: 300px) { + font-size: 12px; + } +} + +.pyrometry-param-list { + @extend .param-list; + + dt { + width: 512px; + + @media (max-width: 820px) { + width: 352px; + } + + @media (max-width: 620px) { + width: 184px; + } + + @media (max-width: 420px) { + width: 142px; + } + + @media (max-width: 380px) { + width: 112px; + } + } +} diff --git a/static/methodology_fig1.webp b/static/methodology_fig1.webp new file mode 100644 index 0000000..28d69ad Binary files /dev/null and b/static/methodology_fig1.webp differ diff --git a/static/methodology_fig2.webp b/static/methodology_fig2.webp new file mode 100644 index 0000000..19f1224 Binary files /dev/null and b/static/methodology_fig2.webp differ diff --git a/static/methodology_fig3.webp b/static/methodology_fig3.webp new file mode 100644 index 0000000..4826eca Binary files /dev/null and b/static/methodology_fig3.webp differ diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5c56cee --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } +}