diff --git a/include/viennaps/models/psPlasmaEtching.hpp b/include/viennaps/models/psPlasmaEtching.hpp index f2b970e2..a45a1f76 100644 --- a/include/viennaps/models/psPlasmaEtching.hpp +++ b/include/viennaps/models/psPlasmaEtching.hpp @@ -108,6 +108,13 @@ class PlasmaEtchingSurfaceModel : public SurfaceModel { ieRate->at(i) = 0.; chRate->at(i) = 0.; } + } else if (MaterialMap::isMaterial(materialIds[i], Material::Polymer)) { + etchRate[i] = -(1 / params.Polymer.rho) * sputterRate * unitConversion; + if (Logger::getLogLevel() > 3) { + spRate->at(i) = sputterRate; + ieRate->at(i) = 0.; + chRate->at(i) = 0.; + } } else { etchRate[i] = -(1 / params.Substrate.rho) * (chemicalRate + sputterRate + ionEnhancedRate) * @@ -214,6 +221,10 @@ class PlasmaEtchingIon A_sp = params.Mask.A_sp; B_sp = params.Mask.B_sp; Eth_sp = params.Mask.Eth_sp; + } else if (MaterialMap::isMaterial(materialId, Material::Polymer)) { + A_sp = params.Polymer.A_sp; + B_sp = params.Polymer.B_sp; + Eth_sp = params.Polymer.Eth_sp; } // NumericType f_sp_theta = 1.; diff --git a/include/viennaps/models/psPlasmaEtchingParameters.hpp b/include/viennaps/models/psPlasmaEtchingParameters.hpp index 5effbd03..8dd0e947 100644 --- a/include/viennaps/models/psPlasmaEtchingParameters.hpp +++ b/include/viennaps/models/psPlasmaEtchingParameters.hpp @@ -28,6 +28,17 @@ template struct PlasmaEtchingParameters { NumericType B_sp = 9.3; } Mask; + // Polymer + struct PolymerType { + // density + NumericType rho = 5.0; // 1e22 atoms/cm³ + + // sputtering coefficients + NumericType Eth_sp = 15.; // eV + NumericType A_sp = 0.02; + NumericType B_sp = 8.5; + } Polymer; + // Etching material struct MaterialType { // density diff --git a/include/viennaps/models/psSF6C4F8Etching.hpp b/include/viennaps/models/psSF6C4F8Etching.hpp new file mode 100644 index 00000000..1d2b3426 --- /dev/null +++ b/include/viennaps/models/psSF6C4F8Etching.hpp @@ -0,0 +1,157 @@ +#pragma once + +#include +#include +#include + +#include "../psConstants.hpp" +#include "../psProcessModel.hpp" +#include "../psSurfaceModel.hpp" +#include "../psUnits.hpp" +#include "../psVelocityField.hpp" + +#include "psPlasmaEtching.hpp" +#include "psPlasmaEtchingParameters.hpp" + +namespace viennaps { + +using namespace viennacore; + +/// Model for etching Si in a SF6/C4F8 plasma. This model extends the SF6O2 +/// etching model to include polymer etching. The polymer layer is deposited +/// by a separate process and etched by sputtering similarly to the mask +/// material. No passivation occurs in this model. +template +class SF6C4F8Etching : public ProcessModel { +public: + SF6C4F8Etching() { + params = defaultParameters(); + initializeModel(); + } + + // All flux values are in units 1e15 / cm² + SF6C4F8Etching(const double ionFlux, const double etchantFlux, + const NumericType meanEnergy /* eV */, + const NumericType sigmaEnergy /* eV */, // 4 parameters + const NumericType ionExponent = 300., + const NumericType etchStopDepth = + std::numeric_limits::lowest()) { + params = defaultParameters(); + params.ionFlux = ionFlux; + params.etchantFlux = etchantFlux; + params.passivationFlux = 0.; // No passivation + params.Ions.meanEnergy = meanEnergy; + params.Ions.sigmaEnergy = sigmaEnergy; + params.Ions.exponent = ionExponent; + params.etchStopDepth = etchStopDepth; + initializeModel(); + } + + SF6C4F8Etching(const PlasmaEtchingParameters &pParams) + : params(pParams) { + initializeModel(); + } + + void setParameters(const PlasmaEtchingParameters &pParams) { + params = pParams; + initializeModel(); + } + + PlasmaEtchingParameters &getParameters() { return params; } + + static PlasmaEtchingParameters defaultParameters() { + + PlasmaEtchingParameters defParams; + + // fluxes in (1e15 /cm² /s) + defParams.ionFlux = 12.; + defParams.etchantFlux = 1.8e3; + defParams.passivationFlux = 0.; // No passivation + + // sticking probabilities + defParams.beta_E = {{1, 0.7}, {0, 0.7}}; + // No beta_P needed since passivationFlux = 0 + + defParams.etchStopDepth = std::numeric_limits::lowest(); + + // Mask + defParams.Mask.rho = 500.; // 1e22 atoms/cm³ + defParams.Mask.Eth_sp = 20.; // eV + defParams.Mask.A_sp = 0.0139; + defParams.Mask.B_sp = 9.3; + + // Polymer (C4F8) - deposited by separate process, etched by sputtering + defParams.Polymer.rho = 5.0; // 1e22 atoms/cm³ + defParams.Polymer.Eth_sp = 15.; // eV + defParams.Polymer.A_sp = 0.02; + defParams.Polymer.B_sp = 8.5; + + // Si + defParams.Substrate.rho = 5.02; // 1e22 atoms/cm³ + defParams.Substrate.Eth_sp = 20.; // eV + defParams.Substrate.Eth_ie = 15.; // eV + defParams.Substrate.A_sp = 0.0337; + defParams.Substrate.B_sp = 9.3; + defParams.Substrate.A_ie = 7.; + defParams.Substrate.B_ie = 0.8; + defParams.Substrate.k_sigma = 3.0e2; // in (1e15 cm⁻²s⁻¹) + defParams.Substrate.beta_sigma = 4.0e-2; // in (1e15 cm⁻²s⁻¹) + + // Passivation (unused in this model) + defParams.Passivation.Eth_ie = 10.; // eV + defParams.Passivation.A_ie = 3; + + // Ions + defParams.Ions.meanEnergy = 100.; // eV + defParams.Ions.sigmaEnergy = 10.; // eV + defParams.Ions.exponent = 500.; + + defParams.Ions.inflectAngle = 1.55334303; + defParams.Ions.n_l = 10.; + defParams.Ions.minAngle = 1.3962634; + + defParams.Ions.thetaRMin = constants::degToRad(70.); + defParams.Ions.thetaRMax = constants::degToRad(90.); + return defParams; + } + +private: + void initializeModel() { + // check if units have been set + if (units::Length::getInstance().getUnit() == units::Length::UNDEFINED || + units::Time::getInstance().getUnit() == units::Time::UNDEFINED) { + Logger::getInstance().addError("Units have not been set.").print(); + } + + // particles + this->particles.clear(); + if (params.ionFlux > 0) { + auto ion = + std::make_unique>(params); + this->insertNextParticleType(ion); + } + if (params.etchantFlux > 0) { + auto etchant = + std::make_unique>( + "etchantFlux", params.beta_E, 2); + this->insertNextParticleType(etchant); + } + // No passivation particle since passivationFlux = 0 + + // surface model + auto surfModel = + SmartPointer>::New( + params); + this->setSurfaceModel(surfModel); + + // velocity field + auto velField = SmartPointer>::New(2); + this->setVelocityField(velField); + + this->setProcessName("SF6C4F8Etching"); + } + + PlasmaEtchingParameters params; +}; + +} // namespace viennaps diff --git a/python/pyWrap.cpp b/python/pyWrap.cpp index 9a403799..2d1870b0 100644 --- a/python/pyWrap.cpp +++ b/python/pyWrap.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -823,7 +824,7 @@ PYBIND11_MODULE(VIENNAPS_MODULE_NAME, module) { pybind11::arg("reactionOrderIon") = 1., pybind11::arg("minAngleIon") = 0.); - // SF6O2 Parameters + // Plasma Etching Parameters pybind11::class_::MaskType>( module, "PlasmaEtchingParametersMask") .def(pybind11::init<>()) @@ -832,6 +833,15 @@ PYBIND11_MODULE(VIENNAPS_MODULE_NAME, module) { .def_readwrite("B_sp", &PlasmaEtchingParameters::MaskType::B_sp) .def_readwrite("Eth_sp", &PlasmaEtchingParameters::MaskType::Eth_sp); + pybind11::class_::PolymerType>( + module, "PlasmaEtchingParametersPolymer") + .def(pybind11::init<>()) + .def_readwrite("rho", &PlasmaEtchingParameters::PolymerType::rho) + .def_readwrite("A_sp", &PlasmaEtchingParameters::PolymerType::A_sp) + .def_readwrite("B_sp", &PlasmaEtchingParameters::PolymerType::B_sp) + .def_readwrite("Eth_sp", + &PlasmaEtchingParameters::PolymerType::Eth_sp); + pybind11::class_::MaterialType>( module, "PlasmaEtchingParametersSubstrate") .def(pybind11::init<>()) @@ -942,6 +952,28 @@ PYBIND11_MODULE(VIENNAPS_MODULE_NAME, module) { pybind11::return_value_policy::reference) .def_static("defaultParameters", &HBrO2Etching::defaultParameters); + // SF6C4F8 Etching + pybind11::class_, SmartPointer>>( + module, "SF6C4F8Etching", processModel) + .def(pybind11::init<>()) + .def( + pybind11::init(&SmartPointer>::New< + const double /*ionFlux*/, const double /*etchantFlux*/, + const T /*meanEnergy*/, const T /*sigmaEnergy*/, + const T /*ionExponent*/, const T /*etchStopDepth*/>), + pybind11::arg("ionFlux"), pybind11::arg("etchantFlux"), + pybind11::arg("meanEnergy"), pybind11::arg("sigmaEnergy"), + pybind11::arg("ionExponent") = 300., + pybind11::arg("etchStopDepth") = std::numeric_limits::lowest()) + .def(pybind11::init(&SmartPointer>::New< + const PlasmaEtchingParameters &>), + pybind11::arg("parameters")) + .def("setParameters", &SF6C4F8Etching::setParameters) + .def("getParameters", &SF6C4F8Etching::getParameters, + pybind11::return_value_policy::reference) + .def_static("defaultParameters", + &SF6C4F8Etching::defaultParameters); + // CF4O2 Parameters pybind11::class_::MaskType>(module, "CF4O2ParametersMask") .def(pybind11::init<>()) diff --git a/python/viennaps2d/__init__.pyi b/python/viennaps2d/__init__.pyi index 54dabb1e..026e3c3e 100644 --- a/python/viennaps2d/__init__.pyi +++ b/python/viennaps2d/__init__.pyi @@ -1,3 +1,6 @@ from .viennaps2d import * +from _typeshed import Incomplete + +ptxPath: Incomplete def ReadConfigFile(fileName: str): ... diff --git a/python/viennaps2d/viennaps2d.pyi b/python/viennaps2d/viennaps2d.pyi index 7a8ca8e6..67ea2008 100644 --- a/python/viennaps2d/viennaps2d.pyi +++ b/python/viennaps2d/viennaps2d.pyi @@ -1013,6 +1013,13 @@ class PlasmaEtchingParametersPassivation: Eth_ie: float def __init__(self) -> None: ... +class PlasmaEtchingParametersPolymer: + A_sp: float + B_sp: float + Eth_sp: float + rho: float + def __init__(self) -> None: ... + class PlasmaEtchingParametersSubstrate: A_ie: float A_sp: float @@ -1125,6 +1132,34 @@ class RayTracingParameters: useRandomSeeds: bool def __init__(self) -> None: ... +class Reader: + @overload + def __init__(self) -> None: ... + @overload + def __init__(self, fileName: str) -> None: ... + def apply(self) -> Domain: ... + def setFileName(self, arg0: str) -> None: ... + +class SF6C4F8Etching(ProcessModel): + @overload + def __init__(self) -> None: ... + @overload + def __init__( + self, + ionFlux: float, + etchantFlux: float, + meanEnergy: float, + sigmaEnergy: float, + ionExponent: float = ..., + etchStopDepth: float = ..., + ) -> None: ... + @overload + def __init__(self, parameters: PlasmaEtchingParameters) -> None: ... + @staticmethod + def defaultParameters() -> PlasmaEtchingParameters: ... + def getParameters(self) -> PlasmaEtchingParameters: ... + def setParameters(self, arg0: PlasmaEtchingParameters) -> None: ... + class SF6O2Etching(ProcessModel): @overload def __init__(self) -> None: ... @@ -1245,16 +1280,8 @@ class Writer: def __init__(self, domain: Domain) -> None: ... @overload def __init__(self, domain: Domain, fileName: str) -> None: ... - def setDomain(self, domain: Domain) -> None: ... - def setFileName(self, fileName: str) -> None: ... def apply(self) -> None: ... - -class Reader: - @overload - def __init__(self) -> None: ... - @overload - def __init__(self, fileName: str) -> None: ... - def setFileName(self, fileName: str) -> None: ... - def apply(self) -> Domain: ... + def setDomain(self, arg0: Domain) -> None: ... + def setFileName(self, arg0: str) -> None: ... def setNumThreads(arg0: int) -> None: ... diff --git a/python/viennaps3d/__init__.pyi b/python/viennaps3d/__init__.pyi index 0cfb31c3..71e2dfd3 100644 --- a/python/viennaps3d/__init__.pyi +++ b/python/viennaps3d/__init__.pyi @@ -1,3 +1,6 @@ from .viennaps3d import * +from _typeshed import Incomplete + +ptxPath: Incomplete def ReadConfigFile(fileName: str): ... diff --git a/python/viennaps3d/viennaps3d.pyi b/python/viennaps3d/viennaps3d.pyi index 6ab03086..6af79fa9 100644 --- a/python/viennaps3d/viennaps3d.pyi +++ b/python/viennaps3d/viennaps3d.pyi @@ -942,6 +942,13 @@ class PlasmaEtchingParametersPassivation: Eth_ie: float def __init__(self) -> None: ... +class PlasmaEtchingParametersPolymer: + A_sp: float + B_sp: float + Eth_sp: float + rho: float + def __init__(self) -> None: ... + class PlasmaEtchingParametersSubstrate: A_ie: float A_sp: float @@ -1054,6 +1061,34 @@ class RayTracingParameters: useRandomSeeds: bool def __init__(self) -> None: ... +class Reader: + @overload + def __init__(self) -> None: ... + @overload + def __init__(self, fileName: str) -> None: ... + def apply(self) -> Domain: ... + def setFileName(self, arg0: str) -> None: ... + +class SF6C4F8Etching(ProcessModel): + @overload + def __init__(self) -> None: ... + @overload + def __init__( + self, + ionFlux: float, + etchantFlux: float, + meanEnergy: float, + sigmaEnergy: float, + ionExponent: float = ..., + etchStopDepth: float = ..., + ) -> None: ... + @overload + def __init__(self, parameters: PlasmaEtchingParameters) -> None: ... + @staticmethod + def defaultParameters() -> PlasmaEtchingParameters: ... + def getParameters(self) -> PlasmaEtchingParameters: ... + def setParameters(self, arg0: PlasmaEtchingParameters) -> None: ... + class SF6O2Etching(ProcessModel): @overload def __init__(self) -> None: ... @@ -1174,16 +1209,8 @@ class Writer: def __init__(self, domain: Domain) -> None: ... @overload def __init__(self, domain: Domain, fileName: str) -> None: ... - def setDomain(self, domain: Domain) -> None: ... - def setFileName(self, fileName: str) -> None: ... def apply(self) -> None: ... - -class Reader: - @overload - def __init__(self) -> None: ... - @overload - def __init__(self, fileName: str) -> None: ... - def setFileName(self, fileName: str) -> None: ... - def apply(self) -> Domain: ... + def setDomain(self, arg0: Domain) -> None: ... + def setFileName(self, arg0: str) -> None: ... def setNumThreads(arg0: int) -> None: ...