Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions examples/depth_map_part/input.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
steps:
- 3dthesis:
class: depth_map_part
application: thesis
configure:
res: 250.0e-6
execute:
np: 1
data:
build:
datatype: Peregrine
name: myna_output
path: ..
parts:
P5:
layers: [51]
myna:
workspace: ../example-workspace.yaml
6 changes: 6 additions & 0 deletions examples/example-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ thesis:
res: 25e-6
execute:
batch: True
depth_map_part:
executable: 3DThesis
configure:
res: 25e-6
execute:
batch: True
exaca:
microstructure_region:
executable: ExaCA
5 changes: 5 additions & 0 deletions src/myna/application/thesis/depth_map_part/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Application to use 3DThesis to generate a 2D map of the melt pool depth
given the laser path and process conditions for a layer.
"""

from .app import ThesisDepthMapPart
131 changes: 131 additions & 0 deletions src/myna/application/thesis/depth_map_part/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#
# Copyright (c) 2024 Oak Ridge National Laboratory.
#
# This file is part of Myna. For details, see the top-level license
# at https://github.com/ORNL-MDF/Myna/LICENSE.md.
#
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause.
#
"""Defines application behavior for the thesis/depth_map_part
simulation type
"""
import os
import glob
import polars as pl
from myna.application.thesis import Thesis, adjust_parameter, read_parameter


class ThesisDepthMapPart(Thesis):
"""Simulation type to simulate a map of the melt pool depth for layers of a part"""

def __init__(self, name="depth_map_part"):
super().__init__(name, output_suffix=".Solidification")

def parse_mynafile_path_to_dict(self, mynafile):
"""Parses the path of the output Myna file into a dictionary containing the
build, part, and layer names.

