├── .gitignore
├── License.txt
├── README.md
├── build.xml
├── demo
├── convergent_divergent_nozzle.png
├── flow_over_cylinder.png
├── forward_facing_step.png
├── multi_block_mesh_example.png
├── oblique_shock.png
├── sample_output.png
├── sample_output_1.png
├── sample_output_2.png
└── sample_output_3.png
├── manifest.mf
├── mesh.su2
├── mesh.vtk
├── mesh_BottomWall.vtk
├── mesh_Inlet.vtk
├── mesh_Outlet.vtk
├── mesh_TopWall.vtk
├── nbproject
├── build-impl.xml
├── genfiles.properties
├── private
│ └── private.properties
├── project.properties
└── project.xml
├── src
├── geometry
│ ├── Angle.java
│ ├── Geometry.java
│ ├── GeometryFromFile.java
│ ├── ParametricCurve.java
│ ├── ParametricCurvesGeometry.java
│ ├── Point.java
│ ├── SimpleQuadGeometry.java
│ └── builder
│ │ ├── Corner1.java
│ │ ├── Corner2.java
│ │ ├── Corner3.java
│ │ ├── Corner4.java
│ │ ├── CubicCurve.java
│ │ └── GeometryBuilder.java
├── io
│ ├── GeometryFileReader.java
│ ├── MeshFileWriter.java
│ ├── Su2MeshWriter.java
│ └── VtkMeshWriter.java
├── main
│ └── StructuredMeshGenerator2D.java
├── mesh
│ ├── Element.java
│ ├── Face.java
│ ├── MeshDefinition.java
│ ├── Node.java
│ ├── Parameter.java
│ ├── StructuredMesh.java
│ ├── TransfiniteInterpolator.java
│ └── UnstructuredMesh.java
└── util
│ └── Range.java
└── support
├── create_geom.py
├── geometry1.dat
├── geometry2.dat
├── geometry3.dat
├── geometry4.dat
├── geometry5.dat
├── geometry6.dat
├── geometry7.dat
├── geometry8.dat
├── geometry_block_mesh.png
├── geometry_block_mesh.svg
├── plot.py
├── start_end_angles.png
└── start_end_angles.svg
/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
--------------------------------------------------------------------------------
/License.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Sourabh Bhat
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # StructuredMeshGenerator2D
2 | A structured mesh generator for creating 2D mesh using Transfinite Interpolation (TFI) method.
3 |
4 | Below is an example of multi-block mesh generated using multiple geometry defining files:
5 |
6 | 
7 |
8 | Below is another example of multi-block mesh generated using multiple quad blocks:
9 |
10 | 
11 |
12 | and here is a solution produced by importing the above multi-block (unstructured) mesh in a CFD solver, which uses the boundary markers applied in this meshing code:
13 |
14 | 
15 |
16 | Below is a sample mesh generated, where the geometry is created using some helper
17 | methods available within this project.
18 |
19 | 
20 |
21 | and here is the mesh being used to solve convergent-divergent nozzle problem in a CFD solver.
22 |
23 | 
24 |
25 | Here is a mesh generated using geometry read from a file:
26 |
27 | 
28 |
29 | and here is a CFD solution for flow over a cylinder using the above mesh:
30 |
31 | 
32 |
33 | Here is another mesh generated using geometry from file:
34 |
35 | 
36 |
37 | and here is a CFD solution for compressible flow using the above mesh:
38 |
39 | 
40 |
41 |
42 |
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Builds, tests, and runs the project StructuredMeshGenerator2D.
12 |
13 |
73 |
74 |
--------------------------------------------------------------------------------
/demo/convergent_divergent_nozzle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/demo/convergent_divergent_nozzle.png
--------------------------------------------------------------------------------
/demo/flow_over_cylinder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/demo/flow_over_cylinder.png
--------------------------------------------------------------------------------
/demo/forward_facing_step.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/demo/forward_facing_step.png
--------------------------------------------------------------------------------
/demo/multi_block_mesh_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/demo/multi_block_mesh_example.png
--------------------------------------------------------------------------------
/demo/oblique_shock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/demo/oblique_shock.png
--------------------------------------------------------------------------------
/demo/sample_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/demo/sample_output.png
--------------------------------------------------------------------------------
/demo/sample_output_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/demo/sample_output_1.png
--------------------------------------------------------------------------------
/demo/sample_output_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/demo/sample_output_2.png
--------------------------------------------------------------------------------
/demo/sample_output_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/demo/sample_output_3.png
--------------------------------------------------------------------------------
/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | X-COMMENT: Main-Class will be added automatically by build
3 |
4 |
--------------------------------------------------------------------------------
/mesh_BottomWall.vtk:
--------------------------------------------------------------------------------
1 | # vtk DataFile Version 2.0
2 | Block Mesh
3 | ASCII
4 | DATASET UNSTRUCTURED_GRID
5 | POINTS 161 double
6 | 1.120000 0.200000 0.000000
7 | 1.660000 0.200000 0.000000
8 | 0.220000 0.000000 0.000000
9 | 1.180000 0.200000 0.000000
10 | 1.800000 0.200000 0.000000
11 | 1.000000 0.200000 0.000000
12 | 2.740000 0.200000 0.000000
13 | 0.200000 0.000000 0.000000
14 | 2.060000 0.200000 0.000000
15 | 1.280000 0.200000 0.000000
16 | 1.220000 0.200000 0.000000
17 | 1.260000 0.200000 0.000000
18 | 0.600000 0.000000 0.000000
19 | 1.920000 0.200000 0.000000
20 | 0.640000 0.200000 0.000000
21 | 2.020000 0.200000 0.000000
22 | 0.040000 0.000000 0.000000
23 | 1.100000 0.200000 0.000000
24 | 2.720000 0.200000 0.000000
25 | 1.340000 0.200000 0.000000
26 | 1.460000 0.200000 0.000000
27 | 0.440000 0.000000 0.000000
28 | 2.320000 0.200000 0.000000
29 | 2.040000 0.200000 0.000000
30 | 2.220000 0.200000 0.000000
31 | 0.600000 0.180000 0.000000
32 | 0.460000 0.000000 0.000000
33 | 1.760000 0.200000 0.000000
34 | 0.360000 0.000000 0.000000
35 | 0.080000 0.000000 0.000000
36 | 1.240000 0.200000 0.000000
37 | 0.820000 0.200000 0.000000
38 | 0.880000 0.200000 0.000000
39 | 1.720000 0.200000 0.000000
40 | 2.300000 0.200000 0.000000
41 | 0.960000 0.200000 0.000000
42 | 1.540000 0.200000 0.000000
43 | 2.780000 0.200000 0.000000
44 | 1.560000 0.200000 0.000000
45 | 1.360000 0.200000 0.000000
46 | 1.880000 0.200000 0.000000
47 | 0.140000 0.000000 0.000000
48 | 0.160000 0.000000 0.000000
49 | 1.020000 0.200000 0.000000
50 | 1.620000 0.200000 0.000000
51 | 0.600000 0.140000 0.000000
52 | 0.400000 0.000000 0.000000
53 | 2.460000 0.200000 0.000000
54 | 0.900000 0.200000 0.000000
55 | 0.240000 0.000000 0.000000
56 | 1.080000 0.200000 0.000000
57 | 0.740000 0.200000 0.000000
58 | 2.920000 0.200000 0.000000
59 | 2.080000 0.200000 0.000000
60 | 1.780000 0.200000 0.000000
61 | 0.800000 0.200000 0.000000
62 | 0.760000 0.200000 0.000000
63 | 0.600000 0.100000 0.000000
64 | 2.640000 0.200000 0.000000
65 | 2.380000 0.200000 0.000000
66 | 0.380000 0.000000 0.000000
67 | 1.400000 0.200000 0.000000
68 | 2.540000 0.200000 0.000000
69 | 0.660000 0.200000 0.000000
70 | 2.880000 0.200000 0.000000
71 | 0.600000 0.080000 0.000000
72 | 1.040000 0.200000 0.000000
73 | 1.300000 0.200000 0.000000
74 | 3.000000 0.200000 0.000000
75 | 1.060000 0.200000 0.000000
76 | 1.680000 0.200000 0.000000
77 | 2.360000 0.200000 0.000000
78 | 0.700000 0.200000 0.000000
79 | 2.700000 0.200000 0.000000
80 | 0.520000 0.000000 0.000000
81 | 2.240000 0.200000 0.000000
82 | 2.520000 0.200000 0.000000
83 | 1.600000 0.200000 0.000000
84 | 0.780000 0.200000 0.000000
85 | 2.260000 0.200000 0.000000
86 | 0.280000 0.000000 0.000000
87 | 2.940000 0.200000 0.000000
88 | 1.160000 0.200000 0.000000
89 | 0.600000 0.020000 0.000000
90 | 0.620000 0.200000 0.000000
91 | 1.860000 0.200000 0.000000
92 | 2.600000 0.200000 0.000000
93 | 0.480000 0.000000 0.000000
94 | 1.980000 0.200000 0.000000
95 | 0.600000 0.120000 0.000000
96 | 1.520000 0.200000 0.000000
97 | 1.960000 0.200000 0.000000
98 | 2.760000 0.200000 0.000000
99 | 2.180000 0.200000 0.000000
100 | 1.900000 0.200000 0.000000
101 | 2.000000 0.200000 0.000000
102 | 1.320000 0.200000 0.000000
103 | 2.100000 0.200000 0.000000
104 | 0.020000 0.000000 0.000000
105 | 2.420000 0.200000 0.000000
106 | 1.740000 0.200000 0.000000
107 | 0.540000 0.000000 0.000000
108 | 2.280000 0.200000 0.000000
109 | 2.340000 0.200000 0.000000
110 | 2.840000 0.200000 0.000000
111 | 0.000000 0.000000 0.000000
112 | 1.820000 0.200000 0.000000
113 | 2.200000 0.200000 0.000000
114 | 2.680000 0.200000 0.000000
115 | 2.860000 0.200000 0.000000
116 | 0.720000 0.200000 0.000000
117 | 1.500000 0.200000 0.000000
118 | 0.940000 0.200000 0.000000
119 | 1.580000 0.200000 0.000000
120 | 1.140000 0.200000 0.000000
121 | 2.980000 0.200000 0.000000
122 | 0.600000 0.040000 0.000000
123 | 2.120000 0.200000 0.000000
124 | 0.600000 0.160000 0.000000
125 | 0.580000 0.000000 0.000000
126 | 1.200000 0.200000 0.000000
127 | 1.440000 0.200000 0.000000
128 | 2.500000 0.200000 0.000000
129 | 0.300000 0.000000 0.000000
130 | 1.640000 0.200000 0.000000
131 | 2.800000 0.200000 0.000000
132 | 1.480000 0.200000 0.000000
133 | 0.600000 0.060000 0.000000
134 | 0.840000 0.200000 0.000000
135 | 2.560000 0.200000 0.000000
136 | 2.140000 0.200000 0.000000
137 | 0.980000 0.200000 0.000000
138 | 1.700000 0.200000 0.000000
139 | 0.340000 0.000000 0.000000
140 | 2.660000 0.200000 0.000000
141 | 2.440000 0.200000 0.000000
142 | 0.560000 0.000000 0.000000
143 | 2.620000 0.200000 0.000000
144 | 2.820000 0.200000 0.000000
145 | 0.600000 0.200000 0.000000
146 | 0.180000 0.000000 0.000000
147 | 0.320000 0.000000 0.000000
148 | 1.940000 0.200000 0.000000
149 | 1.380000 0.200000 0.000000
150 | 0.260000 0.000000 0.000000
151 | 0.100000 0.000000 0.000000
152 | 0.120000 0.000000 0.000000
153 | 0.420000 0.000000 0.000000
154 | 2.960000 0.200000 0.000000
155 | 0.060000 0.000000 0.000000
156 | 1.840000 0.200000 0.000000
157 | 2.580000 0.200000 0.000000
158 | 1.420000 0.200000 0.000000
159 | 2.900000 0.200000 0.000000
160 | 2.160000 0.200000 0.000000
161 | 0.680000 0.200000 0.000000
162 | 2.400000 0.200000 0.000000
163 | 0.500000 0.000000 0.000000
164 | 0.860000 0.200000 0.000000
165 | 0.920000 0.200000 0.000000
166 | 2.480000 0.200000 0.000000
167 |
168 | CELLS 160 480
169 | 2 12 83
170 | 2 83 116
171 | 2 116 127
172 | 2 127 65
173 | 2 65 57
174 | 2 57 89
175 | 2 89 45
176 | 2 45 118
177 | 2 118 25
178 | 2 25 139
179 | 2 105 98
180 | 2 98 16
181 | 2 16 149
182 | 2 149 29
183 | 2 29 145
184 | 2 145 146
185 | 2 146 41
186 | 2 41 42
187 | 2 42 140
188 | 2 140 7
189 | 2 7 2
190 | 2 2 49
191 | 2 49 144
192 | 2 144 80
193 | 2 80 123
194 | 2 123 141
195 | 2 141 133
196 | 2 133 28
197 | 2 28 60
198 | 2 60 46
199 | 2 46 147
200 | 2 147 21
201 | 2 21 26
202 | 2 26 87
203 | 2 87 157
204 | 2 157 74
205 | 2 74 101
206 | 2 101 136
207 | 2 136 119
208 | 2 119 12
209 | 2 139 84
210 | 2 84 14
211 | 2 14 63
212 | 2 63 155
213 | 2 155 72
214 | 2 72 110
215 | 2 110 51
216 | 2 51 56
217 | 2 56 78
218 | 2 78 55
219 | 2 55 31
220 | 2 31 128
221 | 2 128 158
222 | 2 158 32
223 | 2 32 48
224 | 2 48 159
225 | 2 159 112
226 | 2 112 35
227 | 2 35 131
228 | 2 131 5
229 | 2 5 43
230 | 2 43 66
231 | 2 66 69
232 | 2 69 50
233 | 2 50 17
234 | 2 17 0
235 | 2 0 114
236 | 2 114 82
237 | 2 82 3
238 | 2 3 120
239 | 2 120 10
240 | 2 10 30
241 | 2 30 11
242 | 2 11 9
243 | 2 9 67
244 | 2 67 96
245 | 2 96 19
246 | 2 19 39
247 | 2 39 143
248 | 2 143 61
249 | 2 61 152
250 | 2 152 121
251 | 2 121 20
252 | 2 20 126
253 | 2 126 111
254 | 2 111 90
255 | 2 90 36
256 | 2 36 38
257 | 2 38 113
258 | 2 113 77
259 | 2 77 44
260 | 2 44 124
261 | 2 124 1
262 | 2 1 70
263 | 2 70 132
264 | 2 132 33
265 | 2 33 100
266 | 2 100 27
267 | 2 27 54
268 | 2 54 4
269 | 2 4 106
270 | 2 106 150
271 | 2 150 85
272 | 2 85 40
273 | 2 40 94
274 | 2 94 13
275 | 2 13 142
276 | 2 142 91
277 | 2 91 88
278 | 2 88 95
279 | 2 95 15
280 | 2 15 23
281 | 2 23 8
282 | 2 8 53
283 | 2 53 97
284 | 2 97 117
285 | 2 117 130
286 | 2 130 154
287 | 2 154 93
288 | 2 93 107
289 | 2 107 24
290 | 2 24 75
291 | 2 75 79
292 | 2 79 102
293 | 2 102 34
294 | 2 34 22
295 | 2 22 103
296 | 2 103 71
297 | 2 71 59
298 | 2 59 156
299 | 2 156 99
300 | 2 99 135
301 | 2 135 47
302 | 2 47 160
303 | 2 160 122
304 | 2 122 76
305 | 2 76 62
306 | 2 62 129
307 | 2 129 151
308 | 2 151 86
309 | 2 86 137
310 | 2 137 58
311 | 2 58 134
312 | 2 134 108
313 | 2 108 73
314 | 2 73 18
315 | 2 18 6
316 | 2 6 92
317 | 2 92 37
318 | 2 37 125
319 | 2 125 138
320 | 2 138 104
321 | 2 104 109
322 | 2 109 64
323 | 2 64 153
324 | 2 153 52
325 | 2 52 81
326 | 2 81 148
327 | 2 148 115
328 | 2 115 68
329 |
330 | CELL_TYPES 160
331 | 3
332 | 3
333 | 3
334 | 3
335 | 3
336 | 3
337 | 3
338 | 3
339 | 3
340 | 3
341 | 3
342 | 3
343 | 3
344 | 3
345 | 3
346 | 3
347 | 3
348 | 3
349 | 3
350 | 3
351 | 3
352 | 3
353 | 3
354 | 3
355 | 3
356 | 3
357 | 3
358 | 3
359 | 3
360 | 3
361 | 3
362 | 3
363 | 3
364 | 3
365 | 3
366 | 3
367 | 3
368 | 3
369 | 3
370 | 3
371 | 3
372 | 3
373 | 3
374 | 3
375 | 3
376 | 3
377 | 3
378 | 3
379 | 3
380 | 3
381 | 3
382 | 3
383 | 3
384 | 3
385 | 3
386 | 3
387 | 3
388 | 3
389 | 3
390 | 3
391 | 3
392 | 3
393 | 3
394 | 3
395 | 3
396 | 3
397 | 3
398 | 3
399 | 3
400 | 3
401 | 3
402 | 3
403 | 3
404 | 3
405 | 3
406 | 3
407 | 3
408 | 3
409 | 3
410 | 3
411 | 3
412 | 3
413 | 3
414 | 3
415 | 3
416 | 3
417 | 3
418 | 3
419 | 3
420 | 3
421 | 3
422 | 3
423 | 3
424 | 3
425 | 3
426 | 3
427 | 3
428 | 3
429 | 3
430 | 3
431 | 3
432 | 3
433 | 3
434 | 3
435 | 3
436 | 3
437 | 3
438 | 3
439 | 3
440 | 3
441 | 3
442 | 3
443 | 3
444 | 3
445 | 3
446 | 3
447 | 3
448 | 3
449 | 3
450 | 3
451 | 3
452 | 3
453 | 3
454 | 3
455 | 3
456 | 3
457 | 3
458 | 3
459 | 3
460 | 3
461 | 3
462 | 3
463 | 3
464 | 3
465 | 3
466 | 3
467 | 3
468 | 3
469 | 3
470 | 3
471 | 3
472 | 3
473 | 3
474 | 3
475 | 3
476 | 3
477 | 3
478 | 3
479 | 3
480 | 3
481 | 3
482 | 3
483 | 3
484 | 3
485 | 3
486 | 3
487 | 3
488 | 3
489 | 3
490 | 3
491 |
492 |
--------------------------------------------------------------------------------
/mesh_Inlet.vtk:
--------------------------------------------------------------------------------
1 | # vtk DataFile Version 2.0
2 | Block Mesh
3 | ASCII
4 | DATASET UNSTRUCTURED_GRID
5 | POINTS 51 double
6 | 0.000000 0.220000 0.000000
7 | 0.000000 0.700000 0.000000
8 | 0.000000 0.660000 0.000000
9 | 0.000000 0.440000 0.000000
10 | 0.000000 0.640000 0.000000
11 | 0.000000 0.900000 0.000000
12 | 0.000000 0.960000 0.000000
13 | 0.000000 0.020000 0.000000
14 | 0.000000 0.280000 0.000000
15 | 0.000000 0.800000 0.000000
16 | 0.000000 0.380000 0.000000
17 | 0.000000 0.000000 0.000000
18 | 0.000000 0.480000 0.000000
19 | 0.000000 0.560000 0.000000
20 | 0.000000 0.160000 0.000000
21 | 0.000000 0.500000 0.000000
22 | 0.000000 0.240000 0.000000
23 | 0.000000 0.820000 0.000000
24 | 0.000000 0.780000 0.000000
25 | 0.000000 0.940000 0.000000
26 | 0.000000 0.180000 0.000000
27 | 0.000000 0.460000 0.000000
28 | 0.000000 0.540000 0.000000
29 | 0.000000 0.620000 0.000000
30 | 0.000000 0.600000 0.000000
31 | 0.000000 0.120000 0.000000
32 | 0.000000 0.880000 0.000000
33 | 0.000000 0.400000 0.000000
34 | 0.000000 0.200000 0.000000
35 | 0.000000 0.340000 0.000000
36 | 0.000000 0.920000 0.000000
37 | 0.000000 0.580000 0.000000
38 | 0.000000 0.520000 0.000000
39 | 0.000000 0.980000 0.000000
40 | 0.000000 0.860000 0.000000
41 | 0.000000 0.360000 0.000000
42 | 0.000000 1.000000 0.000000
43 | 0.000000 0.080000 0.000000
44 | 0.000000 0.420000 0.000000
45 | 0.000000 0.840000 0.000000
46 | 0.000000 0.740000 0.000000
47 | 0.000000 0.300000 0.000000
48 | 0.000000 0.720000 0.000000
49 | 0.000000 0.100000 0.000000
50 | 0.000000 0.260000 0.000000
51 | 0.000000 0.320000 0.000000
52 | 0.000000 0.040000 0.000000
53 | 0.000000 0.060000 0.000000
54 | 0.000000 0.680000 0.000000
55 | 0.000000 0.760000 0.000000
56 | 0.000000 0.140000 0.000000
57 |
58 | CELLS 50 150
59 | 2 11 7
60 | 2 7 46
61 | 2 46 47
62 | 2 47 37
63 | 2 37 43
64 | 2 43 25
65 | 2 25 50
66 | 2 50 14
67 | 2 14 20
68 | 2 20 28
69 | 2 28 0
70 | 2 0 16
71 | 2 16 44
72 | 2 44 8
73 | 2 8 41
74 | 2 41 45
75 | 2 45 29
76 | 2 29 35
77 | 2 35 10
78 | 2 10 27
79 | 2 27 38
80 | 2 38 3
81 | 2 3 21
82 | 2 21 12
83 | 2 12 15
84 | 2 15 32
85 | 2 32 22
86 | 2 22 13
87 | 2 13 31
88 | 2 31 24
89 | 2 24 23
90 | 2 23 4
91 | 2 4 2
92 | 2 2 48
93 | 2 48 1
94 | 2 1 42
95 | 2 42 40
96 | 2 40 49
97 | 2 49 18
98 | 2 18 9
99 | 2 9 17
100 | 2 17 39
101 | 2 39 34
102 | 2 34 26
103 | 2 26 5
104 | 2 5 30
105 | 2 30 19
106 | 2 19 6
107 | 2 6 33
108 | 2 33 36
109 |
110 | CELL_TYPES 50
111 | 3
112 | 3
113 | 3
114 | 3
115 | 3
116 | 3
117 | 3
118 | 3
119 | 3
120 | 3
121 | 3
122 | 3
123 | 3
124 | 3
125 | 3
126 | 3
127 | 3
128 | 3
129 | 3
130 | 3
131 | 3
132 | 3
133 | 3
134 | 3
135 | 3
136 | 3
137 | 3
138 | 3
139 | 3
140 | 3
141 | 3
142 | 3
143 | 3
144 | 3
145 | 3
146 | 3
147 | 3
148 | 3
149 | 3
150 | 3
151 | 3
152 | 3
153 | 3
154 | 3
155 | 3
156 | 3
157 | 3
158 | 3
159 | 3
160 | 3
161 |
162 |
--------------------------------------------------------------------------------
/mesh_Outlet.vtk:
--------------------------------------------------------------------------------
1 | # vtk DataFile Version 2.0
2 | Block Mesh
3 | ASCII
4 | DATASET UNSTRUCTURED_GRID
5 | POINTS 41 double
6 | 3.000000 0.760000 0.000000
7 | 3.000000 0.860000 0.000000
8 | 3.000000 0.980000 0.000000
9 | 3.000000 0.500000 0.000000
10 | 3.000000 0.420000 0.000000
11 | 3.000000 0.900000 0.000000
12 | 3.000000 0.960000 0.000000
13 | 3.000000 0.640000 0.000000
14 | 3.000000 0.720000 0.000000
15 | 3.000000 0.580000 0.000000
16 | 3.000000 0.520000 0.000000
17 | 3.000000 0.460000 0.000000
18 | 3.000000 0.240000 0.000000
19 | 3.000000 0.880000 0.000000
20 | 3.000000 0.360000 0.000000
21 | 3.000000 0.820000 0.000000
22 | 3.000000 0.260000 0.000000
23 | 3.000000 0.540000 0.000000
24 | 3.000000 0.660000 0.000000
25 | 3.000000 0.480000 0.000000
26 | 3.000000 0.340000 0.000000
27 | 3.000000 1.000000 0.000000
28 | 3.000000 0.200000 0.000000
29 | 3.000000 0.620000 0.000000
30 | 3.000000 0.400000 0.000000
31 | 3.000000 0.440000 0.000000
32 | 3.000000 0.300000 0.000000
33 | 3.000000 0.380000 0.000000
34 | 3.000000 0.700000 0.000000
35 | 3.000000 0.920000 0.000000
36 | 3.000000 0.940000 0.000000
37 | 3.000000 0.320000 0.000000
38 | 3.000000 0.840000 0.000000
39 | 3.000000 0.280000 0.000000
40 | 3.000000 0.680000 0.000000
41 | 3.000000 0.780000 0.000000
42 | 3.000000 0.560000 0.000000
43 | 3.000000 0.220000 0.000000
44 | 3.000000 0.600000 0.000000
45 | 3.000000 0.800000 0.000000
46 | 3.000000 0.740000 0.000000
47 |
48 | CELLS 40 120
49 | 2 22 37
50 | 2 37 12
51 | 2 12 16
52 | 2 16 33
53 | 2 33 26
54 | 2 26 31
55 | 2 31 20
56 | 2 20 14
57 | 2 14 27
58 | 2 27 24
59 | 2 24 4
60 | 2 4 25
61 | 2 25 11
62 | 2 11 19
63 | 2 19 3
64 | 2 3 10
65 | 2 10 17
66 | 2 17 36
67 | 2 36 9
68 | 2 9 38
69 | 2 38 23
70 | 2 23 7
71 | 2 7 18
72 | 2 18 34
73 | 2 34 28
74 | 2 28 8
75 | 2 8 40
76 | 2 40 0
77 | 2 0 35
78 | 2 35 39
79 | 2 39 15
80 | 2 15 32
81 | 2 32 1
82 | 2 1 13
83 | 2 13 5
84 | 2 5 29
85 | 2 29 30
86 | 2 30 6
87 | 2 6 2
88 | 2 2 21
89 |
90 | CELL_TYPES 40
91 | 3
92 | 3
93 | 3
94 | 3
95 | 3
96 | 3
97 | 3
98 | 3
99 | 3
100 | 3
101 | 3
102 | 3
103 | 3
104 | 3
105 | 3
106 | 3
107 | 3
108 | 3
109 | 3
110 | 3
111 | 3
112 | 3
113 | 3
114 | 3
115 | 3
116 | 3
117 | 3
118 | 3
119 | 3
120 | 3
121 | 3
122 | 3
123 | 3
124 | 3
125 | 3
126 | 3
127 | 3
128 | 3
129 | 3
130 | 3
131 |
132 |
--------------------------------------------------------------------------------
/mesh_TopWall.vtk:
--------------------------------------------------------------------------------
1 | # vtk DataFile Version 2.0
2 | Block Mesh
3 | ASCII
4 | DATASET UNSTRUCTURED_GRID
5 | POINTS 151 double
6 | 0.320000 1.000000 0.000000
7 | 2.020000 1.000000 0.000000
8 | 1.340000 1.000000 0.000000
9 | 0.120000 1.000000 0.000000
10 | 0.660000 1.000000 0.000000
11 | 2.060000 1.000000 0.000000
12 | 2.660000 1.000000 0.000000
13 | 2.800000 1.000000 0.000000
14 | 0.340000 1.000000 0.000000
15 | 1.220000 1.000000 0.000000
16 | 0.500000 1.000000 0.000000
17 | 0.640000 1.000000 0.000000
18 | 0.460000 1.000000 0.000000
19 | 2.080000 1.000000 0.000000
20 | 0.600000 1.000000 0.000000
21 | 0.940000 1.000000 0.000000
22 | 0.920000 1.000000 0.000000
23 | 2.680000 1.000000 0.000000
24 | 1.440000 1.000000 0.000000
25 | 0.580000 1.000000 0.000000
26 | 1.880000 1.000000 0.000000
27 | 2.260000 1.000000 0.000000
28 | 0.200000 1.000000 0.000000
29 | 2.540000 1.000000 0.000000
30 | 0.440000 1.000000 0.000000
31 | 1.320000 1.000000 0.000000
32 | 2.940000 1.000000 0.000000
33 | 0.220000 1.000000 0.000000
34 | 0.740000 1.000000 0.000000
35 | 2.320000 1.000000 0.000000
36 | 1.080000 1.000000 0.000000
37 | 1.180000 1.000000 0.000000
38 | 1.740000 1.000000 0.000000
39 | 0.700000 1.000000 0.000000
40 | 1.820000 1.000000 0.000000
41 | 0.100000 1.000000 0.000000
42 | 0.840000 1.000000 0.000000
43 | 0.800000 1.000000 0.000000
44 | 2.000000 1.000000 0.000000
45 | 2.600000 1.000000 0.000000
46 | 1.540000 1.000000 0.000000
47 | 1.800000 1.000000 0.000000
48 | 1.760000 1.000000 0.000000
49 | 1.020000 1.000000 0.000000
50 | 1.860000 1.000000 0.000000
51 | 0.300000 1.000000 0.000000
52 | 1.140000 1.000000 0.000000
53 | 0.900000 1.000000 0.000000
54 | 2.880000 1.000000 0.000000
55 | 1.200000 1.000000 0.000000
56 | 1.940000 1.000000 0.000000
57 | 2.280000 1.000000 0.000000
58 | 1.120000 1.000000 0.000000
59 | 0.420000 1.000000 0.000000
60 | 1.620000 1.000000 0.000000
61 | 0.480000 1.000000 0.000000
62 | 0.680000 1.000000 0.000000
63 | 2.380000 1.000000 0.000000
64 | 1.100000 1.000000 0.000000
65 | 2.900000 1.000000 0.000000
66 | 0.780000 1.000000 0.000000
67 | 1.980000 1.000000 0.000000
68 | 0.000000 1.000000 0.000000
69 | 2.200000 1.000000 0.000000
70 | 0.860000 1.000000 0.000000
71 | 2.340000 1.000000 0.000000
72 | 2.480000 1.000000 0.000000
73 | 2.620000 1.000000 0.000000
74 | 1.480000 1.000000 0.000000
75 | 0.620000 1.000000 0.000000
76 | 0.260000 1.000000 0.000000
77 | 1.380000 1.000000 0.000000
78 | 2.300000 1.000000 0.000000
79 | 0.980000 1.000000 0.000000
80 | 0.760000 1.000000 0.000000
81 | 1.900000 1.000000 0.000000
82 | 2.220000 1.000000 0.000000
83 | 0.720000 1.000000 0.000000
84 | 1.420000 1.000000 0.000000
85 | 2.960000 1.000000 0.000000
86 | 1.000000 1.000000 0.000000
87 | 0.160000 1.000000 0.000000
88 | 1.600000 1.000000 0.000000
89 | 1.840000 1.000000 0.000000
90 | 2.180000 1.000000 0.000000
91 | 1.720000 1.000000 0.000000
92 | 0.240000 1.000000 0.000000
93 | 1.920000 1.000000 0.000000
94 | 0.520000 1.000000 0.000000
95 | 2.740000 1.000000 0.000000
96 | 0.040000 1.000000 0.000000
97 | 2.500000 1.000000 0.000000
98 | 2.140000 1.000000 0.000000
99 | 1.400000 1.000000 0.000000
100 | 2.460000 1.000000 0.000000
101 | 2.780000 1.000000 0.000000
102 | 2.040000 1.000000 0.000000
103 | 0.360000 1.000000 0.000000
104 | 2.520000 1.000000 0.000000
105 | 2.160000 1.000000 0.000000
106 | 0.080000 1.000000 0.000000
107 | 1.640000 1.000000 0.000000
108 | 2.580000 1.000000 0.000000
109 | 2.560000 1.000000 0.000000
110 | 0.540000 1.000000 0.000000
111 | 2.100000 1.000000 0.000000
112 | 1.240000 1.000000 0.000000
113 | 1.040000 1.000000 0.000000
114 | 2.700000 1.000000 0.000000
115 | 2.420000 1.000000 0.000000
116 | 0.560000 1.000000 0.000000
117 | 1.460000 1.000000 0.000000
118 | 1.060000 1.000000 0.000000
119 | 2.920000 1.000000 0.000000
120 | 0.400000 1.000000 0.000000
121 | 1.660000 1.000000 0.000000
122 | 2.640000 1.000000 0.000000
123 | 0.880000 1.000000 0.000000
124 | 1.560000 1.000000 0.000000
125 | 1.680000 1.000000 0.000000
126 | 2.440000 1.000000 0.000000
127 | 0.140000 1.000000 0.000000
128 | 1.160000 1.000000 0.000000
129 | 1.700000 1.000000 0.000000
130 | 2.720000 1.000000 0.000000
131 | 0.820000 1.000000 0.000000
132 | 1.280000 1.000000 0.000000
133 | 1.300000 1.000000 0.000000
134 | 0.020000 1.000000 0.000000
135 | 1.520000 1.000000 0.000000
136 | 0.060000 1.000000 0.000000
137 | 1.360000 1.000000 0.000000
138 | 2.820000 1.000000 0.000000
139 | 2.860000 1.000000 0.000000
140 | 2.980000 1.000000 0.000000
141 | 0.280000 1.000000 0.000000
142 | 3.000000 1.000000 0.000000
143 | 0.960000 1.000000 0.000000
144 | 2.400000 1.000000 0.000000
145 | 1.580000 1.000000 0.000000
146 | 1.260000 1.000000 0.000000
147 | 2.840000 1.000000 0.000000
148 | 1.960000 1.000000 0.000000
149 | 2.360000 1.000000 0.000000
150 | 0.380000 1.000000 0.000000
151 | 2.760000 1.000000 0.000000
152 | 1.780000 1.000000 0.000000
153 | 2.240000 1.000000 0.000000
154 | 0.180000 1.000000 0.000000
155 | 1.500000 1.000000 0.000000
156 | 2.120000 1.000000 0.000000
157 |
158 | CELLS 150 450
159 | 2 62 128
160 | 2 128 90
161 | 2 90 130
162 | 2 130 100
163 | 2 100 35
164 | 2 35 3
165 | 2 3 121
166 | 2 121 81
167 | 2 81 148
168 | 2 148 22
169 | 2 22 27
170 | 2 27 86
171 | 2 86 70
172 | 2 70 135
173 | 2 135 45
174 | 2 45 0
175 | 2 0 8
176 | 2 8 97
177 | 2 97 144
178 | 2 144 114
179 | 2 114 53
180 | 2 53 24
181 | 2 24 12
182 | 2 12 55
183 | 2 55 10
184 | 2 10 88
185 | 2 88 104
186 | 2 104 110
187 | 2 110 19
188 | 2 19 14
189 | 2 14 69
190 | 2 69 11
191 | 2 11 4
192 | 2 4 56
193 | 2 56 33
194 | 2 33 77
195 | 2 77 28
196 | 2 28 74
197 | 2 74 60
198 | 2 60 37
199 | 2 37 125
200 | 2 125 36
201 | 2 36 64
202 | 2 64 117
203 | 2 117 47
204 | 2 47 16
205 | 2 16 15
206 | 2 15 137
207 | 2 137 73
208 | 2 73 80
209 | 2 80 43
210 | 2 43 107
211 | 2 107 112
212 | 2 112 30
213 | 2 30 58
214 | 2 58 52
215 | 2 52 46
216 | 2 46 122
217 | 2 122 31
218 | 2 31 49
219 | 2 49 9
220 | 2 9 106
221 | 2 106 140
222 | 2 140 126
223 | 2 126 127
224 | 2 127 25
225 | 2 25 2
226 | 2 2 131
227 | 2 131 71
228 | 2 71 93
229 | 2 93 78
230 | 2 78 18
231 | 2 18 111
232 | 2 111 68
233 | 2 68 149
234 | 2 149 129
235 | 2 129 40
236 | 2 40 118
237 | 2 118 139
238 | 2 139 82
239 | 2 82 54
240 | 2 54 101
241 | 2 101 115
242 | 2 115 119
243 | 2 119 123
244 | 2 123 85
245 | 2 85 32
246 | 2 32 42
247 | 2 42 146
248 | 2 146 41
249 | 2 41 34
250 | 2 34 83
251 | 2 83 44
252 | 2 44 20
253 | 2 20 75
254 | 2 75 87
255 | 2 87 50
256 | 2 50 142
257 | 2 142 61
258 | 2 61 38
259 | 2 38 1
260 | 2 1 96
261 | 2 96 5
262 | 2 5 13
263 | 2 13 105
264 | 2 105 150
265 | 2 150 92
266 | 2 92 99
267 | 2 99 84
268 | 2 84 63
269 | 2 63 76
270 | 2 76 147
271 | 2 147 21
272 | 2 21 51
273 | 2 51 72
274 | 2 72 29
275 | 2 29 65
276 | 2 65 143
277 | 2 143 57
278 | 2 57 138
279 | 2 138 109
280 | 2 109 120
281 | 2 120 94
282 | 2 94 66
283 | 2 66 91
284 | 2 91 98
285 | 2 98 23
286 | 2 23 103
287 | 2 103 102
288 | 2 102 39
289 | 2 39 67
290 | 2 67 116
291 | 2 116 6
292 | 2 6 17
293 | 2 17 108
294 | 2 108 124
295 | 2 124 89
296 | 2 89 145
297 | 2 145 95
298 | 2 95 7
299 | 2 7 132
300 | 2 132 141
301 | 2 141 133
302 | 2 133 48
303 | 2 48 59
304 | 2 59 113
305 | 2 113 26
306 | 2 26 79
307 | 2 79 134
308 | 2 134 136
309 |
310 | CELL_TYPES 150
311 | 3
312 | 3
313 | 3
314 | 3
315 | 3
316 | 3
317 | 3
318 | 3
319 | 3
320 | 3
321 | 3
322 | 3
323 | 3
324 | 3
325 | 3
326 | 3
327 | 3
328 | 3
329 | 3
330 | 3
331 | 3
332 | 3
333 | 3
334 | 3
335 | 3
336 | 3
337 | 3
338 | 3
339 | 3
340 | 3
341 | 3
342 | 3
343 | 3
344 | 3
345 | 3
346 | 3
347 | 3
348 | 3
349 | 3
350 | 3
351 | 3
352 | 3
353 | 3
354 | 3
355 | 3
356 | 3
357 | 3
358 | 3
359 | 3
360 | 3
361 | 3
362 | 3
363 | 3
364 | 3
365 | 3
366 | 3
367 | 3
368 | 3
369 | 3
370 | 3
371 | 3
372 | 3
373 | 3
374 | 3
375 | 3
376 | 3
377 | 3
378 | 3
379 | 3
380 | 3
381 | 3
382 | 3
383 | 3
384 | 3
385 | 3
386 | 3
387 | 3
388 | 3
389 | 3
390 | 3
391 | 3
392 | 3
393 | 3
394 | 3
395 | 3
396 | 3
397 | 3
398 | 3
399 | 3
400 | 3
401 | 3
402 | 3
403 | 3
404 | 3
405 | 3
406 | 3
407 | 3
408 | 3
409 | 3
410 | 3
411 | 3
412 | 3
413 | 3
414 | 3
415 | 3
416 | 3
417 | 3
418 | 3
419 | 3
420 | 3
421 | 3
422 | 3
423 | 3
424 | 3
425 | 3
426 | 3
427 | 3
428 | 3
429 | 3
430 | 3
431 | 3
432 | 3
433 | 3
434 | 3
435 | 3
436 | 3
437 | 3
438 | 3
439 | 3
440 | 3
441 | 3
442 | 3
443 | 3
444 | 3
445 | 3
446 | 3
447 | 3
448 | 3
449 | 3
450 | 3
451 | 3
452 | 3
453 | 3
454 | 3
455 | 3
456 | 3
457 | 3
458 | 3
459 | 3
460 | 3
461 |
462 |
--------------------------------------------------------------------------------
/nbproject/genfiles.properties:
--------------------------------------------------------------------------------
1 | build.xml.data.CRC32=74e503e6
2 | build.xml.script.CRC32=b93a467b
3 | build.xml.stylesheet.CRC32=8064a381@1.79.1.48
4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
6 | nbproject/build-impl.xml.data.CRC32=74e503e6
7 | nbproject/build-impl.xml.script.CRC32=551d9421
8 | nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
9 |
--------------------------------------------------------------------------------
/nbproject/private/private.properties:
--------------------------------------------------------------------------------
1 | compile.on.save=true
2 | user.properties.file=/home/sourabh/.netbeans/8.1/build.properties
3 |
--------------------------------------------------------------------------------
/nbproject/project.properties:
--------------------------------------------------------------------------------
1 | annotation.processing.enabled=true
2 | annotation.processing.enabled.in.editor=false
3 | annotation.processing.processor.options=
4 | annotation.processing.processors.list=
5 | annotation.processing.run.all.processors=true
6 | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
7 | build.classes.dir=${build.dir}/classes
8 | build.classes.excludes=**/*.java,**/*.form
9 | # This directory is removed when the project is cleaned:
10 | build.dir=build
11 | build.generated.dir=${build.dir}/generated
12 | build.generated.sources.dir=${build.dir}/generated-sources
13 | # Only compile against the classpath explicitly listed here:
14 | build.sysclasspath=ignore
15 | build.test.classes.dir=${build.dir}/test/classes
16 | build.test.results.dir=${build.dir}/test/results
17 | # Uncomment to specify the preferred debugger connection transport:
18 | #debug.transport=dt_socket
19 | debug.classpath=\
20 | ${run.classpath}
21 | debug.test.classpath=\
22 | ${run.test.classpath}
23 | # Files in build.classes.dir which should be excluded from distribution jar
24 | dist.archive.excludes=
25 | # This directory is removed when the project is cleaned:
26 | dist.dir=dist
27 | dist.jar=${dist.dir}/StructuredMeshGenerator2D.jar
28 | dist.javadoc.dir=${dist.dir}/javadoc
29 | excludes=
30 | includes=**
31 | jar.compress=false
32 | javac.classpath=
33 | # Space-separated list of extra javac options
34 | javac.compilerargs=
35 | javac.deprecation=false
36 | javac.external.vm=true
37 | javac.processorpath=\
38 | ${javac.classpath}
39 | javac.source=1.8
40 | javac.target=1.8
41 | javac.test.classpath=\
42 | ${javac.classpath}:\
43 | ${build.classes.dir}
44 | javac.test.processorpath=\
45 | ${javac.test.classpath}
46 | javadoc.additionalparam=
47 | javadoc.author=false
48 | javadoc.encoding=${source.encoding}
49 | javadoc.noindex=false
50 | javadoc.nonavbar=false
51 | javadoc.notree=false
52 | javadoc.private=false
53 | javadoc.splitindex=true
54 | javadoc.use=true
55 | javadoc.version=false
56 | javadoc.windowtitle=
57 | main.class=main.StructuredMeshGenerator2D
58 | manifest.file=manifest.mf
59 | meta.inf.dir=${src.dir}/META-INF
60 | mkdist.disabled=false
61 | platform.active=default_platform
62 | run.classpath=\
63 | ${javac.classpath}:\
64 | ${build.classes.dir}
65 | # Space-separated list of JVM arguments used when running the project.
66 | # You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
67 | # To set system properties for unit tests define test-sys-prop.name=value:
68 | run.jvmargs=
69 | run.test.classpath=\
70 | ${javac.test.classpath}:\
71 | ${build.test.classes.dir}
72 | source.encoding=UTF-8
73 | src.dir=src
74 | test.src.dir=test
75 |
--------------------------------------------------------------------------------
/nbproject/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.netbeans.modules.java.j2seproject
4 |
5 |
6 | StructuredMeshGenerator2D
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/geometry/Angle.java:
--------------------------------------------------------------------------------
1 | package geometry;
2 |
3 | /**
4 | *
5 | * @author Sourabh Bhat
6 | */
7 | public class Angle {
8 |
9 | private final double radians;
10 |
11 | private Angle(double radians) {
12 | this.radians = radians;
13 | }
14 |
15 | public static Angle inRadians(double radians) {
16 | return new Angle(radians);
17 | }
18 |
19 | public static Angle inDegrees(double degrees) {
20 | return new Angle(Math.toRadians(degrees));
21 | }
22 |
23 | public double inRadians() {
24 | return radians;
25 | }
26 |
27 | public double inDegrees() {
28 | return Math.toDegrees(radians);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/geometry/Geometry.java:
--------------------------------------------------------------------------------
1 | package geometry;
2 |
3 | import mesh.Parameter;
4 |
5 | /**
6 | *
7 | * @author Sourabh Bhat
8 | */
9 | public interface Geometry {
10 |
11 | public Point xi_0(Parameter eta);
12 |
13 | public Point xi_1(Parameter eta);
14 |
15 | public Point eta_0(Parameter xi);
16 |
17 | public Point eta_1(Parameter xi);
18 | }
19 |
--------------------------------------------------------------------------------
/src/geometry/GeometryFromFile.java:
--------------------------------------------------------------------------------
1 | package geometry;
2 |
3 | import io.GeometryFileReader;
4 | import java.io.File;
5 | import java.io.FileNotFoundException;
6 | import java.util.stream.IntStream;
7 | import mesh.Parameter;
8 | import util.Range;
9 |
10 | /**
11 | *
12 | * @author Sourabh Bhat
13 | */
14 | public class GeometryFromFile implements Geometry {
15 |
16 | private static final double TOLERANCE = 1e-8;
17 |
18 | private final Point[] points_xi_0;
19 | private final Point[] points_xi_1;
20 | private final Point[] points_eta_0;
21 | private final Point[] points_eta_1;
22 |
23 | private final double[] xi_0_map, xi_1_map, eta_0_map, eta_1_map;
24 |
25 | public GeometryFromFile(File file) throws FileNotFoundException {
26 | points_xi_0 = GeometryFileReader.readPoints(file, GeometryFileReader.SideLabel.xi_0);
27 | points_xi_1 = GeometryFileReader.readPoints(file, GeometryFileReader.SideLabel.xi_1);
28 | points_eta_0 = GeometryFileReader.readPoints(file, GeometryFileReader.SideLabel.eta_0);
29 | points_eta_1 = GeometryFileReader.readPoints(file, GeometryFileReader.SideLabel.eta_1);
30 |
31 | if (points_xi_0.length < 2 || points_xi_1.length < 2
32 | || points_eta_0.length < 2 || points_eta_1.length < 2) {
33 | throw new IllegalArgumentException("The number of points per side must be at least 2.");
34 | }
35 |
36 | // Check continuity of geometry
37 | if (!overlapping(points_xi_0[0], points_eta_0[0])
38 | || !overlapping(points_xi_0[points_xi_0.length - 1], points_eta_1[0])
39 | || !overlapping(points_xi_1[0], points_eta_0[points_eta_0.length - 1])
40 | || !overlapping(points_xi_1[points_xi_1.length - 1], points_eta_1[points_eta_1.length - 1])) {
41 | throw new IllegalArgumentException("The geometry points supplied do not overlap properly.");
42 | }
43 |
44 | // create the mapping between points and parameters
45 | xi_0_map = calculateParameterMapping(points_xi_0);
46 | xi_1_map = calculateParameterMapping(points_xi_1);
47 | eta_0_map = calculateParameterMapping(points_eta_0);
48 | eta_1_map = calculateParameterMapping(points_eta_1);
49 | }
50 |
51 | private double[] calculateParameterMapping(Point[] points) {
52 | double[] lengths = IntStream.range(1, points.length)
53 | .mapToDouble(i -> points[i].dist(points[i - 1]))
54 | .toArray();
55 |
56 | double[] cumLen = new double[points.length];
57 | cumLen[0] = 0.0;
58 | for (int i = 1; i < points.length; i++) {
59 | cumLen[i] = cumLen[i - 1] + lengths[i - 1];
60 | }
61 |
62 | for (int i = 0; i < cumLen.length; i++) {
63 | cumLen[i] = cumLen[i] / cumLen[cumLen.length - 1];
64 | }
65 |
66 | return cumLen;
67 | }
68 |
69 | private boolean overlapping(Point p1, Point p2) {
70 | if (p1.dist(p2) < TOLERANCE) {
71 | return true;
72 | } else {
73 | System.out.println(p1 + " does not overlap " + p2);
74 | return false;
75 | }
76 | }
77 |
78 | private Point getPoint(Parameter parameter, double[] paramter_map, Point[] points) {
79 | // where does the parameter lie
80 | double parVal = parameter.value;
81 | int indexR = IntStream.range(1, paramter_map.length)
82 | .filter(i -> (paramter_map[i - 1] - TOLERANCE) < parVal && (paramter_map[i] + TOLERANCE) > parVal)
83 | .findFirst().getAsInt();
84 | int indexL = indexR - 1;
85 | double parL = paramter_map[indexL];
86 | double parR = paramter_map[indexR];
87 | Point pointL = points[indexL];
88 | Point pointR = points[indexR];
89 |
90 | double x = Range.map(parVal, new Range(parL, parR), new Range(pointL.x, pointR.x));
91 | double y = Range.map(parVal, new Range(parL, parR), new Range(pointL.y, pointR.y));
92 | return new Point(x, y);
93 | }
94 |
95 | @Override
96 | public Point xi_0(Parameter eta) {
97 | return getPoint(eta, xi_0_map, points_xi_0);
98 | }
99 |
100 | @Override
101 | public Point xi_1(Parameter eta) {
102 | return getPoint(eta, xi_1_map, points_xi_1);
103 | }
104 |
105 | @Override
106 | public Point eta_0(Parameter xi) {
107 | return getPoint(xi, eta_0_map, points_eta_0);
108 | }
109 |
110 | @Override
111 | public Point eta_1(Parameter xi) {
112 | return getPoint(xi, eta_1_map, points_eta_1);
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/geometry/ParametricCurve.java:
--------------------------------------------------------------------------------
1 | package geometry;
2 |
3 | import mesh.Parameter;
4 |
5 | /**
6 | *
7 | * @author Sourabh Bhat
8 | */
9 | @FunctionalInterface
10 | public interface ParametricCurve {
11 |
12 | public Point getPoint(Parameter parameter);
13 |
14 | default ParametricCurve reverse() {
15 | return parameter -> getPoint(new Parameter(1.0 - parameter.value));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/geometry/ParametricCurvesGeometry.java:
--------------------------------------------------------------------------------
1 | package geometry;
2 |
3 | import java.util.List;
4 | import mesh.Parameter;
5 |
6 | /**
7 | *
8 | * @author Sourabh Bhat
9 | */
10 | public class ParametricCurvesGeometry implements Geometry {
11 |
12 | private final List listCurves;
13 |
14 | /**
15 | * Geometry made up of a list of parametric curves.
16 | *
17 | * @param listCurves The curves provided must be in clockwise or
18 | * anti-clockwise direction
19 | */
20 | public ParametricCurvesGeometry(List listCurves) {
21 | if (listCurves.size() != 4) {
22 | throw new IllegalArgumentException("Exactly 4 curves are required to build the geometry.");
23 | }
24 | this.listCurves = listCurves;
25 | }
26 |
27 | @Override
28 | public Point xi_0(Parameter eta) {
29 | // index 3, curve reversed
30 | ParametricCurve curve = listCurves.get(3).reverse();
31 | return curve.getPoint(eta);
32 | }
33 |
34 | @Override
35 | public Point xi_1(Parameter eta) {
36 | // index 1
37 | ParametricCurve curve = listCurves.get(1);
38 | return curve.getPoint(eta);
39 | }
40 |
41 | @Override
42 | public Point eta_0(Parameter xi) {
43 | // index 0
44 | ParametricCurve curve = listCurves.get(0);
45 | return curve.getPoint(xi);
46 | }
47 |
48 | @Override
49 | public Point eta_1(Parameter xi) {
50 | // index 2, curve reversed
51 | ParametricCurve curve = listCurves.get(2).reverse();
52 | return curve.getPoint(xi);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/geometry/Point.java:
--------------------------------------------------------------------------------
1 | package geometry;
2 |
3 | /**
4 | *
5 | * @author Sourabh Bhat
6 | */
7 | public class Point {
8 |
9 | public final double x;
10 | public final double y;
11 |
12 | public Point(double x, double y) {
13 | this.x = x;
14 | this.y = y;
15 | }
16 |
17 | public Point mult(double scalar) {
18 | return new Point(x * scalar, y * scalar);
19 | }
20 |
21 | public Point add(Point p) {
22 | return new Point(x + p.x, y + p.y);
23 | }
24 |
25 | public Point sub(Point p) {
26 | return new Point(x - p.x, y - p.y);
27 | }
28 |
29 | public double dist(Point other) {
30 | double dx = other.x - x;
31 | double dy = other.y - y;
32 |
33 | return Math.sqrt(dx * dx + dy * dy);
34 | }
35 |
36 | @Override
37 | public String toString() {
38 | return " " + x + ", " + y + " ";
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/geometry/SimpleQuadGeometry.java:
--------------------------------------------------------------------------------
1 | package geometry;
2 |
3 | import mesh.Parameter;
4 | import util.Range;
5 |
6 | /**
7 | *
8 | * @author Sourabh Bhat
9 | */
10 | public class SimpleQuadGeometry implements Geometry {
11 |
12 | private final Point p1, p2, p3, p4;
13 | private final Range parameterRange;
14 |
15 | /**
16 | * Points p1, p2, p3 and p4 must be in a clockwise or anti-clockwise order.
17 | *
18 | * @param p1 Corner xi_0, eta_0
19 | * @param p2 Corner xi_1, eta_0
20 | * @param p3 Corner xi_1, eta_1
21 | * @param p4 Corner xi_0, eta_1
22 | */
23 | public SimpleQuadGeometry(Point p1, Point p2, Point p3, Point p4) {
24 | this.p1 = p1;
25 | this.p2 = p2;
26 | this.p3 = p3;
27 | this.p4 = p4;
28 |
29 | parameterRange = new Range(0, 1);
30 | }
31 |
32 | @Override
33 | public Point xi_0(Parameter eta) {
34 | return new Point(
35 | Range.map(eta.value, parameterRange, new Range(p1.x, p4.x)),
36 | Range.map(eta.value, parameterRange, new Range(p1.y, p4.y))
37 | );
38 | }
39 |
40 | @Override
41 | public Point xi_1(Parameter eta) {
42 | return new Point(
43 | Range.map(eta.value, parameterRange, new Range(p2.x, p3.x)),
44 | Range.map(eta.value, parameterRange, new Range(p2.y, p3.y))
45 | );
46 | }
47 |
48 | @Override
49 | public Point eta_0(Parameter xi) {
50 | return new Point(
51 | Range.map(xi.value, parameterRange, new Range(p1.x, p2.x)),
52 | Range.map(xi.value, parameterRange, new Range(p1.y, p2.y))
53 | );
54 | }
55 |
56 | @Override
57 | public Point eta_1(Parameter xi) {
58 | return new Point(
59 | Range.map(xi.value, parameterRange, new Range(p4.x, p3.x)),
60 | Range.map(xi.value, parameterRange, new Range(p4.y, p3.y))
61 | );
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/geometry/builder/Corner1.java:
--------------------------------------------------------------------------------
1 | package geometry.builder;
2 |
3 | import com.sun.istack.internal.Nullable;
4 | import geometry.Angle;
5 | import java.util.ArrayList;
6 | import java.util.List;
7 | import geometry.Point;
8 | import geometry.ParametricCurve;
9 |
10 | /**
11 | *
12 | * @author Sourabh Bhat
13 | */
14 | public class Corner1 {
15 |
16 | private final Point point1;
17 |
18 | Corner1(Point point1) {
19 | this.point1 = point1;
20 | }
21 |
22 | public Corner2 curveToCorner2(Point point2) {
23 | return curveToCorner2(point2, null, null);
24 | }
25 |
26 | public Corner2 curveToCorner2(Angle startAngle, Point point2) {
27 | return curveToCorner2(point2, startAngle, null);
28 | }
29 |
30 | public Corner2 curveToCorner2(Point point2, Angle endAngle) {
31 | return curveToCorner2(point2, null, endAngle);
32 | }
33 |
34 | public Corner2 curveToCorner2(Angle startAngle, Point point2, Angle endAngle) {
35 | return curveToCorner2(point2, startAngle, endAngle);
36 | }
37 |
38 | private Corner2 curveToCorner2(Point point2, @Nullable Angle startAngle, @Nullable Angle endAngle) {
39 | List listCurves = new ArrayList<>();
40 |
41 | listCurves.add(new CubicCurve(point1, point2, startAngle, endAngle));
42 |
43 | return new Corner2(point2, listCurves);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/geometry/builder/Corner2.java:
--------------------------------------------------------------------------------
1 | package geometry.builder;
2 |
3 | import com.sun.istack.internal.Nullable;
4 | import geometry.Angle;
5 | import java.util.List;
6 | import geometry.Point;
7 | import geometry.ParametricCurve;
8 |
9 | /**
10 | *
11 | * @author Sourabh Bhat
12 | */
13 | public class Corner2 {
14 |
15 | private final Point point2;
16 | private final List listCurves;
17 |
18 | Corner2(Point point2, List listCurves) {
19 | this.listCurves = listCurves;
20 | this.point2 = point2;
21 | }
22 |
23 | public Corner3 curveToCorner3(Point point3) {
24 | return curveToCorner3(point3, null, null);
25 | }
26 |
27 | public Corner3 curveToCorner3(Angle startAngle, Point point3) {
28 | return curveToCorner3(point3, startAngle, null);
29 | }
30 |
31 | public Corner3 curveToCorner3(Point point3, Angle endAngle) {
32 | return curveToCorner3(point3, null, endAngle);
33 | }
34 |
35 | public Corner3 curveToCorner3(Angle startAngle, Point point3, Angle endAngle) {
36 | return curveToCorner3(point3, startAngle, endAngle);
37 | }
38 |
39 | private Corner3 curveToCorner3(Point point3, @Nullable Angle startAngle, @Nullable Angle endAngle) {
40 | listCurves.add(new CubicCurve(point2, point3, startAngle, endAngle));
41 |
42 | return new Corner3(point3, listCurves);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/geometry/builder/Corner3.java:
--------------------------------------------------------------------------------
1 | package geometry.builder;
2 |
3 | import com.sun.istack.internal.Nullable;
4 | import geometry.Angle;
5 | import java.util.List;
6 | import geometry.Point;
7 | import geometry.ParametricCurve;
8 |
9 | /**
10 | *
11 | * @author Sourabh Bhat
12 | */
13 | public class Corner3 {
14 |
15 | private final Point point3;
16 | private final List listCurves;
17 |
18 | Corner3(Point point3, List listCurves) {
19 | this.point3 = point3;
20 | this.listCurves = listCurves;
21 | }
22 |
23 | public Corner4 curveToCorner4(Point point4) {
24 | return curveToCorner4(point4, null, null);
25 | }
26 |
27 | public Corner4 curveToCorner4(Angle startAngle, Point point4) {
28 | return curveToCorner4(point4, startAngle, null);
29 | }
30 |
31 | public Corner4 curveToCorner4(Point point4, Angle endAngle) {
32 | return curveToCorner4(point4, null, endAngle);
33 | }
34 |
35 | public Corner4 curveToCorner4(Angle startAngle, Point point4, Angle endAngle) {
36 | return curveToCorner4(point4, startAngle, endAngle);
37 | }
38 |
39 | private Corner4 curveToCorner4(Point point4, @Nullable Angle startAngle, @Nullable Angle endAngle) {
40 | listCurves.add(new CubicCurve(point3, point4, startAngle, endAngle));
41 |
42 | return new Corner4(point4, listCurves);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/geometry/builder/Corner4.java:
--------------------------------------------------------------------------------
1 | package geometry.builder;
2 |
3 | import com.sun.istack.internal.Nullable;
4 | import geometry.ParametricCurvesGeometry;
5 | import geometry.Angle;
6 | import geometry.Geometry;
7 | import java.util.List;
8 | import mesh.Parameter;
9 | import geometry.Point;
10 | import geometry.ParametricCurve;
11 |
12 | /**
13 | *
14 | * @author Sourabh Bhat
15 | */
16 | public class Corner4 {
17 |
18 | private final Point point4;
19 | private final List listCurves;
20 |
21 | Corner4(Point point4, List listCurves) {
22 | this.point4 = point4;
23 | this.listCurves = listCurves;
24 | }
25 |
26 | public Geometry close() {
27 | return close(null, null);
28 | }
29 |
30 | public Geometry close(@Nullable Angle startAngle, @Nullable Angle endAngle) {
31 | Point point1 = listCurves.get(0).getPoint(new Parameter(0));
32 |
33 | listCurves.add(new CubicCurve(point4, point1, startAngle, endAngle));
34 |
35 | return new ParametricCurvesGeometry(listCurves);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/geometry/builder/CubicCurve.java:
--------------------------------------------------------------------------------
1 | package geometry.builder;
2 |
3 | import com.sun.istack.internal.Nullable;
4 | import geometry.Angle;
5 | import mesh.Parameter;
6 | import geometry.Point;
7 | import util.Range;
8 | import geometry.ParametricCurve;
9 |
10 | /**
11 | *
12 | * @author Sourabh Bhat
13 | */
14 | public class CubicCurve implements ParametricCurve {
15 |
16 | private final Point p1, p2;
17 | private final Angle startAngle;
18 | private final Angle endAngle;
19 |
20 | public CubicCurve(Point p1, Point p2, @Nullable Angle startAngle, @Nullable Angle endAngle) {
21 | this.p1 = p1;
22 | this.p2 = p2;
23 | this.startAngle = startAngle;
24 | this.endAngle = endAngle;
25 | }
26 |
27 | @Override
28 | public Point getPoint(Parameter parameter) {
29 | // Both angles not defined so just a straight line
30 | if (startAngle == null && endAngle == null) {
31 | return new Point(
32 | Range.map(parameter.value, new Range(0, 1), new Range(p1.x, p2.x)),
33 | Range.map(parameter.value, new Range(0, 1), new Range(p1.y, p2.y))
34 | );
35 | } else if (startAngle != null && endAngle == null) {
36 | // Quadratic curve using start angle
37 | // eqn x : ax0 + ax1 * t + ax2 * t^2 = x
38 | // eqn dx/dt: ax1 + ax2 * 2 * t = dx/dt = cos(ang) * curve_length
39 | // eqn y : ay0 + ay1 * t + ay2 * t^2 = y
40 | // eqn dy/dt: ay1 + ay2 * 2 * t = dy/dt = sin(ang) * curve_length
41 |
42 | // @t=0, x=p1.x => ax0 = p1.x
43 | // @t=0, y=p1.y => ay0 = p1.y
44 | // @t=0, dx/dt=cos(startAng)*l => ax1 = cos(startAng)*l
45 | // @t=0, dy/dt=sin(startAng)*l => ay1 = sin(startAng)*l
46 | // @t=1, ax0 + ax1 + ax2 = p2.x => ax2 = p2.x - (ax0 + ax1)
47 | // @t=1, ay0 + ay1 + ay2 = p2.y => ay2 = p2.y - (ay0 + ay1)
48 | double l = p1.dist(p2); // Approximate curve length
49 |
50 | double ax0 = p1.x;
51 | double ax1 = Math.cos(startAngle.inRadians()) * l;
52 | double ax2 = p2.x - (ax0 + ax1);
53 |
54 | double ay0 = p1.y;
55 | double ay1 = Math.sin(startAngle.inRadians()) * l;
56 | double ay2 = p2.y - (ay0 + ay1);
57 |
58 | double t = parameter.value;
59 |
60 | double x = ax0 + ax1 * t + ax2 * t * t;
61 | double y = ay0 + ay1 * t + ay2 * t * t;
62 |
63 | return new Point(x, y);
64 | } else if (startAngle == null && endAngle != null) {
65 | // Quadratic curve using end angle
66 | // eqn x : ax0 + ax1 * t + ax2 * t^2 = x
67 | // eqn dx/dt: ax1 + ax2 * 2 * t = dx/dt = -cos(ang) * curve_length
68 | // eqn y : ay0 + ay1 * t + ay2 * t^2 = y
69 | // eqn dy/dt: ay1 + ay2 * 2 * t = dy/dt = -sin(ang) * curve_length
70 |
71 | // @t=0, x=p1.x => ax0 = p1.x
72 | // @t=0, y=p1.y => ay0 = p1.y
73 | // @t=1, dx/dt= -cos(ang)*l => ax1 + 2 * ax2 = -cos(endAng)*l
74 | // @t=1, ax0 + ax1 + ax2 = p2.x => ax1 = 2 * (p2.x - ax0 + cos(endAng)*l / 2)
75 | // @t=1, ax0 + ax1 + ax2 = p2.x => ax2 = p2.x - (ax0 + ax1)
76 | // Similiarly,
77 | // => ay1 = 2 * (p2.y - ay0 + sin(endAng)*l / 2)
78 | // => ay2 = p2.y - (ay0 + ay1)
79 | double l = p1.dist(p2); // Approximate curve length
80 |
81 | double ax0 = p1.x;
82 | double ax1 = 2.0 * (p2.x - ax0 + Math.cos(endAngle.inRadians()) * l / 2.0);
83 | double ax2 = p2.x - (ax0 + ax1);
84 |
85 | double ay0 = p1.y;
86 | double ay1 = 2.0 * (p2.y - ay0 + Math.sin(endAngle.inRadians()) * l / 2.0);
87 | double ay2 = p2.y - (ay0 + ay1);
88 |
89 | double t = parameter.value;
90 |
91 | double x = ax0 + ax1 * t + ax2 * t * t;
92 | double y = ay0 + ay1 * t + ay2 * t * t;
93 |
94 | return new Point(x, y);
95 | } else {
96 | // Cubic curve using both the start and the end angle
97 | // eqn x : ax0 + ax1 * t + ax2 * t^2 + ax3 * t^3 = x
98 | // eqn dx/dt: ax1 + ax2 * 2 * t + ax3 * 3 * t^2 = dx/dt = (-)cos(ang) * curve_length
99 | // eqn y : ay0 + ay1 * t + ay2 * t^2 + ay3 * t^3 = y
100 | // eqn dy/dt: ay1 + ay2 * 2 * t + ay3 * 3 * t^2 = dy/dt = (-)sin(ang) * curve_length
101 | // Solving the above equations with,
102 | // @t=0, x=p1.x
103 | // @t=0, ang=startAng
104 | // @t=1, x=p2.x
105 | // @t=1, ang=endAng & dx/dt has its sign reversed
106 | // results in the following:
107 | // ax0 = p1.x
108 | // ax1 = cos(startAng) * l
109 | // ax2 = 3 * p2.x - 3 * ax0 - 2 * ax1 - cos(endAng) * l
110 | // ax3 = p2.x - (ax0 + ax1 + ax2)
111 |
112 | double l = p1.dist(p2); // Approximate curve length
113 |
114 | double ax0 = p1.x;
115 | double ax1 = Math.cos(startAngle.inRadians()) * l;
116 | double ax2 = 3.0 * p2.x - 3.0 * ax0 - 2.0 * ax1 + Math.cos(endAngle.inRadians()) * l;
117 | double ax3 = p2.x - (ax0 + ax1 + ax2);
118 |
119 | double ay0 = p1.y;
120 | double ay1 = Math.sin(startAngle.inRadians()) * l;
121 | double ay2 = 3.0 * p2.y - 3.0 * ay0 - 2.0 * ay1 + Math.sin(endAngle.inRadians()) * l;
122 | double ay3 = p2.y - (ay0 + ay1 + ay2);
123 |
124 | double t = parameter.value;
125 |
126 | double x = ax0 + ax1 * t + ax2 * t * t + ax3 * t * t * t;
127 | double y = ay0 + ay1 * t + ay2 * t * t + ay3 * t * t * t;
128 |
129 | return new Point(x, y);
130 | }
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/geometry/builder/GeometryBuilder.java:
--------------------------------------------------------------------------------
1 | package geometry.builder;
2 |
3 | import geometry.Point;
4 |
5 | /**
6 | * Convenience class for building a list of ParametricCurve
s for
7 | * creating Geometry
object.
8 | *
9 | * @author Sourabh Bhat
10 | */
11 | public class GeometryBuilder {
12 |
13 | private GeometryBuilder() {
14 | }
15 |
16 | public static Corner1 beginFrom(Point point1) {
17 | Corner1 corner1 = new Corner1(point1);
18 | return corner1;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/io/GeometryFileReader.java:
--------------------------------------------------------------------------------
1 | package io;
2 |
3 | import geometry.Point;
4 | import java.io.File;
5 | import java.io.FileNotFoundException;
6 | import java.util.Scanner;
7 |
8 | /**
9 | *
10 | * @author Sourabh Bhat
11 | */
12 | public class GeometryFileReader {
13 |
14 | public enum SideLabel {
15 | xi_0, xi_1, eta_0, eta_1
16 | }
17 |
18 | private GeometryFileReader() {
19 | }
20 |
21 | public static Point[] readPoints(File file, SideLabel label) throws FileNotFoundException {
22 | Point[] points;
23 | try (Scanner fileScanner = new Scanner(file, "UTF-8")) {
24 | int numPoints = 0;
25 | String nextValidLine;
26 | while ((nextValidLine = getNextValidLine(fileScanner)) != null) {
27 | if (nextValidLine.startsWith(label.toString())) {
28 | String[] tokens = nextValidLine.split("[\\s:=]+");
29 | try {
30 | numPoints = Integer.parseInt(tokens[tokens.length - 1]);
31 | } catch (NumberFormatException ex) {
32 | numPoints = 0;
33 | }
34 | break;
35 | }
36 | }
37 |
38 | points = new Point[numPoints];
39 | for (int i = 0; i < numPoints; i++) {
40 | String nextLine = getNextValidLine(fileScanner);
41 | String[] coordinates = nextLine.split("[\\s]+");
42 | double x = Double.parseDouble(coordinates[0].trim());
43 | double y = Double.parseDouble(coordinates[1].trim());
44 | points[i] = new Point(x, y);
45 | }
46 | }
47 |
48 | return points;
49 | }
50 |
51 | private static String getNextValidLine(Scanner fileScanner) {
52 | while (fileScanner.hasNextLine()) {
53 | String nextLine = fileScanner.nextLine().split("#")[0].trim();
54 | if (!nextLine.isEmpty()) {
55 | return nextLine;
56 | }
57 | }
58 |
59 | return null;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/io/MeshFileWriter.java:
--------------------------------------------------------------------------------
1 | package io;
2 |
3 | import java.io.FileOutputStream;
4 | import java.io.IOException;
5 | import java.io.OutputStreamWriter;
6 | import java.nio.charset.StandardCharsets;
7 | import mesh.Node;
8 |
9 | /**
10 | *
11 | * @author Sourabh Bhat
12 | */
13 | public class MeshFileWriter {
14 |
15 | private MeshFileWriter() {
16 | }
17 |
18 | public static void write(Node[][] nodes, String fileName) throws IOException {
19 | if (!fileName.endsWith(".dat")) {
20 | fileName += ".dat";
21 | }
22 | System.out.println("Writing structured mesh file: " + fileName);
23 | try (OutputStreamWriter fileWriter
24 | = new OutputStreamWriter(new FileOutputStream(fileName),
25 | StandardCharsets.UTF_8)) {
26 | int numXiNodes = nodes.length;
27 | int numEtaNodes = nodes[0].length;
28 |
29 | fileWriter.write(String.format("dimension=%d\n", 2));
30 | fileWriter.write(String.format("xi=%d\n", numXiNodes));
31 | fileWriter.write(String.format("eta=%d\n", numEtaNodes));
32 | fileWriter.write(String.format("%-20s %-20s\n", "x", "y"));
33 | for (int i = 0; i < numXiNodes; i++) {
34 | for (int j = 0; j < numEtaNodes; j++) {
35 | fileWriter.write(String.format("%-20f %-20f\n", nodes[i][j].point.x, nodes[i][j].point.y));
36 | }
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/io/Su2MeshWriter.java:
--------------------------------------------------------------------------------
1 | package io;
2 |
3 | import geometry.Point;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 | import java.io.OutputStreamWriter;
7 | import java.nio.charset.StandardCharsets;
8 | import java.util.List;
9 | import java.util.Set;
10 | import java.util.stream.IntStream;
11 | import mesh.Element;
12 | import mesh.Face;
13 | import mesh.Node;
14 | import mesh.UnstructuredMesh;
15 |
16 | /**
17 | *
18 | * @author Sourabh Bhat
19 | */
20 | public class Su2MeshWriter {
21 |
22 | public static void write(UnstructuredMesh mesh, String fileNamePrefix) throws IOException {
23 | IntStream.range(0, mesh.nodeList.size())
24 | .forEach(i -> mesh.nodeList.get(i).index = i);
25 |
26 | final int NUM_ELEMS = mesh.elemList.size();
27 | final int NUM_NODES = mesh.nodeList.size();
28 | final int NUM_BNDRS = mesh.boundaries.size();
29 | final int VTK_QUAD = 9;
30 |
31 | System.out.print("Writing unstructured mesh file in su2 format: " + fileNamePrefix + ".su2" + " ... ");
32 | try (OutputStreamWriter fileWriter = new OutputStreamWriter(new FileOutputStream(fileNamePrefix + ".su2"),
33 | StandardCharsets.UTF_8)) {
34 | writeln(fileWriter, "NDIME= 2");
35 |
36 | // Write elements
37 | writeln(fileWriter, String.format("NELEM= %d", NUM_ELEMS));
38 | for (int i = 0; i < NUM_ELEMS; i++) {
39 | Element elem = mesh.elemList.get(i);
40 | writeln(fileWriter, String.format("%-10d %-10d %-10d %-10d %-10d %d", VTK_QUAD,
41 | elem.nodes[0].index, elem.nodes[1].index, elem.nodes[2].index, elem.nodes[3].index, i));
42 | }
43 |
44 | // Write nodes
45 | writeln(fileWriter, String.format("NPOIN= %d", NUM_NODES));
46 | for (int i = 0; i < NUM_NODES; i++) {
47 | Node node = mesh.nodeList.get(i);
48 | Point p = node.point;
49 | writeln(fileWriter, String.format("%-20f %-20f %d", p.x, p.y, node.index));
50 | }
51 |
52 | // Write boundaries
53 | final int VTK_LINE = 3;
54 | writeln(fileWriter, String.format("NMARK= %d", NUM_BNDRS));
55 | Set markers = mesh.boundaries.keySet();
56 | for (String marker : markers) {
57 | writeln(fileWriter, String.format("MARKER_TAG= %s", marker));
58 |
59 | List bndryFaces = mesh.boundaries.get(marker);
60 | int numBndryFaces = bndryFaces.size();
61 |
62 | writeln(fileWriter, String.format("MARKER_ELEMS= %d", numBndryFaces));
63 |
64 | for (int i = 0; i < numBndryFaces; i++) {
65 | Node node1 = bndryFaces.get(i).node1;
66 | Node node2 = bndryFaces.get(i).node2;
67 | writeln(fileWriter, String.format("%-10d %-10d %-10d", VTK_LINE, node1.index, node2.index));
68 | }
69 | }
70 | }
71 |
72 | System.out.println(" Done.");
73 | }
74 |
75 | private static void writeln(OutputStreamWriter fileWriter, String str) throws IOException {
76 | fileWriter.write(str + "\n");
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/io/VtkMeshWriter.java:
--------------------------------------------------------------------------------
1 | package io;
2 |
3 | import geometry.Point;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 | import java.io.OutputStreamWriter;
7 | import java.nio.charset.StandardCharsets;
8 | import java.util.ArrayList;
9 | import java.util.List;
10 | import java.util.Set;
11 | import java.util.stream.Collectors;
12 | import java.util.stream.IntStream;
13 | import java.util.stream.Stream;
14 | import mesh.Element;
15 | import mesh.Face;
16 | import mesh.Node;
17 | import mesh.UnstructuredMesh;
18 |
19 | /**
20 | *
21 | * @author Sourabh Bhat
22 | */
23 | public class VtkMeshWriter {
24 |
25 | private VtkMeshWriter() {
26 | }
27 |
28 | public static void write(Point[][] nodes, String fileNamePrefix) throws IOException {
29 | System.out.println("Writing structured mesh file in vtk format: " + fileNamePrefix + ".vtk");
30 |
31 | try (OutputStreamWriter fileWriter
32 | = new OutputStreamWriter(new FileOutputStream(fileNamePrefix + ".vtk"),
33 | StandardCharsets.UTF_8)) {
34 | int numXiNodes = nodes.length;
35 | int numEtaNodes = nodes[0].length;
36 | int numZetaNodes = 1;
37 |
38 | int totalNodes = numXiNodes * numEtaNodes * numZetaNodes;
39 |
40 | fileWriter.write("# vtk DataFile Version 2.0" + "\n");
41 | fileWriter.write("Structured mesh file." + "\n");
42 | fileWriter.write("ASCII" + "\n");
43 |
44 | fileWriter.write("DATASET " + "STRUCTURED_GRID" + "\n");
45 | fileWriter.write(String.format("DIMENSIONS %d %d %d", numXiNodes, numEtaNodes, numZetaNodes) + "\n");
46 |
47 | fileWriter.write(String.format("POINTS %d %s", totalNodes, "double") + "\n");
48 |
49 | for (int k = 0; k < numZetaNodes; k++) {
50 | for (int j = 0; j < numEtaNodes; j++) {
51 | for (int i = 0; i < numXiNodes; i++) {
52 | fileWriter.write(String.format("%-20f %-20f %-20f", nodes[i][j].x, nodes[i][j].y, 0.0) + "\n");
53 | }
54 | }
55 | }
56 | }
57 | }
58 |
59 | public static void write(UnstructuredMesh mesh, String fileNamePrefix) throws IOException {
60 | IntStream.range(0, mesh.nodeList.size())
61 | .forEach(i -> mesh.nodeList.get(i).index = i);
62 |
63 | System.out.print("Writing unstructured mesh file in vtk format: " + fileNamePrefix + ".vtk" + " ... ");
64 | try (OutputStreamWriter fileWriter = new OutputStreamWriter(new FileOutputStream(fileNamePrefix + ".vtk"),
65 | StandardCharsets.UTF_8)) {
66 |
67 | // Header
68 | fileWriter.write("# vtk DataFile Version 2.0" + "\n");
69 |
70 | // Info string max 256 characters allowed
71 | String title = "Block Mesh";
72 | fileWriter.write((title.length() > 255 ? title.substring(0, 255) : title) + "\n");
73 |
74 | // File type
75 | fileWriter.write("ASCII" + "\n");
76 |
77 | // Data type
78 | fileWriter.write("DATASET UNSTRUCTURED_GRID" + "\n");
79 |
80 | // Point data
81 | fileWriter.write("POINTS " + mesh.nodeList.size() + " double" + "\n");
82 | for (Node node : mesh.nodeList) {
83 | fileWriter.write(String.format("%-20f %-20f %-20f\n",
84 | node.point.x, node.point.y, 0.0));
85 | }
86 | fileWriter.write("\n");
87 |
88 | // Cell connectivity
89 | final int NUM_CELLS = mesh.elemList.size();
90 | int totalConnectNodes = mesh.elemList.stream()
91 | .mapToInt(cell -> cell.nodes.length)
92 | .sum();
93 | fileWriter.write("CELLS " + NUM_CELLS + " " + (NUM_CELLS + totalConnectNodes) + "\n");
94 | for (Element cell : mesh.elemList) {
95 | fileWriter.write(cell.nodes.length + " ");
96 |
97 | for (Node node : cell.nodes) {
98 | fileWriter.write(node.index + " ");
99 | }
100 |
101 | fileWriter.write("\n");
102 | }
103 | fileWriter.write("\n");
104 |
105 | // Cell Types
106 | fileWriter.write("CELL_TYPES " + NUM_CELLS + "\n");
107 | int VTK_QUAD = 9;
108 | for (Element cell : mesh.elemList) {
109 | fileWriter.write(VTK_QUAD + "\n");
110 | }
111 | fileWriter.write("\n");
112 | }
113 |
114 | // Write boundaries as separate datasets
115 | for (String key : mesh.boundaries.keySet()) {
116 | try (OutputStreamWriter fileWriter = new OutputStreamWriter(new FileOutputStream(fileNamePrefix + "_" + key + ".vtk"),
117 | StandardCharsets.UTF_8)) {
118 | List bndryFaces = mesh.boundaries.get(key);
119 | writeBoundary(bndryFaces, fileWriter);
120 | }
121 | }
122 |
123 | System.out.println(" Done.");
124 | }
125 |
126 | private static void writeBoundary(List bndryFaces, OutputStreamWriter fileWriter) throws IOException {
127 |
128 | Set bndryNodes = bndryFaces.stream()
129 | .flatMap(face -> Stream.of(face.node1, face.node2))
130 | .collect(Collectors.toSet());
131 |
132 | List nodeList = new ArrayList<>(bndryNodes);
133 |
134 | IntStream.range(0, nodeList.size())
135 | .forEach(i -> nodeList.get(i).index = i);
136 |
137 | // Header
138 | fileWriter.write("# vtk DataFile Version 2.0" + "\n");
139 |
140 | // Info string max 256 characters allowed
141 | String title = "Block Mesh";
142 | fileWriter.write((title.length() > 255 ? title.substring(0, 255) : title) + "\n");
143 |
144 | // File type
145 | fileWriter.write("ASCII" + "\n");
146 |
147 | // Data type
148 | fileWriter.write("DATASET UNSTRUCTURED_GRID" + "\n");
149 |
150 | // Point data
151 | fileWriter.write("POINTS " + nodeList.size() + " double" + "\n");
152 | for (Node node : nodeList) {
153 | fileWriter.write(String.format("%-20f %-20f %-20f\n",
154 | node.point.x, node.point.y, 0.0));
155 | }
156 | fileWriter.write("\n");
157 |
158 | // Cell connectivity
159 | final int NUM_CELLS = bndryFaces.size();
160 | int totalConnectNodes = NUM_CELLS * 2;
161 | fileWriter.write("CELLS " + NUM_CELLS + " " + (NUM_CELLS + totalConnectNodes) + "\n");
162 | for (Face cell : bndryFaces) {
163 | fileWriter.write("2" + " ");
164 | fileWriter.write(cell.node1.index + " " + cell.node2.index);
165 | fileWriter.write("\n");
166 | }
167 | fileWriter.write("\n");
168 |
169 | // Cell Types
170 | fileWriter.write("CELL_TYPES " + NUM_CELLS + "\n");
171 | int VTK_LINE = 3;
172 | for (Face cell : bndryFaces) {
173 | fileWriter.write(VTK_LINE + "\n");
174 | }
175 | fileWriter.write("\n");
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/src/main/StructuredMeshGenerator2D.java:
--------------------------------------------------------------------------------
1 | package main;
2 |
3 | import mesh.TransfiniteInterpolator;
4 | import geometry.Point;
5 | import geometry.Geometry;
6 | import geometry.SimpleQuadGeometry;
7 | import io.Su2MeshWriter;
8 | import io.VtkMeshWriter;
9 | import java.io.IOException;
10 | import mesh.MeshDefinition;
11 | import mesh.StructuredMesh;
12 | import mesh.UnstructuredMesh;
13 |
14 | /**
15 | * Code for 2D structured mesh generation using Transfinite Interpolation
16 | *
17 | * @author Sourabh Bhat
18 | */
19 | public class StructuredMeshGenerator2D {
20 |
21 | public static void main(String[] args) throws IOException {
22 | Point p1 = new Point(0, 0);
23 | Point p2 = new Point(0.6, 0);
24 | Point p3 = new Point(0.6, 0.2);
25 | Point p4 = new Point(3.0, 0.2);
26 | Point p5 = new Point(3.0, 1);
27 | Point p6 = new Point(0.6, 1);
28 | Point p7 = new Point(0, 1);
29 | Point p8 = new Point(0, 0.2);
30 |
31 | String markerInlet = "Inlet";
32 | String markerOutlet = "Outlet";
33 | String markerBottomWall = "Bottom Wall";
34 | String markerTopWall = "Top Wall";
35 |
36 | Geometry geom1 = new SimpleQuadGeometry(p1, p2, p3, p8);
37 | int numXiNodes1 = 61;
38 | int numEtaNodes1 = 21;
39 | MeshDefinition meshDefBlock1 = new MeshDefinition(geom1, numXiNodes1, numEtaNodes1, markerInlet, markerBottomWall, markerBottomWall, null);
40 | StructuredMesh meshBlock1 = new TransfiniteInterpolator(meshDefBlock1).interpolate();
41 |
42 | Geometry geom2 = new SimpleQuadGeometry(p8, p3, p6, p7);
43 | int numXiNodes2 = numXiNodes1;
44 | int numEtaNodes2 = 81;
45 | MeshDefinition meshDefBlock2 = new MeshDefinition(geom2, numXiNodes2, numEtaNodes2, markerInlet, null, null, markerTopWall);
46 | StructuredMesh meshBlock2 = new TransfiniteInterpolator(meshDefBlock2).interpolate();
47 |
48 | Geometry geom3 = new SimpleQuadGeometry(p3, p4, p5, p6);
49 | int numXiNodes3 = 241;
50 | int numEtaNodes3 = numEtaNodes2;
51 | MeshDefinition meshDefBlock3 = new MeshDefinition(geom3, numXiNodes3, numEtaNodes3, null, markerOutlet, markerBottomWall, markerTopWall);
52 | StructuredMesh meshBlock3 = new TransfiniteInterpolator(meshDefBlock3).interpolate();
53 |
54 | UnstructuredMesh combinedMesh = new UnstructuredMesh(meshBlock1)
55 | .stitch(new UnstructuredMesh(meshBlock2))
56 | .stitch(new UnstructuredMesh(meshBlock3));
57 |
58 | Su2MeshWriter.write(combinedMesh, "mesh");
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/mesh/Element.java:
--------------------------------------------------------------------------------
1 | package mesh;
2 |
3 | /**
4 | *
5 | * @author Sourabh Bhat
6 | */
7 | public class Element {
8 |
9 | public final Node[] nodes;
10 |
11 | public Element(Node[] nodes) {
12 | this.nodes = nodes;
13 | }
14 |
15 | public void replaceNode(Node oldNode, Node newNode) {
16 | if (newNode == null || oldNode == null) {
17 | throw new IllegalArgumentException("The newNode/oldNode provided must not be null.");
18 | }
19 |
20 | for (int i = 0; i < nodes.length; i++) {
21 | if (nodes[i] == oldNode) {
22 | nodes[i] = newNode;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/mesh/Face.java:
--------------------------------------------------------------------------------
1 | package mesh;
2 |
3 | /**
4 | *
5 | * @author Sourabh Bhat
6 | */
7 | public class Face {
8 |
9 | public Node node1, node2;
10 |
11 | public Face(Node node1, Node node2) {
12 | this.node1 = node1;
13 | this.node2 = node2;
14 | }
15 |
16 | public boolean isOnBoundary() {
17 | return node1.isOnBoundary() && node2.isOnBoundary();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/mesh/MeshDefinition.java:
--------------------------------------------------------------------------------
1 | package mesh;
2 |
3 | import geometry.Geometry;
4 |
5 | /**
6 | *
7 | * @author Sourabh Bhat
8 | */
9 | public class MeshDefinition {
10 |
11 | public static final String DEFAULT_MARKER = "Unnamed";
12 |
13 | public final Geometry geometry;
14 | public final int numXiNodes;
15 | public final int numEtaNodes;
16 |
17 | public final String xi_0_marker;
18 | public final String xi_1_marker;
19 | public final String eta_0_marker;
20 | public final String eta_1_marker;
21 |
22 | public MeshDefinition(Geometry geometry, int numXiNodes, int numEtaNodes,
23 | String xi_0_marker, String xi_1_marker,
24 | String eta_0_marker, String eta_1_marker) {
25 | this.geometry = geometry;
26 | this.numXiNodes = numXiNodes;
27 | this.numEtaNodes = numEtaNodes;
28 |
29 | this.xi_0_marker = markerName(xi_0_marker);
30 | this.xi_1_marker = markerName(xi_1_marker);
31 | this.eta_0_marker = markerName(eta_0_marker);
32 | this.eta_1_marker = markerName(eta_1_marker);
33 | }
34 |
35 | private static String markerName(String name) {
36 | String modifiedName = (name == null || name.isEmpty()) ? DEFAULT_MARKER : name;
37 | modifiedName = modifiedName.replaceAll(" ", "");
38 |
39 | return modifiedName;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/mesh/Node.java:
--------------------------------------------------------------------------------
1 | package mesh;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import geometry.Point;
6 | import java.util.Objects;
7 |
8 | /**
9 | *
10 | * @author Sourabh Bhat
11 | */
12 | public class Node {
13 |
14 | private static final double TOLERANCE = 1e-8;
15 |
16 | public final Point point;
17 | public final List belongsTo;
18 | public int index = -1;
19 |
20 | public Node(Point point) {
21 | this.point = point;
22 | this.belongsTo = new ArrayList<>(4);
23 | }
24 |
25 | public boolean isOnBoundary() {
26 | return belongsTo.size() != 4;
27 | }
28 |
29 | @Override
30 | public boolean equals(Object obj) {
31 | if (obj == null) {
32 | return false;
33 | } else if (!(obj instanceof Node)) {
34 | return false;
35 | } else {
36 | Node other = (Node) obj;
37 | return overlapping(this.point, other.point);
38 | }
39 | }
40 |
41 | @Override
42 | public int hashCode() {
43 | int hash = 7;
44 | hash = 37 * hash + Objects.hashCode(this.point);
45 | return hash;
46 | }
47 |
48 | private boolean overlapping(Point p1, Point p2) {
49 | return p1.dist(p2) < TOLERANCE;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/mesh/Parameter.java:
--------------------------------------------------------------------------------
1 | package mesh;
2 |
3 | /**
4 | *
5 | * @author Sourabh Bhat
6 | */
7 | public class Parameter {
8 |
9 | public final double value;
10 |
11 | /**
12 | * A value between 0 and 1.
13 | * @param value Saves a double restricted in closed range [0, 1].
14 | */
15 | public Parameter(double value) {
16 | if (value < 0.0 || value > 1.0) {
17 | throw new IllegalArgumentException("The parameter must be within the range 0.0 and 1.0");
18 | }
19 | this.value = value;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/mesh/StructuredMesh.java:
--------------------------------------------------------------------------------
1 | package mesh;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 |
6 | /**
7 | *
8 | * @author Sourabh Bhat
9 | */
10 | public class StructuredMesh {
11 |
12 | public final Node[][] nodes;
13 | public final Map> boundaries;
14 |
15 | public StructuredMesh(Node[][] nodes, Map> boundaries) {
16 | this.nodes = nodes;
17 | this.boundaries = boundaries;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/mesh/TransfiniteInterpolator.java:
--------------------------------------------------------------------------------
1 | package mesh;
2 |
3 | import geometry.Geometry;
4 | import geometry.Point;
5 | import java.util.ArrayList;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | /**
11 | *
12 | * @author Sourabh Bhat
13 | */
14 | public class TransfiniteInterpolator {
15 |
16 | private final MeshDefinition meshDef;
17 |
18 | public TransfiniteInterpolator(MeshDefinition meshDef) {
19 | this.meshDef = meshDef;
20 | }
21 |
22 | public StructuredMesh interpolate() {
23 | int numXiNodes = meshDef.numXiNodes;
24 | int numEtaNodes = meshDef.numEtaNodes;
25 | Geometry geom = meshDef.geometry;
26 |
27 | double dXi = 1.0 / (numXiNodes - 1);
28 | double dEta = 1.0 / (numEtaNodes - 1);
29 |
30 | Node[][] nodes = new Node[numXiNodes][numEtaNodes];
31 | for (int i = 0; i < numXiNodes; i++) {
32 | Parameter xi = new Parameter(i * dXi);
33 | for (int j = 0; j < numEtaNodes; j++) {
34 | Parameter eta = new Parameter(j * dEta);
35 | Point point = interpolate(geom, xi, eta);
36 | nodes[i][j] = new Node(point);
37 | }
38 | }
39 |
40 | List xi_0_faces = new ArrayList<>(numEtaNodes - 1);
41 | List xi_1_faces = new ArrayList<>(numEtaNodes - 1);
42 | List eta_0_faces = new ArrayList<>(numXiNodes - 1);
43 | List eta_1_faces = new ArrayList<>(numXiNodes - 1);
44 |
45 | for (int i = 0; i < numXiNodes - 1; i++) {
46 | int j = 0;
47 | Node node1 = nodes[i][j];
48 | Node node2 = nodes[i + 1][j];
49 | Face eta_0_face = new Face(node1, node2);
50 | eta_0_faces.add(eta_0_face);
51 |
52 | j = numEtaNodes - 1;
53 | node1 = nodes[i][j];
54 | node2 = nodes[i + 1][j];
55 | Face eta_1_face = new Face(node1, node2);
56 | eta_1_faces.add(eta_1_face);
57 | }
58 |
59 | for (int j = 0; j < numEtaNodes - 1; j++) {
60 | int i = 0;
61 | Node node1 = nodes[i][j];
62 | Node node2 = nodes[i][j + 1];
63 | Face xi_0_face = new Face(node1, node2);
64 | xi_0_faces.add(xi_0_face);
65 |
66 | i = numXiNodes - 1;
67 | node1 = nodes[i][j];
68 | node2 = nodes[i][j + 1];
69 | Face xi_1_face = new Face(node1, node2);
70 | xi_1_faces.add(xi_1_face);
71 | }
72 |
73 | Map> boundaries = new HashMap<>();
74 | addBoundaryfaces(boundaries, meshDef.xi_0_marker, xi_0_faces);
75 | addBoundaryfaces(boundaries, meshDef.xi_1_marker, xi_1_faces);
76 | addBoundaryfaces(boundaries, meshDef.eta_0_marker, eta_0_faces);
77 | addBoundaryfaces(boundaries, meshDef.eta_1_marker, eta_1_faces);
78 |
79 | return new StructuredMesh(nodes, boundaries);
80 | }
81 |
82 | private void addBoundaryfaces(Map> boundaries, String marker, List faces) {
83 | if (boundaries.containsKey(marker)) {
84 | boundaries.get(marker).addAll(faces);
85 | } else {
86 | boundaries.put(marker, faces);
87 | }
88 | }
89 |
90 | private static Point interpolate(Geometry geom, Parameter xi, Parameter eta) {
91 | return geom.xi_0(eta).mult((1 - xi.value))
92 | .add(geom.xi_1(eta).mult(xi.value))
93 | .add(geom.eta_0(xi).mult(1 - eta.value))
94 | .add(geom.eta_1(xi).mult(eta.value))
95 | .sub(geom.eta_0(new Parameter(0)).mult((1 - xi.value) * (1 - eta.value)))
96 | .sub(geom.eta_1(new Parameter(0)).mult(eta.value * (1 - xi.value)))
97 | .sub(geom.eta_0(new Parameter(1)).mult((1 - eta.value) * xi.value))
98 | .sub(geom.eta_1(new Parameter(1)).mult(xi.value * eta.value));
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/mesh/UnstructuredMesh.java:
--------------------------------------------------------------------------------
1 | package mesh;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.HashMap;
6 | import java.util.HashSet;
7 | import java.util.List;
8 | import java.util.Map;
9 | import java.util.Set;
10 | import java.util.stream.Collectors;
11 | import java.util.stream.Stream;
12 |
13 | /**
14 | *
15 | * @author Sourabh Bhat
16 | */
17 | public class UnstructuredMesh {
18 |
19 | public final List elemList;
20 | public final List nodeList;
21 | public final Map> boundaries;
22 |
23 | public UnstructuredMesh(StructuredMesh structuredMesh) {
24 | final int NUM_XI_NODES = structuredMesh.nodes.length;
25 | final int NUM_ETA_NODES = structuredMesh.nodes[0].length;
26 |
27 | Node[][] nodes = new Node[NUM_XI_NODES][NUM_ETA_NODES];
28 | nodeList = new ArrayList<>(NUM_XI_NODES * NUM_ETA_NODES);
29 |
30 | for (int i = 0; i < NUM_XI_NODES; i++) {
31 | for (int j = 0; j < NUM_ETA_NODES; j++) {
32 | nodes[i][j] = structuredMesh.nodes[i][j];
33 | nodeList.add(nodes[i][j]);
34 | }
35 | }
36 |
37 | elemList = new ArrayList<>((NUM_XI_NODES - 1) * (NUM_ETA_NODES - 1));
38 | for (int i = 0; i < NUM_XI_NODES - 1; i++) {
39 | for (int j = 0; j < NUM_ETA_NODES - 1; j++) {
40 | Node node0 = nodes[i][j];
41 | Node node1 = nodes[i + 1][j];
42 | Node node2 = nodes[i + 1][j + 1];
43 | Node node3 = nodes[i][j + 1];
44 |
45 | // Added in the order as per VTK_QUAD
46 | Element elem = new Element(new Node[]{
47 | node0, node1, node2, node3
48 | });
49 |
50 | elemList.add(elem);
51 |
52 | node0.belongsTo.add(elem);
53 | node1.belongsTo.add(elem);
54 | node2.belongsTo.add(elem);
55 | node3.belongsTo.add(elem);
56 | }
57 | }
58 |
59 | // Set up the boundary markers
60 | boundaries = structuredMesh.boundaries;
61 | }
62 |
63 | public UnstructuredMesh stitch(UnstructuredMesh other) {
64 | if (this == other) {
65 | return this;
66 | }
67 |
68 | // Check if any node in other mesh is at same position as a node in this mesh.
69 | // if yes then replaceNode the node from this mesh by other mesh node.
70 | Set bndryNodes = new HashSet<>();
71 | for (Node node : this.nodeList) {
72 | if (node.isOnBoundary()) {
73 | bndryNodes.add(node);
74 | }
75 | }
76 | Set otherBndryNodes = new HashSet<>();
77 | for (Node node : other.nodeList) {
78 | if (node.isOnBoundary()) {
79 | otherBndryNodes.add(node);
80 | }
81 | }
82 |
83 | for (Node nodeOther : otherBndryNodes) {
84 | for (Node node : bndryNodes) {
85 | if (node.equals(nodeOther)) {
86 | for (Element elem : node.belongsTo) {
87 | elem.replaceNode(node, nodeOther);
88 | }
89 | }
90 | }
91 | }
92 |
93 | elemList.addAll(other.elemList); // Adding the two mesh cells together
94 |
95 | // Clear the old nodelist so that the combined list can be populated
96 | nodeList.clear();
97 | Set nodeSet = new HashSet<>();
98 | for (Element ele : elemList) {
99 | nodeSet.addAll(Arrays.asList(ele.nodes));
100 | }
101 | nodeList.addAll(nodeSet);
102 |
103 | // Clear the belongsTo and new belongsTo cells are populated
104 | for (Node node : nodeList) {
105 | node.belongsTo.clear();
106 | }
107 | for (Element elem : elemList) {
108 | for (Node node : elem.nodes) {
109 | node.belongsTo.add(elem);
110 | }
111 | }
112 |
113 | // remove internal boundary faces
114 | List> bndryMarkerFaces = boundaries.keySet().stream()
115 | .map(key -> boundaries.get(key))
116 | .collect(Collectors.toList());
117 |
118 | List otherBndryMarkerNodes = other.boundaries.keySet().stream()
119 | .flatMap(key -> other.boundaries.get(key).stream())
120 | .flatMap(face -> Stream.of(face.node1, face.node2))
121 | .collect(Collectors.toList());
122 |
123 | for (Node node : otherBndryMarkerNodes) { // Replace overlapping nodes from this boundary faces with other boundary nodes
124 | for (List bndryFaceList : bndryMarkerFaces) {
125 | for (Face face : bndryFaceList) {
126 | if (face.node1.equals(node)) {
127 | face.node1 = node;
128 | }
129 | if (face.node2.equals(node)) {
130 | face.node2 = node;
131 | }
132 | }
133 | }
134 | }
135 |
136 | Map> allBoundaries = combine(boundaries, other.boundaries);
137 | allBoundaries.keySet().stream()
138 | .forEach(marker -> {
139 | allBoundaries.get(marker)
140 | .removeIf(face -> !face.isOnBoundary());
141 | });
142 | List emptyMarkers = allBoundaries.keySet().stream()
143 | .filter(key -> allBoundaries.get(key).isEmpty())
144 | .collect(Collectors.toList());
145 |
146 | emptyMarkers.stream()
147 | .forEach(emptyMarker -> allBoundaries.remove(emptyMarker));
148 |
149 | boundaries.clear();
150 |
151 | boundaries.putAll(allBoundaries);
152 |
153 | return this;
154 | }
155 |
156 | private Map> combine(Map> boundaries1, Map> boundaries2) {
157 | Map> newMap = new HashMap<>();
158 | boundaries1.keySet().stream().forEach((marker) -> {
159 | // Add all the lists from boundaries1
160 | newMap.put(marker, boundaries1.get(marker));
161 | });
162 |
163 | // While adding boundaries2, check if the marker exists,
164 | // if it does then append to the existing list,
165 | // else add the new list to map
166 | boundaries2.keySet().stream().forEach((marker) -> {
167 | if (newMap.containsKey(marker)) {
168 | newMap.get(marker).addAll(boundaries2.get(marker));
169 | } else {
170 | newMap.put(marker, boundaries2.get(marker));
171 | }
172 | });
173 |
174 | return newMap;
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/src/util/Range.java:
--------------------------------------------------------------------------------
1 | package util;
2 |
3 | /**
4 | *
5 | * @author Sourabh Bhat
6 | */
7 | public class Range {
8 |
9 | private final double a, b;
10 | private final double width;
11 |
12 | public Range(double a, double b) {
13 | this.a = a;
14 | this.b = b;
15 | this.width = b - a;
16 | }
17 |
18 | public double getMin() {
19 | return Math.min(a, b);
20 | }
21 |
22 | public double getMax() {
23 | return Math.max(a, b);
24 | }
25 |
26 | public double getA() {
27 | return a;
28 | }
29 |
30 | public double getB() {
31 | return b;
32 | }
33 |
34 | public static double map(double value, Range mapFrom, Range mapTo) {
35 | return mapTo.a + mapTo.width / mapFrom.width * (value - mapFrom.a);
36 | }
37 |
38 | public static double clamp(double value, Range limits) {
39 | double min = limits.getMin();
40 | double max = limits.getMax();
41 | if (value < min) {
42 | return min;
43 | }
44 | if (value > max) {
45 | return max;
46 | }
47 | return value;
48 | }
49 |
50 | /**
51 | * Width of the range. The width will be negative if a
>
52 | * b
.
53 | *
54 | * @return b
- a
55 | */
56 | public double width() {
57 | return width;
58 | }
59 |
60 | public boolean inRange(double value) {
61 | return value > getMin() && value < getMax();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/support/create_geom.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | numPoints = 10
4 | circRadius = 2.0
5 | cx = 0.0
6 | cy = 0.0
7 | angles = np.linspace(0 * np.pi / 180, 45 * np.pi / 180, numPoints)
8 | for a in angles:
9 | x = circRadius * np.cos(a) + cx
10 | y = circRadius * np.sin(a) + cy
11 | print("%-20.15f %-20.15f"%(x,y))
--------------------------------------------------------------------------------
/support/geometry1.dat:
--------------------------------------------------------------------------------
1 | # Geometry for annular geometry
2 |
3 |
4 | xi_0 = 2
5 | -4 1.414213562373095
6 | -4 4
7 |
8 |
9 | xi_1 = 2
10 | -1.414213562373095 1.414213562373095
11 | -1.414213562373095 4
12 |
13 |
14 | eta_0 = 2
15 | -4 1.414213562373095
16 | -1.414213562373095 1.414213562373095
17 |
18 |
19 | eta_1 = 2
20 | -4 4
21 | -1.414213562373095 4
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/support/geometry2.dat:
--------------------------------------------------------------------------------
1 | # Geometry for annular geometry
2 |
3 |
4 | xi_0 = 2
5 | -1.414213562373095 1.414213562373095
6 | -1.414213562373095 4
7 |
8 |
9 | xi_1 = 2
10 | 1.414213562373095 1.414213562373095
11 | 1.414213562373095 4
12 |
13 |
14 | eta_0 = 20
15 | -1.414213562373095 1.414213562373095
16 | -1.292598475721882 1.526168136399613
17 | -1.162153630803876 1.627697434540390
18 | -1.023770098179202 1.718107908739770
19 | -0.878393177694740 1.796781963783958
20 | -0.727015941127659 1.863182176102558
21 | -0.570672448498210 1.916854964916505
22 | -0.410430684391269 1.957433690654709
23 | -0.247385262538695 1.984641159474090
24 | -0.082649948497627 1.998291516774602
25 | 0.082649948497627 1.998291516774602
26 | 0.247385262538695 1.984641159474090
27 | 0.410430684391269 1.957433690654709
28 | 0.570672448498211 1.916854964916505
29 | 0.727015941127660 1.863182176102558
30 | 0.878393177694741 1.796781963783958
31 | 1.023770098179202 1.718107908739770
32 | 1.162153630803877 1.627697434540390
33 | 1.292598475721882 1.526168136399613
34 | 1.414213562373095 1.414213562373095
35 |
36 |
37 | eta_1 = 2
38 | -1.414213562373095 4
39 | 1.414213562373095 4
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/support/geometry3.dat:
--------------------------------------------------------------------------------
1 | # Geometry for annular geometry
2 |
3 |
4 | xi_0 = 2
5 | 4 1.414213562373095
6 | 4 4
7 |
8 |
9 | xi_1 = 2
10 | 1.414213562373095 1.414213562373095
11 | 1.414213562373095 4
12 |
13 |
14 | eta_0 = 2
15 | 4 1.414213562373095
16 | 1.414213562373095 1.414213562373095
17 |
18 |
19 | eta_1 = 2
20 | 4 4
21 | 1.414213562373095 4
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/support/geometry4.dat:
--------------------------------------------------------------------------------
1 | # Geometry for annular geometry
2 |
3 |
4 | xi_0 = 2
5 | -4 0
6 | -4 1.414213562373095
7 |
8 |
9 | xi_1 = 10
10 | -2.000000000000000 0.000000000000000
11 | -1.992389396183491 0.174311485495316
12 | -1.969615506024416 0.347296355333861
13 | -1.931851652578136 0.517638090205042
14 | -1.879385241571817 0.684040286651338
15 | -1.812615574073300 0.845236523481399
16 | -1.732050807568877 1.000000000000000
17 | -1.638304088577983 1.147152872702093
18 | -1.532088886237956 1.285575219373079
19 | -1.414213562373095 1.414213562373095
20 |
21 |
22 | eta_0 = 2
23 | -4 0
24 | -2 0
25 |
26 |
27 | eta_1 = 2
28 | -4 1.414213562373095
29 | -1.414213562373095 1.414213562373095
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/support/geometry5.dat:
--------------------------------------------------------------------------------
1 | # Geometry for annular geometry
2 |
3 |
4 | xi_0 = 2
5 | -2 0
6 | -1 0
7 |
8 |
9 | xi_1 = 2
10 | -1.414213562373095 1.414213562373095
11 | -0.7071067811865475 0.7071067811865475
12 |
13 |
14 | eta_0 = 10
15 | -2.000000000000000 0.000000000000000
16 | -1.992389396183491 0.174311485495316
17 | -1.969615506024416 0.347296355333861
18 | -1.931851652578136 0.517638090205042
19 | -1.879385241571817 0.684040286651338
20 | -1.812615574073300 0.845236523481399
21 | -1.732050807568877 1.000000000000000
22 | -1.638304088577983 1.147152872702093
23 | -1.532088886237956 1.285575219373079
24 | -1.414213562373095 1.414213562373095
25 |
26 |
27 | eta_1 = 10
28 | -1.000000000000000 0.000000000000000
29 | -0.996194698091746 0.087155742747658
30 | -0.984807753012208 0.173648177666930
31 | -0.965925826289068 0.258819045102521
32 | -0.939692620785908 0.342020143325669
33 | -0.906307787036650 0.422618261740699
34 | -0.866025403784439 0.500000000000000
35 | -0.819152044288992 0.573576436351046
36 | -0.766044443118978 0.642787609686539
37 | -0.707106781186547 0.707106781186548
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/support/geometry6.dat:
--------------------------------------------------------------------------------
1 | # Geometry for annular geometry
2 |
3 |
4 | xi_0 = 2
5 | -0.7071067811865475 0.7071067811865475
6 | -1.414213562373095 1.414213562373095
7 |
8 |
9 | xi_1 = 2
10 | 0.7071067811865475 0.7071067811865475
11 | 1.414213562373095 1.414213562373095
12 |
13 |
14 | eta_0 = 20
15 | -0.707106781186547 0.707106781186548
16 | -0.646299237860941 0.763084068199806
17 | -0.581076815401938 0.813848717270195
18 | -0.511885049089601 0.859053954369885
19 | -0.439196588847370 0.898390981891979
20 | -0.363507970563830 0.931591088051279
21 | -0.285336224249105 0.958427482458253
22 | -0.205215342195634 0.978716845327354
23 | -0.123692631269347 0.992320579737045
24 | -0.041324974248813 0.999145758387301
25 | 0.041324974248813 0.999145758387301
26 | 0.123692631269348 0.992320579737045
27 | 0.205215342195634 0.978716845327354
28 | 0.285336224249105 0.958427482458253
29 | 0.363507970563830 0.931591088051279
30 | 0.439196588847370 0.898390981891979
31 | 0.511885049089601 0.859053954369885
32 | 0.581076815401938 0.813848717270195
33 | 0.646299237860941 0.763084068199806
34 | 0.707106781186548 0.707106781186547
35 |
36 |
37 | eta_1 = 20
38 | -1.414213562373095 1.414213562373095
39 | -1.292598475721882 1.526168136399613
40 | -1.162153630803876 1.627697434540390
41 | -1.023770098179202 1.718107908739770
42 | -0.878393177694740 1.796781963783958
43 | -0.727015941127659 1.863182176102558
44 | -0.570672448498210 1.916854964916505
45 | -0.410430684391269 1.957433690654709
46 | -0.247385262538695 1.984641159474090
47 | -0.082649948497627 1.998291516774602
48 | 0.082649948497627 1.998291516774602
49 | 0.247385262538695 1.984641159474090
50 | 0.410430684391269 1.957433690654709
51 | 0.570672448498211 1.916854964916505
52 | 0.727015941127660 1.863182176102558
53 | 0.878393177694741 1.796781963783958
54 | 1.023770098179202 1.718107908739770
55 | 1.162153630803877 1.627697434540390
56 | 1.292598475721882 1.526168136399613
57 | 1.414213562373095 1.414213562373095
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/support/geometry7.dat:
--------------------------------------------------------------------------------
1 | # Geometry for annular geometry
2 |
3 |
4 | xi_0 = 2
5 | 0.7071067811865475 0.7071067811865475
6 | 1.414213562373095 1.414213562373095
7 |
8 |
9 | xi_1 = 2
10 | 1 0
11 | 2 0
12 |
13 |
14 | eta_0 = 10
15 | 0.707106781186548 0.707106781186547
16 | 0.766044443118978 0.642787609686539
17 | 0.819152044288992 0.573576436351046
18 | 0.866025403784439 0.500000000000000
19 | 0.906307787036650 0.422618261740699
20 | 0.939692620785908 0.342020143325669
21 | 0.965925826289068 0.258819045102521
22 | 0.984807753012208 0.173648177666930
23 | 0.996194698091746 0.087155742747658
24 | 1.000000000000000 0.000000000000000
25 |
26 |
27 | eta_1 = 10
28 | 1.414213562373095 1.414213562373095
29 | 1.532088886237956 1.285575219373079
30 | 1.638304088577984 1.147152872702092
31 | 1.732050807568877 1.000000000000000
32 | 1.812615574073300 0.845236523481399
33 | 1.879385241571817 0.684040286651337
34 | 1.931851652578137 0.517638090205042
35 | 1.969615506024416 0.347296355333861
36 | 1.992389396183491 0.174311485495316
37 | 2.000000000000000 0.000000000000000
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/support/geometry8.dat:
--------------------------------------------------------------------------------
1 | # Geometry for annular geometry
2 |
3 |
4 | xi_0 = 10
5 | 2.000000000000000 0.000000000000000
6 | 1.992389396183491 0.174311485495316
7 | 1.969615506024416 0.347296355333861
8 | 1.931851652578137 0.517638090205041
9 | 1.879385241571817 0.684040286651337
10 | 1.812615574073300 0.845236523481399
11 | 1.732050807568877 1.000000000000000
12 | 1.638304088577984 1.147152872702092
13 | 1.532088886237956 1.285575219373079
14 | 1.414213562373095 1.414213562373095
15 |
16 |
17 | xi_1 = 2
18 | 4 0
19 | 4 1.414213562373095
20 |
21 |
22 | eta_0 = 2
23 | 2 0
24 | 4 0
25 |
26 |
27 | eta_1 = 2
28 | 1.414213562373095 1.414213562373095
29 | 4 1.414213562373095
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/support/geometry_block_mesh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/support/geometry_block_mesh.png
--------------------------------------------------------------------------------
/support/geometry_block_mesh.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
1112 |
--------------------------------------------------------------------------------
/support/plot.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 |
4 | fileName = "mesh.dat"
5 | meshFile = open(fileName)
6 | dims = int(meshFile.readline().split("=")[1])
7 | numXi = int(meshFile.readline().split("=")[1])
8 | numEta = int(meshFile.readline().split("=")[1])
9 |
10 | x, y = np.loadtxt(fileName, skiprows=4, unpack=True)
11 | x = np.reshape(x, (numXi, numEta))
12 | y = np.reshape(y, (numXi, numEta))
13 |
14 | plt.clf()
15 | # plot internal lines
16 | for xi in range(numXi):
17 | if xi == 0: label="$\\xi$=constant"
18 | else: label = None
19 | plt.plot(x[xi], y[xi], "-", color=(0, 0, 1, 0.5), label=label)
20 | for eta in range(numEta):
21 | if eta == 0: label="$\\eta$=constant"
22 | else: label = None
23 | plt.plot(x[:,eta], y[:,eta], "-", color=(1, 0, 0, 0.5), label=label)
24 |
25 | plt.plot(x[:,0], y[:,0], "-r", lw=1.5)
26 | plt.plot(x[:,-1], y[:,-1], "-r", lw=1.5)
27 |
28 | plt.plot(x[0], y[0], "-b", label=label)
29 | plt.plot(x[-1], y[-1], "-b", label=label)
30 |
31 | plt.legend(loc="best")
32 | plt.axes().set_aspect("equal")
33 |
34 |
--------------------------------------------------------------------------------
/support/start_end_angles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heySourabh/StructuredMeshGenerator2D/7b121b0bd94edec46b1a9c398c26cb38fc3cfdbf/support/start_end_angles.png
--------------------------------------------------------------------------------
/support/start_end_angles.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
336 |
--------------------------------------------------------------------------------