diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 66b2725c..aca6a9bf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,9 +54,15 @@ jobs: - name: ๐Ÿฆฅ Cache Dependencies uses: actions/cache@v4 with: - key: test-${{ matrix.os }}-${{ matrix.config }} + key: test-${{ matrix.os }}-${{ matrix.config }}-${{ hashFiles('CMakeLists.txt', 'cmake/**', 'pyproject.toml') }} path: build + - name: ๐Ÿงน Clean FetchContent deps (Windows) + if: ${{ matrix.os == 'windows-latest' }} + shell: pwsh + run: | + if (Test-Path build/_deps) { Remove-Item -Recurse -Force build/_deps } + - name: ๐Ÿ—๏ธ Compile run: cmake -DVIENNAPS_BUILD_TESTS=ON -B build && cmake --build build --config ${{ matrix.config }} diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 30973319..aeb661b2 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -51,9 +51,15 @@ jobs: - name: ๐Ÿฆฅ Cache Dependencies uses: actions/cache@v4 with: - key: python-${{ matrix.os }} + key: python-${{ matrix.os }}-${{ hashFiles('CMakeLists.txt', 'cmake/**', 'pyproject.toml') }} path: build + - name: ๐Ÿงน Clean FetchContent deps (Windows) + if: ${{ matrix.os == 'windows-latest' }} + shell: pwsh + run: | + if (Test-Path build/_deps) { Remove-Item -Recurse -Force build/_deps } + - name: ๐Ÿ› ๏ธ Disable IPO (Alpine) if: ${{ matrix.os == 'ubuntu-latest' }} run: | @@ -164,4 +170,4 @@ jobs: merge-multiple: true - name: ๐Ÿš€ Publish Wheels - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@release/v1 \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index dd8750b8..f604d4df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,7 +105,7 @@ include("cmake/cpm.cmake") CPMAddPackage( NAME ViennaCore - VERSION 1.9.2 + VERSION 1.9.4 GIT_REPOSITORY "https://github.com/ViennaTools/ViennaCore" EXCLUDE_FROM_ALL ${VIENNAPS_BUILD_PYTHON} OPTIONS "VIENNACORE_USE_GPU ${VIENNAPS_USE_GPU}") @@ -124,7 +124,7 @@ CPMAddPackage( CPMAddPackage( NAME ViennaLS - VERSION 5.4.0 + VERSION 5.5.0 GIT_REPOSITORY "https://github.com/ViennaTools/ViennaLS" EXCLUDE_FROM_ALL ${VIENNAPS_BUILD_PYTHON}) diff --git a/examples/holeEtching/config.txt b/examples/holeEtching/config.txt index 81f19b0f..7c4a1d5d 100644 --- a/examples/holeEtching/config.txt +++ b/examples/holeEtching/config.txt @@ -30,5 +30,7 @@ A_Si=7 # Si yield constant etchStopDepth=-10 # maximum etching depth spatialScheme=EO_1 temporalScheme=RK3 +fluxEngine=CD raysPerPoint=1000 +outputFile=final.vtp diff --git a/examples/holeEtching/holeEtching.cpp b/examples/holeEtching/holeEtching.cpp index 831cf822..18b59df7 100644 --- a/examples/holeEtching/holeEtching.cpp +++ b/examples/holeEtching/holeEtching.cpp @@ -8,9 +8,10 @@ using namespace viennaps; int main(int argc, char *argv[]) { using NumericType = double; - constexpr int D = 3; + constexpr int D = 2; - omp_set_num_threads(16); + Logger::setLogLevel(LogLevel::ERROR); + omp_set_num_threads(8); // Parse the parameters util::Parameters params; @@ -30,54 +31,77 @@ int main(int argc, char *argv[]) { units::Length::setUnit(params.get("lengthUnit")); units::Time::setUnit(params.get("timeUnit")); - // geometry setup - auto geometry = Domain::New( - params.get("gridDelta"), params.get("xExtent"), params.get("yExtent")); - MakeHole(geometry, params.get("holeRadius"), - 0.0, // holeDepth - 0.0, // holeTaperAngle - params.get("maskHeight"), params.get("taperAngle"), - HoleShape::HALF) - .apply(); - - // use pre-defined model SF6O2 etching model - auto modelParams = SF6O2Etching::defaultParameters(); - modelParams.ionFlux = params.get("ionFlux"); - modelParams.etchantFlux = params.get("etchantFlux"); - modelParams.passivationFlux = 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.Substrate.A_ie = params.get("A_Si"); - modelParams.etchStopDepth = params.get("etchStopDepth"); - auto model = SmartPointer>::New(modelParams); - - CoverageParameters coverageParams; - coverageParams.tolerance = 1e-4; - - RayTracingParameters rayTracingParams; - rayTracingParams.raysPerPoint = params.get("raysPerPoint"); - - AdvectionParameters advectionParams; - advectionParams.spatialScheme = - util::convertSpatialScheme(params.get("spatialScheme")); - advectionParams.temporalScheme = - util::convertTemporalScheme(params.get("temporalScheme")); - - // process setup - Process process(geometry, model); - process.setProcessDuration(params.get("processTime")); - process.setParameters(coverageParams); - process.setParameters(rayTracingParams); - process.setParameters(advectionParams); - - // print initial surface - geometry->saveSurfaceMesh("initial.vtp"); - - // run the process - process.apply(); - - // print final surface - geometry->saveSurfaceMesh("final.vtp", true, 0.01, true); + auto runSimulation = [&](bool intermediateVelocities, std::string suffix) { + // geometry setup + auto geometry = Domain::New( + params.get("gridDelta"), params.get("xExtent"), params.get("yExtent")); + MakeHole(geometry, params.get("holeRadius"), + 0.0, // holeDepth + 0.0, // holeTaperAngle + params.get("maskHeight"), params.get("taperAngle"), + HoleShape::QUARTER) + .apply(); + + // use pre-defined model SF6O2 etching model + auto modelParams = SF6O2Etching::defaultParameters(); + modelParams.ionFlux = params.get("ionFlux"); + modelParams.etchantFlux = params.get("etchantFlux"); + modelParams.passivationFlux = 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.Substrate.A_ie = params.get("A_Si"); + modelParams.etchStopDepth = params.get("etchStopDepth"); + auto model = SmartPointer>::New(modelParams); + + CoverageParameters coverageParams; + coverageParams.tolerance = 1e-4; + + RayTracingParameters rayTracingParams; + rayTracingParams.raysPerPoint = params.get("raysPerPoint"); + + AdvectionParameters advectionParams; + advectionParams.spatialScheme = + util::convertSpatialScheme(params.get("spatialScheme")); + advectionParams.temporalScheme = + util::convertTemporalScheme(params.get("temporalScheme")); + advectionParams.calculateIntermediateVelocities = intermediateVelocities; + + // process setup + const std::string fluxEngineStr = params.get("fluxEngine"); + const auto fluxEngine = util::convertFluxEngineType(fluxEngineStr); + + Process process(geometry, model); + process.setProcessDuration(params.get("processTime")); + process.setParameters(coverageParams); + process.setParameters(rayTracingParams); + process.setParameters(advectionParams); + process.setFluxEngineType(fluxEngine); + + // print initial surface + if (suffix == "_noIntermediate") + geometry->saveSurfaceMesh("initial.vtp"); + + // run the process + process.apply(); + + // print final surface + std::string outputFile = params.get("outputFile"); + auto pos = outputFile.find_last_of('.'); + if (pos != std::string::npos) { + outputFile.insert(pos, suffix); + } else { + outputFile += suffix; + } + geometry->saveSurfaceMesh(outputFile, true, 0.01, true); + }; + + std::cout << "Running simulation without intermediate velocity calculation..." + << std::endl; + runSimulation(false, "_noIntermediate"); + + std::cout << "Running simulation with intermediate velocity calculation..." + << std::endl; + runSimulation(true, "_intermediate"); } diff --git a/examples/holeEtching/holeEtching.py b/examples/holeEtching/holeEtching.py index 43ae0c62..51437aee 100644 --- a/examples/holeEtching/holeEtching.py +++ b/examples/holeEtching/holeEtching.py @@ -13,62 +13,90 @@ else: print("Running 3D simulation.") ps.setDimension(args.dim) +ps.setNumThreads(16) params = ps.readConfigFile(args.filename) ps.Length.setUnit(params["lengthUnit"]) ps.Time.setUnit(params["timeUnit"]) -# geometry setup, all units in um -geometry = ps.Domain( - gridDelta=params["gridDelta"], - xExtent=params["xExtent"], - yExtent=params["yExtent"], -) -ps.MakeHole( - domain=geometry, - holeRadius=params["holeRadius"], - holeDepth=0.0, - maskHeight=params["maskHeight"], - maskTaperAngle=params["taperAngle"], - holeShape=ps.HoleShape.HALF, -).apply() - -# use pre-defined model SF6O2 etching model -modelParams = ps.SF6O2Etching.defaultParameters() -modelParams.ionFlux = params["ionFlux"] -modelParams.etchantFlux = params["etchantFlux"] -modelParams.passivationFlux = params["oxygenFlux"] -modelParams.Ions.meanEnergy = params["meanEnergy"] -modelParams.Ions.sigmaEnergy = params["sigmaEnergy"] -modelParams.Ions.exponent = params["ionExponent"] -modelParams.Passivation.A_ie = params["A_O"] -modelParams.Substrate.A_ie = params["A_Si"] -modelParams.etchStopDepth = params["etchStopDepth"] -model = ps.SF6O2Etching(modelParams) - -covParams = ps.CoverageParameters() -covParams.tolerance = 1e-4 - -rayParams = ps.RayTracingParameters() -rayParams.raysPerPoint = int(params["raysPerPoint"]) -rayParams.smoothingNeighbors = 2 - -advParams = ps.AdvectionParameters() -advParams.spatialScheme = ps.util.convertSpatialScheme(params["spatialScheme"]) - -# process setup -process = ps.Process(geometry, model) -process.setProcessDuration(params["processTime"]) # seconds -process.setParameters(covParams) -process.setParameters(rayParams) -process.setParameters(advParams) - -# print initial surface -geometry.saveSurfaceMesh(filename="initial.vtp") - -# run the process -process.apply() - -# print final surface -geometry.saveSurfaceMesh(filename="final.vtp", addInterfaces=True) +def run_simulation(intermediate_velocities, suffix): + # geometry setup, all units in um + geometry = ps.Domain( + gridDelta=params["gridDelta"], + xExtent=params["xExtent"], + yExtent=params["yExtent"], + ) + + hole_shape = ps.HoleShape.QUARTER if args.dim == 3 else ps.HoleShape.HALF + + ps.MakeHole( + domain=geometry, + holeRadius=params["holeRadius"], + holeDepth=0.0, + maskHeight=params["maskHeight"], + maskTaperAngle=params["taperAngle"], + holeShape=hole_shape, + ).apply() + + # use pre-defined model SF6O2 etching model + modelParams = ps.SF6O2Etching.defaultParameters() + modelParams.ionFlux = params["ionFlux"] + modelParams.etchantFlux = params["etchantFlux"] + modelParams.passivationFlux = params["oxygenFlux"] + modelParams.Ions.meanEnergy = params["meanEnergy"] + modelParams.Ions.sigmaEnergy = params["sigmaEnergy"] + modelParams.Ions.exponent = params["ionExponent"] + modelParams.Passivation.A_ie = params["A_O"] + modelParams.Substrate.A_ie = params["A_Si"] + modelParams.etchStopDepth = params["etchStopDepth"] + model = ps.SF6O2Etching(modelParams) + + covParams = ps.CoverageParameters() + covParams.tolerance = 1e-4 + + rayParams = ps.RayTracingParameters() + rayParams.raysPerPoint = int(params["raysPerPoint"]) + + advParams = ps.AdvectionParameters() + advParams.spatialScheme = ps.util.convertSpatialScheme( + params["spatialScheme"] + ) + advParams.temporalScheme = ps.util.convertTemporalScheme( + params["temporalScheme"] + ) + advParams.calculateIntermediateVelocities = intermediate_velocities + + # process setup + process = ps.Process(geometry, model) + process.setProcessDuration(params["processTime"]) # seconds + process.setParameters(covParams) + process.setParameters(rayParams) + process.setParameters(advParams) + + fluxEngineStr = params["fluxEngine"] + fluxEngine = ps.util.convertFluxEngineType(fluxEngineStr) + process.setFluxEngineType(fluxEngine) + + # print initial surface + if suffix == "_noIntermediate": + geometry.saveSurfaceMesh(filename="initial.vtp") + + # run the process + process.apply() + + # print final surface + output_file = params["outputFile"] + if "." in output_file: + parts = output_file.rsplit(".", 1) + output_file = f"{parts[0]}{suffix}.{parts[1]}" + else: + output_file += suffix + + geometry.saveSurfaceMesh(filename=output_file, addInterfaces=True, boolMaterials=True) + +print("Running simulation without intermediate velocity calculation...") +run_simulation(False, "_noIntermediate") + +print("Running simulation with intermediate velocity calculation...") +run_simulation(True, "_intermediate") diff --git a/examples/simpleEtching/CMakeLists.txt b/examples/simpleEtching/CMakeLists.txt new file mode 100644 index 00000000..d8339baf --- /dev/null +++ b/examples/simpleEtching/CMakeLists.txt @@ -0,0 +1,3 @@ +project(simpleEtching LANGUAGES CXX) + +viennaps_add_example(${PROJECT_NAME} "${PROJECT_NAME}.cpp") diff --git a/examples/simpleEtching/simpleEtching.cpp b/examples/simpleEtching/simpleEtching.cpp new file mode 100644 index 00000000..6021fa1a --- /dev/null +++ b/examples/simpleEtching/simpleEtching.cpp @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include + +namespace ps = viennaps; + +int main() { + // Dimension of the domain: 2 for Trench, 3 for Hole + constexpr int D = 2; + omp_set_num_threads(16); + using NumericType = double; + + ps::Logger::setLogLevel(ps::LogLevel::INFO); + + // Geometry parameters + NumericType gridDelta = 0.05; + NumericType xExtent = 3.0; + NumericType yExtent = 3.0; + NumericType featureWidth = 1.0; // Diameter for hole, Width for trench + NumericType maskHeight = 1.0; + NumericType taperAngle = 0.0; + + // Single Particle Process Model + // Parameters: rate, stickingProbability, yield, maskMaterial + NumericType rate = -2.0; + NumericType stickingProbability = 0.2; + NumericType sourcePower = 1.0; + NumericType processTime = 1.0; + + auto runSimulation = [&](ps::TemporalScheme temporalScheme, + bool calcIntermediate) { + std::string suffix = viennacore::util::toString(temporalScheme); + if (calcIntermediate) { + suffix += "_recalc"; + } + auto domain = ps::SmartPointer>::New( + gridDelta, xExtent, yExtent); + + if constexpr (D == 3) { + // Create a Hole in 3D + ps::MakeHole(domain, featureWidth / 2.0, 0.0, 0.0, + maskHeight, taperAngle, + ps::HoleShape::QUARTER) + .apply(); + } else { + // Create a Trench in 2D + ps::MakeTrench(domain, featureWidth, 0.0, 0.0, maskHeight, + taperAngle, false) + .apply(); + } + + auto model = + ps::SmartPointer>::New( + rate, stickingProbability, sourcePower, ps::Material::Mask); + + ps::Process process(domain, model, processTime); + + const auto fluxEngine = viennacore::util::convertFluxEngineType("CT"); + + ps::AdvectionParameters advectionParams; + advectionParams.spatialScheme = ps::SpatialScheme::WENO_3RD_ORDER; + advectionParams.temporalScheme = temporalScheme; + advectionParams.calculateIntermediateVelocities = calcIntermediate; + process.setParameters(advectionParams); + process.setFluxEngineType(fluxEngine); + + ps::Logger::getInstance().addInfo("Running simulation: " + suffix).print(); + + process.apply(); + + domain->saveSurfaceMesh("simpleEtching_" + suffix + ".vtp"); + }; + + runSimulation(ps::TemporalScheme::FORWARD_EULER, false); + runSimulation(ps::TemporalScheme::RUNGE_KUTTA_2ND_ORDER, false); + runSimulation(ps::TemporalScheme::RUNGE_KUTTA_2ND_ORDER, true); + runSimulation(ps::TemporalScheme::RUNGE_KUTTA_3RD_ORDER, false); + runSimulation(ps::TemporalScheme::RUNGE_KUTTA_3RD_ORDER, true); + + return 0; +} diff --git a/examples/simpleEtching/simpleEtching.py b/examples/simpleEtching/simpleEtching.py new file mode 100644 index 00000000..dfa8eaa1 --- /dev/null +++ b/examples/simpleEtching/simpleEtching.py @@ -0,0 +1,70 @@ +import viennaps +import viennaps.d2 as vps2 +import viennaps.d3 as vps3 + +def main(): + # Dimension of the domain: 2 for Trench, 3 for Hole + D = 2 + + viennaps.Logger.setLogLevel(viennaps.LogLevel.INFO) + + # Geometry parameters + grid_delta = 0.05 + x_extent = 3.0 + y_extent = 3.0 + feature_width = 1.0 # Diameter for hole, Width for trench + mask_height = 1.0 + taper_angle = 0.0 + + # Single Particle Process Model + # Parameters: rate, stickingProbability, yield, maskMaterial + rate = -2.0 + sticking_probability = 0.2 + source_power = 1.0 + process_time = 1.0 + + def run_simulation(temporal_scheme, calc_intermediate): + suffix = str(temporal_scheme).split(".")[-1] + if calc_intermediate: + suffix += "_recalc" + if D == 3: + # Create a Hole in 3D + domain = vps3.Domain(grid_delta, x_extent, y_extent) + vps3.MakeHole(domain, feature_width / 2.0, 0.0, 0.0, + mask_height, taper_angle, + viennaps.HoleShape.QUARTER).apply() + + model = vps3.SingleParticleProcess(rate, sticking_probability, source_power, viennaps.Material.Mask) + process = vps3.Process(domain, model, process_time) + else: + # Create a Trench in 2D + domain = vps2.Domain(grid_delta, x_extent, y_extent) + vps2.MakeTrench(domain, feature_width, 0.0, 0.0, mask_height, + taper_angle, False).apply() + + model = vps2.SingleParticleProcess(rate, sticking_probability, source_power, viennaps.Material.Mask) + process = vps2.Process(domain, model, process_time) + + advection_params = viennaps.AdvectionParameters() + advection_params.spatialScheme = viennaps.util.convertSpatialScheme("WENO_5TH_ORDER") + advection_params.temporalScheme = temporal_scheme + advection_params.calculateIntermediateVelocities = calc_intermediate + process.setParameters(advection_params) + + fluxEngine = viennaps.util.convertFluxEngineType("GT") + process.setFluxEngineType(fluxEngine) + + viennaps.Logger.getInstance().addInfo(f"Running simulation: {suffix}").print() + process.apply() + + domain.saveSurfaceMesh(f"simpleEtching_{suffix}.vtp") + + run_simulation(viennaps.util.convertTemporalScheme("FORWARD_EULER"), False) + run_simulation(viennaps.util.convertTemporalScheme("RUNGE_KUTTA_2ND_ORDER"), False) + run_simulation(viennaps.util.convertTemporalScheme("RUNGE_KUTTA_2ND_ORDER"), True) + run_simulation(viennaps.util.convertTemporalScheme("RUNGE_KUTTA_3RD_ORDER"), False) + run_simulation(viennaps.util.convertTemporalScheme("RUNGE_KUTTA_3RD_ORDER"), True) + +if __name__ == "__main__": + main() + \ No newline at end of file diff --git a/include/viennaps/process/psAdvectionHandler.hpp b/include/viennaps/process/psAdvectionHandler.hpp index 6399a0a7..06c2fe1a 100644 --- a/include/viennaps/process/psAdvectionHandler.hpp +++ b/include/viennaps/process/psAdvectionHandler.hpp @@ -29,6 +29,7 @@ template class AdvectionHandler { discSchem != SpatialScheme::ENGQUIST_OSHER_2ND_ORDER && discSchem != SpatialScheme::LOCAL_LOCAL_LAX_FRIEDRICHS_1ST_ORDER && discSchem != SpatialScheme::LOCAL_LOCAL_LAX_FRIEDRICHS_2ND_ORDER && + discSchem != SpatialScheme::WENO_3RD_ORDER && discSchem != SpatialScheme::WENO_5TH_ORDER)) { VIENNACORE_LOG_WARNING( "Translation field method not supported in combination " @@ -71,6 +72,12 @@ template class AdvectionHandler { advectionKernel_.setAdvectionTime(time); } + void setVelocityUpdateCallback( + std::function>)> + callback) { + advectionKernel_.setVelocityUpdateCallback(callback); + } + void disableSingleStep() { advectionKernel_.setSingleStep(false); } void prepareAdvection(const ProcessContext &context) { diff --git a/include/viennaps/process/psFluxProcessStrategy.hpp b/include/viennaps/process/psFluxProcessStrategy.hpp index 1c6b3a0d..d145f708 100644 --- a/include/viennaps/process/psFluxProcessStrategy.hpp +++ b/include/viennaps/process/psFluxProcessStrategy.hpp @@ -165,6 +165,42 @@ class FluxProcessStrategy final : public ProcessStrategy { // Initialize advection handler PROCESS_CHECK(advectionHandler_.initialize(context)); + // Register velocity update callback for high-order time integration + if (context.advectionParams.calculateIntermediateVelocities) { + advectionHandler_.setVelocityUpdateCallback( + [this, + &context](SmartPointer> domain) { + // Update the mesh and translator based on the intermediate level + // set + this->updateState(context); + + // If coverages are used, map them from the grid (which holds t^n + // data) to the new intermediate surface + if (context.flags.useCoverages) { + this->advectionHandler_.updateCoveragesFromAdvectedSurface( + context, this->translator_); + } + + // Update the surface in the flux engine + if (this->fluxEngine_->updateSurface(context) != + ProcessResult::SUCCESS) + return false; + + // Calculate fluxes on the intermediate surface + auto fluxes = SmartPointer>::New(); + if (this->fluxEngine_->calculateFluxes(context, fluxes) != + ProcessResult::SUCCESS) + return false; + + // Calculate velocities + auto velocities = this->calculateVelocities(context, fluxes); + context.model->getVelocityField()->prepare( + context.domain, velocities, context.processTime); + + return true; + }); + } + if (context.flags.useAdvectionCallback) { context.model->getAdvectionCallback()->setDomain(context.domain); } diff --git a/include/viennaps/process/psProcessParams.hpp b/include/viennaps/process/psProcessParams.hpp index 75708e2e..60e70556 100644 --- a/include/viennaps/process/psProcessParams.hpp +++ b/include/viennaps/process/psProcessParams.hpp @@ -69,6 +69,7 @@ struct AdvectionParameters { bool velocityOutput = false; bool ignoreVoids = false; bool adaptiveTimeStepping = false; + bool calculateIntermediateVelocities = false; auto toMetaData() const { std::unordered_map> metaData; @@ -88,7 +89,9 @@ struct AdvectionParameters { "\nCheckDissipation: " + util::toString(checkDissipation) + "\nVelocityOutput: " + util::toString(velocityOutput) + "\nIgnoreVoids: " + util::toString(ignoreVoids) + - "\nAdaptiveTimeStepping: " + util::toString(adaptiveTimeStepping); + "\nAdaptiveTimeStepping: " + util::toString(adaptiveTimeStepping) + + "\nCalculateIntermediateVelocities: " + + util::toString(calculateIntermediateVelocities); } }; diff --git a/include/viennaps/psUtil.hpp b/include/viennaps/psUtil.hpp index 65a5b92d..ab443c77 100644 --- a/include/viennaps/psUtil.hpp +++ b/include/viennaps/psUtil.hpp @@ -48,6 +48,8 @@ convertSpatialScheme(const std::string &s) { return viennals::SpatialSchemeEnum::LOCAL_LAX_FRIEDRICHS_2ND_ORDER; if (s == "STENCIL_LOCAL_LAX_FRIEDRICHS_1ST_ORDER" || s == "SLLF_1") return viennals::SpatialSchemeEnum::STENCIL_LOCAL_LAX_FRIEDRICHS_1ST_ORDER; + if (s == "WENO_3RD_ORDER" || s == "WENO_3") + return viennals::SpatialSchemeEnum::WENO_3RD_ORDER; if (s == "WENO_5TH_ORDER" || s == "WENO_5") return viennals::SpatialSchemeEnum::WENO_5TH_ORDER; throw std::invalid_argument( @@ -60,6 +62,7 @@ convertSpatialScheme(const std::string &s) { "LOCAL_LAX_FRIEDRICHS_1ST_ORDER, " "LOCAL_LAX_FRIEDRICHS_2ND_ORDER, " "STENCIL_LOCAL_LAX_FRIEDRICHS_1ST_ORDER, " + "WENO_3RD_ORDER, " "WENO_5TH_ORDER"); } @@ -127,6 +130,8 @@ convertSpatialSchemeToString(viennals::SpatialSchemeEnum scheme) { return "LOCAL_LAX_FRIEDRICHS_2ND_ORDER"; case viennals::SpatialSchemeEnum::STENCIL_LOCAL_LAX_FRIEDRICHS_1ST_ORDER: return "STENCIL_LOCAL_LAX_FRIEDRICHS_1ST_ORDER"; + case viennals::SpatialSchemeEnum::WENO_3RD_ORDER: + return "WENO_3RD_ORDER"; case viennals::SpatialSchemeEnum::WENO_5TH_ORDER: return "WENO_5TH_ORDER"; default: diff --git a/pyproject.toml b/pyproject.toml index c9904de7..4e486d10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ name = "ViennaPS" readme = "README.md" license = { file = "LICENSE" } description = "Topography simulation library for microelectronic fabrication processes" -dependencies = ["ViennaLS>=5.4.0"] +dependencies = ["ViennaLS>=5.5.0"] [project.urls] Homepage = "https://viennatools.github.io/ViennaPS/" diff --git a/python/pyWrap.cpp b/python/pyWrap.cpp index 47328e16..3af71fe6 100644 --- a/python/pyWrap.cpp +++ b/python/pyWrap.cpp @@ -539,6 +539,8 @@ PYBIND11_MODULE(VIENNAPS_MODULE_NAME, module) { &AdvectionParameters::adaptiveTimeStepping) .def_readwrite("adaptiveTimeStepSubdivisions", &AdvectionParameters::adaptiveTimeStepSubdivisions) + .def_readwrite("calculateIntermediateVelocities", + &AdvectionParameters::calculateIntermediateVelocities) .def("toMetaData", &AdvectionParameters::toMetaData, "Convert the advection parameters to a metadata dict.") .def("toMetaDataString", &AdvectionParameters::toMetaDataString, @@ -549,6 +551,7 @@ PYBIND11_MODULE(VIENNAPS_MODULE_NAME, module) { .def(py::init<>()) .def_readwrite("tolerance", &CoverageParameters::tolerance) .def_readwrite("maxIterations", &CoverageParameters::maxIterations) + .def_readwrite("initialized", &CoverageParameters::initialized) .def("toMetaData", &CoverageParameters::toMetaData, "Convert the coverage parameters to a metadata dict.") .def("toMetaDataString", &CoverageParameters::toMetaDataString, diff --git a/python/scripts/install_ViennaPS.py b/python/scripts/install_ViennaPS.py index 67f740bc..d9460868 100644 --- a/python/scripts/install_ViennaPS.py +++ b/python/scripts/install_ViennaPS.py @@ -9,7 +9,7 @@ from pathlib import Path REQUIRED_NVCC_MAJOR = 12 -DEFAULT_VIENNALS_VERSION = "5.4.0" +DEFAULT_VIENNALS_VERSION = "5.5.0" # Detect OS IS_WINDOWS = sys.platform == "win32" or os.name == "nt" diff --git a/python/viennaps/_core/__init__.pyi b/python/viennaps/_core/__init__.pyi index 3f9bb9da..2c01b829 100644 --- a/python/viennaps/_core/__init__.pyi +++ b/python/viennaps/_core/__init__.pyi @@ -16,6 +16,7 @@ from . import util __all__: list[str] = ['AdvectionParameters', 'AtomicLayerProcessParameters', 'CF4O2Parameters', 'CF4O2ParametersIons', 'CF4O2ParametersMask', 'CF4O2ParametersPassivation', 'CF4O2ParametersSi', 'CF4O2ParametersSiGe', 'CoverageParameters', 'Extrude', 'FaradayCageParameters', 'FluorocarbonMaterialParameters', 'FluorocarbonParameters', 'FluorocarbonParametersIons', 'FluxEngineType', 'HoleShape', 'IBEParameters', 'IBEParametersCos4Yield', 'Length', 'LengthUnit', 'Logger', 'Material', 'MaterialCategory', 'MaterialInfo', 'MaterialMap', 'MetaDataLevel', 'NormalizationType', 'PlasmaEtchingParameters', 'PlasmaEtchingParametersIons', 'PlasmaEtchingParametersMask', 'PlasmaEtchingParametersPassivation', 'PlasmaEtchingParametersPolymer', 'PlasmaEtchingParametersSubstrate', 'ProcessParams', 'RateSet', 'RayTracingParameters', 'RenderMode', 'Slice', 'Time', 'TimeUnit', 'constants', 'd2', 'd3', 'gpu', 'gpuAvailable', 'setNumThreads', 'util', 'version'] class AdvectionParameters: adaptiveTimeStepping: bool + calculateIntermediateVelocities: bool checkDissipation: bool ignoreVoids: bool integrationScheme: viennals._core.SpatialSchemeEnum @@ -363,6 +364,12 @@ class CoverageParameters: def maxIterations(self, arg0: typing.SupportsInt) -> None: ... @property + def initialized(self) -> bool: + ... + @initialized.setter + def initialized(self, arg0: bool) -> None: + ... + @property def tolerance(self) -> float: ... @tolerance.setter diff --git a/tests/removeStrayPoints/removeStrayPoints.cpp b/tests/removeStrayPoints/removeStrayPoints.cpp index a0be8b5c..d6aa44a4 100644 --- a/tests/removeStrayPoints/removeStrayPoints.cpp +++ b/tests/removeStrayPoints/removeStrayPoints.cpp @@ -41,7 +41,7 @@ int main() { std::cout << "Number of components before removing stray points: " << domain->getNumberOfComponents() << std::endl; - VC_TEST_ASSERT(domain->getNumberOfComponents() == 7); + VC_TEST_ASSERT(domain->getNumberOfComponents() == 8); domain->removeStrayPoints(); @@ -50,12 +50,12 @@ int main() { std::cout << "Number of components after removing stray points: " << domain->getNumberOfComponents() << std::endl; - VC_TEST_ASSERT(domain->getNumberOfComponents() == 1); + VC_TEST_ASSERT(domain->getNumberOfComponents() == 2); MakeTrench(domain, 5.0, 0.0, 0.0, 1.0).apply(); domain->removeMaterial(Material::Si); - VC_TEST_ASSERT(domain->getNumberOfComponents() == 2); + VC_TEST_ASSERT(domain->getNumberOfComponents() == 3); domain->saveLevelSetMesh("testInitial"); -} \ No newline at end of file +}