Path to the Myna file is expected to be in the format:
`working_dir/build/part/layer/stepname/mynafile`
"""
dir_parts = os.path.dirname(mynafile).split(os.path.sep)
case_dict = {
"build": dir_parts[-4],
"part": dir_parts[-3],
"layer": dir_parts[-2],
"case_dir": os.path.dirname(mynafile),
"mynafile": mynafile,
}
return case_dict

def configure_case(self, myna_file):
"""Configure a valid 3DThesis case from Myna data"""
# Load case information
case_info = self.parse_mynafile_path_to_dict(myna_file)

# Copy template case
self.copy(case_info["case_dir"])

# Update case parameters
self.update_case_parameters(
case_info["case_dir"], part=case_info["part"], layer=case_info["layer"]
)

def configure(self):
"""Configure all simulations associated with the Myna step"""

# Get expected Myna output files
myna_files = self.settings["data"]["output_paths"][self.step_name]

# Run each case
for myna_file in myna_files:
self.configure_case(myna_file)

def execute_case(
self,
case_directory,
proc_list,
check_for_existing_results=True,
):
"""Run the individual 3DThesis case"""
# Update simulation threads
settings_file = os.path.join(case_directory, self.case_files["settings"])
adjust_parameter(settings_file, "MaxThreads", self.args.np)

# Check if output file exists
if check_for_existing_results:
output_files = glob.glob(os.path.join(case_directory, "Data", "*.csv"))
if (len(output_files) > 0) and not self.args.overwrite:
print(f"{case_directory} has already been simulated. Skipping.")
return proc_list or []

# Run Simulation
procs = proc_list or []
procs = self.run_thesis_case(case_directory, procs)

return procs or []

def execute(self):
"""Execute all cases for the Myna step"""
# Get expected Myna output files
myna_files = self.settings["data"]["output_paths"][self.step_name]

# Run each case
proc_list = []
for case_dir in [os.path.dirname(x) for x in myna_files]:
proc_list = self.execute_case(case_dir, proc_list)

# Wait for any remaining processes
for proc in proc_list:
pid = proc.pid
print(f"- {pid=}: Waiting for simulation to complete")
proc.wait()
print(f"- {pid=}: Simulation complete")

def postprocess(self):
"""Postprocess files from the executed 3DThesis cases for the Myna step"""

# Get expected Myna output files
myna_files = self.settings["data"]["output_paths"][self.step_name]

# Post-process results to convert to Myna format
for mynafile in myna_files:

# Get list of result file(s), accounting for MPI ranks
case_directory = os.path.dirname(mynafile)
case_input_file = os.path.join(case_directory, "ParamInput.txt")
output_name = read_parameter(case_input_file, "Name")[0]
result_file_pattern = os.path.join(
case_directory, "Data", f"{output_name}{self.output_suffix}.Final*.csv"
)
output_files = sorted(glob.glob(result_file_pattern))
for i, filepath in enumerate(output_files):
df = pl.read_csv(filepath)
df = df.filter(pl.col("z") == df["z"].max())
df = df.rename({"x": "x (m)", "y": "y (m)", "depth": "depth (m)"})
df = df.select(["x (m)", "y (m)", "depth (m)"])
if i == 0:
df_all = df.clone()
else:
df_all = pl.concat([df_all, df])
df_all.write_csv(mynafile)
24 changes: 24 additions & 0 deletions src/myna/application/thesis/depth_map_part/configure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# Copyright (c) 2024 Oak Ridge National Laboratory.
#
# This file is part of Myna. For details, see the top-level license
# at https://github.com/ORNL-MDF/Myna/LICENSE.md.
#
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause.
#
"""Script to be executed by the configure stage of `myna.core.workflow.run` to set up
valid 3DThesis cases based on the specified user inputs and template
"""
from myna.application.thesis.depth_map_part.app import (
ThesisDepthMapPart,
)


def configure():
"""Configure all case directories"""
app = ThesisDepthMapPart()
app.configure()


if __name__ == "__main__":
configure()
24 changes: 24 additions & 0 deletions src/myna/application/thesis/depth_map_part/execute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# Copyright (c) 2024 Oak Ridge National Laboratory.
#
# This file is part of Myna. For details, see the top-level license
# at https://github.com/ORNL-MDF/Myna/LICENSE.md.
#
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause.
#
"""Script to be executed by the configure stage of `myna.core.workflow.run` to set up
valid 3DThesis cases based on the specified user inputs and template
"""
from myna.application.thesis.depth_map_part.app import (
ThesisDepthMapPart,
)


def execute():
"""Configure all case directories"""
app = ThesisDepthMapPart()
app.execute()


if __name__ == "__main__":
execute()
24 changes: 24 additions & 0 deletions src/myna/application/thesis/depth_map_part/postprocess.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# Copyright (c) 2024 Oak Ridge National Laboratory.
#
# This file is part of Myna. For details, see the top-level license
# at https://github.com/ORNL-MDF/Myna/LICENSE.md.
#
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause.
#
"""Script to be executed by the configure stage of `myna.core.workflow.run` to set up
valid 3DThesis cases based on the specified user inputs and template
"""
from myna.application.thesis.depth_map_part.app import (
ThesisDepthMapPart,
)


def postprocess():
"""Configure all case directories"""
app = ThesisDepthMapPart()
app.postprocess()


if __name__ == "__main__":
postprocess()
11 changes: 11 additions & 0 deletions src/myna/application/thesis/depth_map_part/template/Beam.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Shape
{
Width_X 130.0e-6
Width_Y 130.0e-6
Depth_Z 10.0e-6
}
Intensity
{
Power 350
Efficiency 0.40
}
12 changes: 12 additions & 0 deletions src/myna/application/thesis/depth_map_part/template/Domain.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
X
{
Res 100e-6
}
Y
{
Res 100e-6
}
Z
{
Res 10e-6
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Constants
{
T_0 298.15
T_L 1733.0
k 29.7658
c 592.555
p 7800.0
}
5 changes: 5 additions & 0 deletions src/myna/application/thesis/depth_map_part/template/Mode.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Solidification
{
Tracking Surface
Timestep 1e-4
}
33 changes: 33 additions & 0 deletions src/myna/application/thesis/depth_map_part/template/Output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Grid
{
x 1
y 1
z 1
}
Temperature
{
T 0
T_hist 0
}
Solidification
{
tSol 0
G 0
Gx 0
Gy 0
Gz 0
V 0
dTdt 0
eqFrac 0
RDF 0
numMelt 0
depth 1
mpStats 0
}
Solidification+
{
H 0
Hx 0
Hy 0
Hz 0
}
14 changes: 14 additions & 0 deletions src/myna/application/thesis/depth_map_part/template/ParamInput.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Simulation
{
Name thermal_3dthesis
Mode Mode.txt
Material Material.txt
Beam Beam.txt
Path Path.txt
}
Options
{
Domain Domain.txt
Output Output.txt
Settings Settings.txt
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Compute
{
MaxThreads 4
}
Loading