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

Geometry export workflow #1

Closed mostaphaRoudsari closed 8 years ago

mostaphaRoudsari commented 9 years ago

Hello all,

Right now the main question that I have is about the best way to export the geometry to OpenFOAM.

@stefan-buildSCI sent me an example file of a room with two windows. I did a test to generate blockMeshDict from scratch. It is all good but creating multiple blocks is not really easy. It can get really hard for more complex geometries.

For this particular reason I think it might be a better idea to use Grasshopper > STL > OpenFOAM workflow. I couldn't find a good example file to see how to do this using the command line? I can export the geometry to STL with no problem. STL to OpenFOAM is the question.

  1. What are your thoughts on this?
  2. Does anyone have a good example?

@mcneillj @stefan-buildSCI @TheodoreGalanos

TheodoreGalanos commented 9 years ago

Hello Mostapha,

I have been using exactly that workflow for OpenFOAM in Linux. We can load the stl file directly through the snappyhexmesh dict. Actually what I usually do is pretty simple:

  1. Get the bounding box of the whole geometry, which is usually the block mesh (actually in external flows you always want a bigger blockMesh around your geometry but for internal I am guessing this is ok.
  2. Populate blockMeshDict using the vertices of the bounding box. I have a handy excel file I will share which takes the defining coordinates of the cube (bottom left & top right) and creates the blockMesh vertices. It's quite simple, I'll upload it tomorrow in github since it's in my work pc.
  3. After blockMesh is created, load geometry in snappyHexMesh from the .stl file(s) exported from Rhino.

I am guessing this workflow works as well in Windows, it shouldn't be different. The issue here is that internal CFDs have (or can have) much different snappyHexMesh dictionary. I will upload an example of an internal tutorial from OpenFOAM tomorrow.

Sorry I was out of it for a few days, was sick + work got crazy. Hoping to get much more time on this once a competition that is ongoing finishes.

stefan-buildSCI commented 9 years ago

Hi Mostapha,

I have a new test case ready here (sorry, I haven't figured out how to upload files to Github yet, next thing on my list! I'll use dropbox for now)

https://www.dropbox.com/s/39jy1ruwjg8tokr/2_building_test.zip?dl=0

I had begun typing this up before Theodore posted, so there is some repeating. I definitely agree with everything he says, and that Excel file will help with defining the vertices.

There are lots of issues with using STL geometry for blunt shaped objects. The mesher is not good at smoothing cells along these sharp edges, although it can work better if all corners are 90 degrees and aligned with the grid.

I managed to make a test case similar to the last test file of a room with two windows. It's uploaded to Butterfly/OpenFOAM_Sample_Files/originalFromStefan

The STL file needs to be labeled correctly. The facets representing the windows must have their own solid label, which you can see in constant/triSurface/building.stl.

I had an additional window on the east side but accidentally deleted it, Doh!

SnappyHexMesh is the command used to generate meshes from STL geometry. the parameters of snappyhexmesh are found in system/snappyHexMeshDict. For now the only parameters we are concerned with are under castellatedMeshControls in this file.

Basically to use snappyHexMesh, you must first generate a simple blockMesh. This mesh must be as big or bigger than the dimensions of the STL file you're using. It would be good to calculate the min, max dimensions of the STL file in xyz direction, and use this to fill out the vertex points of the blockMesh. The other parts of blockMesh should not be modified, basically we are making a big cube that will completely enclose the STL file.

Onto the snappyHexMeshDict....

locationInMesh{} is very important! SnappyHexMesh works by seeing where the blockMesh intersects the STL file. Say you had an STL file of a cylinder (representing a pipe) and a blockMesh surrounding the pipe geometry. If you wanted to simulate the fluid flowing through the pipe, you'd want to create a mesh of the inside of the pipe, so you could simulate pipe flow through the cylinder. If you wanted to simulate air flowing around the pipe, you would want the mesh surrounding the cylinder, but you wouldn't are about any of the mesh points inside of the cylinder. For natural ventilation inside buildings, we don't care about any mesh points that fall outside of the building, so the locationInMesh{} parameter should point to a spot inside the STL geometry boundary. That way when snappyHexMesh creates the mesh, it will cut off any mesh points outside of the boundary and keep all items that are inside the building.

Now to make the mesh set up in this file, first type the command

blockMesh

once it's finished, type

snappyHexMesh

Don't worry about getting a fatal error here, it is still making the mesh, we can fix that error later.

Type paraFoam to open paraview and view the mesh. It helps to set Representation to "surface with edges"

image

in the top of paraview there is a play, and backwards/forwards buttons.

image

You automatically start at 0. This mesh here is the blockMesh created. When you click forward to get to 1, which is the mesh that snappyHexMesh generated. Right now it looks good because of the simple geometry, but once we have non-orthongonal surfaces we will run into problems.

If you look at "Mesh Regions"

image

You can see the different parts of the mesh that were created. Uncheck internalmesh, and check the window regions. You can now see that the windows have been imported as separate patches! This means we can apply our inlet/outlet conditions to them! We will no doubt want to separately label all the surfaces in the STL geometry so we can set them all with their corresponding temperatures from EnergyPlus.

I'll be on a short vacation from tomorrow night until sunday, but let me know if there are any issues/questions.

TheodoreGalanos commented 9 years ago

Hello since it's quite simple, and to be honest I haven't uploaded a file yet here, I'll write down the way the excel sheet works.

To identify any square mesh or bounding box all you need is two points, as Stefan said the min and max. If we assume:

min = ( x1 , y1 , z1) and max = (x2 , y2 , z2) then the 8 vertices of the blockMesh grid will be:

( x1 y1 z1 ) ( x2 y1 z1 ) ( x2 y2 z1 ) ( x1 y2 z1 ) ( x1 y1 z2 ) ( x2 y1 z2 ) ( x2 y2 z2 ) (x1 y2 z2 )

A few other variables are:

Distance = [ ( x2 - x1 ) , ( y2 - y1) , (z2 - z1) ]

Now by dividing each distance, on the x-, y-, and z-axis, with the grid resolution (the values right next to the "hex ( 0 1 2 3 4 5 6 7 ) .." part of the code) we get the number of cells on each direction.

So we have:

Ci = Di/Ri , where Ci: cells on x,y,z direction, Di: distance on x,y,z direction.

Multiplying the number of cells in each direction (Cx * Cy * Cz) gives us the total number of cells of our blockMesh grid, with the current grid resolution.

I think both of these items can be added in our component. They are not revolutionary, as you can see it's simple calculations, but they add a nice functionality for new users in automatically writing a part of the blockMesh (the tedious one) and giving an idea of size, complexity, and estimated simulation time the blockMesh, and of SHM after it, to the user.

Hope this is ok, I'll start providing more useful input after this weekend I promise!

When do you all think we can have our Skype call btw? :)

