Skip to content

Commit

Permalink
Implemented Python bindings and update models (#47)
Browse files Browse the repository at this point in the history
* Start Python wrapping

* Added function parameters

* Planarize function

* Surface model trampoline class

* Python Wrapping for ViennaPS (#46)

* Fixed psProcess merge

* Update Python building setup

* Python install working

* Stack etching example using Python bindings

* Added single TEOS deposition Python example

* More example Python wrapping

* Update README with Python install instructions

* Wrap cell set and models+exmaples

* Add default particles

* Add signal handling and rayParticle update

* Remove 'ps' prefix in Python bindings

* Remove 'ps' prefix in examples

* Change include guards and update application

* Add wet etching example in Python

* Fix small typos

* Update version to 1.3.0

* Format project

---------

Co-authored-by: serb1231 <serban.ionescu15@gmail.com>
  • Loading branch information
tobre1 and serb1231 authored Oct 25, 2023
1 parent 012140a commit 7723298
Show file tree
Hide file tree
Showing 92 changed files with 3,293 additions and 753 deletions.
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ install*
CMakeSettings.json
docs/doxygen/*.txt
dependencies/
!docs/doxygen/doxygen_template.txt
!docs/doxygen/doxygen_template.txt
*.so
*.py[cod]
*.egg-info
*env*
.eggs/
141 changes: 114 additions & 27 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

project("ViennaPS" VERSION 1.0.0)
project(ViennaPS VERSION 1.3.0)

include(GNUInstallDirs)
# Store version in cache
set(VIENNAPS_VERSION
${PROJECT_VERSION}
CACHE STRING "The version of ViennaPS" FORCE)

# c++17 for inline constexpr variables
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD "17")

# Set default build type
add_definitions(-DVIENNAPS_VERSION=${PROJECT_VERSION})

include(GNUInstallDirs)

# Setup of default build type
set(DEFAULT_BUILD_TYPE "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.")
Expand All @@ -19,41 +26,116 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
"RelWithDebInfo")
endif()

# tell VS to export all symbols to its dll files
# Tell VS to export all symbols to its dll files
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
TRUE
CACHE BOOL "Export all symbols")
CACHE BOOL "Export all symbols" FORCE)
add_compile_definitions(_USE_MATH_DEFINES)
endif()

# ##################################################################################################
# CONFIGURATION OPTIONS
# ##################################################################################################

# Build the included examples
option(VIENNAPS_BUILD_EXAMPLES "Build examples." OFF)

# Build the application binary
option(VIENNAPS_BUILD_APPLICATION "Build ViennaPS application." OFF)

# ##################################################################################################
# AUTOMATIC DEPENDENCY PREPARATION
# ##################################################################################################

# With the stampfile mechanism, cmake automatically retriggers the configure step after the
# buildDependencies targed has been executed. Thus all dependencies that were built with
# buildDependencies should then be made available by the find_package calls.
set(STAMPFILE ${CMAKE_BINARY_DIR}/target.stamp)
# When the buildDependencies target is executed, the stamp file is touched
add_custom_target(buildDependencies COMMAND ${CMAKE_COMMAND} -E touch ${STAMPFILE})

# Include the external dependencies
include(ExternalProject)
if(NOT DEFINED VIENNAPS_DEPENDENCIES_DIR)
set(DEPENDENCIES_DIR ${CMAKE_SOURCE_DIR}/dependencies)
else()
set(DEPENDENCIES_DIR
${VIENNAPS_DEPENDENCIES_DIR}
CACHE PATH "Directory for downloading, building and installing external dependencies")
endif()
add_subdirectory(external/upstream)

# Create the initial stamp file
file(TOUCH ${STAMPFILE})
# Include the stamp file, so that cmake is forced to re-run once the file has been touched
include(${STAMPFILE})

# Binary store the binary directory for use in subprojects
set(ViennaPS_BINARY_DIR
${PROJECT_BINARY_DIR}
CACHE PATH "Path to local ViennaPS installation" FORCE)

# build dependencies
set(DEPENDENCIES_DIR ${CMAKE_SOURCE_DIR}/dependencies)
# ##################################################################################################
# DEPENDENCY CHECKS
# ##################################################################################################
set(DEPENDENCIES_FOUND TRUE)

# Include all external dependencies
include(ExternalProject)
add_custom_target(buildDependencies)
add_subdirectory(external/upstream)
list(APPEND VIENNAPS_DEPENDENCIES "viennals_external")
find_package(ViennaLS QUIET CONFIG PATHS ${ViennaLS_DIR} NO_DEFAULT_PATH)
if(NOT ViennaLS_FOUND)
set(DEPENDENCIES_FOUND FALSE)
endif()

list(APPEND VIENNAPS_DEPENDENCIES "viennaray_external")
find_package(ViennaRay QUIET CONFIG PATHS ${ViennaRay_DIR} NO_DEFAULT_PATH)
if(NOT ViennaRay_FOUND)
set(DEPENDENCIES_FOUND FALSE)
endif()

if(VIENNAPS_BUILD_PYTHON)
list(APPEND VIENNAPS_DEPENDENCIES "pybind11_external")
find_package(pybind11 QUIET PATHS ${pybind11_DIR} NO_DEFAULT_PATH)
if(NOT pybind11_FOUND)
set(DEPENDENCIES_FOUND FALSE)
endif()
endif()

if(DEPENDENCIES_FOUND)
# Remove the buildDependencies target from the ALL target to prevent unnecessary re-builds
set_target_properties(buildDependencies PROPERTIES EXCLUDE_FROM_ALL true)
else()
message(WARNING "Not all dependencies were found. Execute buildDependencies target first.")
# Add the buildDependencies target to the ALL target
set_target_properties(buildDependencies PROPERTIES EXCLUDE_FROM_ALL false)
endif()

# ##################################################################################################
# DIRECTORY CONFIGURATIONS
# ##################################################################################################

# install config files locations are provided by GNUInstallDirs
add_library(${PROJECT_NAME} INTERFACE)

# set the correct paths for installation
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/")
endif()
set(LOCAL_CONFIG_DIR "lib/cmake/${PROJECT_NAME}")

# This variable is used by the example, test, python and precompiled library target, since those are
# compiled before the project is installed in its proper install location.
set(VIENNAPS_BUILD_INCLUDE_DIRS "${${PROJECT_NAME}_SOURCE_DIR}/include")

# Adding the install interface generator expression makes sure that the include files are installed
# to the proper location (provided by GNUInstallDirs)
set(VIENNAPS_BUILD_INCLUDE_DIRS "${${PROJECT_NAME}_SOURCE_DIR}/include")
target_include_directories(
${PROJECT_NAME} INTERFACE $<BUILD_INTERFACE:${VIENNAPS_BUILD_INCLUDE_DIRS}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_11)

target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17)

# ##################################################################################################
# CMAKE CONFIG FILE SETUP
# ##################################################################################################
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${PROJECT_NAME}ConfigVersion.cmake"
Expand All @@ -67,23 +149,29 @@ configure_package_config_file(
# ##################################################################################################
# BUILD EXAMPLES
# ##################################################################################################
option(VIENNAPS_BUILD_EXAMPLES "Build examples." OFF)
if(VIENNAPS_BUILD_EXAMPLES)
if(VIENNAPS_BUILD_EXAMPLES AND DEPENDENCIES_FOUND)
add_subdirectory(Examples)
endif(VIENNAPS_BUILD_EXAMPLES)
endif()

# ##################################################################################################
# BUILD VIENNAPS APPLICATION
# ##################################################################################################
option(VIENNAPS_BUILD_APPLICATION "Build ViennaPS application." OFF)
if(VIENNAPS_BUILD_APPLICATION)
if(VIENNAPS_BUILD_APPLICATION AND DEPENDENCIES_FOUND)
add_subdirectory(app)
endif(VIENNAPS_BUILD_APPLICATION)
endif()

# ##################################################################################################
# INSTALL
# BUILD VIENNAPS PYTHON BINDINGS
# ##################################################################################################
# Build Python bindings
option(VIENNAPS_BUILD_PYTHON "Build for python3.x." OFF)
if(VIENNAPS_BUILD_PYTHON AND DEPENDENCIES_FOUND)
add_subdirectory(Python)
endif()

# ##################################################################################################
# INSTALL
# ##################################################################################################
install(
TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}_Targets
Expand All @@ -100,10 +188,9 @@ install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION ${LOCAL_CONFIG_DIR})

# install include files
# Install include files
file(GLOB_RECURSE HEADER_FILES "${PROJECT_SOURCE_DIR}/include/*.hpp")

install(FILES ${HEADER_FILES} DESTINATION "include")
install(FILES ${HEADER_FILES} DESTINATION include)

# uninstall target
if(NOT TARGET uninstall)
Expand Down
1 change: 1 addition & 0 deletions Examples/CantileverWetEtching/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ project("CantileverWetEtching")
add_executable(${PROJECT_NAME} ${PROJECT_NAME}.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC ${VIENNAPS_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${VIENNAPS_LIBRARIES})
configure_file(CantileverWetEtching.py ${CMAKE_CURRENT_BINARY_DIR}/CantileverWetEtching.py COPYONLY)
configure_file(cantilever_mask.gds ${CMAKE_CURRENT_BINARY_DIR}/cantilever_mask.gds COPYONLY)

add_dependencies(buildExamples ${PROJECT_NAME})
55 changes: 55 additions & 0 deletions Examples/CantileverWetEtching/CantileverWetEtching.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This example only works in 3D mode
import viennaps3d as vps
import viennals3d as vls

maskFileName = "cantilever_mask.gds"

minutes = int(120 / 5) # total etch time (2 hours)
x_add = 50.0 # add space to domain boundary
y_add = 50.0
gridDelta = 5.0 # um

# read GDS mask file
boundaryConditions = [
vls.lsBoundaryConditionEnum.REFLECTIVE_BOUNDARY,
vls.lsBoundaryConditionEnum.REFLECTIVE_BOUNDARY,
vls.lsBoundaryConditionEnum.INFINITE_BOUNDARY,
]

gds_mask = vps.GDSGeometry(gridDelta)
gds_mask.setBoundaryConditions(boundaryConditions)
gds_mask.setBoundaryPadding(x_add, y_add)
vps.GDSReader(gds_mask, maskFileName).apply()

# convert GDS geometry to level set
mask = gds_mask.layerToLevelSet(1, 0.0, 4 * gridDelta, True)

# create plane geometry as substrate
bounds = gds_mask.getBounds()
plane = vls.lsDomain(bounds, boundaryConditions, gridDelta)
vls.lsMakeGeometry(plane, vls.lsPlane([0.0, 0.0, 0.0], [0.0, 0.0, 1.0])).apply()

# combine geometries
geometry = vps.Domain()
geometry.insertNextLevelSet(mask)
geometry.insertNextLevelSet(plane)
geometry.printSurface("InitialGeometry.vtp", True)

# wet etch process
model = vps.WetEtching(0)

process = vps.Process()
process.setDomain(geometry)
process.setProcessModel(model)
process.setProcessDuration(5.0 * 60.0) # 5 minutes of etching
process.setPrintTimeInterval(-1.0)
process.setIntegrationScheme(
vls.lsIntegrationSchemeEnum.STENCIL_LOCAL_LAX_FRIEDRICHS_1ST_ORDER
)

for n in range(minutes):
process.apply()
# run process
geometry.printSurface("WetEtchingSurface_" + str(n) + ".vtp", True)

geometry.printSurface("FinalGeometry.vtp", True)
2 changes: 0 additions & 2 deletions Examples/ExampleProcess/Particles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ class Particle : public rayParticle<Particle<NumericType, D>, NumericType> {
direction};
}
void initNew(rayRNG &RNG) override final {}

int getRequiredLocalDataSize() const override final { return 1; }
NumericType getSourceDistributionPower() const override final {
return sourcePower;
}
Expand Down
4 changes: 2 additions & 2 deletions Examples/ExampleProcess/SurfaceModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class SurfaceModel : public psSurfaceModel<NumericType> {
*Rates->getScalarData("particleRate"));
}

void
updateCoverages(psSmartPointer<psPointData<NumericType>> Rates) override {
void updateCoverages(psSmartPointer<psPointData<NumericType>> Rates,
const std::vector<NumericType> &materialIds) override {
// update coverages
}
};
2 changes: 1 addition & 1 deletion Examples/ExampleProcess/VelocityField.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ template <class T> class VelocityField : public psVelocityField<T> {
}

void setVelocities(psSmartPointer<std::vector<T>> passedVelocities) override {
// additional alerations can be made to the velocities here
// additional alterations can be made to the velocities here
velocities = passedVelocities;
}

Expand Down
1 change: 1 addition & 0 deletions Examples/GDSReader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ project("GDSReader")
add_executable(${PROJECT_NAME} ${PROJECT_NAME}.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC ${VIENNAPS_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${VIENNAPS_LIBRARIES})
configure_file(GDSReader.py ${CMAKE_CURRENT_BINARY_DIR}/GDSReader.py COPYONLY)
configure_file(mask.gds ${CMAKE_CURRENT_BINARY_DIR}/mask.gds COPYONLY)

add_dependencies(buildExamples ${PROJECT_NAME})
14 changes: 6 additions & 8 deletions Examples/GDSReader/GDSReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ int main(int argc, char **argv) {

// read GDS mask file
const NumericType gridDelta = 0.01;
typename lsDomain<NumericType, D>::BoundaryType boundaryCons[D];
for (int i = 0; i < D - 1; i++)
boundaryCons[i] =
lsDomain<NumericType, D>::BoundaryType::REFLECTIVE_BOUNDARY;
boundaryCons[D - 1] =
lsDomain<NumericType, D>::BoundaryType::INFINITE_BOUNDARY;
lsBoundaryConditionEnum<D> boundaryConds[D] = {
lsBoundaryConditionEnum<D>::REFLECTIVE_BOUNDARY,
lsBoundaryConditionEnum<D>::REFLECTIVE_BOUNDARY,
lsBoundaryConditionEnum<D>::INFINITE_BOUNDARY};
auto mask = psSmartPointer<psGDSGeometry<NumericType, D>>::New(gridDelta);
mask->setBoundaryConditions(boundaryCons);
mask->setBoundaryConditions(boundaryConds);
psGDSReader<NumericType, D>(mask, "mask.gds").apply();

// geometry setup
Expand All @@ -28,7 +26,7 @@ int main(int argc, char **argv) {
NumericType origin[D] = {0., 0., 0.};
NumericType normal[D] = {0., 0., 1.};
auto plane = psSmartPointer<lsDomain<NumericType, D>>::New(
bounds, boundaryCons, gridDelta);
bounds, boundaryConds, gridDelta);
lsMakeGeometry<NumericType, D>(
plane, psSmartPointer<lsPlane<NumericType, D>>::New(origin, normal))
.apply();
Expand Down
38 changes: 38 additions & 0 deletions Examples/GDSReader/GDSReader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import viennaps3d as vps

try:
# ViennaLS Python bindings are needed for the extrusion tool
import viennals3d as vls
except ModuleNotFoundError:
print("ViennaLS Python module not found. Can not parse GDS file.")
exit(1)

gridDelta = 0.01
boundaryConds = [
vls.lsBoundaryConditionEnum.REFLECTIVE_BOUNDARY,
vls.lsBoundaryConditionEnum.REFLECTIVE_BOUNDARY,
vls.lsBoundaryConditionEnum.INFINITE_BOUNDARY,
]

mask = vps.GDSGeometry(gridDelta)
mask.setBoundaryConditions(boundaryConds)
vps.GDSReader(mask, "mask.gds").apply()

bounds = mask.getBounds()
geometry = vps.Domain()

# substrate plane
origin = [0.0, 0.0, 0.0]
normal = [0.0, 0.0, 1.0]
plane = vls.lsDomain(bounds, boundaryConds, gridDelta)
vls.lsMakeGeometry(plane, vls.lsPlane(origin, normal)).apply()

geometry.insertNextLevelSet(plane)

layer0 = mask.layerToLevelSet(0, 0.0, 0.1, False)
geometry.insertNextLevelSet(layer0)

layer1 = mask.layerToLevelSet(1, -0.15, 0.45, False)
geometry.insertNextLevelSet(layer1)

geometry.printSurface("Geometry.vtp", True)
1 change: 1 addition & 0 deletions Examples/HoleEtching/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ project("HoleEtching")
add_executable(${PROJECT_NAME} ${PROJECT_NAME}.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC ${VIENNAPS_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${VIENNAPS_LIBRARIES})
configure_file(HoleEtching.py ${CMAKE_CURRENT_BINARY_DIR}/HoleEtching.py COPYONLY)
configure_file(config.txt ${CMAKE_CURRENT_BINARY_DIR}/config.txt COPYONLY)

add_dependencies(buildExamples ${PROJECT_NAME})
Loading

0 comments on commit 7723298

Please sign in to comment.