Lorena A. Barba group

Announcing AeroPython!


I haven't lectured in two years. I've of course been teaching, but have stopped using the method known as "the lecture"—delivering a set amount of material (aka, "covering") from the front of the classroom to a group of mostly quiet, note-taking students. Like greater profs before me, I am a converted lecturer.1

It was Spring 2012 when I went full-steam ahead with the flipped classroom idea for my Computational Fluid Dynamics course. I've written before about how this came about, but the impetus resulted from already having done the lecture capture, live, in a previous version of the CFD course. I uploaded the videos from that live lecture capture to YouTube (after minor editing and cutting into segments) where, since then, they have collected nearly 220,000 public views (checked 20 April'14). My challenge that semester was coming up with class activities—but that should be the topic of another post.

Two years later

Teaching a classical Aerodynamics class for the first time at the George Washington University this Spring, I did not have a pre-recorded set of videos to use in the expected "move content to video" mode of the flipped classroom. But I did not want to lecture. What to do?

Introducing AeroPython!

I decided to develop a set of lessons using IPython Notebooks, to use as the scaffold for interactive class meetings. IPython Notebooks allow me to create media-rich content for the students, embedding executable Python code within it.

One of the reasons that many lecture-based courses fail is that they "cover" way too much material. By some estimates, after exams are past, students retain only about 20% of the content from a course. What's the point of covering so much content?

So I asked myself: what is the one thing that I want students to take from a classical Aerodynamics course? The one thing? My answer was the use of potential flow for aerodynamic analysis, via the panel method.

With the help of my bright PhD student, Olivier Mesnard, we set about to create a series of lessons that would begin from the simplest concept in potential flow, and take students in a step-by-step fashion to build their own 2D panel-method code for lifting bodies.

We now announce the public release of the 11 lessons that make AeroPython! Find them on the public GitHub repository.

Assuming no previous programming knowledge, we started with a "lesson zero" giving the basics of using Python for numerical computing. Each lesson is meant to be possible to complete in one 2.5-hr class meeting (but often students continue working after, if they did not finish in class). The lessons are:

Lesson 0: Python Crash Course
Lesson 1: Source & Sink
Lesson 2: Source & Sink in a Freestream
Lesson 3: Doublet
Lesson 4: Vortex
Lesson 5: Infinite row of vortices (student task)
Lesson 6: Lift on a cylinder
Lesson 7: Method of images
Lesson 8: Source Sheet
Lesson 9: Flow over a cylinder with source panels
Lesson 10: Source panel method
Lesson 11: Source-vortex panel method

What did we do in class?

The class meets in a computer lab, and each student sits in front of a workstation (a few brought their own laptops, too). To organize class communications, Q&A, and distribute complementary material, we used Piazza. I also surprised the students with a short quiz every couple of classes; I used Socrative for the quizzes.

For the first couple of lessons, students downloaded the IPython Notebook and were guided to work on a separate interactive Python session to execute the code from each lesson. I insisted that they type the code, not copy and paste (sometimes they did, of course, copy-paste; but they quickly learned that this shortcut only got them in trouble).

After that, they got a sales pitch from me about GitHub and they all created an account and gingerly began to sync with the AeroPython repo. By Lesson 5—which is really an assignment—students were maintaining their own GitHub repositories. They had to submit their work by simply posting on Piazza a link to their notebook on GitHub!

Each class, I asked questions and discussed with the students as a group, went around the room asking questions individually while looking at their work, and let the conversations be carried by the misunderstandings, difficulties or curiosity of the students. I never concerned myself with "covering material."

As students have all completed the AeroPython lessons by now, with a month left of the semester, they have started individual class projects. Most will use their version of the panel method to either study a problem they are interested in, or to extend it with a new feature. Example projects include: adding boundary-layer correction, adding an airfoil wake, building a two-airfoil solution, comparing a doublet- with a vortex-panel method.

A few students will work on a project using a well-known open-source potential-flow solver called XFLR. I'm not concerned about them using a "package" because they already know the fundamentals, they know the limits of potential-flow solutions and they use the tool critically.

What did I learn?

Like in my flipped CFD class two years ago, I witnessed the students in some rather unusual behavior—coming to class early and being hard at work by the time I arrived for our class meetings. This got me thinking about motivation.

But more surprising even was to see how students engaged with the material on potential flow. This is a rather dreary subject, usually offered to the students as a catalog of fundamental solutions, followed by problems by rote calculations.

The students using AeroPython in class used the tool of computing to investigate the subject matter, to make it palpable through the visualizations, and engage with it. I remember a dialogue with one student using Lesson 4 on Vortex Lift. He called me over declaring "The stagnation points disappeared!" —I looked at his code and asked for different values of the vortex strength: "What happens if you decrease it? If you decrease it a bit more?" Eventually, it became clear: "Ah! They move away from the cylinder!" All books show this, all aerodynamics teachers draw it on the board. But I'm confident my student will remember it better from having it discovered it through experimentation. This is the power of learning with computing.