mcneillj commented 9 years ago

It has been a couple years since I have used OpenFOAM heavily, but I had a slightly different workflow than what is shown above by Theodore and Stefan.

I was doing internal flow problems and found BlockMesh and SnappyHexMesh to be a bit cumbersome. I used Sketchup to create a STEP file, then GMSH (http://geuz.org/gmsh/) to create the mesh, and then on to OpenFOAM for the simulation. This worked pretty seamlessly for me and GMSH has very nice meshing tools built into it.

I'll be out of town this weekend, so won't be able to look up my old projects until next week, but this is a possible alternative workflow. Ideally, it would be nicer to keep everything within the OpenFOAM ecosystem, though.

It'll be interesting to see how we can integrate the meshing portion into a Rhino/Grasshopper tool. It would be really great to have the meshing be an interactive part of the 3D tool, since it's so important to the simulation. I've seen other attempts at simple CFD tools gloss over the meshing, which has lowered my confidence in the results. I'm hoping we can find a nice, elegant way to do this without overwhelming the users.

TheodoreGalanos commented 9 years ago

I totally agree with James, meshing is its own science to be honest and is probably more important in most cases than solving the case, as it is the base for it.

I am not as experienced in internal CFDs but in my brief time with them I also noticed that SHM was not as ideal for it as it is for external CFDs. I also followed the route of a 3rd party option, and I am using Salome (I worked in Linux so). Would be worth checking GMSH if it works in Windows. Unfortunately, unlike solvers, meshing programs are very rarely free (that's the value of SHM).

But I'd second the idea of investigating options on how to incorporate meshing directly in Grasshopper. I know Rhino has some capabilities for it but haven't checked them out.

mostaphaRoudsari commented 9 years ago

Thank you all for the great comments and sorry for getting back to you very late. I'm finally back to the US and this is the first weekend that I am at home.

My understanding is that we will need to use snappyHexMesh eventually at least for the outdoor studies so it's worthwhile to get the workflow to work. I also checked GMSH and it is licensed under GPL which means we can include it in the project with no problem.

I was thinking to generate the mesh outside Rhino/Grasshopper and import it back to Grasshopper for visualization. At the same time Grasshopper has very great plugins for meshing that might provide what @mcneillj mentioned. In that case we need to write our own mesh export in a way to be compatible with OpenFoam.

For the first next step (Proof of concept) I will try to get the process work based on @stefan-buildSCI's and @TheodoreGalanos's description. That also helps for having a prototype that I can share with you and from there it will much easier to make modifications and define alternative solutions.

@stefan-buildSCI the only question that I have is how do you generate the template to start before making any modifications? Do I need to create the file structure by myself or OpenFoam has a command for that to create a new project?

stefan-buildSCI commented 9 years ago

As far as I know you need to generate it yourself. If you look in $FOAM_TUTORIALS/heatTransfer/buoyantBoussinesqSimpleFoam you'll find example files that pertain to the type of simulations we want to do.

On Sat, Aug 15, 2015 at 10:08 PM, Mostapha Sadeghipour Roudsari < notifications@github.com> wrote:

Thank you all for the great comments and sorry for getting back to you very late. I'm finally back to the US and this is the first weekend that I am at home.

My understanding is that we will need to use snappyHexMesh eventually at least for the outdoor studies so it's worthwhile to get the workflow to work. I also checked GMSH and it is licensed under GPL which means we can include it in the project with no problem.

I was thinking to generate the mesh outside Rhino/Grasshopper and import it back to Grasshopper for visualization. At the same time Grasshopper has very great plugins for meshing that might provide what @mcneillj https://github.com/mcneillj mentioned. In that case we need to write our own mesh export in a way to be compatible with OpenFoam.

For the first next step (Proof of concept) I will try to get the process work based on @stefan-buildSCI https://github.com/stefan-buildSCI's and @TheodoreGalanos https://github.com/TheodoreGalanos's description. That also helps for having a prototype that I can share with you and from there it will much easier to make modifications and define alternative solutions.

@stefan-buildSCI https://github.com/stefan-buildSCI the only question that I have is how do you generate the template to start before making any modifications? Do I need to create the file structure by myself or OpenFoam has a command for that to create a new project?

— Reply to this email directly or view it on GitHub https://github.com/mostaphaRoudsari/Butterfly/issues/1#issuecomment-131491148 .

mostaphaRoudsari commented 9 years ago

Thanks! Now I have all I need for this weekend! :tada:

TheodoreGalanos commented 9 years ago

Hello everyone,

Sorry for being out of it for a bit.

I didn't manage to find out how to upload files in here so I added you in my dropbox folder Mostapha and you can upload perhaps.

It is the 2D case you asked me for. The .stl is a bit on the high side (can be zipped almost 95% though) but the dictionaries are quite light. It is an external case that was transformed into a 2D. Essentially 2D cases are exactly the same with 3D cases with the only difference that you choose the patches in the direction you don't want to be type 'empty'. Most of the times this is useful if you want to run a quick calculation of the case.

The model running is komega-sst and there are alos ABL Conditions (that is a logarithmic inlet profile of the wind.

In the files there is also a quite good SHM dictionary. Also, OF 2.4 supports now multi-grading in blockMesh, that might now work in our version but I left it there as a future perhaps addition. I haven't still tried OF in windows so I also included the simpleGrading option in case it doesn't yet support it. Although I do hope it does soon as MG is quite good option to have.

Finally, I also have included a function object in the case. Function objects are extremely important for analyzing and post-processing (in parallel and while simulating) cases. I am using the probes object which (if run in 3D of course) calculates the pressure in each point (aka probe) for each timestep.

I will make a list of all the interesting function objects and upload their code to the site soon. They all go in the controlDict file (at the very end) so it can be easily commented out if someone wants to try without.

Kind regards, Theodore.

TheodoreGalanos commented 9 years ago

Hi everyone,

I have also uploaded a small python script I was using to convert Salome meshes into open foam. Since it is in python, even though it involves a different program, perhaps you might find it helpful in checking how to write a mesh export.

Kind regards, Theodore.

mostaphaRoudsari commented 9 years ago

Hi @TheodoreGalanos, Thanks. They all sound very helpful. Can you upload the files to github and not dropbox?

You can add them under https://github.com/mostaphaRoudsari/Butterfly/tree/master/OpenFOAM_Sample_Files

TheodoreGalanos commented 9 years ago

Hi @mostaphaRoudsari thanks for uploading. I feel kind of stupid right now but I couldn't figure out the upload sequence in github, seemed like it wanted me to type my text files or smth. Ofc I did spent only a few minutes on it. I promise I'll google a guide or smth next time.

On a further note I have been creating default cases lately for my own simulations, SHM settings, boundary conditions, and solvers/codes that work for different cases. Once we are there I can contribute the dictionaries.

Kind regards, Theodore.

antonszilasi commented 9 years ago

@TheodoreGalanos @mostaphaRoudsari @stefan-buildSCI

Hi Theodore and Stefan

Thank you for your example files and your contribution to this discussion.

At the moment, I am pushing hard to get the basics developed for Butterfly, so I am using your example files.

Unfortunately I'm a beginner with OpenFOAM - although I did study CFD in university with ANYSYS. Subsequently I'm really struggling to understand your files, and I must say the file structure of OpenFOAM in general as well as how GH can be wrapped around it.

If either of you (or all of us together) would be able to have a Skype session, so I would be able to ask you some burning questions which I have about your example files and Openfoam in general. This would help me a great deal with my development.

My skype is anton.szilasi. Please add me and we can discuss a time on Skype, I am online most of the time.

Regards,

Anton

TheodoreGalanos commented 9 years ago

Well, this is a prompt response all right :)

I am sorry I was completely away. I am able to have a skype meeting during the weekend if that is ok with you. Time difference might be brutal for us, I live in Kuala Lumpur at the moment.

My skype ID is teddian, add me whenever you see this. I'll try and add you as well.

Kind regards, Theodore.

antonszilasi commented 8 years ago

@TheodoreGalanos

Sorry I didn't see your message from 10 days ago. I see you have added me on Skype and I didn't realise who you were. Lets talk over skype

stefan-buildSCI commented 8 years ago

Hi Anton,

I had added you on Skype and sent a message too. On Oct 17, 2015 2:06 PM, "Anton Szilasi" notifications@github.com wrote:

@TheodoreGalanos https://github.com/TheodoreGalanos

Sorry I didn't see your message from 10 days ago. I see you have added me on Skype and I didn't realise who you were. Lets talk over skype

— Reply to this email directly or view it on GitHub https://github.com/mostaphaRoudsari/Butterfly/issues/1#issuecomment-148950929 .

mostaphaRoudsari commented 8 years ago

All, I downloaded the new OpenFOAM for Windows today and I was able to follow @stefan-buildSCI's direction. What @TheodoreGalanos's has sent is a bit more complicated as it has extra files but the process should be very similar.

I just committed the libraries for creating base folders and writing solvers (902c77013fb13c6491df6faf0634ef05794e312b). If you run testButterfly.py it will create a folder under c:\user\%USERNAME%\butterfly\test and creates two solvers under folder 0. You can create your own solvers or use the ones that I created so far based on the example files. I won't have time to work on butterfly this week but if anyone wants to go ahead and create objects for constant and/or system folder let me know.

from butterfly import core
import butterfly.solvers as solvers

## initiate project
p = core.BFProject("test")

# boundary conditions in the model
bConditions = ["floor", "ceiling", "fixedWalls"]

# create the solver with default values
# you can create your own solver by using solvers.Solver > check solver.py for examples
p_rgh = solvers.P_RGH()
# add boundary field
for bc in bConditions: p_rgh.add_boundaryField(bc, other = {"rho":"rhok"})
p.add_solver(p_rgh) #add p_rgh to project

# add one more solver as an example
k = solvers.K()
for bc in bConditions: k.add_boundaryField(bc)
p.add_solver(k) # add to project

# write project
p.createProject()

Once we have the classes working we can start experimenting with stl and meshing. Have a look at new files and let me know your thoughts. I suggest to open a new issue for the new suggestions.

mostaphaRoudsari commented 8 years ago

I can finally close this! Thank you everyone for your comments! Now we have the workflow working with snappyHexMesh.

https://cloud.githubusercontent.com/assets/2915573/16251243/724df150-37f2-11e6-85e3-4dd630ece057.png

I opened a new issue #21 for following up the discussion about the default values.