Skip to content

Commit c7dcf89

Browse files
authored
Implement 2D triangle engines and transmission benchmark (#178)
* Implement 2D triangle tracing on CPU * Working engine test for CPU engines * Engine test working for all engines * Line engine smoothing * 2D benchmark * Assertions * Implement ALD GPU model * Add transmission benchmark * Transmission test on different surfaces * Fix CPU disk transmission test * Bump ViennaRay * Format and add missing ignoreFluxBoundary setters
1 parent ac8e8c9 commit c7dcf89

26 files changed

Lines changed: 1390 additions & 280 deletions

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ CPMAddPackage(
113113

114114
CPMFindPackage(
115115
NAME ViennaRay
116-
VERSION 3.7.2
116+
VERSION 3.8.0
117117
GIT_REPOSITORY "https://github.com/ViennaTools/ViennaRay"
118118
EXCLUDE_FROM_ALL ${VIENNAPS_BUILD_PYTHON}
119119
OPTIONS "VIENNARAY_USE_GPU ${VIENNAPS_USE_GPU}")

cmake/generate_ptx.cmake

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ function(add_GPU_executable target_name_base target_name_var)
8484
cuda_get_sources_and_options(source_files cmake_options options ${ARGN})
8585

8686
# Isolate OBJ target files. NVCC should only process these files and leave PTX targets for NVRTC
87-
set(cu_obj_source_files)
8887
set(cu_optix_source_files)
8988
foreach(file ${source_files})
9089
get_filename_component(_file_extension ${file} EXT)

examples/atomicLayerDeposition/atomicLayerDeposition.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import viennaps as ps
22
import viennals as ls
33

4+
ps.setDimension(2)
5+
ls.setDimension(2)
46

57
params = ps.readConfigFile("config.txt")
68
geometry = ps.Domain()
@@ -50,7 +52,7 @@
5052
)
5153
print("Mean free path: ", gasMFP, " um")
5254

53-
model = ps.d2.SingleParticleALD(
55+
model = ps.SingleParticleALD(
5456
stickingProbability=params["stickingProbability"],
5557
numCycles=int(params["numCycles"]),
5658
growthPerCycle=params["growthPerCycle"],
@@ -70,7 +72,7 @@
7072
rayParams = ps.RayTracingParameters()
7173
rayParams.raysPerPoint = int(params["numRaysPerPoint"])
7274

73-
ALP = ps.d2.Process(geometry, model)
75+
ALP = ps.Process(geometry, model)
7476
ALP.setParameters(rayParams)
7577
ALP.setParameters(alpParams)
7678
ALP.apply()

examples/ionBeamEtching/config.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ redepositionRate=0.05
2020
planeWaferRate=1.0
2121
angle=35.0
2222

23-
processTime=5
23+
processTime=2

gpu/benchmark/Benchmark.hpp

Lines changed: 195 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,26 @@
66
#include <psDomain.hpp>
77
#include <rayParticle.hpp>
88

9-
#define MAKE_GEO Hole
9+
#define MAKE_GEO Trench
1010
#define DEFAULT_GRID_DELTA 0.1
1111
#define DEFAULT_STICKING 0.1
12-
#define DIM 3
12+
#define DIM 2
13+
#define FIXED_RAYS false
1314

14-
constexpr int particleType = 0;
15+
constexpr int particleType = 1;
1516
using TranslatorType = std::unordered_map<unsigned long, unsigned long>;
17+
using namespace viennaps;
1618

1719
template <class NumericType>
1820
auto Trench(NumericType gridDelta = DEFAULT_GRID_DELTA) {
19-
NumericType xExtent = 10.;
20-
NumericType yExtent = 10.;
21-
NumericType width = 5.;
22-
NumericType depth = 25.;
21+
NumericType xExtent = 20.;
22+
NumericType yExtent = 20.;
23+
NumericType width = 10.;
24+
NumericType depth = 50.;
2325

24-
using namespace viennaps;
2526
auto domain = Domain<NumericType, DIM>::New(
2627
gridDelta, xExtent, yExtent, BoundaryType::REFLECTIVE_BOUNDARY);
27-
MakeTrench<NumericType, DIM>(domain, width, depth).apply().apply();
28+
MakeTrench<NumericType, DIM>(domain, width, depth).apply();
2829
return domain;
2930
}
3031

@@ -35,7 +36,6 @@ auto Hole(NumericType gridDelta = DEFAULT_GRID_DELTA) {
3536
NumericType radius = 3.0;
3637
NumericType depth = 30.;
3738

38-
using namespace viennaps;
3939
auto domain = Domain<NumericType, DIM>::New(
4040
gridDelta, xExtent, yExtent, BoundaryType::REFLECTIVE_BOUNDARY);
4141
MakeHole<NumericType, DIM>(domain, radius, depth).apply();
@@ -159,4 +159,189 @@ auto getDeviceParams() {
159159
deviceParams.redepositionThreshold = params_.redepositionThreshold;
160160

161161
return deviceParams;
162+
}
163+
164+
template <class NumericType, int D, class TracerType>
165+
void setupTriangleGeometry(
166+
SmartPointer<Domain<NumericType, D>> &domain,
167+
SmartPointer<viennals::Mesh<float>> &surfaceMesh_,
168+
SmartPointer<KDTree<NumericType, Vec3D<NumericType>>> &elementKdTree_,
169+
TracerType &rayTracer_) {
170+
CreateSurfaceMesh<NumericType, float, D>(
171+
domain->getLevelSets().back(), surfaceMesh_, elementKdTree_, 1e-12, 0.05)
172+
.apply();
173+
174+
viennaray::TriangleMesh triangleMesh;
175+
176+
if constexpr (D == 2) {
177+
viennaray::LineMesh lineMesh;
178+
lineMesh.gridDelta = static_cast<float>(domain->getGridDelta());
179+
lineMesh.lines = surfaceMesh_->lines;
180+
lineMesh.nodes = surfaceMesh_->nodes;
181+
lineMesh.minimumExtent = surfaceMesh_->minimumExtent;
182+
lineMesh.maximumExtent = surfaceMesh_->maximumExtent;
183+
184+
triangleMesh = convertLinesToTriangles(lineMesh);
185+
assert(triangleMesh.triangles.size() > 0);
186+
187+
std::vector<Vec3D<NumericType>> triangleCenters;
188+
triangleCenters.reserve(triangleMesh.triangles.size());
189+
for (const auto &tri : triangleMesh.triangles) {
190+
Vec3D<NumericType> center = {0, 0, 0};
191+
for (int i = 0; i < 3; ++i) {
192+
center[0] += triangleMesh.nodes[tri[i]][0];
193+
center[1] += triangleMesh.nodes[tri[i]][1];
194+
center[2] += triangleMesh.nodes[tri[i]][2];
195+
}
196+
triangleCenters.push_back(center / static_cast<NumericType>(3.0));
197+
}
198+
assert(triangleCenters.size() > 0);
199+
elementKdTree_->setPoints(triangleCenters);
200+
elementKdTree_->build();
201+
} else {
202+
triangleMesh = CreateTriangleMesh(
203+
static_cast<float>(domain->getGridDelta()), surfaceMesh_);
204+
}
205+
206+
rayTracer_.setGeometry(triangleMesh);
207+
208+
if constexpr (D == 2) {
209+
surfaceMesh_->nodes = std::move(triangleMesh.nodes);
210+
surfaceMesh_->triangles = std::move(triangleMesh.triangles);
211+
surfaceMesh_->getCellData().insertReplaceVectorData(
212+
std::move(triangleMesh.normals), "Normals");
213+
surfaceMesh_->minimumExtent = triangleMesh.minimumExtent;
214+
surfaceMesh_->maximumExtent = triangleMesh.maximumExtent;
215+
}
216+
}
217+
218+
template <class NumericType, int D, class TracerType>
219+
void setupLineGeometry(
220+
SmartPointer<Domain<NumericType, D>> &domain,
221+
SmartPointer<viennals::Mesh<float>> &surfaceMesh_,
222+
SmartPointer<KDTree<NumericType, Vec3D<NumericType>>> &elementKdTree_,
223+
TracerType &rayTracer_) {
224+
CreateSurfaceMesh<NumericType, float, D>(
225+
domain->getLevelSets().back(), surfaceMesh_, elementKdTree_, 1e-12, 0.05)
226+
.apply();
227+
228+
viennaray::LineMesh lineMesh(surfaceMesh_->nodes, surfaceMesh_->lines,
229+
static_cast<float>(domain->getGridDelta()));
230+
// lines might have changed, so we need to update the surfaceMesh_ later
231+
232+
std::vector<Vec3D<NumericType>> elementCenters(lineMesh.lines.size());
233+
for (int i = 0; i < lineMesh.lines.size(); ++i) {
234+
auto const &p0 = lineMesh.nodes[lineMesh.lines[i][0]];
235+
auto const &p1 = lineMesh.nodes[lineMesh.lines[i][1]];
236+
auto center = (p0 + p1) / 2.f;
237+
elementCenters[i] = Vec3D<NumericType>{static_cast<NumericType>(center[0]),
238+
static_cast<NumericType>(center[1]),
239+
static_cast<NumericType>(center[2])};
240+
}
241+
elementKdTree_->setPoints(elementCenters);
242+
elementKdTree_->build();
243+
244+
rayTracer_.setGeometry(lineMesh);
245+
246+
surfaceMesh_->nodes = std::move(lineMesh.nodes);
247+
surfaceMesh_->lines = std::move(lineMesh.lines);
248+
surfaceMesh_->getCellData().insertReplaceVectorData(
249+
std::move(lineMesh.normals), "Normals");
250+
surfaceMesh_->minimumExtent = lineMesh.minimumExtent;
251+
surfaceMesh_->maximumExtent = lineMesh.maximumExtent;
252+
}
253+
254+
template <typename NumericType, class TracerType>
255+
void postProcessLineData(
256+
viennals::PointData<NumericType> &pointData,
257+
SmartPointer<viennals::Mesh<NumericType>> diskMesh, int smoothingNeighbors,
258+
NumericType gridDelta, TracerType &rayTracer_,
259+
SmartPointer<KDTree<NumericType, Vec3D<NumericType>>> elementKdTree_,
260+
SmartPointer<viennals::Mesh<float>> surfaceMesh_) {
261+
262+
const auto numRates = rayTracer_.getNumberOfRates();
263+
const auto numPoints = rayTracer_.getNumberOfElements();
264+
const auto numDisks = diskMesh->nodes.size();
265+
assert(numRates > 0);
266+
auto particles = rayTracer_.getParticles();
267+
auto const &elementNormals =
268+
*surfaceMesh_->getCellData().getVectorData("Normals");
269+
auto const &normals = *diskMesh->getCellData().getVectorData("Normals");
270+
const auto numElements = surfaceMesh_->lines.size();
271+
272+
NumericType conversionRadius = gridDelta * (smoothingNeighbors + 1);
273+
conversionRadius *= conversionRadius; // use squared radius
274+
275+
std::vector<std::vector<std::pair<unsigned, NumericType>>> elementsToPoint;
276+
elementsToPoint.reserve(numDisks);
277+
278+
for (int i = 0; i < numDisks; i++) {
279+
auto closePoints =
280+
elementKdTree_
281+
->findNearestWithinRadius(diskMesh->nodes[i], conversionRadius)
282+
.value();
283+
284+
std::vector<std::pair<unsigned, NumericType>> closePointsArray;
285+
std::vector<NumericType> weights(closePoints.size(), NumericType(0));
286+
287+
unsigned numClosePoints = 0;
288+
for (std::size_t n = 0; n < closePoints.size(); ++n) {
289+
const auto &p = closePoints[n];
290+
assert(p.first < numElements);
291+
292+
NumericType weight = 0;
293+
for (int k = 0; k < 3; ++k) {
294+
weight += normals[i][k] * elementNormals[p.first][k];
295+
}
296+
weight = std::max(weight, NumericType(0));
297+
298+
if (weight > NumericType(1e-6) && !std::isnan(weight)) {
299+
weights[n] = weight;
300+
++numClosePoints;
301+
}
302+
}
303+
304+
if (numClosePoints == 0) { // fallback to nearest point
305+
auto nearestPoint = elementKdTree_->findNearest(diskMesh->nodes[i]);
306+
closePointsArray.emplace_back(nearestPoint->first, NumericType(1));
307+
}
308+
309+
// Compute weighted average
310+
const NumericType sum =
311+
std::accumulate(weights.begin(), weights.end(), NumericType(0));
312+
313+
if (sum > NumericType(0)) {
314+
for (std::size_t k = 0; k < closePoints.size(); ++k) {
315+
if (weights[k] > NumericType(0)) {
316+
closePointsArray.emplace_back(closePoints[k].first, weights[k] / sum);
317+
}
318+
}
319+
} else {
320+
// Fallback if all weights were discarded
321+
auto nearestPoint = elementKdTree_->findNearest(diskMesh->nodes[i]);
322+
closePointsArray.emplace_back(nearestPoint->first, NumericType(1));
323+
}
324+
325+
elementsToPoint.push_back(closePointsArray);
326+
}
327+
assert(elementsToPoint.size() == numDisks);
328+
329+
for (int pIdx = 0; pIdx < particles.size(); pIdx++) {
330+
for (int dIdx = 0; dIdx < particles[pIdx].dataLabels.size(); dIdx++) {
331+
auto elementFlux = rayTracer_.getFlux(pIdx, dIdx, smoothingNeighbors);
332+
auto name = particles[pIdx].dataLabels[dIdx];
333+
334+
// convert line fluxes to disk fluxes
335+
std::vector<NumericType> diskFlux(numDisks, 0.);
336+
337+
for (int i = 0; i < numDisks; i++) {
338+
for (const auto &elemPair : elementsToPoint[i]) {
339+
diskFlux[i] += static_cast<NumericType>(elementFlux[elemPair.first]) *
340+
elemPair.second;
341+
}
342+
}
343+
344+
pointData.insertReplaceScalarData(std::move(diskFlux), name);
345+
}
346+
}
162347
}

gpu/benchmark/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ add_dependencies(ViennaPS-GPU_Benchmark holeComparison)
1818

1919
add_gpu_executable(holeComparisonGrid target_name ${CMAKE_CURRENT_SOURCE_DIR}/holeCompareGrid.cpp)
2020
add_dependencies(ViennaPS-GPU_Benchmark holeComparisonGrid)
21+
22+
add_gpu_executable(transmissionTest target_name ${CMAKE_CURRENT_SOURCE_DIR}/transmission.cpp
23+
TransmissionTest.cu)
24+
add_dependencies(ViennaPS-GPU_Benchmark transmissionTest)

0 commit comments

Comments
 (0)