Skip to content

Commit

Permalink
Implement SF6 etching and Bosch process example
Browse files Browse the repository at this point in the history
  • Loading branch information
tobre1 committed Jul 24, 2024
1 parent 604bb96 commit d18c172
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 4 deletions.
2 changes: 1 addition & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
add_custom_target(ViennaPS_Examples ALL)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${PROJECT_BINARY_DIR}/examples>)
if(WIN32)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${PROJECT_BINARY_DIR}/examples>)
viennacore_setup_embree_env(ViennaPS_Examples ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
viennacore_setup_vtk_env(ViennaPS_Examples ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
viennacore_setup_tbb_env(ViennaPS_Examples ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
Expand Down
8 changes: 8 additions & 0 deletions examples/boschProcess/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
project(boschProcess LANGUAGES CXX)

add_executable(bosch "boschProcess.cpp")
target_link_libraries(bosch PRIVATE ViennaPS)

add_dependencies(ViennaPS_Examples bosch)
# viennacore_setup_bat(bosch ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
configure_file(config.txt ${CMAKE_CURRENT_BINARY_DIR}/config.txt COPYONLY)
75 changes: 75 additions & 0 deletions examples/boschProcess/boschProcess.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <geometries/psMakeHole.hpp>
#include <models/psIsotropicProcess.hpp>
#include <models/psSF6O2Etching.hpp>
#include <psProcess.hpp>
#include <psUtils.hpp>

namespace ps = viennaps;

template <class NumericType, int D>
void etch(ps::SmartPointer<ps::Domain<NumericType, D>> domain,
ps::utils::Parameters &params) {
auto model = ps::SmartPointer<ps::SF6Etching<NumericType, D>>::New(
params.get("ionFlux"), params.get("etchantFlux"),
params.get("meanEnergy"), params.get("sigmaEnergy"),
params.get("ionExponent"));
ps::Process<NumericType, D>(domain, model, params.get("etchTime")).apply();
}

template <class NumericType, int D>
void deposit(ps::SmartPointer<ps::Domain<NumericType, D>> domain,
NumericType time, NumericType rate) {
domain->duplicateTopLevelSet(ps::Material::Polymer);
auto model =
ps::SmartPointer<ps::IsotropicProcess<NumericType, D>>::New(rate);
ps::Process<NumericType, D>(domain, model, time).apply();
}

template <class NumericType, int D>
void ash(ps::SmartPointer<ps::Domain<NumericType, D>> domain) {
domain->removeTopLevelSet();
}

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

ps::Logger::setLogLevel(ps::LogLevel::INFO);
omp_set_num_threads(16);

// Parse the parameters
ps::utils::Parameters params;
if (argc > 1) {
params.readConfigFile(argv[1]);
} else {
std::cout << "Usage: " << argv[0] << " <config file>" << std::endl;
return 1;
}

// 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*/, 0., 0 /* base height */,
false /* periodic boundary */, true /*create mask*/, ps::Material::Si)
.apply();

const NumericType depositionRate = params.get("depositionRate");
const NumericType depositionTime = params.get("depositionTime");
const int numCycles = params.get<int>("numCycles");

int n = 0;
etch(geometry, params);
for (int i = 0; i < numCycles; ++i) {
geometry->saveSurfaceMesh("boschProcess_" + std::to_string(n++) + ".vtp");
deposit(geometry, depositionTime, depositionRate);
geometry->saveSurfaceMesh("boschProcess_" + std::to_string(n++) + ".vtp");
etch(geometry, params);
geometry->saveSurfaceMesh("boschProcess_" + std::to_string(n++) + ".vtp");
ash(geometry);
}

geometry->saveSurfaceMesh("boschProcess_final.vtp");
}
21 changes: 21 additions & 0 deletions examples/boschProcess/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Geometry
gridDelta = 1.0
xExtent = 50.0
yExtent = 50.0
holeRadius = 10.0
maskHeight = 10.0

# all flux values are units 1e16 / cm²
ionFlux=10.
etchantFlux=50.

ionExponent=200
meanEnergy=100 # eV
sigmaEnergy=10 # eV

etchTime = 10.0

depositionRate = 0.2
depositionTime = 10.0

numCycles = 5
133 changes: 130 additions & 3 deletions include/viennaps/models/psSF6O2Etching.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ namespace impl {

template <typename NumericType, int D>
class SF6O2SurfaceModel : public SurfaceModel<NumericType> {
public:
using SurfaceModel<NumericType>::coverages;
const SF6O2Parameters<NumericType> &params;

public:
SF6O2SurfaceModel(const SF6O2Parameters<NumericType> &pParams)
: params(pParams) {}

Expand All @@ -87,7 +87,7 @@ class SF6O2SurfaceModel : public SurfaceModel<NumericType> {
} else {
coverages->clear();
}
std::vector<NumericType> cov(numGeometryPoints);
std::vector<NumericType> cov(numGeometryPoints, 0.);
coverages->insertNextScalarData(cov, "eCoverage");
coverages->insertNextScalarData(cov, "oCoverage");
}
Expand All @@ -104,7 +104,6 @@ class SF6O2SurfaceModel : public SurfaceModel<NumericType> {
const auto ionSputteringRate = rates->getScalarData("ionSputteringRate");
const auto etchantRate = rates->getScalarData("etchantRate");
const auto eCoverage = coverages->getScalarData("eCoverage");
const auto oCoverage = coverages->getScalarData("oCoverage");

bool stop = false;

Expand Down Expand Up @@ -181,6 +180,39 @@ class SF6O2SurfaceModel : public SurfaceModel<NumericType> {
}
};

template <typename NumericType, int D>
class SF6SurfaceModel : public SF6O2SurfaceModel<NumericType, D> {
public:
using SurfaceModel<NumericType>::coverages;
using SF6O2SurfaceModel<NumericType, D>::params;

SF6SurfaceModel(const SF6O2Parameters<NumericType> &pParams)
: SF6O2SurfaceModel<NumericType, D>(pParams) {}

void updateCoverages(SmartPointer<viennals::PointData<NumericType>> rates,
const std::vector<NumericType> &materialIds) override {
// update coverages based on fluxes
const auto numPoints = rates->getScalarData(0)->size();

const auto etchantRate = rates->getScalarData("etchantRate");
const auto ionEnhancedRate = rates->getScalarData("ionEnhancedRate");

// etchant fluorine coverage
auto eCoverage = coverages->getScalarData("eCoverage");
eCoverage->resize(numPoints);
for (size_t i = 0; i < numPoints; ++i) {
if (etchantRate->at(i) < 1e-6) {
eCoverage->at(i) = 0;
} else {
eCoverage->at(i) =
etchantRate->at(i) * params.etchantFlux * params.beta_F /
(etchantRate->at(i) * params.etchantFlux * params.beta_F +
(params.Si.k_sigma + 2 * ionEnhancedRate->at(i) * params.ionFlux));
}
}
}
};

template <typename NumericType, int D>
class SF6O2Ion
: public viennaray::Particle<SF6O2Ion<NumericType, D>, NumericType> {
Expand Down Expand Up @@ -355,6 +387,47 @@ class SF6O2Etchant
}
};

template <typename NumericType, int D>
class SF6Etchant
: public viennaray::Particle<SF6Etchant<NumericType, D>, NumericType> {
const SF6O2Parameters<NumericType> &params;

public:
SF6Etchant(const SF6O2Parameters<NumericType> &pParams) : params(pParams) {}

void surfaceCollision(NumericType rayWeight, const Vec3D<NumericType> &,
const Vec3D<NumericType> &, const unsigned int primID,
const int,
viennaray::TracingData<NumericType> &localData,
const viennaray::TracingData<NumericType> *,
RNG &) override final {
localData.getVectorData(0)[primID] += rayWeight;
}
std::pair<NumericType, Vec3D<NumericType>>
surfaceReflection(NumericType rayWeight, const Vec3D<NumericType> &rayDir,
const Vec3D<NumericType> &geomNormal,
const unsigned int primID, const int materialId,
const viennaray::TracingData<NumericType> *globalData,
RNG &rngState) override final {

// F surface coverage
const auto &phi_F = globalData->getVectorData(0)[primID];
// Obtain the sticking probability
NumericType beta = params.beta_F;
if (MaterialMap::isMaterial(materialId, Material::Mask))
beta = params.Mask.beta_F;
NumericType S_eff = beta * std::max(1. - phi_F, 0.);

auto direction =
viennaray::ReflectionDiffuse<NumericType, D>(geomNormal, rngState);
return std::pair<NumericType, Vec3D<NumericType>>{S_eff, direction};
}
NumericType getSourceDistributionPower() const override final { return 1.; }
std::vector<std::string> getLocalDataLabels() const override final {
return {"etchantRate"};
}
};

template <typename NumericType, int D>
class SF6O2Oxygen
: public viennaray::Particle<SF6O2Oxygen<NumericType, D>, NumericType> {
Expand Down Expand Up @@ -461,4 +534,58 @@ class SF6O2Etching : public ProcessModel<NumericType, D> {
SF6O2Parameters<NumericType> params;
};

template <typename NumericType, int D>
class SF6Etching : public ProcessModel<NumericType, D> {
public:
SF6Etching() { initializeModel(); }

// All flux values are in units 1e16 / cm²
SF6Etching(const double ionFlux, const double etchantFlux,
const NumericType meanEnergy /* eV */,
const NumericType sigmaEnergy /* eV */, // 5 parameters
const NumericType ionExponent = 300.,
const NumericType etchStopDepth =
std::numeric_limits<NumericType>::lowest()) {
params.ionFlux = ionFlux;
params.etchantFlux = etchantFlux;
params.Ions.meanEnergy = meanEnergy;
params.Ions.sigmaEnergy = sigmaEnergy;
params.Ions.exponent = ionExponent;
params.etchStopDepth = etchStopDepth;
initializeModel();
}

SF6Etching(const SF6O2Parameters<NumericType> &pParams) : params(pParams) {
initializeModel();
}

void setParameters(const SF6O2Parameters<NumericType> &pParams) {
params = pParams;
}

SF6O2Parameters<NumericType> &getParameters() { return params; }

private:
void initializeModel() {
// particles
auto ion = std::make_unique<impl::SF6O2Ion<NumericType, D>>(params);
auto etchant = std::make_unique<impl::SF6Etchant<NumericType, D>>(params);

// surface model
auto surfModel =
SmartPointer<impl::SF6SurfaceModel<NumericType, D>>::New(params);

// velocity field
auto velField = SmartPointer<DefaultVelocityField<NumericType>>::New(2);

this->setSurfaceModel(surfModel);
this->setVelocityField(velField);
this->setProcessName("SF6Etching");
this->insertNextParticleType(ion);
this->insertNextParticleType(etchant);
}

SF6O2Parameters<NumericType> params;
};

} // namespace viennaps
File renamed without changes.

0 comments on commit d18c172

Please sign in to comment.