Sunday, March 2, 2014

Cyclorotor CFD Simulations in OpenFOAM

A few months ago, I became interested in the cyclorotor concept. This concept goes by many names, including cyclogyro and cyclocopter. The cyclorotor concept has been around since the early 1900's, and has recently had revived interest. I think this is due to modern materials and controls making the concept more feasible. Some universities I have seen in research papers include the University of Maryland and Seoul National University. To see one in action, check out this video:

I ran a few simulations in OpenFOAM to explore the capabilities of the cyclorotor. Here, I will describe validation runs that show that OpenFOAM can accurately predict cyclorotor performance. I used the pimpleDyMFoam solver in PISO mode (no SIMPLE iterations) and a Spalart-Allmaras RANS turbulence model with curvature correction.

Some more solver details:
-Max Courant number of 2
-First order in space and time
-Upwind spatial discretization scheme

OpenFOAM cannot run cyclorotor simulations 'out of the box'. It requires some custom solidBodyMotionFunctions, because the blades rotate in a certain way about its own pitch center, while being displaced by rotating around the rotor center. I have uploaded the code I used to Github here:

The mesh I used consisted of a square far-field boundary with inflation layers near the shaft and blades. I meshed it in Gmsh.

The following videos show the velocity magnitude and pressure fields.

The following shows experimental results from a Seoul National University research paper, and my OpenFOAM simulations. OpenFOAM results match quite closely. The OpenFOAM simulations were performed in 2D.

Ultimately, I found the cyclorotor concept not very practical (at the time of writing this). These are the reasons:
-Complicated mechanisms
-Forward flight performance not favorable
-Structures. Centrifugal loads are very high, and the blades have to resist this in a weak orientation (i.e. tangential vs radial chord line alignment).

Although there is an interesting track mechanism that I have seen in research reports that can alleviate forward flight problems and greater blade pitch control in general, but in my opinion it is still complicated and sensitive to geometry. The mechanism involves wheels on the tips of the blades that ride on the inside of a specially-shaped track. The wheel stays on the track by the inherent centrifugal forces on the blades. Control comes from translating the track in the plane of rotation, as well as the in the direction of the rotation vector. The track changes shape smoothly along the direction of the rotation vector so as to get the desired pitches.

In my opinion the most significant advantage of the cyclorotor is thrust direction freedom.

At the request of Francois, you can find the mesh files here:

