QPROP: Propeller Analysis Code

Mark Deela wrote the QProp application to help design propeller/electric motor combinations for powered flight. The last release of this code was produced in 2009 (Qprop 1.31). In this note we will look at the part of this code that deals with the propeller design. The intent here is to work toward code that can be used for indoor propeller design.

We will start this work by making sure the original code can be compiled and run on my Macbook. Later, we will test this process on Windows as well.

Download Qprop v1.22

!curl https://web.mit.edu/drela/Public/web/qprop/qprop1.22.tar.gz -o ../master/qprop1.22.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  211k  100  211k    0     0   654k      0 --:--:-- --:--:-- --:--:--  672k

Extract the Code

! cd ../master && tar zxvf qprop1.22.tar.gz
x Qprop/
x Qprop/README
x Qprop/bin/
x Qprop/bin/Makefile
x Qprop/qmil_doc.txt
x Qprop/qprop_doc.txt
x Qprop/runs/
x Qprop/runs/air/
x Qprop/runs/air/apc80.dat
x Qprop/runs/air/apc1.dat
x Qprop/runs/air/apc2.dat
x Qprop/runs/air/gunther.dat
x Qprop/runs/air/propi.dat
x Qprop/runs/air/s9.dat
x Qprop/runs/kagan_cruise.txt
x Qprop/runs/airship.mil
x Qprop/runs/apc.txt
x Qprop/runs/apc14x10e
x Qprop/runs/apc16x10e
x Qprop/runs/apc18x10e
x Qprop/runs/apc5.5x4.5
x Qprop/runs/apc6x4
x Qprop/runs/apc7x4
x Qprop/runs/apc8x3.8
x Qprop/runs/apc8x6
x Qprop/runs/apc8x8
x Qprop/runs/axi2204-54
x Qprop/runs/axi4130-16
x Qprop/runs/axi4130-20
x Qprop/runs/axi5320-28
x Qprop/runs/cam6x3
x Qprop/runs/cam6x3mod
x Qprop/runs/cam6x4
x Qprop/runs/cam6x7
x Qprop/runs/df1.mil
x Qprop/runs/dfpar1
x Qprop/runs/dfpar2
x Qprop/runs/dfprop
x Qprop/runs/ep1280
x Qprop/runs/f1d
x Qprop/runs/f1d.mil
x Qprop/runs/f1dVD0
x Qprop/runs/f1dVD1
x Qprop/runs/fid
x Qprop/runs/gunther
x Qprop/runs/kagan
x Qprop/runs/kagan.raw
x Qprop/runs/motors.pdf
x Qprop/runs/param1
x Qprop/runs/param2
x Qprop/runs/param3
x Qprop/runs/pot30w10v
x Qprop/runs/qcon.def
x Qprop/runs/s280-6v-dd
x Qprop/runs/s300-7v-5.3
x Qprop/runs/s300-7v-dd
x Qprop/runs/s400-6v-4.0
x Qprop/runs/s400-6v-dd
x Qprop/runs/s400-7v-dd
x Qprop/runs/s600-10.0
x Qprop/runs/s600-8v-dd
x Qprop/runs/s9.mil
x Qprop/runs/solar
x Qprop/runs/solar.mil
x Qprop/runs/t
x Qprop/runs/t80
x Qprop/runs/t88
x Qprop/runs/t88a
x Qprop/runs/t88h
x Qprop/runs/t92
x Qprop/runs/temp.prop
x Qprop/runs/template.mil
x Qprop/runs/test.mil
x Qprop/runs/test1
x Qprop/runs/wind
x Qprop/runs/wind.mil
x Qprop/runs/wind0.mil
x Qprop/runs/windb.mil
x Qprop/runs/winds.mil
x Qprop/src/
x Qprop/src/q.ftnchek
x Qprop/src/Makefile
x Qprop/src/QDEF.INC
x Qprop/src/bnsolv.f
x Qprop/src/cdfun.f
x Qprop/src/gvcalc.f
x Qprop/src/io.f
x Qprop/src/motor.f
x Qprop/src/qm.ftnchek
x Qprop/src/qcget.f
x Qprop/src/qmil.f
x Qprop/src/qprop.f
x Qprop/src/spline.f
x Qprop/src/test1.f
x Qprop/src/test2.f
x Qprop/src/testc.f
x Qprop/src/testm.f
x Qprop/src/tpdes.f
x Qprop/src/tqcalc.f
x Qprop/version_notes.txt
! cd ../master/Qprop/bin && cat Makefile
SRC = ../src
VLSRC = ../vlsrc
FFLAGS = -O -r8 

#------------------------------------
# default Unix fortran
FC = f77
FTNLIB =

#------------------------------------
# Intel Fortran Compiler
FC = ifort
#FTNLIB = -Vaxlib
#FTNLIB = -Vaxlib /usr/lib/C-ctype.o /usr/lib/C_name.o /usr/lib/ctype-info.o

#------------------------------------
#FC = g77
#FFLAGS = -O -dbl

#------------------------------------

qprop: qprop.o gvcalc.o cdfun.o tqcalc.o motor.o spline.o io.o qcget.o
	$(FC) -o qprop qprop.o gvcalc.o cdfun.o tqcalc.o motor.o \
spline.o io.o qcget.o $(FTNLIB)

qmil: qmil.o tpdes.o gvcalc.o cdfun.o tqcalc.o bnsolv.o \
spline.o io.o qcget.o
	$(FC) -o qmil qmil.o tpdes.o gvcalc.o cdfun.o tqcalc.o bnsolv.o \
