Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SF6O2 model update, units, coverage metric #106

Merged
merged 27 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: 🧪 Run Tests

on:
push:
branches:
- master
pull_request:
branches:
- master
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: 🔍 Check Formatting

on:
push:
branches:
- master
pull_request:
branches:
- master
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ on:
types:
- published
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
inputs:
publish:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dist/
dependencies/
*.ipynb
old_*
*_old.*
*a.out
install*
*.vtk
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ CPMAddPackage(

CPMFindPackage(
NAME ViennaRay
VERSION 3.1.0
VERSION 3.1.1
GIT_REPOSITORY "https://github.com/ViennaTools/ViennaRay"
EXCLUDE_FROM_ALL ${VIENNAPS_BUILD_PYTHON})

Expand Down
8 changes: 4 additions & 4 deletions examples/faradayCageEtching/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
project(faradayCageEtching LANGUAGES CXX)

add_executable(${PROJECT_NAME}.exe "${PROJECT_NAME}.cpp")
target_link_libraries(${PROJECT_NAME}.exe PRIVATE ViennaPS)
add_executable(${PROJECT_NAME} "${PROJECT_NAME}.cpp")
target_link_libraries(${PROJECT_NAME} PRIVATE ViennaPS)

configure_file(faradayCageEtching.py ${CMAKE_CURRENT_BINARY_DIR}/faradayCageEtching.py COPYONLY)
configure_file(config.txt ${CMAKE_CURRENT_BINARY_DIR}/config.txt COPYONLY)

add_dependencies(ViennaPS_Examples ${PROJECT_NAME}.exe)
viennacore_setup_bat(${PROJECT_NAME}.exe ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
add_dependencies(ViennaPS_Examples ${PROJECT_NAME})
viennacore_setup_bat(${PROJECT_NAME} ${VIENNAPS_ARTIFACTS_DIRECTORY})
6 changes: 4 additions & 2 deletions examples/faradayCageEtching/faradayCageEtching.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from argparse import ArgumentParser

# parse config file name and simulation dimension
parser = ArgumentParser(prog="faradayCageEtching", description="Run a faraday cage etching process.")
parser = ArgumentParser(
prog="faradayCageEtching", description="Run a faraday cage etching process."
)
parser.add_argument("-D", "-DIM", dest="dim", type=int, default=2)
parser.add_argument("filename")
args = parser.parse_args()
Expand Down Expand Up @@ -33,7 +35,7 @@
material=vps.Material.Si,
).apply()

# use pre-defined model SF6O2 etching model
# use pre-defined etching model
parameters = vps.FaradayCageParameters()
parameters.cageAngle = params["cageAngle"]
parameters.ibeParams.tiltAngle = params["tiltAngle"]
Expand Down
4 changes: 2 additions & 2 deletions examples/holeEtching/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
project(holeEtching LANGUAGES CXX)

add_executable(${PROJECT_NAME} "${PROJECT_NAME}.cpp")
target_link_libraries(${PROJECT_NAME} PRIVATE ViennaPS)
add_executable("${PROJECT_NAME}" "${PROJECT_NAME}.cpp")
target_link_libraries("${PROJECT_NAME}" PRIVATE ViennaPS)

configure_file(holeEtching.py ${CMAKE_CURRENT_BINARY_DIR}/holeEtching.py COPYONLY)
configure_file(config.txt ${CMAKE_CURRENT_BINARY_DIR}/config.txt COPYONLY)
Expand Down
34 changes: 20 additions & 14 deletions examples/holeEtching/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,34 @@

# all length units are in micrometers (um)
# Domain
gridDelta=4.0 # um
xExtent=100.0 # um
yExtent=100.0 # um
lengthUnit=um
gridDelta=0.03 # um
xExtent=1.0 # um
yExtent=1.0 # um

# Geometry
holeRadius=20.0 # um
maskHeight=20.0 # um
taperAngle=0.0 # degree
holeRadius=0.175 # um
maskHeight=1.2 # um
taperAngle=1.193 # degree

# Process parameters
processTime=150 # seconds
processTime=3
timeUnit=min

# all flux values are units 1e16 / cm²
ionFlux=1.
etchantFlux=180.
oxygenFlux=30.
# all flux values are units 1e15 / cm²
ionFlux=10.
etchantFlux=3000.
oxygenFlux=1500.

ionExponent=200
meanEnergy=100 # eV
sigmaEnergy=10 # eV
A_O=3 # passivation layer sputtering coefficient
A_O=2 # passivation layer yield constant
A_Si=7 # Si yield constant

etchStopDepth=-1000 # maximum etching depth
etchStopDepth=-10 # maximum etching depth
integrationScheme=EO_1

raysPerPoint=1000
raysPerPoint=1000

outputFile=final_y0p62
46 changes: 26 additions & 20 deletions examples/holeEtching/holeEtching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace ps = viennaps;

int main(int argc, char *argv[]) {
using NumericType = double;
constexpr int D = 3;
constexpr int D = 2;

ps::Logger::setLogLevel(ps::LogLevel::INTERMEDIATE);
ps::Logger::setLogLevel(ps::LogLevel::DEBUG);
omp_set_num_threads(16);

// Parse the parameters
Expand All @@ -25,33 +25,39 @@ int main(int argc, char *argv[]) {
// geometry setup
auto geometry = ps::SmartPointer<ps::Domain<NumericType, D>>::New();
ps::MakeHole<NumericType, D>(
geometry, params.get("gridDelta") /* grid delta */,
params.get("xExtent") /*x extent*/, params.get("yExtent") /*y extent*/,
params.get("holeRadius") /*hole radius*/,
params.get("maskHeight") /* mask height*/,
params.get("taperAngle") /* tapering angle in degrees */,
0 /* base height */, false /* periodic boundary */, true /*create mask*/,
ps::Material::Si)
geometry, params.get("gridDelta"), params.get("xExtent"),
params.get("yExtent"), params.get("holeRadius"), params.get("maskHeight"),
params.get("taperAngle"), 0 /* base height */,
false /* periodic boundary */, true /*create mask*/, ps::Material::Si)
.apply();

// set parameter units
ps::units::Length::setUnit(params.get<std::string>("lengthUnit"));
ps::units::Time::setUnit(params.get<std::string>("timeUnit"));

// use pre-defined model SF6O2 etching model
auto model = ps::SmartPointer<ps::SF6O2Etching<NumericType, D>>::New(
params.get("ionFlux") /*ion flux*/,
params.get("etchantFlux") /*etchant flux*/,
params.get("oxygenFlux") /*oxygen flux*/,
params.get("meanEnergy") /*mean energy*/,
params.get("sigmaEnergy") /*energy sigma*/,
params.get("ionExponent") /*source power cosine distribution exponent*/,
params.get("A_O") /*oxy sputter yield*/,
params.get("etchStopDepth") /*max etch depth*/);
ps::SF6O2Parameters<NumericType> modelParams;
modelParams.ionFlux = params.get("ionFlux");
modelParams.etchantFlux = params.get("etchantFlux");
modelParams.oxygenFlux = params.get("oxygenFlux");
modelParams.Ions.meanEnergy = params.get("meanEnergy");
modelParams.Ions.sigmaEnergy = params.get("sigmaEnergy");
modelParams.Ions.exponent = params.get("ionExponent");
modelParams.Passivation.A_ie = params.get("A_O");
modelParams.Si.A_ie = params.get("A_Si");
modelParams.etchStopDepth = params.get("etchStopDepth");
auto model =
ps::SmartPointer<ps::SF6O2Etching<NumericType, D>>::New(modelParams);

// process setup
ps::Process<NumericType, D> process;
process.setDomain(geometry);
process.setProcessModel(model);
process.setMaxCoverageInitIterations(10);
process.setMaxCoverageInitIterations(50);
process.setNumberOfRaysPerPoint(params.get("raysPerPoint"));
process.setProcessDuration(params.get("processTime"));
process.setIntegrationScheme(
params.get<viennals::IntegrationSchemeEnum>("integrationScheme"));

// print initial surface
geometry->saveSurfaceMesh("initial.vtp");
Expand All @@ -60,5 +66,5 @@ int main(int argc, char *argv[]) {
process.apply();

// print final surface
geometry->saveSurfaceMesh("final.vtp");
geometry->saveSurfaceMesh(params.get<std::string>("outputFile"));
}
1 change: 1 addition & 0 deletions examples/holeEtching/holeEtching.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
process.setMaxCoverageInitIterations(10)
process.setNumberOfRaysPerPoint(int(params["raysPerPoint"]))
process.setProcessDuration(params["processTime"]) # seconds
process.setIntegrationScheme(vps.util.convertIntegrationScheme(params["integrationScheme"]))

# print initial surface
geometry.saveSurfaceMesh(filename="initial.vtp", addMaterialIds=True)
Expand Down
93 changes: 93 additions & 0 deletions examples/holeEtching/testFluxes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from argparse import ArgumentParser
import numpy as np

# parse config file name and simulation dimension
parser = ArgumentParser(
prog="testFluxes", description="Test different flux configurations."
)
parser.add_argument("-D", "-DIM", dest="dim", type=int, default=2)
args = parser.parse_args()

# switch between 2D and 3D mode
if args.dim == 2:
print("Running 2D simulation.")
import viennaps2d as vps
else:
print("Running 3D simulation.")
import viennaps3d as vps

vps.setNumThreads(16)
vps.Logger.setLogLevel(vps.LogLevel.INFO)

vps.Length.setUnit("um")
vps.Time.setUnit("min")

# hole geometry parameters
gridDelta = 0.03 # um
xExtent = 1.0
yExtent = 1.0
holeRadius = 0.175
maskHeight = 1.2
taperAngle = 1.193

# fluxes
ionFlux = [10.0, 10.0, 10.0, 10.0, 10.0]
etchantFlux = [4.8e3, 4.5e3, 4e3, 3.5e3, 4e3]
oxygenFlux = [3e2, 8e2, 2e3, 2.5e3, 0.0]
A_O = [2, 2, 2, 1, 1]
yo2 = [0.44, 0.5, 0.56, 0.62, 0]

# etching model parameters
params = vps.SF6O2Parameters()
params.Si.A_ie = 5.0
params.Si.Eth_ie = 15.0

params.Si.A_sp = 0.0337
params.Si.Eth_sp = 20.0

params.Ions.exponent = 500
params.Ions.meanEnergy = 100.0
params.Ions.sigmaEnergy = 10.0
params.Ions.minAngle = np.deg2rad(85.0)
params.Ions.inflectAngle = np.deg2rad(89.0)

# simulation parameters
processDuration = 3 # min
integrationScheme = vps.ls.IntegrationSchemeEnum.ENGQUIST_OSHER_2ND_ORDER
numberOfRaysPerPoint = int(1000)

for i in range(len(yo2)):

geometry = vps.Domain()
vps.MakeHole(
geometry,
gridDelta,
xExtent,
yExtent,
holeRadius,
maskHeight,
taperAngle,
0.0,
False,
True,
vps.Material.Si,
).apply()

process = vps.Process()
process.setDomain(geometry)
process.setMaxCoverageInitIterations(40)
process.setProcessDuration(processDuration)
process.setIntegrationScheme(integrationScheme)
process.setNumberOfRaysPerPoint(numberOfRaysPerPoint)

params.ionFlux = ionFlux[i]
params.etchantFlux = etchantFlux[i]
params.oxygenFlux = oxygenFlux[i]
params.Passivation.A_ie = A_O[i]

model = vps.SF6O2Etching(params)

process.setProcessModel(model)
process.apply()

geometry.saveSurfaceMesh("hole_y{:.2f}_EO2.vtp".format(yo2[i]), True)
2 changes: 1 addition & 1 deletion examples/stackEtching/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
project(stackEtching LANGUAGES CXX)

set(PROGRAM_NAME stackEtching.exe)
set(PROGRAM_NAME stackEtching)
add_executable(${PROGRAM_NAME} "${PROJECT_NAME}.cpp")
target_link_libraries(${PROGRAM_NAME} PRIVATE ViennaPS)

Expand Down
10 changes: 7 additions & 3 deletions include/viennaps/models/psIonBeamEtching.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ template <typename NumericType> struct IBEParameters {
NumericType minAngle = 5; // degree
NumericType tiltAngle = 0; // degree
std::function<NumericType(NumericType)> yieldFunction =
[](NumericType cosTheta) { return 1.; };
[](NumericType theta) { return 1.; };
};

namespace impl {
Expand Down Expand Up @@ -87,11 +87,14 @@ class IBEIon : public viennaray::Particle<IBEIon<NumericType, D>, NumericType> {
viennaray::TracingData<NumericType> &localData,
const viennaray::TracingData<NumericType> *,
RNG &) override final {
NumericType cosTheta = -DotProduct(rayDir, geomNormal);
auto cosTheta = -DotProduct(rayDir, geomNormal);
NumericType theta =
std::acos(std::max(std::min(cosTheta, static_cast<NumericType>(1.)),
static_cast<NumericType>(0.)));

localData.getVectorData(0)[primID] +=
std::max(std::sqrt(energy_) - std::sqrt(params_.thresholdEnergy), 0.) *
params_.yieldFunction(cosTheta);
params_.yieldFunction(theta);
}

std::pair<NumericType, Vec3D<NumericType>>
Expand Down Expand Up @@ -191,6 +194,7 @@ class IonBeamEtching : public ProcessModel<NumericType, D> {
this->particles.clear();
this->setSurfaceModel(surfModel);
this->setVelocityField(velField);
this->particles.clear();
this->insertNextParticleType(particle);
this->setProcessName("IonBeamEtching");
firstInit = true;
Expand Down
Loading
Loading