Skip to content

Commit bd1bd33

Browse files
Add DRAM wiggle example and HBrO2 model (#133)
* Added initial implementation for mask optical proximity correction * Add psGDSMaskProximity to viennaps namespace * Fixed scaling between rasterization and level set grids, other minor fixes * Multi-Gaussian exposure model and CSV for logger>INFO * Multi-Gaussian exposure model and CSV for logger>INFO * GDS geometry extrusion using level sets with lsExtrude, updated GDSReader example * Added blurring to GDS import using level sets * ... * Gaussian blurring parametrized * Updated GDS import to support transformation * Removed minor redundancy in GDSMaskProximity * Added new GDSGeometry to pyWrap.cpp * fixed merge with master, wrapped updated GDS, updated python GDS example * Fix to adapt to upodated ViennaCore * Remove 'make' folder * Format * Working with different LS and exposure grids * Formatting * Format check * Added python example for oxideRegrowth * Added python example for oxideRegrowth * Separate beam application grid from exposure storage grid * Format GDS example * ExposureLS and ExposureMap stored on coarse grid, only exposure results stored on fine grid. * GDS Reader works in 2D and 3D * Format fix * Fix pyWrap formatting * Improved compatibility for GDS Geometry in 2D and 3D * HBr plasma etching model and DRAM wiggling * Pass GDS file as config parameter * polygon aligned on grid causes seg fault - adjust gridDelta * Implement general plasma etching model * Fix SF6O2 plasma etching * Fix HBrO2 model * Fix GPU SF6O2 etching * Fix Python bindings * update examples and python stubs * add HBrO2 gpu model * Bump version * fix tests --------- Co-authored-by: Lado Filipovic <filipovic@iue.tuwien.ac.at> Co-authored-by: = <=>
1 parent 83bb9f8 commit bd1bd33

32 files changed

+1671
-795
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ CMakeSettings.json
1919
*.egg-info
2020
*env*
2121
.eggs/
22+
output/
2223
*.ptx
23-
*.optixir
24+
*.optixir

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
22
project(
33
ViennaPS
44
LANGUAGES CXX C
5-
VERSION 3.4.1)
5+
VERSION 3.5.0)
66