spline.o io.o qcget.o $(FTNLIB)

vlprop: vlprop.o cdfun.o vlset.o motor.o aic.o \
spline.o io.o qcget.o aread.o lefinda.o
	$(FC) -o vlprop vlprop.o cdfun.o vlset.o motor.o aic.o \
spline.o io.o qcget.o aread.o lefinda.o $(FTNLIB)



qprop.o: $(SRC)/qprop.f $(SRC)/QDEF.INC
	$(FC) -c $(FFLAGS) $(SRC)/qprop.f

qmil.o: $(SRC)/qmil.f $(SRC)/QDEF.INC
	$(FC) -c $(FFLAGS) $(SRC)/qmil.f

tpdes.o: $(SRC)/tpdes.f
	$(FC) -c $(FFLAGS) $(SRC)/tpdes.f

gvcalc.o: $(SRC)/gvcalc.f
	$(FC) -c $(FFLAGS) $(SRC)/gvcalc.f

cdfun.o: $(SRC)/cdfun.f
	$(FC) -c $(FFLAGS) $(SRC)/cdfun.f

tqcalc.o: $(SRC)/tqcalc.f
	$(FC) -c $(FFLAGS) $(SRC)/tqcalc.f

motor.o: $(SRC)/motor.f
	$(FC) -c $(FFLAGS) $(SRC)/motor.f

bnsolv.o: $(SRC)/bnsolv.f
	$(FC) -c $(FFLAGS) $(SRC)/bnsolv.f

spline.o: $(SRC)/spline.f
	$(FC) -c $(FFLAGS) $(SRC)/spline.f

io.o: $(SRC)/io.f
	$(FC) -c $(FFLAGS) $(SRC)/io.f

qcget.o: $(SRC)/qcget.f
	$(FC) -c $(FFLAGS) $(SRC)/qcget.f


vlprop.o: $(VLSRC)/vlprop.f
	$(FC) -c $(FFLAGS) $(VLSRC)/vlprop.f

vlset.o: $(VLSRC)/vlset.f
	$(FC) -c $(FFLAGS) $(VLSRC)/vlset.f

helxyz.o: $(VLSRC)/helxyz.f
	$(FC) -c $(FFLAGS) $(VLSRC)/helxyz.f

helcam.o: $(VLSRC)/helcam.f
	$(FC) -c $(FFLAGS) $(VLSRC)/helcam.f

aread.o: $(VLSRC)/aread.f
	$(FC) -c $(FFLAGS) $(VLSRC)/aread.f

lefinda.o: $(VLSRC)/lefinda.f
	$(FC) -c $(FFLAGS) $(VLSRC)/lefinda.f

aic.o: $(VLSRC)/aic.f
	$(FC) -c $(FFLAGS) $(VLSRC)/aic.f

Looking at this file, we see that several programs are constructed using this code: qprop, qmil, and vlprop. However, the code needed for that last program does not seem to be present in the archive.

Qmil is a design program that generates data files to be processed by Qprop. For the moment, we will focus only on the Qprop code.

Compiling Qprop

The **Makefile found in the bin directory is set up to use the Intel Fortran compiler. We will use GFortran which is part of the Gnu tool chain.

Here is a check that gfortran is available:

! gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/12.2.0/bin/../libexec/gcc/x86_64-apple-darwin21/12/lto-wrapper
Target: x86_64-apple-darwin21
Configured with: ../configure --prefix=/usr/local/opt/gcc --libdir=/usr/local/opt/gcc/lib/gcc/current --disable-nls --enable-checking=release --with-gcc-major-version-only --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-12 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-zstd=/usr/local/opt/zstd --with-pkgversion='Homebrew GCC 12.2.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --with-system-zlib --build=x86_64-apple-darwin21 --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (Homebrew GCC 12.2.0) 

Building Qprop is fairly easy. In real development, we would use a tool like GNU Make to set up the build. However, we will let Python do things directly in this page to show what steps are needed.

Copy Source Files

In order to leave the master files untouched, we will copy the needed source files into a build directory:

!mkdir -p ../master/build-qprop

From the master Makefile, here are the files needed to build the program:

FSRCS = [
    "qprop.f", 
    "gvcalc.f", 
    "cdfun.f", 
    "tqcalc.f", 
    "motor.f",
    "spline.f", 
    "io.f", 
    "qcget.f"
]

Copy the files to the build directory

import shutil
BUILD = "../master/build-qprop/"
for f in FSRCS:
    print(f"Copying {f}")
    src = "../master/Qprop/src/" + f
    dst = BUILD + f
    shutil.copyfile(src, dst)
Copying qprop.f
Copying gvcalc.f
Copying cdfun.f
Copying tqcalc.f
Copying motor.f
Copying spline.f
Copying io.f
Copying qcget.f

Generate Object Files

Now, we generate the object files. This first step deletes any old object files that may be present:

import os
cmd = f"rm -f {BUILD}*.o"
cmd
ret = os.system(cmd)
for f in FSRCS:
    src = f"{BUILD}{f}"
    dst = f"{BUILD}{f}.o"
    cmd = f"gfortran -c {src} -o {dst}"
    ret = os.system(cmd)
../master/build-qprop/qprop.f:85:0:

   85 |       INCLUDE 'QDEF.INC'
      | 
Fatal Error: Cannot open included file 'QDEF.INC'
compilation terminated.

Test the Application

We can test the program using an example input file from the master copy:

!../master/build-qprop/qprop ../master/Qprop/runs/cam6x3
zsh:1: no such file or directory: ../master/build-qprop/qprop