├── .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 | ![Sample output](https://github.com/heySourabh/StructuredMeshGenerator2D/blob/master/demo/multi_block_mesh_example.png) 7 | 8 | Below is another example of multi-block mesh generated using multiple quad blocks: 9 | 10 | ![Sample output](https://github.com/heySourabh/StructuredMeshGenerator2D/blob/master/demo/sample_output_3.png) 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 | ![Sample output](https://github.com/heySourabh/StructuredMeshGenerator2D/blob/master/demo/forward_facing_step.png) 15 | 16 | Below is a sample mesh generated, where the geometry is created using some helper 17 | methods available within this project. 18 | 19 | ![Sample output](https://github.com/heySourabh/StructuredMeshGenerator2D/blob/master/demo/sample_output.png) 20 | 21 | and here is the mesh being used to solve convergent-divergent nozzle problem in a CFD solver. 22 | 23 | ![Sample output](https://github.com/heySourabh/StructuredMeshGenerator2D/blob/master/demo/convergent_divergent_nozzle.png) 24 | 25 | Here is a mesh generated using geometry read from a file: 26 | 27 | ![Sample output](https://github.com/heySourabh/StructuredMeshGenerator2D/blob/master/demo/sample_output_1.png) 28 | 29 | and here is a CFD solution for flow over a cylinder using the above mesh: 30 | 31 | ![Sample output](https://github.com/heySourabh/StructuredMeshGenerator2D/blob/master/demo/flow_over_cylinder.png) 32 | 33 | Here is another mesh generated using geometry from file: 34 | 35 | ![Sample output](https://github.com/heySourabh/StructuredMeshGenerator2D/blob/master/demo/sample_output_2.png) 36 | 37 | and here is a CFD solution for compressible flow using the above mesh: 38 | 39 | ![Sample output](https://github.com/heySourabh/StructuredMeshGenerator2D/blob/master/demo/oblique_shock.png) 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 ParametricCurves 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 | 22 | 48 | 50 | 58 | 64 | 65 | 73 | 79 | 80 | 88 | 94 | 95 | 103 | 109 | 110 | 118 | 124 | 125 | 133 | 139 | 140 | 148 | 154 | 155 | 163 | 169 | 170 | 179 | 185 | 186 | 194 | 200 | 201 | 209 | 215 | 216 | 225 | 231 | 232 | 241 | 247 | 248 | 256 | 262 | 263 | 271 | 277 | 278 | 286 | 292 | 293 | 301 | 307 | 308 | 316 | 322 | 323 | 331 | 337 | 338 | 346 | 352 | 353 | 361 | 367 | 368 | 376 | 382 | 383 | 391 | 397 | 398 | 406 | 412 | 413 | 421 | 427 | 428 | 436 | 442 | 443 | 452 | 458 | 459 | 467 | 473 | 474 | 482 | 488 | 489 | 490 | 492 | 493 | 495 | image/svg+xml 496 | 498 | 499 | 500 | 501 | 502 | 507 | 509 | 521 | 524 | 530 | 542 | 543 | 549 | 554 | 559 | 564 | 569 | 574 | 579 | 583 | 589 | 1 600 | 601 | 605 | 611 | 4 622 | 623 | 627 | 633 | 2 644 | 645 | 649 | 655 | 6 666 | 667 | 671 | 677 | 5 688 | 689 | 693 | 699 | 7 710 | 711 | 715 | 721 | 8 732 | 733 | 737 | 743 | 3 754 | 755 | 760 | 772 | 775 | 800 | 805 | 810 | 815 | 821 | 827 | 832 | 837 | 842 | 847 | 852 | 857 | 862 | 867 | 872 | 877 | 882 | 887 | 892 | 897 | 900 | 945 | 948 | 989 | 992 | 1009 | 1012 | 1029 | 1032 | 1049 | 1052 | 1069 | 1072 | 1089 | 1092 | 1109 | 1110 | 1111 | 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 | 19 | 44 | 46 | 54 | 60 | 61 | 69 | 75 | 76 | 84 | 90 | 91 | 99 | 105 | 106 | 114 | 120 | 121 | 129 | 135 | 136 | 144 | 150 | 151 | 160 | 166 | 167 | 175 | 181 | 182 | 183 | 185 | 186 | 188 | image/svg+xml 189 | 191 | 192 | 193 | 194 | 195 | 200 | 206 | 212 | 218 | 223 | 228 | 240 | 252 | 255 | 276 | 279 | 300 | 306 | Start (t=0) 317 | 323 | End (t=1) 334 | 335 | 336 | --------------------------------------------------------------------------------