At the request of Thomas, I have posted the case and mesh files here:


  1. hi ım mehmet from Turkey engineering student ı want to meet you and ask some ques.. about pic and esc,brushless dc motor speed control please contact me on my emaıl address that;

    1. If you ask on the blog, everyone can see it, which may answer some people's questions.

  2. Great work !

    I'm also using OpenFOAM and gmsh for various CFD simulation.
    Your boundary layer mesh are quite nice.

    What feature/algorithm did you use to obtain those hybrid (boundary layr+unstructured) meshes ? Could you link your .geo file ?

    Any way great post !


    1. Hello Francois,
      I used Gmsh for about a year or so before realizing you could do hybrid meshes. It is very sijmple; you simply declare the region you want to be structured or unstructured. Of course, you have to create the regions such that they will be amenable to being declared structured. The mesh you see is simply two adjacent regions that are unstructured (recombined) and structured. I have attached the mesh files in the link at the bottom of the post so you can see.

    2. I'm sorry to be so late
      Thank you very very much, I really appreciate :)

  3. Hi,

    This is fantastic work!!! Im doing a University project on cyclocopters at the moment at the University of Bath. The aim is to get a working rotor made to do various lift and power tests. Thank god ive found this code, its great work.

    This is my first time using openFOAM so I may have a couple of questions if thats OK? You seem to know whats going on pretty well


    1. Thanks! I am glad someone else sees the value in what I am doing, and that it could potentially be useful to you.

      Sure, all questions are welcome. Preferably, you can ask them here so that everyone can see the answers.

    2. Its a great value. I am currently working on a mathematical model in Matlab that can calculate the power and lift and cfd analysis like youve done would help support my model.

      This may seem like a stupid question, but how do you get openFOAM to run the code? I am totally new to openFOAM, ive only used flow simulation in SolidWorks for previous CFD projects which is a lot simpler.

      I have downloaded the code from github, and got the mesh files youve previously posted, what is the next step?



    3. Ah, first you have to learn to use OpenFOAM. I use Ubuntu OS. It is pretty simple to install these days just follow the instructions on the OpenFOAM official website. Then once you have verified your installation is working you can follow the instructions for compiling my code that you have downloaded from Github. The instructions are inside the main folder of the code you downloaded. Then it should be relatively straightforward but feel free to ask anything.

    4. Ive installed Ubuntu, and openFOAM, and done the first few tutorials to confirm its all working.

      When I run ./remake I get an error:
      make: *** [Make/linux64GccDPOpt/cycloRamp.o] Error 1
      cp: cannot stat `/home/tom/OpenFOAM/tom-2.3.0/platforms/linux64GccDPOpt/lib/': No such file or directory

      Do you know what this is?

    5. This comment has been removed by the author.

    6. OK, ive read through the 'compiling new OpenFOAM source' file.

      All the points in that are done from the files in Github except the add library to controlDict. Does that line get added to the controlDict in file system/opt/openfoam230/etc?

      Do you need to put the files in a specific folder? or can they just be run from the Home/OpenFOAM_Additions/cycloRamp folder?

      Alternatly, Ive run the remake file with sudo privileges, and its saying wclean and wmake are not found and 'missing destination file operand after `/''

      Thanks for the help, its much appreciated


    7. Just to be sure, did you follow the 'compiling new OpenFOAM source' instructions step by step? If so, what step do you get the first error?

    8. Ive followed it up till the add line to controlDict. Where do I find controlDict?

  4. This comment has been removed by the author.

  5. Ive followed it up till the add line to controlDict. Where do I find controlDict?

    1. The controlDict is one of the main input files to any OpenFOAM case. It is also essential; you cannot run a simulation without it. You can find it under the system folder.

    2. This comment has been removed by the author.

  6. OK, I think im pretty much there, which controlDict do I add the line to? as in, which example case do I run to make the code work.

    I asked the questions here:

    I hope you dont mind, it was just with the time difference it would take longer to get it working. Im pretty sure I know what im doing now, just need to know what example to run to make use of the new library


    1. Hmmm I suppose I made an underestimation in the difficulty for others to get it running. I will post a case file on your forum thread. I don't mind of course! I did post it on the Internet after all. Please check your thread in at most a few hours.

    2. It should be up now on your thread, in case you did not get the notification.

  7. Good stuff. Thanks for sharing your work. I wrote the papers regarding the cam mechanism you referred to and have designed, build, and flown some cyclogyro aircraft. I am active in this research field I am happy to speak with you if you have any questions regarding the analytic or experimental side of things. tomakeitflyiseverything @gmail

    1. Awesome! Hopefully more people who are interested in developing the cyclorotor technology can use OpenFOAM, as it is free and accurate and thus can be a powerful design tool.

      I do have one question; How does cyclorotor technology fare in forward flight these days? From the research papers I have read when I used to have University access to research papers, forward flight is not in the natural capability of the cyclorotor tech and required special design. Have there been any updates? Your cam mechanism can probably easily handle forward flight, but does it require a special forward flight state that is distinct from the high-lift hover state?

    2. I am developing another OpenFOAM model now with a bit more detail. I may pass it to you when I complete it. I value open source software. 

      Cyclorotors are in the infancy stage for forward flight, however they hold some promise. To my knowledge only one graduate student (Tejaswi Jarugumilli) has experimentally and computationally evaluated the problem in detail. He found that there are complex interactions between blades in forward flight, and that the performance, not surprisingly, is extremely sensitive to blade pitching kinematics. However, no one has developed a theory to identify optimum pitching kinematics. The bottom line is that we don't understand the flow physics in forward flight well yet, so we cannot optimize the pitching kinematics, and therefore achieve performance to compare with other systems. 

      However, cyclorotors hold a lot of promise for forward flight application for a couple of big reasons. First, with the proper pitching motions the entire blade can more or less be optimized for every flight condition. This is not the case for helicopter rotors or propellers which can only be optimized for a single flight condition due to blade twist. Second, when applied to produce lift and thrust, they do not produce asymmetric lift at high speeds from retreating blade stall. Thus they can operate at advance ratios both well above and below one. However, more research must be done to begin to realize these advantages. I believe the central problem now is identifying the optimum pitching kinematics. It will probably require a new analytical theory. Pitching motions predicted by the theory can then be refined with high fidelity simulations and validated with experiments. 

      I'm not sure I understand your last question. The cam mechanism can make an arbitrary pitching motion for each forward speed. At each speed that motion can be tweaked by cam motion to adjust forces. Thus an optimum adjustable pitching motion can be produced for hovering, and each forward flight mode. 

      Hope this helps.

  8. Lordvon,

    Again, thanks for your cyclorotor openFoam work. I am excited that others are working on cyclorotors and cycloturbines. For my PhD dissertation research, I am working to optimize pitching motions for cyclorotors and cycloturbines (variable pitch vertical axis wind turbines), and establish a more fundamental understanding of the physics of these machines at advance ratios greater than zero. My research is necessarily theoretical, computational, and experimental. Theory is necessary to establish baseline optimized pitching motions, which can be further optimized, and understood with higher fidelity simulations (in my case 2D viscous CFD with appropriate turbulence modeling) and experiments.

    Before I found your blog I started developing my own cyclorotor/turbine openFOAM code. My goal is to develop a code in which the user can simply specify the rotor geometry (chord, number of blades, airfoil section, etc), the pitching schedule, and environmental variables (TSR/advance ratio and Reynolds number), then the code will generate an appropriate mesh and run the code.

    Over the last couple of months I developed a mesh generation code. I am unfamiliar with C++ so I wrote it in Octave. As far as I can tell, I got this part to work. It allows the user to input the geometry of the rotor (with a minimum of two blades) and mesh details and then generates a blockMeshDict file for openFoam to generate the mesh. It allows for considerable flexibility in changing mesh resolution in various parts of the mesh. Users can change the spacing in the boundary layer, airfoil wake regions, rotor interior, rotor wake, etc.

  9. Now I am attempting to implement this mesh generation tool in openFoam with a blade motion generation tool. I am impressed that you created motion functions specifically for cyclorotors. I thought that I could accomplish the same thing with a more arbitrary simple approach. I developed another octave code that took an arbitrary pitching schedule defined by arrays in octave and spit out 6DOF .dat files for each blade and the rotor mesh (thus the number of .dat files equals the number of blades +1). The same program also creates a dynamicMeshDict file to implement those motion files with the existing mesh.

    After creating these tools I started trying to test them in openFoam by manually writing the remaining dictionaries. I quickly found myself in the inevitable debugging nightmare. After many days of work I have exhausted all of my expertise and I need a little help. Would you be willing to assist? My expertise is experimental, and I am still learning computational simulations.

    When I get this working I intend to release it. It would allow anyone to reasonably simply run parametric computational studies on cyclorotors and cycloturbines of arbitrary geometry. I value your first step in making this happen. I think the automated meshing tool I created is the next logical and important step for an open source cyclorotor computational tool.

    I have uploaded all of the files to:

    There is a writer document in the file with a few more details on my code as well as how to run it, and the trouble I am having.

    Namely I am running into what I believe is a divide by zero error when the mesh tries to move for the new time step. This error (may not make any sense without digging):

    “[0] [1] #0 Foam::error::printStack(Foam::Ostream&)[2] #0 Foam::error::printStack(Foam::Ostream&)[3] #0 Foam::error::printStack(Foam::Ostream&)#0 Foam::error::printStack(Foam::Ostream&) in "/opt/openfoam230/platforms/linux64GccDPOpt/lib/"
    [1] #1 Foam::sigFpe::sigHandler(int) in "/opt/openfoam230/platforms/linux64GccDPOpt/lib/"”

    I suspect the solution is simply a bad boundary condition or mesh movement parameter. However I have tried everything. I have tried many different turbulence models (including laminar) with the same error. I have also tried modifying the mesh, and the motion files.

    If this cannot be corrected perhaps we can combine our efforts. We could use my mesh generation code for meshing and your motion files for moving the blades and rotor.

    Thanks for your assistance in advance if you can help. I am more than happy to help out wherever I can.



    1. Hello Crasher,
      I would be happy to help as my time allows. If you are still debugging it, I would suggest using 'moveDynamicMesh', which only moves the mesh according to the dynamicMeshDict file. You can save the timesteps as in a normal simulation via the controlDict, and then view how the mesh moves before the simulation crashes. This way, you can identify the nature of the mesh movement error if it is indeed the mesh movement, and also identify whether the error is isolated to the mesh movement, rather than the fluid dynamics-related parameters.
      Could you put a compressed version of your files on google drive? I can't find an option to download all of the files to try out on my machine, and I don't want to download them individually.
      I saw that in your Notes you said that you were in the Eastern time zone (as am I). If you don't mind me asking, do you happen to go to UMD? I have seen many cyclorotor papers from there.

    2. Robert,

      Thank you for your help. Time is always precious and I especially value your assistance. Let me know how I can help in return. I uploaded a compressed version here:

      I always wished, but was unaware that I could troubleshoot with just mesh movement. I will work with that this week and see if I can find the error with that troubleshooting technique.

      I have worked with the cyclorotor group at UMD, but currently I'm at Purdue.


    3. Robert,

      I have been working with the moveDynamicMesh command without success. I suspect my error is not in mesh motion but a different dictionary since specifying the mesh to not move does not change the error. When I run "moveDynamicMesh" I get the following error:
      Create time

      Create mesh for time = 0

      Selecting dynamicFvMesh multiSolidBodyMotionFvMesh
      Selecting solid-body motion function tabulated6DoFMotion
      Applying solid body motion tabulated6DoFMotion to 49526 points of cellZone rotor
      Selecting solid-body motion function tabulated6DoFMotion
      Applying solid body motion tabulated6DoFMotion to 17442 points of cellZone blade1
      Selecting solid-body motion function tabulated6DoFMotion
      Applying solid body motion tabulated6DoFMotion to 17390 points of cellZone blade2
      Selecting solid-body motion function tabulated6DoFMotion
      Applying solid body motion tabulated6DoFMotion to 17442 points of cellZone blade3
      Selecting solid-body motion function tabulated6DoFMotion
      Applying solid body motion tabulated6DoFMotion to 17390 points of cellZone blade4
      forces forces:
      Not including porosity effects

      forceCoeffs forceCoeffs:
      Not including porosity effects

      Time = 0.01
      solidBodyMotionFunctions::tabulated6DoFMotion::transformation(): Time = 0.01 transformation: ((0 0 0) (0.952313 (0 0 -0.305121)))
      solidBodyMotionFunctions::tabulated6DoFMotion::transformation(): Time = 0.01 transformation: ((-0.581142 1.1862 0) (0.952313 (0 0 -0.305121)))
      solidBodyMotionFunctions::tabulated6DoFMotion::transformation(): Time = 0.01 transformation: ((-2.58114 -0.813802 0) (0.457634 (0 0 -0.889141)))
      solidBodyMotionFunctions::tabulated6DoFMotion::transformation(): Time = 0.01 transformation: ((-0.581142 -2.8138 0) (-0.305121 (0 0 -0.952313)))
      solidBodyMotionFunctions::tabulated6DoFMotion::transformation(): Time = 0.01 transformation: ((1.41886 -0.813802 0) (-0.889141 (0 0 -0.457634)))
      AMI: Creating addressing and weights between 270 source faces and 160 target faces
      --> FOAM Warning :
      From function AMIMethod::checkPatches()
      in file lnInclude/AMIMethod.C at line 57
      Source and target patch bounding boxes are not similar
      source box span : (0.999962 0.999962 0.05)
      target box span : (0.999951 1.00004 0.05)
      source box : (-0.267319 0.105073 0) (0.732643 1.10503 0.05)
      target box : (0.313771 -1.08119 0) (1.31372 -0.0811493 0.05)
      inflated target box : (0.243016 -1.15195 -0.0707546) (1.38448 -0.0103947 0.120755)

      Unable to find initial target face

      From function void Foam::AMIMethod::initialise(label&, label&)
      in file lnInclude/AMIMethod.C at line 139.

      FOAM aborting

      #0 Foam::error::printStack(Foam::Ostream&) at ??:?
      #1 Foam::error::abort() at ??:?
      #2 Foam::AMIMethod > const&, Foam::Vector >, Foam::PrimitivePatch > const&, Foam::Vector > >::initialise(Foam::List >&, Foam::List >&, Foam::List >&, Foam::List >&, int&, int&) at ??:?

    4. This comment has been removed by the author.

    5. I also realized that I may have missed an Octave subfile in the repository I previously uploaded. I have that file (to be placed in the main directory here:

      Once again thank you for the help. I'm sure I'm just making a simple error that is due to my poor understanding of C++.



    6. Hi Crasher,
      I see it's been a long time of your attempt regarding cycloturbine (geom+mesh+motion) files, but can you still help on this issue?

  10. Can you post the case files on GitHub as well? I am most curious about how to activate the curvature correction in the Spalart-Allamaras model. That looks like a really nice mesh too. Do you have any good resources on how to learn to create one like it, especially moving into 3D?

    1. Hi Pete,
      I will have to dig around for the original case files, but I believe I posted a copy on the CFD-online forums here:
      (Look at the 6th post)

      The Spalart-Allmaras with Curvature correction is probably of minor significance (if any). The mesh was created by simply defining (recombined) unstructured and structured regions with a common boundary in Gmsh. A 3D version of the above can be easily and efficiently made with extrusions. Good luck and feel free to ask for help.

  11. Hi lordvon,
    I have took almost 8 months to learn openfoam and linux system and reference your great work. I generated mesh with background grid mesh by blockMeshdict then used snappyhexmesh to make 4 airfoil and rotating zones(from airfoil stl files). Currently I think mesh and pitching motion is okay, but problem is after 0.18 sec running simulation some kind of shockwave(?) is generated from right lower corner..

    I changed rpm and tried finer mesh but usually simulation cannot preceed more than three revolution. I used your fvscheme, fvsolution, ras turbulence setting(several properties files in constant file). I don't how to get through this little shockwave. Any comment or advise would be my pleasure.

    1. Hi 조재영,

      Would it be possible for me to download your case files? When you say 'right lower corner' you mean of the whole domain? That is really strange, but fortunately it sounds like an easy fix. There is probably some small BC change that needs to be made.

    2. Hi 조재영,

      Would it be possible for me to download your case files? When you say 'right lower corner' you mean of the whole domain? That is really strange, but fortunately it sounds like an easy fix. There is probably some small BC change that needs to be made.

    3. Hello lordvon,

      Is there any provision in Gmsh for adaptive 3D meshing, similar to the 2D mesh you created?

      Thanks already

  12. Hi Lordvon,

    Are you still here active?
    any one replies?