77
# --------------------------------------------------------------------------------------------------------
88
# Library switches
@@ -22,6 +22,7 @@ option(VIENNAPS_PACKAGE_PYTHON "Build python bindings with intent to publish whe
2222

2323
set(VIENNAPS_LOOKUP_DIRS
2424
""
25+
# "${CMAKE_CURRENT_SOURCE_DIR}/../install/"
2526
CACHE STRING "Directories to account for when searching installed dependencies")
2627

2728
list(APPEND CMAKE_PREFIX_PATH ${VIENNAPS_LOOKUP_DIRS})

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ We recommend using [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake) to consum
115115

116116
* Installation with CPM
117117
```cmake
118-
CPMAddPackage("gh:viennatools/viennaps@3.4.1")
118+
CPMAddPackage("gh:viennatools/viennaps@3.5.0")
119119
```
120120

121121
* With a local installation
@@ -253,4 +253,4 @@ http://www.iue.tuwien.ac.at/
253253

254254
License
255255
--------------------------
256-
See file LICENSE in the base directory.
256+
See file LICENSE in the base directory.

cmake/generate_ptx.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,6 @@ function(add_GPU_executable target_name_base target_name_var)
145145
target_include_directories(${target_name} PRIVATE ${OptiX_INCLUDE} ${VIENNARAY_GPU_INCLUDE}
146146
${VIENNAPS_GPU_INCLUDE} ${CUDA_INCLUDE_DIRS})
147147
target_link_libraries(${target_name} PRIVATE ViennaPS ${VIENNACORE_GPU_LIBS})
148+
target_compile_definitions(${target_name}
149+
PRIVATE VIENNACORE_KERNELS_PATH_DEFINE=${VIENNACORE_PTX_DIR})
148150
endfunction()
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
project(DRAMWiggling LANGUAGES CXX)
2+
3+
add_executable(${PROJECT_NAME} "${PROJECT_NAME}.cpp")
4+
target_link_libraries(${PROJECT_NAME} PRIVATE ViennaPS)
5+
6+
configure_file(config.txt ${CMAKE_CURRENT_BINARY_DIR}/config.txt COPYONLY)
7+
# Find all .gds files in the current source directory
8+
file(GLOB GDS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.gds")
9+
# Copy each .gds file to the binary directory
10+
foreach(GDS_FILE ${GDS_FILES})
11+
get_filename_component(FILENAME ${GDS_FILE} NAME)
12+
configure_file(${GDS_FILE} ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME} COPYONLY)
13+
endforeach()
14+
15+
add_dependencies(ViennaPS_Examples ${PROJECT_NAME})
16+
viennacore_setup_bat(${PROJECT_NAME} ${VIENNAPS_ARTIFACTS_DIRECTORY})
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#include <geometries/psMakePlane.hpp>
2+
#include <models/psHBrO2Etching.hpp>
3+
#include <psProcess.hpp>
4+
#include <psUtil.hpp>
5+
6+
#include <psDomain.hpp>
7+
#include <psGDSReader.hpp>
8+
#include <psMaterials.hpp>
9+
10+
using namespace viennaps;
11+
12+
int main(int argc, char **argv) {
13+
using NumericType = double;
14+
constexpr int D = 3;
15+
16+
Logger::setLogLevel(LogLevel::ERROR);
17+
omp_set_num_threads(12);
18+
19+
// Parse the parameters
20+
util::Parameters params;
21+
if (argc > 1) {
22+
params.readConfigFile(argv[1]);
23+
} else {
24+
std::cout << "Usage: " << argv[0] << " <config file>" << std::endl;
25+
return 1;
26+
}
27+
28+
// set parameter units
29+
units::Length::setUnit(params.get<std::string>("lengthUnit"));
30+
units::Time::setUnit(params.get<std::string>("timeUnit"));
31+
32+
constexpr NumericType gridDelta = 0.01 * (1. + 1e-12);
33+
BoundaryType boundaryConds[D] = {BoundaryType::REFLECTIVE_BOUNDARY,
34+
BoundaryType::REFLECTIVE_BOUNDARY,
35+
BoundaryType::INFINITE_BOUNDARY};
36+
37+
auto mask =
38+
SmartPointer<GDSGeometry<NumericType, D>>::New(gridDelta, boundaryConds);
39+
mask->setBoundaryPadding(0.1, 0.1);
40+
GDSReader<NumericType, D>(mask, params.get<std::string>("gdsFile")).apply();
41+
42+
// geometry setup
43+
auto geometry = Domain<NumericType, D>::New();
44+
auto maskLS = mask->layerToLevelSet(0, 0.0, 0.18);
45+
geometry->insertNextLevelSetAsMaterial(maskLS, Material::Mask);
46+
MakePlane<NumericType, D>(geometry, 0.0, Material::Si, true).apply();
47+
48+
auto modelParams = HBrO2Etching<NumericType, D>::defaultParameters();
49+
modelParams.ionFlux = params.get("ionFlux");
50+
modelParams.etchantFlux = params.get("etchantFlux");
51+
modelParams.passivationFlux = params.get("oxygenFlux");
52+
modelParams.Ions.meanEnergy = params.get("meanEnergy");
53+
modelParams.Ions.sigmaEnergy = params.get("sigmaEnergy");
54+
modelParams.Ions.exponent = params.get("ionExponent");
55+
modelParams.Ions.n_l = 200;
56+
auto model = SmartPointer<HBrO2Etching<NumericType, D>>::New(modelParams);
57+
58+
// Process setup
59+
Process<NumericType, D> process;
60+
process.setDomain(geometry);
61+
process.setProcessModel(model);
62+
process.setCoverageDeltaThreshold(1e-4);
63+
process.setNumberOfRaysPerPoint(static_cast<int>(params.get("raysPerPoint")));
64+
process.setProcessDuration(params.get("processTime"));
65+
process.setIntegrationScheme(util::convertIntegrationScheme(
66+
params.get<std::string>("integrationScheme")));
67+
68+
// print initial surface
69+
geometry->saveSurfaceMesh("DRAM_Initial.vtp");
70+
71+
const int numSteps = params.get("numSteps");
72+
for (int i = 0; i < numSteps; ++i) {
73+
process.apply();
74+
geometry->saveSurfaceMesh("DRAM_Etched_" + std::to_string(i + 1) + ".vtp");
75+
}
76+
77+
geometry->saveHullMesh("DRAM_Final");
78+
79+
return 0;
80+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import viennaps3d as vps
2+
from argparse import ArgumentParser
3+
4+
# parse config file name and simulation dimension
5+
parser = ArgumentParser(
6+
prog="DRAMWiggling",
7+
description="Run a DRAM etching process which results in AA wiggling.",
8+
)
9+
parser.add_argument("filename")
10+
args = parser.parse_args()
11+
12+
gridDelta = 0.01 * (1.0 + 1e-12)
13+
boundaryConds = [
14+
vps.ls.BoundaryConditionEnum.REFLECTIVE_BOUNDARY,
15+
vps.ls.BoundaryConditionEnum.REFLECTIVE_BOUNDARY,
16+
vps.ls.BoundaryConditionEnum.INFINITE_BOUNDARY,
17+
]
18+
19+
params = vps.ReadConfigFile(args.filename)
20+
21+
mask = vps.GDSGeometry(gridDelta, boundaryConds)
22+
mask.setBoundaryPadding(0.1, 0.1)
23+
reader = vps.GDSReader(mask, params["gdsFile"])
24+
reader.apply()
25+
26+
# Prepare geometry
27+
geometry = vps.Domain()
28+
29+
# Insert GDS layers
30+
maskLS = mask.layerToLevelSet(0, 0.0, 0.18)
31+
geometry.insertNextLevelSetAsMaterial(maskLS, vps.Material.Mask)
32+
33+
# Add plane
34+
vps.MakePlane(geometry, 0.0, vps.Material.Si, True).apply()
35+
36+
# print intermediate output surfaces during the process
37+
vps.Logger.setLogLevel(vps.LogLevel.INFO)
38+
39+
vps.Length.setUnit(params["lengthUnit"])
40+
vps.Time.setUnit(params["timeUnit"])
41+
42+
modelParams = vps.HBrO2Etching.defaultParameters()
43+
modelParams.ionFlux = params["ionFlux"]
44+
modelParams.etchantFlux = params["etchantFlux"]
45+
modelParams.passivationFlux = params["oxygenFlux"]
46+
modelParams.Ions.meanEnergy = params["meanEnergy"]
47+
modelParams.Ions.sigmaEnergy = params["sigmaEnergy"]
48+
modelParams.Ions.exponent = params["ionExponent"]
49+
modelParams.Ions.n_l = 200
50+
model = vps.HBrO2Etching(modelParams)
51+
52+
# process setup
53+
process = vps.Process()
54+
process.setDomain(geometry)
55+
process.setProcessModel(model)
56+
process.setMaxCoverageInitIterations(10)
57+
process.setNumberOfRaysPerPoint(int(params["raysPerPoint"]))
58+
process.setProcessDuration(params["processTime"]) # seconds
59+
process.setIntegrationScheme(
60+
vps.util.convertIntegrationScheme(params["integrationScheme"])
61+
)
62+
63+
# print initial surface
64+
geometry.saveSurfaceMesh(filename="DRAM_Initial.vtp", addMaterialIds=True)
65+
66+
numSteps = int(params["numSteps"])
67+
for i in range(numSteps):
68+
# run the process
69+
process.apply()
70+
geometry.saveSurfaceMesh(filename=f"DRAM_Etched_{i + 1}.vtp", addMaterialIds=True)
71+
72+
# print final volume
73+
geometry.saveHullMesh("DRAM_Final")

examples/DRAMWiggling/config.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Config file for a hole etching example process
2+
3+
# all length units are in micrometers (um)
4+
# Domain
5+
lengthUnit=um
6+
7+
# Process parameters
8+
processTime=1
9+
timeUnit=second
10+
11+
# all flux values are units 1e15 / cm²
12+
ionFlux=10.
13+
etchantFlux=4.5e3
14+
oxygenFlux=2.5e3
15+
16+
ionExponent=1000
17+
meanEnergy=200 # eV
18+
sigmaEnergy=10 # eV
19+
20+
integrationScheme=LF_2
21+
22+
numSteps=100
23+
raysPerPoint=1000
24+
gdsFile=wiggle_full.gds

examples/DRAMWiggling/wiggle.gds

336 Bytes
Binary file not shown.
876 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)