It will take me a while to reflect and process the connections between motivation, engagement and learning with computing. Stay tuned!


  • DavidKetcheson

    Thanks so much for posting this, Lorena! I have been struggling with the best way to use IPython notebooks (similar to these, though not as polished) in my courses. Your positive experiences are encouraging for me. It is hard to know how much code to give to the students, and how much to ask them to write.

    I also get frustrated with maintaining separate versions of the notebooks, one with the "answers" and one without. I could just keep them all in the same repository and ask the students not to peek until they've finished the exercise on their own, but I worry about some of them wanting to just do the minimum to get by. And then it is difficult to ensure that updates get applied to both versions of the notebook...

    The styling of your notebooks makes them much more enjoyable to read. It would be nice if the CSS sheets could be applied automatically upon opening them, without needing to run that cell at the bottom. I suppose that's a request for the IPython devs.

    • Thank you for leaving a comment, David!

      Regarding the issue of "how much code to give the students," bear in mind two things: (1) the students in my class had NO previous Python experience, so the lessons provide a complete instructional scaffolding; and (2) it's a very small class, so I can sit down with each student, every class, and ask questions. So I may ask: "What are the contents of array X? ... try the size( ) function ... well, google it ... now, what does it tell you? ... and what is meshgrid( ) doing with it? ... ok ... now, this bit of code ... " (and so on).

      The lessons start with simple code and it's all given to the students, but they have to re-do it on their own script, and experiment with parameters, etc. Each lesson builds on the previous, and some code is repeated. After a few notebooks like that, as they are gaining confidence, the training wheels come off for an assignment, where no code is given. I think students need to read a lot of code that is given to them at first.

    • RamSaravanan

      I used IPython notebooks to teach an intro programming course in the Spring, and the students really liked the interface. I too had trouble deciding how much code to give to students and when. One solution I came up with with was what I call "progressively fillable" (PF) notebooks. (I am trying to come up with a better name for this feature!)

      Here's how it works: as students work with a PF notebook, they are only able to see up to the current code cell they are working on. The current cell shows working code, with some key lines redacted out. The expected output, textual or graphical, is also displayed. Students can try to "fill in the blanks" and repeatedly execute the code using Control-Enter. When they get the expected answer, or decide to give up, they press Shift-Enter and the correct code is displayed and executed, and the next code cell and associated Markdown cells are revealed. Also, the last version of code input by the student and the corresponding (wrong) output generated, is transformed to Markdown and inserted above the completed code cell, for the student's future reference (or possibly for grading). When working on the next code cell, all the previous code cells would have been executed correctly, thus setting up the scaffolding needed to continue building a complex program. (To convert a standard notebook to a PF notebook, the code lines to be redacted are simply suffixed with a special comment string ## ANSWER)

      You can see a short write-up describing PF notebooks at http://code.mindmeldr.com/graphterm/progressive.html

      I'd be interested in any feedback you have on this, perhaps at SciPy2014?

  • Pingback: This Week in CFD | Another Fine Mesh()

  • Pingback: Announcing “Practical Numerical Methods with Python” MOOC :: Lorena A. Barba Group()

  • Robert Gosling

    Hi Lorena, I've followed your Aeropython course and found it to be extremely useful. I'm currently studyin Mechanical Engineering and have (foolishly as aerodynamics is not taught in my school) decided to focus my thesis on downforce generated by race car rear wings. So first off I would like to say a massive thankyou for providing this course to everyone as it has helped my immensely.

    I do have a query that hopefully you could find the time to help me with. In the final lesson where we are implementing the Vortex Panel Method I cannot get the discretization to work on anything other than the NACA0012 file provided; I keep getting an error saying " IndexError: index 62 is out of bounds for axis 0 with size 62". I have tried a few different airfoils and I still get the same problem. I would be extremely grateful if you could find the time to explain why this happens.

    Thanks very much,


    • Hi Robert,

      Did you know that we have an online course platform for the Aerodynamics class this semester, and it's open for registration from anyone? It has a discussion board, and you might get help there ...


      • Robert Gosling

        Hi Lorena,

        Thanks very much for the reply. I didn't know about the online course platform, I shall join up and see what I can find out.

        Thanks again


  • Volkan ÇAKIR

    Thank you for contribution, it is great work for not just aerodynamics but hydrodynamics.

  • gokul

    I get a lot of great information from this blog. Thanks for sharing this valuable information to our vision. You have posted a trust worthy blog keep sharing.
    Python training in Chennai