ladybug-tools / butterfly

:butterfly: A light python API for creating and running OpenFoam cases for CFD simulation.
http://ladybug-tools.github.io/butterfly.html
GNU General Public License v3.0
248 stars 70 forks source link

Butterfly Roadmap 3. From Theodore's workflow #7

Closed antonszilasi closed 8 years ago

antonszilasi commented 8 years ago

3a. The next step of the workflow is to create the mesh, by setting up the snappyHexMeshDict file. I'd like to note here that what is below stands for external simulations. I do not believe that SHM is good for internal meshing as it complicates things a lot. I will suggest a different program (opensource, tied to OF, and available in windows) for internal cases. SHM looks frightening at first glance, it has almost 100 options. However, a handful of these options can or should be adjusted, the rest can remain default values unless the user is experienced and wants to edit the dictionary by hand. The options that I usually change from simulation to simulation are:

1) maxLocalCells, the maximum number of cells per processor usually tied to the next option. 2) MaxGlobalCells, the total cells of the resulting mesh (most of the times the mesh is bigger than this). This defines when refinement stops, once it passes the limit and it is tied to the capacities of your computer, mainly ram. 3) MinRefinementCells, when the refinement process stops. I usually have this down to 10, since I want refined meshes. 4) NcellsBetweenLevels, defined the number of cells between the different levels of refinement in each region. Higher numbers make for a more gradual mesh but I find that 1 is the best option here. Can be default 5) refinementSurfaces { }, here is where we define the surfaces and regions to be refined, as well as the level of refinement. By level we mean how many times the original blockMesh cell is divided. 6) LocationInMesh, very important in defining what is the inside of your mesh. I usually put this somewhere high up near the top of my blockMesh for external and also never on coordinates like (100, 200, 50) but smth like (100.123 200.431 50.112). If this happens to be 'inside' a geometry, then snappyHexMesh will do an internal meshing and that would be wrong. Perhaps a check can exist here to tell the user the point u selected is inside an stl. 7) The rest are mostly quality options on meshing. We can leave them default or create low, medium, high quality templates. I will share some of mine soon.

As mentioned in 1b, after exporting our geometry we should end up with either 1 .stl file containing all regions of the model or several .stl files with each region of the model. This file or files are then what we call in the geometry { } section of the snappyHexMeshDict. The convention of renaming each file or each region within the single file or in each file, as described in 1b, becomes important here. In the refinementSurfaces section of the SHM dictionary, it is that specific name that we use in order to 'call' the region and assign it a specific refinement level (in my example below, in order to save cells, I refine the context and podium in a much much lower degree than my towers):

refinementSurfaces { Development //the name of the single, joined, stl filename { level (1 1) // the level of refinement for the WHOLE geometry regions //here we define the specific regions WITHIN the single stl { Context { level (2 2) } Podium { level (3 3) } Tower_1 { level (5 5) } Tower_2 { level (5 5) } Tower_3 { level (5 5) }
} }

3b. After we run snappyHexMesh, we will end up with a number of different folders containing a different version of the mesh. These depend on the first three options of the SHM dict:

• castellatedMesh • snap • addLayers

These represent the 3 different stages of mesh creation. A folder is created for each option set to true. In castellatedMesh, the geometry is assigned the different refinement levels and the different regions are refined and cells are added accordingly. In the snap stage, the geometry is then snapped into the blockMesh, and then optimised, chiseled, in a way. In the addLayers stage, layers of cells are added to the boundaries. For most of the external simulations that we would be doing, this is not necessary. It is also something that snappyHexMesh does badly. So I propose that the standard is here:

castellatedMesh true; snap true; addLayers false;

(although I usually have addLayers to true, but without adding layers, which adds a couple more extra quality controls to the process. I am unsure how this affects quality though, still to be tested more.)

The above means that 2 folders will be created in our case folder. Each folder has a polymesh inside. To run the simulation we need the last one, but openfoam allows you to export all in order to see and test your meshing step by step. The usual process, and this you can see in the very useful bash scripts in the openFoam tutorials (Allrun), is to copy the polymesh from the last time folder to your constant/ folder, then delete the 1/ 2/ folders from the main folder. We could either use the bashscripts to do this or we can code it ourselves, since it mainly has to do with folder manipulation. The final folder has to have a 0/, constant (with the last polyMesh inside), and system/ folders. **NOTE: I like to have things clean and neat so this is my workflow. Openfoam allows you to not delete any folders created by SHM but instead to start solving from the last 'time directory' which would be the last folder of SHM. So most allrun scripts just copy the '0' folder in the last SHM folder and run. I find this very messy as it leaves things I dont want or need in my case folder. But it is easier I guess.

3c. After the meshing process is done and the whole folder clean up happens we need to make sure that the new polyMesh/boundary file is in accordance to our 0 folder files. That means that every geometry we added to the mesh (the boundaryfileds added here are linked to the refinementSurfaces names used, which are linked to the .stl file names, you see the importance of renaming them in the first place to avoid errors). These are typically walls and specific type of boundary conditions are added to them (I will also upload a few documents on this soon). But what is important in order for the thing to run is every boundaryfield in the polymesh/boundary file is there in our 0 folders.

3d. After that we should be ready to run our simulation. To run a simulation a few additional files are needed:

controlDict: defines the solver, when to save results, etc. and ALSO the function objects (i.e. real-time post-processing). I will also add a few incredible function objects for us here to input on our tool. Function objects are the things that give OF power and versatility. FvSolution: the options for solving all equations, accuracies, and when to stop fvSchemes: the numerical schemes to solve these equations.

**NOTE: I have left the parallel computation outside of this document, we can discuss it in the future, it really changes nothing on the above.

For all these I will again provide some standard values for each type of simulation, solver, and more importantly mesh quality. But ofc, these will just be my input more are welcome here!

When all these are set, we simply call the solver (which is defined in controlDict) by name and run the simulation. In future documents I will go more into detail on these last parts, but I think the setting up of the case folders which I tried to describe here is more important atm.

mostaphaRoudsari commented 8 years ago

This is done! If there is any pieces left let's start a open a new more specific issue.

mostaphaRoudsari commented 8 years ago

via https://github.com/mostaphaRoudsari/Butterfly/commit/01ea582c5d0a2925888674fd6de131fff2e91cc5