Speed up calculation for large scale annual irradiation calculation


This is a follow up to a question I asked a few years ago about calculating the total irradiation on a pedestrian in an outdoor space.

For one single pedestrian position and a full year I do the following (based on Greg suggestion):

# <combined.rad>
# Combined ground and sky vault for calculating cylindrical irradiance

# Start by telling rfluxmtx to generate a single coefficient for the ground:
#@rfluxmtx h=u

void glow groundglow
0 0 4 .8 1.1 .8 0
groundglow source ground
0 0 4 0 0 -1 180

# Now, tell rfluxmtx to generate a set of Tregenza sky patches using Y for "north/up":
#@rfluxmtx h=r1 u=+Y

void glow sky_glow
0 0 4 1 1 1 0
sky_glow source sky
0 0 4 0 0 1 180

Generate sky matrix (only once);

gendaymtx weather.wea > sky.mtx

I then generate random sample points on an ideal cylinder:

cnt 2 | rcalc -e 'HT:2;RAD:0.2' \
 -e 'rrad=RAD*sqrt(rand(.836*recno+.238));phi=2*PI*rand(-.3582*recno+.861);' \
 -e '$1=rrad*cos(phi);$2=rrad*sin(phi);$3=HT;$4=0;$5=0;$6=1' > samps.txt

cnt 40 | rcalc -e 'HT:2;RAD:0.2' \
 -e 'rht=HT*rand(.571*recno-.7633);phi=2*PI*rand(-.6716*recno-.1023)' \
 -e '$1=RAD*cos(phi);$2=RAD*sin(phi);$3=rht;$4=cos(phi);$5=sin(phi);$6=0' >> samps.txt

I then use rfluxmyx to calculate the irradiation coefficients (geometry and materials if needed):

rfluxmtx -I+ -c 42 -y 1 -ab 2 - combined.rad  shadow_mask_materials.rad shadow_mask_geometry.rad < samps.txt > daycoef.mtx

And finally multiply

dctimestep daycoef.mtx sky.mtx > annual.out

The last three operations need to be repeated for each one of the positions considered. This number can be as high as 20,000 in my case. I have timed the execution and it takes around 0.65s per position. For 20,000 positions this is around 3.6 hours.

real    0m0.626s
user    0m0.584s
sys     0m0.035s

From what I understand, I should be able to speed it up by using binary io and, I think, not writing to disk all the intermediate files, but I am struggling to write the correct command. If I try

rfluxmtx -I+ -c 42 -y 1 -ab 2 - combined.rad  shadow_mask_materials.rad shadow_mask_geometry.rad < samps.txt | dctimestep sky.mtx > annual.out 

I get the error fatal - unexpected column count in header

What am I doing wrong? Is this the right approach or do you have any advice?


Hi Ruggiero,

The main problem is that dctimestep is expecting the sky matrix from stdin, rather than the daylight coefficient matrix. The order is wrong, hence your error. You could use:

gendaymtx weather.wea | dctimestep daycoef.mtx > annual.out

instead and it should work, though I don’t think it would save a lot of time. Switching to binary matrices is easy enough, just add a “-faf” option to rfluxmtx. Again, I don’t think it would save a lot of time, since your DC matrix is only 1 row of 146 color coefficients.

When you say you are repeating the last three steps, are you running rfluxmtx with different scene files (i.e., “combined.rad” and “shadow_mask_geometry.rad”)? If so, then I don’t think there is much way to speed up your overall process beyond what you are doing.


Hi Guggiero,

have you considered using Kid Cuttle’s cubic illuminance (cubic irradiance in your case)? You would measure the irradiance in the 6 mayor directions, and then take the average. I can’t quite follow why you would base your measurements on a cylinder, assuming that what you’re after will lead to the Mean Radiant Temperature.

The cubic irradiance approach would give you six annual irradiance matrixes (+x, -x, +y, -y, +z, -z), which you should be able to average into a single one.

Or are you saying that the height of the person is important, so the measurements need to be taken between ground level and head height, rather than at a single point in space?


Hi Greg,

I am not sure the order is the problem.

dctimestep daycoef.mtx sky.mtx > annual.orig.out
dctimestep < sky.mtx daycoef.mtx > annual.new.out
gendaymtx weather.wea | dctimestep daycoef.mtx > annual.pipe.out

All return the same matrix.

For every position I recalculate the samples on the cylinder because the position changes. The expressions are actually, for (x, y, z):

cnt 2 | rcalc -e ‘HT:z;RAD:0.2’
-e ‘rrad=RADsqrt(rand(.836recno+.238));phi=2PIrand(-.3582recno+.861);’
-e '$1=x+rrad
cos(phi);$2=y+rrad*sin(phi);$3=HT;$4=0;$5=0;$6=1’ > samps.txt

Same for the other count…


Hi Alex,

You are correct. I am after the MRT eventually. I will have a look at Kid Cuttle’s cubic illuminance. It is the first time I hear about it, but it sounds very interesting.


All 3 of your dctimestep commands do the same thing and should generate the same matrix. This is because dctimestep reads the final matrix from stdin if it is not given. In your original question, you were trying to give the first matrix on stdin, which dctimestep doesn’t support. Bear in mind that:
command < inputA inputB > output
is the same as:
command inputB < inputA > output
and also the same as:
cat inputA | command inputB > output
Position doesn’t matter for redirected files, input or output.

Is it only the cylinder position that is changing, or cylinder position along with sky matrix (weather file)? If you are computing many positions in the same setting, you can do this much faster by creating a matrix with one row per cylinder position, e.g.:

rm samps.txt
foreach pos ("`cat xyzfile.txt`")
cnt 2 | rcalc -e "x:$pos[1];y:$pos[2];z:$pos[3]" -e 'HT:z;RAD:0.2'
-e 'rrad=RAD*sqrt(rand(.836recno+.238));phi=2*PI*rand(-.3582recno+.861);'
-e '$1=x+rrad*cos(phi);$2=y+rrad*sin(phi);$3=HT;$4=0;$5=0;$6=1' >> samps.txt
cnt 40 | rcalc -e "x:$pos[1];y:$pos[2];z:$pos[3]" -e 'HT:z;RAD:0.2' \
 -e 'rht=HT*rand(.571*recno-.7633);phi=2*PI*rand(-.6716*recno-.1023)' \
 -e '$1=x+RAD*cos(phi);$2=y+RAD*sin(phi);$3=rht;$4=cos(phi);$5=sin(phi);$6=0' >> samps.txt

rfluxmtx -I+ -c 42 -y `wc -l < xyzfile.txt` -ab 2 - combined.rad  shadow_mask_materials.rad shadow_mask_geometry.rad < samps.txt > daycoef.mtx

This way, you don’t have to loop 20,000 times. Instead, rfluxmtx creates a 20000x146 matrix that will run in a single invocation of dctimestep. Again, this is assuming you have 20,000 positions at one location. Your output from dctimestep will then be 20,000 RGB values for each hour in the weather file. It’s a lot to put into a spreadsheet, though. At this point, you might also gain something by using the -faf option of rfluxmtx, and the -of option of dctimestep.


Thanks Greg.

Amazing. I tested it with 2990 positions (-n 8) and it took only 1m53s!

I also tried -faf and -of and I managed to shave off a few more seconds.

This is part of a larger program so I will not be using spreadsheets.

1 Like