-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDREAM.cpp
145 lines (121 loc) · 4.77 KB
/
DREAM.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <chrono>
#include <iostream>
#include <lsBooleanOperation.hpp>
#include <lsExpand.hpp>
#include <lsGeometricAdvect.hpp>
#include <lsMakeGeometry.hpp>
#include <lsToDiskMesh.hpp>
#include <lsToMesh.hpp>
#include <lsToSurfaceMesh.hpp>
#include <lsVTKWriter.hpp>
#include <lsWriteVisualizationMesh.hpp>
#include "BoschProcess.hpp"
#include "MakeMask.hpp"
double reFromAt(double a_t) {
static constexpr double p0 = 1.17506441;
static constexpr double p1 = 0.61536308;
static constexpr double p2 = -0.42438527;
static constexpr double t0 = p1 / p0 - p2;
static constexpr double tm = p1 / (p0 - 1) - p2;
if (a_t <= t0) {
return 0.;
} else if (a_t >= tm) {
return 1.;
} else {
return p0 - p1 / (p2 + a_t);
}
}
int main() {
omp_set_num_threads(16);
constexpr int D = 2;
typedef double NumericType;
double gridDelta = 0.025; // 0.125;
double extent = 3;
double bounds[2 * D] = {-extent, extent, -extent, extent};
if constexpr (D == 3) {
bounds[4] = -extent;
bounds[5] = extent;
}
typename lsDomain<NumericType, D>::BoundaryType boundaryCons[D];
for (unsigned i = 0; i < D - 1; ++i) {
boundaryCons[i] =
lsDomain<NumericType, D>::BoundaryType::REFLECTIVE_BOUNDARY;
}
boundaryCons[D - 1] =
lsDomain<NumericType, D>::BoundaryType::INFINITE_BOUNDARY;
auto mask = lsSmartPointer<lsDomain<NumericType, D>>::New(
bounds, boundaryCons, gridDelta);
auto levelSet = lsSmartPointer<lsDomain<NumericType, D>>::New(
bounds, boundaryCons, gridDelta);
std::array<NumericType, 3> maskOrigin = {};
NumericType maskRadius = 0.4;
MakeMask<NumericType, D> maskCreator(levelSet, mask);
maskCreator.setMaskOrigin(maskOrigin);
maskCreator.setMaskRadius(maskRadius);
maskCreator.apply();
std::cout << "Output initial" << std::endl;
auto mesh = lsSmartPointer<lsMesh<NumericType>>::New();
// lsToMesh<NumericType, D>(levelSet, mesh).apply();
// lsVTKWriter(mesh, "Surface_i_p.vtp").apply();
lsToSurfaceMesh<NumericType, D>(levelSet, mesh).apply();
lsVTKWriter(mesh, "Surface_i.vtp").apply();
// lsToMesh<NumericType, D>(mask, mesh).apply();
// lsVTKWriter(mesh, "Surface_m_p.vtp").apply();
lsToSurfaceMesh<NumericType, D>(mask, mesh).apply();
lsVTKWriter(mesh, "Surface_m.vtp").apply();
// std::vector<NumericType> bottomFractions{
// 0.13948421397683908, 0.41944813667047265, 0.6400617331600338,
// 0.8183890372615938, 0.909870665101959};
// Take average from etch rate measurements in Fig3.11d from ChangThesis2018
NumericType etchRate =
-(46 + 42 + 44 * 2) / (4 * 119.); //-0.3697478991596639; // 0.39
// Calculate bottom fractions from model, based on ash times; last one is just
// maximum
std::vector<NumericType> ashTimes{0., 1.0, 1.2, 1.5, 2.0, 2.5, 4.0};
std::vector<NumericType> bottomFractions;
for (auto it : ashTimes) {
bottomFractions.push_back(reFromAt(it));
std::cout << bottomFractions.back() << std::endl;
}
BoschProcess<NumericType, D> processKernel;
processKernel.setMask(mask);
processKernel.setNumCycles(100);
processKernel.setIsotropicRate(etchRate *
0.6); // * 1.2 / 2 because it is a radius
processKernel.setCycleEtchDepth(etchRate);
processKernel.setStartWidth(2 * maskRadius);
processKernel.setLateralEtchRatio(0.5);
for (auto it : bottomFractions) {
auto substrate = lsSmartPointer<lsDomain<NumericType, D>>::New(levelSet);
processKernel.setSubstrate(substrate);
processKernel.setBottomWidth(2 * maskRadius * it);
processKernel.setStartOfTapering(-24.5);
std::cout << "r_e: " << it << std::endl;
auto start = std::chrono::high_resolution_clock::now();
processKernel.apply();
auto stop = std::chrono::high_resolution_clock::now();
std::cout << "Geometric advect took: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(stop -
start)
.count()
<< " ms" << std::endl;
std::cout << "Final structure has " << substrate->getNumberOfPoints()
<< " LS points" << std::endl;
// levelSet->print();
lsToSurfaceMesh<NumericType, D>(substrate, mesh).apply();
std::ostringstream out;
out.precision(2);
out << std::fixed << it;
lsVTKWriter(mesh, "surface" + out.str() + ".vtp").apply();
// lsToMesh<NumericType, D>(levelSet, mesh).apply();
// lsVTKWriter(mesh, "points-1.vtp").apply();
std::cout << "Making volume output..." << std::endl;
auto volumeMeshing =
lsSmartPointer<lsWriteVisualizationMesh<NumericType, D>>::New();
volumeMeshing->insertNextLevelSet(mask);
volumeMeshing->insertNextLevelSet(substrate);
volumeMeshing->setFileName("bosch" + out.str());
volumeMeshing->apply();
}
return 0;
}