Skip to content

Commit 7701ccf

Browse files
committed
Update output to blockMeshDict; refresh README
1 parent f33dd52 commit 7701ccf

File tree

4 files changed

+61
-62
lines changed

4 files changed

+61
-62
lines changed

README.md

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@
33
Python classes for easier creation of OpenFOAM's blockMesh dictionaries.
44

55
# About
6+
67
_blockMesh_ is a very powerful mesher but the amount of manual labour it requires to make even the simplest meshes makes it mostly useless. Even attempts to simplify or parametrize blockMeshDicts with `#calc` or even the dreadful `m4` quickly become unmanageable and cryptic.
78

89
classy_blocks' aim is to minimize the amount of meticulous work by providing a
910
more intuitive workflow, off-the-shelf parts and some automatic helpers for building and optimization of block-structured hexahedral meshes.
1011
Still it is not an automatic mesher and therefore some kinds of geometry are more suited than others.
1112

1213
## Tutorial
14+
1315
Check out the [classy_blocks tutorial on damogranlabs.com](https://damogranlabs.com/2023/04/classy_blocks-tutorial-part-1-the-basics/)!
1416

1517
## Useful For
18+
1619
### Fields
20+
1721
- Turbomachinery (impellers, propellers)
1822
- Microfluidics
1923
- Flow around buildings
@@ -22,6 +26,7 @@ Check out the [classy_blocks tutorial on damogranlabs.com](https://damogranlabs.
2226
- Solids (heat transfer, mechanical stresses)
2327

2428
### Cases
29+
2530
- Simpler rotational geometry (immersed rotors, mixers, cyclones)
2631
- Pipes/channels
2732
- Tanks/plenums/containers
@@ -33,60 +38,65 @@ Check out the [classy_blocks tutorial on damogranlabs.com](https://damogranlabs.
3338
- Overset meshes
3439

3540
## Not Good For
41+
3642
- External aerodynamics of vehicles (too complex to mesh manually, without refinement generates too many cells)
3743
- Complex geometry in general
3844
- One-off simulations (use automatic meshers)
3945

4046
# How To Use It
47+
4148
- To install the current _stable_ version from pypi, use `pip install classy_blocks`
42-
- To download the cutting-edge development version, install the development branch from github: `pip install git+https://github.com/damogranlabs/classy_blocks.git@development`
49+
- To download the cutting-edge development version, install the development branch from Github: `pip install git+https://github.com/damogranlabs/classy_blocks.git@development`
4350
- If you want to run examples, follow instructions in [Examples](#examples)
44-
- If you want to contribute, follow instructions in [CONTRIBUTING.rst](CONTRIBUTING.rst)
51+
- If you want to contribute, follow instructions in [CONTRIBUTING.md](CONTRIBUTING.md)
4552

4653
# Features
4754

4855
## Workflow
56+
4957
As opposed to blockMesh, where the user is expected to manually enter pre-calculated vertices, edges, blocks and whatnot, classy_blocks tries to mimic procedural modeling of modern 3D CAD programs. Here, a Python script contains steps that describe geometry of blocks, their cell count, grading, patches and so on. At the end, the procedure is translated directly to blockMeshDict and no manual editing of the latter should be required.
5058

5159
## Building Elements
60+
5261
_Unchecked items are not implemented yet but are on a TODO list_
5362

5463
- [x] Manual definition of a Block with Vertices, Edges and Faces
5564
- [x] Operations (Loft, Extrude, Revolve)
56-
- [x] Loft
57-
- [x] Extrude
58-
- [x] Revolve
59-
- [x] Wedge (a shortcut to Revolve for 2D axisymmetric cases)
60-
- [x] Connector (A Loft between two existing Operations)
65+
- [x] Loft
66+
- [x] Extrude
67+
- [x] Revolve
68+
- [x] Wedge (a shortcut to Revolve for 2D axisymmetric cases)
69+
- [x] Connector (A Loft between two existing Operations)
6170
- [x] Sketches of common cross-sections
62-
- [x] Quarter and Semi circle
63-
- [x] Circle
64-
- [x] Boxed circle
65-
- [x] Oval with straight sides
66-
- [x] Ellipse (and ovals in various configurations)
67-
- [x] Cartesian grid
71+
- [x] Quarter and Semi circle
72+
- [x] Circle
73+
- [x] Boxed circle
74+
- [x] Oval with straight sides
75+
- [x] Ellipse (and ovals in various configurations)
76+
- [x] Cartesian grid
6877
- [x] Simple way of creating custom Sketches
6978
- [x] Easy shape creation from Sketches
7079
- [x] Predefined Shapes
71-
- [x] Box (shortcut to Block aligned with coordinate system)
72-
- [x] Elbow (bent pipe of various diameters/cross-sections)
73-
- [x] Cone Frustum (truncated cone)
74-
- [x] Cylinder
75-
- [x] Ring (annulus)
76-
- [x] Hemisphere
80+
- [x] Box (shortcut to Block aligned with coordinate system)
81+
- [x] Elbow (bent pipe of various diameters/cross-sections)
82+
- [x] Cone Frustum (truncated cone)
83+
- [x] Cylinder
84+
- [x] Ring (annulus)
85+
- [x] Hemisphere
7786
- [x] Stacks (collections of similar Shapes stacked on top of each other)
7887
- [x] Predefined parametric Objects
79-
- [x] T-joint (round pipes)
80-
- [x] X-joint
81-
- [x] N-joint (multiple pipes)
82-
- [ ] Other building tools
83-
- [x] Use existing Operation's Face to generate a new Operation
84-
- [x] Chain Shape's start/end surface to generate a new Shape
85-
- [x] Expand Shape's outer surface to generate a new Shape (Cylinder/Annulus > Annulus)
86-
- [x] Contract Shape's inner surface into a new Shape (Annulus > Cylinder/Annulus)
87-
- [x] Offset Operation's faces to form new operations
88+
- [x] T-joint (round pipes)
89+
- [x] X-joint
90+
- [x] N-joint (multiple pipes)
91+
- [x] Other building tools
92+
- [x] Use existing Operation's Face to generate a new Operation
93+
- [x] Chain Shape's start/end surface to generate a new Shape
94+
- [x] Expand Shape's outer surface to generate a new Shape (Cylinder/Annulus > Annulus)
95+
- [x] Contract Shape's inner surface into a new Shape (Annulus > Cylinder/Annulus)
96+
- [x] Offset Operation's faces to form new operations (Shell)
8897

8998
## Modifiers
99+
90100
After blocks have been placed, it is possible to create new geometry based on placed blocks or to modify them.
91101

92102
- [x] Move Vertex/Edge/Face
@@ -95,6 +105,7 @@ After blocks have been placed, it is possible to create new geometry based on pl
95105
- [x] Optimize point position of a Sketch or mesh vertices
96106

97107
## Meshing Specification
108+
98109
- [x] Simple definition of all supported kinds of edges with a dedicated class (Arc/Origin/Angle/Spline/PolyLine/Project)
99110
- [x] Automatic sorting/reorienting of block vertices based on specified _front_ and _top_ points
100111
- [x] Automatic calculation of cell count and grading by specifying any of a number of parameters (cell-to-cell expansion ratio, start cell width, end cell width, total expansion ratio)
@@ -116,6 +127,7 @@ How to run:
116127
- Open `examples/case/case.foam` in ParaView to view the result
117128

118129
For instance:
130+
119131
```bash
120132
cd examples/chaining
121133
python tank.py
@@ -161,8 +173,8 @@ mesh.add(revolve)
161173

162174
> See `examples/operations` for an example of each operation.
163175
164-
165176
## Shapes
177+
166178
Some basic shapes are ready-made so that there's no need for workout with Operations.
167179

168180
A simple Cylinder:
@@ -204,6 +216,7 @@ Venturi tube
204216
> See `examples/chaining` for an example of each operation.
205217
206218
## Custom Sketches and Shapes
219+
207220
A Sketch is a collection of faces - essentially a 2D geometric object, split into quadrangles. Each Face in a Sketch is transformed into 3D space, creating a Shape.
208221

209222
A number of predefined Sketches is available to choose from but it's easy to create a custom one.
@@ -220,6 +233,7 @@ Points that define a custom sketch can only be placed approximately. Their posit
220233
> See `examples/shape/custom` for an example with a custom sketch.
221234
222235
## Stacks
236+
223237
A collection of similar Shapes; a Stack is created by starting with a Sketch, then transforming it a number of times, obtaining Shapes, stacked on top of each other.
224238

225239
An Oval sketch, translated and rotated to obtain a Shape from which a Stack is made.
@@ -235,23 +249,25 @@ stack = ExtrudedStack(base, side * 2, 2)
235249
# ...
236250
mesh.delete(stack.grid[0][1][1])
237251
```
252+
238253
![Cube](showcase/cube.png "Flow around a Cube")
239254

240255
> See `examples/stack/cube.py` for the full script.
241256
242-
243257
An electric heater in water, a mesh with two cellZones. The heater zone with surrounding fuild of square cross-section is an extruded `WrappedDisk` followed by a `RevolvedStack` of the same cross-sections. The center is then filled with a `SemiCylinder`.
244258
![Heater](showcase/heater.png "Heater")
245259

246260
> See `examples/complex/heater` for the full script.
247261
248262
## Assemblies
263+
249264
A collection of pre-assembled parametric Shapes, ready to be used for further construction.
250265

251266
Three pipes, joined in a single point.
252267
![N-Joint](showcase/n_joint.png)
253268

254269
## Automatic Grading
270+
255271
After blocks have been positioned their cell count must be defined. This can be done manually with something like `operation.chop(axis, start_size=..., c2c_expansion=...)` or anything that `.chop()` method supports. Not all blocks need to be chopped as cell counts will be propagated throughout the mesh so it is advisable to only _chop_ the minimum required.
256272

257273
All that can also be avoided by using automatic graders, for instance, `SmoothGrader` will set counts so that desired cell size will be obtained but will also use multigrading to keep cell sizes between neighbouring blocks as uniform as possible.
@@ -271,7 +287,6 @@ Projecting a block side to a geometry is straightforward; edges, however, can be
271287

272288
Geometry is specified as a simple dictionary of strings and is thrown in blockMeshDict exactly as provided by the user.
273289

274-
275290
```python
276291
geometry = {
277292
'terrain': [
@@ -375,6 +390,7 @@ Airfoil core with blunt trailing edge (imported points from NACA generator) and
375390
![Airfoil](showcase/airfoil.png "Airfoil core mesh")
376391

377392
## Automatic Edge Grading
393+
378394
When setting cell counts and expansion ratios, it is possible to specify which value to keep constant. Mostly this will be used for keeping thickness of the first cell at the wall consistent to maintain desired `y+` throughout the mesh. This is done by simple specifying a `preserve="..."` keyword.
379395

380396
Example: a block chopped in a classic way where cell sizes will increase when block size increases:
@@ -389,12 +405,12 @@ By showing `block_ids` with a proper color scale the blocking can be visualized.
389405
This is useful when blockMesh fails with errors reporting invalid/inside-out blocks but VTK will
390406
happily show anything.
391407

392-
## Also!
408+
## Also
393409

394410
2D mesh for studying Karman Vortex Street
395411
![Karman Vortex Street](showcase/karman.png "Karman vortex street")
396412

397-
A parametric, Low-Re mesh of a real-life impeller *(not included in examples)*
413+
A parametric, Low-Re mesh of a real-life impeller _(not included in examples)_
398414
![Impeller - Low Re](showcase/impeller_full.png "Low-Re Impeller")
399415

400416
A gear, made from a curve of a single tooth, calculated by
@@ -408,9 +424,10 @@ A complex example: parametric, Low-Re mesh of a cyclone
408424
409425
# Prerequisites
410426

411-
Package (python) dependencies can be found in *pyproject.toml* file.
427+
Package (python) dependencies can be found in _pyproject.toml_ file.
412428
Other dependencies that must be installed:
413-
- python3.8 and higher
429+
430+
- python3.9 and higher
414431
- OpenFoam: .org or .com version is supported, foam-extend's blockMesh doesn't support multigrading but is otherwise also compatible. BlockMesh is not required to run Python scripts. There is an ongoing effort to create VTK meshes from within classy_blocks. See the wip_mesher branch for the latest updates.
415432

416433
# Technical Information

classy_blocks.code-workspace

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/classy_blocks/util/constants.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,19 @@ def vector_format(vector) -> str:
6060

6161
MESH_HEADER = (
6262
"/*---------------------------------------------------------------------------*\\\n"
63-
"| ========= | |\n"
63+
"| ========= | |\n"
6464
"| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n"
65-
"| \\ / O peration | Version: v1806/v10 |\n"
66-
"| \\ / A nd | Web: https://www.OpenFOAM.com |\n"
67-
"| \\/ M anipulation | https://www.OpenFOAM.org |\n"
65+
"| \\ / O peration | Script: {script:<40s}|\n"
66+
"| \\ / A nd | Time: {timestamp:<42s}|\n"
67+
"| \\/ M anipulation | |\n"
6868
"\\*---------------------------------------------------------------------------*/\n"
6969
"FoamFile\n"
70-
"{\n"
70+
"{{\n"
7171
" version 2.0;\n"
7272
" format ascii;\n"
7373
" class dictionary;\n"
7474
" object blockMeshDict;\n"
75-
"}\n"
75+
"}}\n"
7676
"// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n"
7777
)
7878

src/classy_blocks/write/writer.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import datetime
2+
import sys
13
from dataclasses import asdict
24
from typing import Callable
35

@@ -77,7 +79,7 @@ def __init__(self, dump: AssembledDump, settings: Settings):
7779

7880
def write(self, output_path: str):
7981
with open(output_path, "w", encoding="utf-8") as output:
80-
output.write(constants.MESH_HEADER)
82+
output.write(constants.MESH_HEADER.format(script=sys.argv[0], timestamp=str(datetime.datetime.now())))
8183

8284
output.write(format_geometry(self.settings.geometry))
8385

0 commit comments

Comments
 (0)