<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://grasswiki.osgeo.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hamish</id>
	<title>GRASS-Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://grasswiki.osgeo.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hamish"/>
	<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/wiki/Special:Contributions/Hamish"/>
	<updated>2026-04-12T07:31:01Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=V.generalize_tutorial&amp;diff=28815</id>
		<title>V.generalize tutorial</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=V.generalize_tutorial&amp;diff=28815"/>
		<updated>2026-03-18T05:02:48Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Simplification */ add some explaining&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== MODULE ==&lt;br /&gt;
&lt;br /&gt;
* GRASS 7.x {{cmd|v.generalize}}&lt;br /&gt;
&lt;br /&gt;
== TUTORIAL ==&lt;br /&gt;
 &lt;br /&gt;
== Introduction ==&lt;br /&gt;
 &lt;br /&gt;
This tutorial presents and explains the functionality of GRASS vector module ''v.generalize''.&lt;br /&gt;
This module implements generalization operators for GRASS vector maps. The topics covered in this tutorial are: simplification, smoothing, network generalization and displacement. For the basic introduction to these operators check the {{cmd|v.generalize}} man page, or for the exhausting introduction check McMaster and Shea (TODO: add reference).&lt;br /&gt;
&lt;br /&gt;
It is recommended to read the official man page before reading this document, or read&lt;br /&gt;
these two documents at the same time since this tutorial does not contain the&lt;br /&gt;
(detail) descriptions of input parameters whereas the man page has very few examples&lt;br /&gt;
and no pictures at all. (Even the author of module and both of the documents must have consult the man page several times....)&lt;br /&gt;
This document is also meant to be a &amp;quot;report&amp;quot; showing the work done during the Google Summer of Code 2007.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Most of the examples in this text work with Spearfish dataset, which can&lt;br /&gt;
be downloaded [[Sample_datasets|here]]. Also, this&lt;br /&gt;
tutorial assumes that the user is already running GRASS session with the Spearfish&lt;br /&gt;
location and a monitor opened. Also, if you click on any picture here, it will be shown in its full size.  &lt;br /&gt;
&lt;br /&gt;
All the algorithms presented in this document (try to) preserve the topology&lt;br /&gt;
of the input maps. This means, for example, that the smoothing and simplification methods&lt;br /&gt;
never remove the first and last points of lines and that displacement preserves the junctions.&lt;br /&gt;
&lt;br /&gt;
== Simplification ==&lt;br /&gt;
 &lt;br /&gt;
''v.generalize'' implements many simplification algorithms. The most widely used&lt;br /&gt;
is Douglas-Peucker algorithm (TODO: reference). We can apply this algorithm to&lt;br /&gt;
any vector map in the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_douglas method=douglas threshold=50&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The explanation of the line above is following: Run v.generalize, apply Douglas-Peucker&lt;br /&gt;
algorithm with threshold equals to 50 to the map roads and store the output in vector&lt;br /&gt;
map output_douglas. The last output line produced by this module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Number of vertices was reduced from 5468 to 2107[38%]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
means that the input file (roads) has 5468 vertices in total and the new map (roads_douglas)&lt;br /&gt;
has only 2107 vertices which is only 38% of original. On the other hand, if we run the &lt;br /&gt;
commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
d.vect roads&lt;br /&gt;
d.vect roads_douglas col=blue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can see that there are no significant differences between the input and output maps. &amp;quot;Only the details were removed&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic1.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
The amount of the details removed can be specified by parameter: threshold. It is the &lt;br /&gt;
case that the output map has fewer vertices and details for greater values of threshold.&lt;br /&gt;
For example, if we run&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_douglas method=douglas threshold=200 --overwrite&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we obtain a map with only 1726 vertices. A disadvantage of the command above is that&lt;br /&gt;
it never removes the lines. &amp;lt;strike&amp;gt;If we also want to remove the small lines, we need to run&lt;br /&gt;
the command above with the -r flag. If the -r flag is presented, lines shorter than&lt;br /&gt;
threshold and areas with areas less than threshold are removed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize -r input=roads output=roads_douglas method=douglas threshold=200 --overwrite&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/strike&amp;gt;&lt;br /&gt;
 Fixme: -r flag and method=remove_small have been removed. Try v.clean for removing small areas or&lt;br /&gt;
 v.edit map=mapname type=line tool=delete query=length thresh=0,0,-0.5&lt;br /&gt;
&amp;lt;strike&amp;gt;&lt;br /&gt;
In this case, roads_douglas has only 850 vertices and it contains 387 lines whereas&lt;br /&gt;
the original map (roads) contains 825 lines. In this case, the output map has very few details,&lt;br /&gt;
but the basic shapes and topology are preserved:&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic2.png|center|thumb|400px|caption text here]]  &lt;br /&gt;
&amp;lt;/strike&amp;gt;&lt;br /&gt;
&amp;lt;strike&amp;gt;It is also possible remove small lines/areas only (without any simplification). This is achieved&lt;br /&gt;
by method=remove_small:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_remove_small method=remove_small threshold=200&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
produces following map with 399 lines. (Note removed lines in the upper left corner)&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic3.png|center|thumb|400px|caption text here]]  &lt;br /&gt;
&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Douglas-Peucker Algorithm has very reasonable results, but it is very hard to find (i.e. guess) the&lt;br /&gt;
correct value to use for ''threshold=''. Moreover, it is also impossible to simplify each line to (for example) 40%.&lt;br /&gt;
Exactly for such cases, ''v.generalize'' provides method=douglas_reduction. This algorithm&lt;br /&gt;
is a modification of Douglas-Peucker Algorithm which takes another parameter ''reduction''&lt;br /&gt;
which denotes (approximate, +/- a few percent) simplification of lines. A value of ''reduction=10'' will keep (approximately) 10% of the original vertices and drop the remaining 90%.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_douglas_reduction method=douglas_reduction \&lt;br /&gt;
  threshold=0 reduction=50 --overwrite&lt;br /&gt;
d.erase&lt;br /&gt;
d.vect roads_douglas_reduction&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
produces following map with 3018 vertices (55%). (Note that there are almost no differencies between the original and the new map)&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic4.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
Also observe that the following commands are equivalent&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=in output=out method=douglas threshold=eps&lt;br /&gt;
v.generalize input=in output=out method=douglas_reduction threshold=eps reduction=100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another algorithm implemented in this modules is &amp;quot;Vertex Reduction&amp;quot;. This algorithm removes&lt;br /&gt;
the consecutive poins (on the same line) which are closer to each other than threshold. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=in output=out method=reduction threshold=0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
removes duplicate points. More precisely, if two consecutive points have the same &lt;br /&gt;
coordinates then the second point is removed and the first is preserved. The last two algorithm&lt;br /&gt;
implemented by this module are &amp;quot;Lang&amp;quot; and &amp;quot;Reumann-Witkam&amp;quot; algorithm. For more information about these two algorithms, please see the {{cmd|v.generalize}} man page.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
The following four pictures show the results obtained by Reumann, Douglas, Lang&lt;br /&gt;
and Vertex Reduction algorithm resp. The algorithms were run with threshold set to 50&lt;br /&gt;
and Lang algorithm with look_ahead=7.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery Caption=&amp;quot;Simplification algorithms&amp;quot; widths=&amp;quot;300px&amp;quot; heights=&amp;quot;225px&amp;quot; perrow=&amp;quot;2&amp;quot;&amp;gt;&lt;br /&gt;
Image:v.generalize.reumann.png|Reumann-Witkam algorithm result containing 2522 [46%] points&lt;br /&gt;
&lt;br /&gt;
Image:v.generalize.douglas.png|Douglas algorithm result containing 2107 [38%] points&lt;br /&gt;
&lt;br /&gt;
Image:v.generalize.lang.png|Lang algorithm result containing 2160 [39%] points&lt;br /&gt;
&lt;br /&gt;
Image:v.generalize.reduction.png|Vertex Reduction algorithm result containing 4296 [78%] points&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The map produced by&lt;br /&gt;
* Reumann-Witkam algorithm contains 2522 [46%] points,&lt;br /&gt;
* Douglas: 2107 [38%] points,&lt;br /&gt;
* Lang: 2160 [39%] and&lt;br /&gt;
* Vertex Reduction: 4296 [78%].&lt;br /&gt;
&lt;br /&gt;
== Smoothing ==&lt;br /&gt;
 &lt;br /&gt;
''v.generalize'' also supports many smoothing algorithm. For basic descriptions, please consult the {{cmd|v.generalize}} man page.&lt;br /&gt;
&lt;br /&gt;
Probably, the best results are produced by &amp;quot;Chaiken&amp;quot;, &amp;quot;Hermite&amp;quot; and &amp;quot;Snakes&amp;quot; algorithms/methods. &lt;br /&gt;
However, the remaining algorithms may also produce very reasonable results. Although&lt;br /&gt;
the Chaiken and Hermite methods may produce the maps with a lot of new points, the methods&lt;br /&gt;
presented above (simplification) provide a good tool for tackling this problem.&lt;br /&gt;
&lt;br /&gt;
If we run the following command&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_chaiken method=chaiken threshold=1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we get a new map with 33364[640%] vertices.&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic5.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
This map looks almost exactly the same as the original map at the current level of detail as the&lt;br /&gt;
picture below shows. This pictures was produced by the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
d.erase&lt;br /&gt;
d.vect roads&lt;br /&gt;
d.vect roads_chaiken col=blue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic6.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
However, if we zoom to a small region, we can see that the new map consists of smooth(er) lines &lt;br /&gt;
which (very reasonable) approximate the original ones. &lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic7.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
If we apply &amp;quot;Hermite&amp;quot; method instead, we will obtain a map with 14640[267%] vertices.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_hermite method=hermite threshold=1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic8.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
Note, that a difference between &amp;quot;Chaiken&amp;quot; and &amp;quot;Hermite&amp;quot; is that the lines produced&lt;br /&gt;
by &amp;quot;Chaiken&amp;quot; &amp;quot;inscribe&amp;quot; the original lines whereas the &amp;quot;Hermite&amp;quot; lines &amp;quot;circumscribe&amp;quot; the&lt;br /&gt;
original lines as can be seen in the picture below. (Black line is original line,&lt;br /&gt;
green line is &amp;quot;Chaiken&amp;quot; and blue is &amp;quot;Hermite&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic9.png|center|thumb|400px|caption text here]]  &lt;br /&gt;
&lt;br /&gt;
The algorithms mentioned above are suitable for smooth approximation of given lines.&lt;br /&gt;
On the other hand, if the aim of smoothing is to &amp;quot;straighten&amp;quot; the lines then the better&lt;br /&gt;
results are achieved by the other methods. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_sa method=sliding_averaging look_ahead=7 slide=1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--[[Image:v.generalize.pic10.png]] ??? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At first sight, we can see that roads_sa contains smooth and straight lines which&lt;br /&gt;
preserve the original shape of the lines. This difference is obvious if we zoom to a small&lt;br /&gt;
region of a map (see below. Again, original line is black, new line is blue)&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic11.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
If the lines are &amp;quot;too straight&amp;quot; then we can set &amp;quot;slide&amp;quot; to a smaller value to obtain the lines&lt;br /&gt;
which better preserve the original shape. In the picture below, original line is black,&lt;br /&gt;
line produced by &amp;quot;slide=1&amp;quot; is blue and &amp;quot;slide=0.3&amp;quot; is green.&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic12.png|center|thumb|400px|caption text here]]  &lt;br /&gt;
&lt;br /&gt;
Very similar results can be obtained by Distance Weighting Algorithm (method=distance_weighting).&lt;br /&gt;
This is not very surprising since these algorithms are almost the same. For example,&lt;br /&gt;
the image below shows the outputs of &amp;quot;Distance Weighting Algorithm&amp;quot;. The image was generated&lt;br /&gt;
by the following sequence of commands&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_dw1 method=distance_weighting look_ahead=7 slide=1&lt;br /&gt;
v.generalize input=roads output=roads_dw2 method=distance_weighting look_ahead=7 slide=0.3&lt;br /&gt;
d.erase&lt;br /&gt;
d.vect roads&lt;br /&gt;
d.vect roads_dw1 col=red&lt;br /&gt;
d.vect roads_dw2 col=blue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic13.png|center|thumb|400px|method=distance_weighting]]&lt;br /&gt;
&lt;br /&gt;
Also, very good resutls can be obtained by the &amp;quot;Snakes&amp;quot; algorithm. On the other hand,&lt;br /&gt;
it is the (asymptotically) slowest&lt;br /&gt;
smoothing algorithm implemented in this however. Behaviour of this algorithm is controlled by&lt;br /&gt;
&amp;quot;alpha&amp;quot; and &amp;quot;beta&amp;quot; parameter. Reasonable range of values for these two parameters is [0..5]&lt;br /&gt;
where higher values correspond to the straighter lines. Module outputs the input map if&lt;br /&gt;
alpha=beta=0. And this command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_snakes method=snakes alpha=1 beta=1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
produces a map containing following region (original line is black)&lt;br /&gt;
[[Image:v.generalize.pic14.png|center|thumb|400px|caption text here]]  &lt;br /&gt;
&lt;br /&gt;
Last smoothing algorithm implemented in this module is &amp;quot;Boyle's Forward-Looking Algorithm&amp;quot; which&lt;br /&gt;
is another &amp;quot;straightening&amp;quot; algorithm.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_boyle method=boyle look_ahead=5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
produces a map containing following region (original line is black)&lt;br /&gt;
[[Image:v.generalize.pic15.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
=== Area smoothing example ===&lt;br /&gt;
&lt;br /&gt;
 # spearfish&lt;br /&gt;
 g.region rast=geology&lt;br /&gt;
 r.reclass in=geology out=geology.claysand &amp;lt;&amp;lt; EOF&lt;br /&gt;
 8 = 8 claysand&lt;br /&gt;
 EOF&lt;br /&gt;
 r.to.vect in=geology.claysand out=geology_claysand feature=area&lt;br /&gt;
 v.generalize in=geology_claysand out=geology_claysand_smooth method=snakes&lt;br /&gt;
&lt;br /&gt;
== Displacement ==&lt;br /&gt;
&lt;br /&gt;
If we render entire Spearfish location, we can see in the upper half of the map two interstates which&lt;br /&gt;
overlap. This is not logically correct (I hope, they do not evarlap in real) and it is also&lt;br /&gt;
considered as an (presentation) error. For solving such problems, ''v.generalize'' provides&lt;br /&gt;
&amp;quot;dislplacement&amp;quot; method. As the name suggests, this method displaces linear features which are&lt;br /&gt;
close to each other so that they do not overlap/collide. Method implemented in this modules (based on Snakes)&lt;br /&gt;
has very good results but not very good perfomance. Therefore the calculations may take few(several) minutes.&lt;br /&gt;
For this reason, displacement is applied to the simplified lines in this document.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_dr method=douglas_reduction threshold=0 reduction=50&lt;br /&gt;
v.generalize input=roads_dr output=roads_dr_disp method=displacement alpha=0.01 beta=0.01 threshold=100 iterations=35&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First command produces simplified lines and then the second command applied displacement operator&lt;br /&gt;
to the simplified line. Parameters alpha and beta specifies the rigidity of the lines. This means&lt;br /&gt;
that displacement is bigger for small values of alpha and beta. Also, the displacement is&lt;br /&gt;
not very significant for higher(&amp;amp;gt;=1.0) values of alpha, beta. Threshold parameter&lt;br /&gt;
denotes the critical distance. Only the points (and their neighbours) which are closer&lt;br /&gt;
than threshold apart are displaced by ''v.generalize''. Module tries to move these&lt;br /&gt;
points such that they are at least threshold apart. However, the displaced points are never&lt;br /&gt;
threshold (or more) apart for positive values of alpha and beta. Displacement as implemented&lt;br /&gt;
in ''v.generalize'' is an iterative process. Parameter &amp;quot;iterarions&amp;quot; specifies the number&lt;br /&gt;
of iterations the collisions between the points are resolved. In general, the quality of displacement&lt;br /&gt;
increases with the number of iterations. However, quality converges quite rapidly and&lt;br /&gt;
for all maps I tried, the sufficient value of iterations was between 20 and 50.&lt;br /&gt;
Two command above produce the picture below. Note that it is now possible to distinguish&lt;br /&gt;
between two &amp;quot;interastate lines&amp;quot; and also observe the free space between interstate and the lines&lt;br /&gt;
directly below it.     &lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic16.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
== Network Generalization ==&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Network generalization is suitable for selecting &amp;quot;the most important&amp;quot; subnetwork&lt;br /&gt;
of a network. For example, to select highways, interstates from a road network. Examples&lt;br /&gt;
in this section work with new GRASS default dataset, which can be downloaded [[Sample_datasets|here]].&lt;br /&gt;
&lt;br /&gt;
If we render map &amp;quot;streets_wake&amp;quot; we really cannot see the streets, but the only&lt;br /&gt;
thing we can see is a big black rhombus. We will try to improve this. Firstly, network&lt;br /&gt;
generalization requites quite a lot of time and memory. Therefore, we begin with&lt;br /&gt;
simplification of &amp;quot;streets_wake&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=streets_wake output=streets_rs method=remove_small threshold=50&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then we can begin with network generalization. If we execute the folllowing command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=streets_rs output=streets_rs_network method=network betweeness_thresh=50&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
we obtain the following map containing &amp;quot;only&amp;quot; 14128. Original map has 49746&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.net50.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
If this is still not enough, we can increase the value of betweeness_thresh to, for example 200.&lt;br /&gt;
For this value, ''v.generalize'' produces following map with 11537 lines.&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.net200.png|center|thumb|400px|caption text here]]&lt;br /&gt;
&lt;br /&gt;
It is also possible to change the values of &amp;quot;closeness_thresh&amp;quot; and &amp;quot;degree_thresh&amp;quot;. Parameter&lt;br /&gt;
&amp;quot;closeness_thresh&amp;quot; is suitable for selecting the &amp;quot;centre(s)&amp;quot; of a network. This parameter&lt;br /&gt;
is always between 0 and 1. And &amp;quot;reasonable values&amp;quot; of this parameter are smaller for&lt;br /&gt;
bigger network.&lt;br /&gt;
&lt;br /&gt;
== Gereneral Parameters ==&lt;br /&gt;
&lt;br /&gt;
''v.generalize'' has some parameters and flags which affect the general behaviour of module.&lt;br /&gt;
&lt;br /&gt;
The simplest one is -c flag. &amp;quot;C&amp;quot; stands for copy and if this flag is on then the attributes&lt;br /&gt;
are copied from the old map to the new map. Note that the attributes of removed features are&lt;br /&gt;
dropped. &lt;br /&gt;
&lt;br /&gt;
Default behaviour of this module is that the selected algorithm/method is applied to the all&lt;br /&gt;
lines/areas. It is possible to apply the most of the algorithms only to the selected features.&lt;br /&gt;
This is achieved by &amp;quot;type&amp;quot;, &amp;quot;layer&amp;quot;, &amp;quot;cats&amp;quot; and &amp;quot;where&amp;quot; parameters. This works for all algorithms&lt;br /&gt;
except &amp;quot;Network Generalization&amp;quot; which is always applied to the all features. &lt;br /&gt;
For example, the following command applies &amp;quot;Douglas Reduction&amp;quot; algorithm to interstates and highways (cat&amp;amp;lt;3)&lt;br /&gt;
and leaves the other lines unaltered. It also copies the attributes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize -c input=roads output=roads_douglas_reduction2 method=douglas_reduction threshold=0 reduction=50 type=line layer=1 where=&amp;quot;cat&amp;amp;lt;3&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the following command removes the small areas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=soils output=soils_remove_small method=remove_small threshold=200 type=area&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, the following command displaces only the interstates (cats=1) and the lines with a different&lt;br /&gt;
category number are not taken into the account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
v.generalize input=roads output=roads_displacement2 method=displacement \&lt;br /&gt;
   threshold=75 alpha=0.01 beta=0.01 iterations=20 layer=1 cats=1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.pic10.png|center|thumb|400px|caption text here]]  &lt;br /&gt;
&lt;br /&gt;
We end up with a complex example of a generalization of &amp;quot;roads&amp;quot; in Spearfish location.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#straighten the lines&lt;br /&gt;
v.generalize input=roads output=step1 method=snakes alpha=1 beta=1&lt;br /&gt;
#simplification&lt;br /&gt;
v.generalize input=step1 output=step2 method=douglas_reduction threshold=0 reduction=55&lt;br /&gt;
#displacement&lt;br /&gt;
v.generalize input=step2 output=step3 method=displacement alpha=0.01 beta=0.01 threshold=100 iterations=50&lt;br /&gt;
#remove small areas&lt;br /&gt;
v.generalize input=step3 output=step4 method=remove_small threshold=75&lt;br /&gt;
#network generalization&lt;br /&gt;
v.generalize input=step4 output=step5 method=network betweeness_thresh=5 closeness_thresh=0.0425&lt;br /&gt;
#smoothing&lt;br /&gt;
v.generalize input=step5 output=step6 method=chaiken threshold=1&lt;br /&gt;
#simplification&lt;br /&gt;
v.generalize input=step6 output=step7 method=douglas threshold=1&lt;br /&gt;
#remove temporary maps&lt;br /&gt;
g.remove vect=step1,step2,step3,step4,step5,step6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result &amp;quot;step7&amp;quot; has 655 lines and 3545 vertices and the commands above have the following effect:&lt;br /&gt;
&lt;br /&gt;
[[Image:v.generalize.anim.gif|center|thumb|400px|caption text here (animation)]]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
Use cases:&lt;br /&gt;
* http://www.custom-scenery.org/Line-data-simpl.275.0.html&lt;br /&gt;
&lt;br /&gt;
== AUTHORS ==&lt;br /&gt;
&lt;br /&gt;
* Daniel Bundala, Google Summer of Code 2007, Student&lt;br /&gt;
* Wolf Bergenheim, Mentor&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Tutorial]]&lt;br /&gt;
[[Category: Vector]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Movies&amp;diff=28723</id>
		<title>Movies</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Movies&amp;diff=28723"/>
		<updated>2025-11-04T03:18:36Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Encode as animated GIF */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Q: How to construct high-quality MPEG-4 movies (animations) from a series of still frames? ====&lt;br /&gt;
&lt;br /&gt;
''Maris wrote'':&lt;br /&gt;
&lt;br /&gt;
Encode all .png files in directory to out.avi with 15 frames per second:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mencoder &amp;quot;mf:///path/to/files/*.png&amp;quot; -mf fps=15 -o out.avi # put -ovc here, see next lines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## for DivX - libavcodec MPEG 4 (DivX5), use:&lt;br /&gt;
-ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=1800 -ffourcc MP4S&lt;br /&gt;
## for XviD, use:&lt;br /&gt;
-ovc xvid -xvidencopts bitrate=1024 -xvidencopts pass=2 -xvidencopts cartoon&lt;br /&gt;
## for DivX4, use:&lt;br /&gt;
-ovc divx4 -divx4opts q=5&lt;br /&gt;
## for x264 use:&lt;br /&gt;
-ovc x264 -x264encopts pass=3 -x264encopts preset=veryslow -x264encopts tune=animation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Uses mplayer's encoder. Choose one of encoding formats and append to end &lt;br /&gt;
of &amp;quot;mencoder&amp;quot; line. Unfortunately only way to know quality settings is by &lt;br /&gt;
encoding, watching result and re-encoding with different params.&lt;br /&gt;
&lt;br /&gt;
Notice - by default encoding with lavc will set video fourcc to FMP4, that can be decoded with ffdshow. Option -ffourcc MP4S will change it to MPS4 (&amp;quot;official&amp;quot; MS fourcc for mpeg4) and video will be playable on Windows by standard MS mpeg4 decoder. It may lead to side effects, if MS mpeg4 decoder is buggy. More info: http://www.itdp.de/mplayer-users/2005-03/msg00069.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other guides:&lt;br /&gt;
* http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-enc-images.html&lt;br /&gt;
* http://electron.mit.edu/~gsteele/ffmpeg/&lt;br /&gt;
* http://www.stillhq.com/extracted/howto-jpeg2mpeg/output.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to construct high-quality WebM movies? ====&lt;br /&gt;
&lt;br /&gt;
A: {{wikipedia|WebM}} is the container for the {{wikipedia|VP8}} and {{wikipedia|VP9}} codecs. VP8 approaches H.264 in quality but differs from H.264 in that it is both patent + license free to use. Likewise, VP9 is an alternative to HEVC/H.265. The audio channel, if used, is encoded using the Ogg {{wikipedia|Vorbis}} codec for VP8 or Opus codec for VP9. Google has been promoting WebM as the standard fallback video format for HTML5 and is moving YouTube content to it. Firefox. Opera, and Google Chrome web browsers support WebM playback out of the box without need for extra plugins.&lt;br /&gt;
&lt;br /&gt;
; Encoding:&lt;br /&gt;
&lt;br /&gt;
First convert PNG or JPEG images to PPM format using the {{wikipedia|NetPBM}} tools.&lt;br /&gt;
: ''This step is pretty fast, I wouldn't worry about trying to parallelize it.''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for file in *.png ; do&lt;br /&gt;
   pngtopnm $file &amp;gt; `basename $file .png`.ppm&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
::or&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for file in *.jpg ; do&lt;br /&gt;
   jpegtopnm $file &amp;gt; `basename $file .jpg`.ppm&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next create a Y4M stream containing a concatenation of the raw PPM frames:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat *.ppm | ppmtoy4m -F 2:1 &amp;gt; all_frames.y4m&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''The &amp;quot;-F 2:1&amp;quot; option above sets the frame rate to 2 frames per second.''&lt;br /&gt;
* ''The &amp;lt;tt&amp;gt;ppmtoy4m&amp;lt;/tt&amp;gt; program comes from the mjpegtools package.''&lt;br /&gt;
* ''For a very high number of frames you may wish to skip this step and create a named FIFO or stdin pipe directly into &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt;, as the raw Y4M file can become extremely large.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, run the &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; encoder to create a high quality WebM video:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
vpxenc all_frames.y4m -o my_movie.webm \&lt;br /&gt;
  --passes=2 --threads=4 \&lt;br /&gt;
  --best --target-bitrate=2000 --end-usage=vbr \&lt;br /&gt;
  --auto-alt-ref=1 --verbose \&lt;br /&gt;
  --minsection-pct=5 --maxsection-pct=800 \&lt;br /&gt;
  --lag-in-frames=16 --kf-min-dist=0 --kf-max-dist=360 \&lt;br /&gt;
  --static-thresh=0 --drop-frame=0 \&lt;br /&gt;
  --min-q=0 --max-q=60&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''Set &amp;quot;--threads=&amp;quot; in the above command to the number of cores on your CPU. (or one less than the number of cores if you have many)''&lt;br /&gt;
* ''If you are encoding to VP8 (and not VP9) consider adding &amp;lt;tt&amp;gt;--token-parts=2&amp;lt;/tt&amp;gt;''&lt;br /&gt;
* ''If &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; complains about &amp;quot;Invalid image format&amp;quot; either add &amp;quot;-S 420jpeg&amp;quot; to the &amp;lt;tt&amp;gt;ppmtoy4m&amp;lt;/tt&amp;gt; options or add &amp;quot;--profile=1&amp;quot; to the &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; options.&lt;br /&gt;
* ''The &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; program comes from the vpx-tools package.''&lt;br /&gt;
* [http://www.webmproject.org/docs/encoder-parameters/#2-pass-best-quality-vbr-encoding Encoder parameters help page]&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to generate an animated GIF, FLI, or MNG? ====&lt;br /&gt;
&lt;br /&gt;
A: for animations of 300 frames or less, animated GIF, [http://woodshole.er.usgs.gov/operations/modeling/flc.html  FLI], or MNG formats are smaller files and better quality (i.e., frames stored as PNG not JPEG). Create with [http://www.lcdf.org/gifsicle/ gifsicle], [http://vento.pi.tu-berlin.de/fli.html ppm2fli], or for MNG use [http://www.imagemagick.org/script/convert.php ImageMagick's 'convert']. With more than 300 frames the players usually have memory issues. Animated GIFs are playable in any web browser of course and also in OpenOffice.&lt;br /&gt;
&lt;br /&gt;
 # with convert, many GIFs into one animated GIF:&lt;br /&gt;
 convert -verbose -delay 20 -loop 0 snapshot*.png animation.gif&lt;br /&gt;
&lt;br /&gt;
Notes: '-delay 20' means 20 hundreds of a second delay between each frame. The '-loop 0' flag lets it loop indefinitely. To loop only 3 times use '-loop 3' etc.&lt;br /&gt;
&lt;br /&gt;
Sample script to export PNGs in GRASS (generates tmean_001.png .. tmean_708.png):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
   export i=0&lt;br /&gt;
   for year in `seq 1950 2008` ; do&lt;br /&gt;
       for m in `seq 1 12` ; do&lt;br /&gt;
           i=`expr $i + 1`&lt;br /&gt;
           # awk trick to generate wildcard-correct file names:&lt;br /&gt;
           i=`echo $i | awk '{printf &amp;quot;%03d\n&amp;quot;, $1}'`&lt;br /&gt;
           r.out.png tmean_europe.$year.$m.avg out=tmean_$i.png&lt;br /&gt;
        done&lt;br /&gt;
    done&lt;br /&gt;
    convert -verbose -delay 20 -loop 0 tmean_*.png tmean_animation.gif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For presentations using a web browser, you can center the image on a blank white page, turn off any toolbars and go into full screen mode (F11 for Firefox or Chrome). Then Alt-Tab your way to the animation at the appropriate time and nobody knows you are using a web browser.&lt;br /&gt;
&lt;br /&gt;
Example HTML for centering image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;HTML&amp;gt;&lt;br /&gt;
&amp;lt;HEAD&amp;gt;&amp;lt;/HEAD&amp;gt;&lt;br /&gt;
&amp;lt;BODY&amp;gt;&lt;br /&gt;
 &amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
 &amp;lt;CENTER&amp;gt;&lt;br /&gt;
  &amp;lt;IMG SRC=&amp;quot;animation.gif&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/CENTER&amp;gt;&lt;br /&gt;
&amp;lt;/BODY&amp;gt;&lt;br /&gt;
&amp;lt;/HTML&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to create dynamic surface movies in NVIZ? ====&lt;br /&gt;
&lt;br /&gt;
A: See slides from the FOSS4G 2006 workshop:&lt;br /&gt;
: http://skagit.meas.ncsu.edu/~helena/grasswork/foss4g/FOSS4G06WKSVisual4anim.odp&lt;br /&gt;
&lt;br /&gt;
See also the example at the bottom of the [http://grass.osgeo.org/grass64/manuals/html64_user/nviz/nviz_panel_kanim.html NVIZ keyframe animator panel help page].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to animate a time series of raster maps? ====&lt;br /&gt;
&lt;br /&gt;
A: Use&lt;br /&gt;
* {{cmd|d.slide.show}} to view in a GRASS xmon (see {{cmd|d.mon}})&lt;br /&gt;
* {{cmd|r.out.mpeg}} to save to a MPEG-1 movie.&lt;br /&gt;
* GRASS GIS 6: {{cmd|xganim|version=64}} to view on screen in X-windows (with live start/stop/speed controls)&lt;br /&gt;
* GRASS GIS 7: {{cmd|g.gui.animation}} to view on screen in wxGUI (with live start/stop/speed controls)&lt;br /&gt;
: See also the wiki page for the [[wxGUI Animation Tool]]:&lt;br /&gt;
{{YouTube|Pi1ESk9iPwk|YouTube video introduction to the WxGUI Animation Tool}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to animate a series of maps, including decorations? ====&lt;br /&gt;
&lt;br /&gt;
A: Use the xmon drivers ({{cmd|d.mon}}) &lt;br /&gt;
to render the displays to a window via a shell script loop, then switch from the ''x0'' to ''PNG'' driver to save as a series of PNG or PPM images. Use a method answered in a FAQ above to combine those into a single animation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to create a screencast (for video tutorials etc)? ====&lt;br /&gt;
&lt;br /&gt;
; GNU/Linux:&lt;br /&gt;
* Easist way: [http://recordmydesktop.sourceforge.net/ recordmydesktop] (user interfaces are 'qt-recordmydesktop' and 'gtk-recordmydesktop')&lt;br /&gt;
:* when uploading videos to Youtube created by &amp;lt;tt&amp;gt;recordmydesktop&amp;lt;/tt&amp;gt; you need to encode the file eg. using &amp;lt;tt&amp;gt;mencoder&amp;lt;/tt&amp;gt;&lt;br /&gt;
:- No sound, just video screencast, as AVI file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;mencoder out.ogv -nosound -ovc lavc -o out.avi&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as AVI file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;mencoder out.ogv -ovc xvid -oac mp3lame -xvidencopts pass=1 -o out.avi&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as WebM file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;ffmpeg -i out.ogv -b:a 24k out.webm&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as MP4 file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;ffmpeg -i out.ogv -ar 44100 -ab 96k -coder ac -strict experimental -vcodec libx264 out.mp4&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [https://wiki.ubuntu.com/MeetingLogs/openweekfeisty/screencast Ubuntu discussion over screencast]&lt;br /&gt;
* [https://wiki.ubuntu.com/ScreencastTeam/RecordingScreencasts Ubuntu screencast how to]&lt;br /&gt;
* [http://www.unixuser.org/~euske/vnc2swf/ vnc2swf] to record a flash movie ([http://www-pool.math.tu-berlin.de/~soeren/grass/modules/screenshots/vnc2swf_usage.html short vnc2swf usage tutorial])&lt;br /&gt;
* [http://www.maartenbaert.be/simplescreenrecorder/ SimpleScreenRecorder]&lt;br /&gt;
&lt;br /&gt;
; MacOSX:&lt;br /&gt;
* [http://crschmidt.net/blog/archives/203/openlayers-screencast/ Chris Schmidt experience on MacOSX]&lt;br /&gt;
&lt;br /&gt;
; MS Windows:&lt;br /&gt;
* [http://camstudio.org/ Camstudio]&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
''Using the [http://grass.osgeo.org/download/data6.php Spearfish] sample dataset''&lt;br /&gt;
&lt;br /&gt;
===== Animate on screen =====&lt;br /&gt;
''Using a shell script''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
GRASS_WIDTH=640 GRASS_HEIGHT=500 \&lt;br /&gt;
  d.mon start=x0&lt;br /&gt;
&lt;br /&gt;
g.region rast=elevation.dem n=4927830 s=4912980&lt;br /&gt;
&lt;br /&gt;
for NUM in `seq 1 0.5 10` ; do&lt;br /&gt;
   d.rast elevation.dem --quiet&lt;br /&gt;
   d.vect roads&lt;br /&gt;
   d.vect bugsites icon=basic/circle col=black fcol=green size=`echo &amp;quot;21-($NUM * 2)&amp;quot; | bc`&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;symbol basic/arrow2 25 80 `echo &amp;quot;10*$NUM&amp;quot; | bc` 80:80:80 125:125:255&amp;quot; | d.graph&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;Spearfish, South Dakota&amp;quot; | d.text size=4.5 at=1,2.25&lt;br /&gt;
   d.barscale at=59.8,93.6 tcol=grey&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Animate to files =====&lt;br /&gt;
''Using [http://grass.osgeo.org/grass64/manuals/html64_user/pngdriver.html GRASS's PNG driver]''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
# set up base map&lt;br /&gt;
g.region rast=elevation.dem n=4927830 s=4912980&lt;br /&gt;
export GRASS_WIDTH=640&lt;br /&gt;
export GRASS_HEIGHT=500&lt;br /&gt;
export GRASS_PNGFILE=base.ppm&lt;br /&gt;
export GRASS_PNG_READ=FALSE&lt;br /&gt;
d.mon start=PNG&lt;br /&gt;
  d.rast elevation.dem&lt;br /&gt;
  d.vect roads&lt;br /&gt;
  echo &amp;quot;Spearfish, South Dakota&amp;quot; | d.text size=4.5 at=1,2.25&lt;br /&gt;
  d.barscale at=59.8,93.6 tcol=grey&lt;br /&gt;
d.mon stop=PNG&lt;br /&gt;
&lt;br /&gt;
# loop to draw variable parts as new frames&lt;br /&gt;
i=0&lt;br /&gt;
export GRASS_PNG_READ=TRUE&lt;br /&gt;
for NUM in `seq 1 0.5 10` ; do&lt;br /&gt;
   i=`expr $i + 1`&lt;br /&gt;
   FRAMENUM=`echo $i | awk '{printf(&amp;quot;%03d&amp;quot;, $1)}'`&lt;br /&gt;
   echo &amp;quot;Processing frame $FRAMENUM ...&amp;quot;&lt;br /&gt;
   export GRASS_PNGFILE=&amp;quot;ganim_${FRAMENUM}.ppm&amp;quot;&lt;br /&gt;
   cp base.ppm &amp;quot;$GRASS_PNGFILE&amp;quot;&lt;br /&gt;
   d.mon start=PNG --quiet&lt;br /&gt;
   d.vect bugsites icon=basic/circle col=black fcol=green \&lt;br /&gt;
      size=`echo &amp;quot;21-($NUM * 2)&amp;quot; | bc`&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;symbol basic/arrow2 25 80 `echo &amp;quot;10*$NUM&amp;quot; | bc` 80:80:80 125:125:255&amp;quot; | d.graph&lt;br /&gt;
   d.mon stop=PNG --quiet&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
# repeat the last frame a few times&lt;br /&gt;
for EXTRA in 1 2 3 ; do&lt;br /&gt;
 i=`expr $i + 1`&lt;br /&gt;
 FRAMENUM=`echo $i | awk '{printf(&amp;quot;%03d&amp;quot;, $1)}'`&lt;br /&gt;
 cp base.ppm &amp;quot;ganim_${FRAMENUM}.ppm&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
\rm base.ppm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as animated GIF =====&lt;br /&gt;
&lt;br /&gt;
* ''Using the [http://www.lcdf.org/gifsicle/ gifsicle] encoder''&lt;br /&gt;
* ''View in a web browser or with ImageMagick's [http://www.imagemagick.org/Usage/basics/#animate animate]''&lt;br /&gt;
* see [[Movies#Q:_How_to_generate_an_animated_GIF.2C_FLI.2C_or_MNG.3F]] above&lt;br /&gt;
&lt;br /&gt;
'''A) Using gifsicle:'''&lt;br /&gt;
&lt;br /&gt;
Advantage: the delay is coded in the animated GIF file and rendered properly e.g. in a Web browser.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
# Imagemagick's `convert` program may do a better job at &lt;br /&gt;
# 256 color quantization than NetPBM's `ppmquant`.&lt;br /&gt;
for IMG in ganim*.ppm ; do   # convert each frame from PPM to GIF&lt;br /&gt;
   #ppmquant 256 $IMG | ppmtogif &amp;gt; &amp;quot;`basename $IMG .ppm`.gif&amp;quot;&lt;br /&gt;
   convert &amp;quot;$IMG&amp;quot; &amp;quot;`basename $IMG .ppm`.gif&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
gifsicle -O2 --delay 20 --no-loopcount --colors 256 ganim_*.gif &amp;gt; ganim.gif&lt;br /&gt;
&lt;br /&gt;
\rm ganim_0*.gif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''B) Using ImageMagick's convert and [http://www.imagemagick.org/Usage/basics/#animate animate]:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
# Generate &amp;quot;film&amp;quot; (create animated GIF, 750 millisec between frames):&lt;br /&gt;
convert -delay 75 lst_monthly_avg_film.00*.png lst_monthly_avg_2002_2012_zoom_film.gif&lt;br /&gt;
&lt;br /&gt;
# play animation (delay 500 millisec between frames, pause for 5 seconds at the end)&lt;br /&gt;
animate -delay 50 -pause 5 lst_monthly_avg_2002_2012_zoom_film.gif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as animated PNG (MNG) =====&lt;br /&gt;
* ''Using the [http://www.imagemagick.org ImageMagick] &amp;quot;convert&amp;quot; encoder''&lt;br /&gt;
* ''View with ImageMagick's &amp;quot;display&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
convert -delay 20 ganim_*.ppm ganim.mng&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as FLI =====&lt;br /&gt;
* ''Using the [http://vento.pi.tu-berlin.de/fli.html ppm2fli] encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer] or [http://xanim.polter.net xanim]''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
ls ganim_*.ppm &amp;gt; frames.txt&lt;br /&gt;
ppm2fli -g&amp;quot;${GRASS_WIDTH}x${GRASS_HEIGHT}&amp;quot; -O -s 15 frames.txt ganim.fli&lt;br /&gt;
\rm frames.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as Flash =====&lt;br /&gt;
&lt;br /&gt;
* ''Using the [http://www.swftools.org/ SWFTools] &amp;lt;tt&amp;gt;png2swf&amp;lt;/tt&amp;gt; encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer]''&lt;br /&gt;
&lt;br /&gt;
 png2swf -o outfile.swf *.png -r 1&lt;br /&gt;
&lt;br /&gt;
===== Encode as MPEG-4 Xvid =====&lt;br /&gt;
* ''Using the [http://www.mplayerhq.hu mencoder] encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer] or similar''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
# doesn't like GRASS's PPMs, convert to PNG&lt;br /&gt;
for IMG in ganim*.ppm ; do&lt;br /&gt;
  pnmtopng $IMG &amp;gt; &amp;quot;`basename $IMG .ppm`.png&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
mencoder &amp;quot;mf://ganim_*.png&amp;quot; -mf &amp;quot;type=png:fps=5&amp;quot; -o ganim.avi \&lt;br /&gt;
   -ovc &amp;quot;xvid&amp;quot; -xvidencopts &amp;quot;bitrate=1024&amp;quot;&lt;br /&gt;
\rm ganim_0*.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Publish your cool videos in this Wiki ====&lt;br /&gt;
We have installed a Mediawiki widget extension and created a special template for including Youtube videos ([[Template:YouTube]]). See also [[WxGUI_Modeler#Video_tutorials|wxGUI Modeler]] page for the usage.&lt;br /&gt;
&lt;br /&gt;
The overall goal is to have many as possible '''[http://www.youtube.com/results?search_query=grass+gis GRASS GIS videos on YouTube]'''&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Visualization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Movies&amp;diff=28722</id>
		<title>Movies</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Movies&amp;diff=28722"/>
		<updated>2025-11-04T03:18:16Z</updated>

		<summary type="html">&lt;p&gt;Hamish: source -&amp;gt; syntaxhighlight&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Q: How to construct high-quality MPEG-4 movies (animations) from a series of still frames? ====&lt;br /&gt;
&lt;br /&gt;
''Maris wrote'':&lt;br /&gt;
&lt;br /&gt;
Encode all .png files in directory to out.avi with 15 frames per second:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mencoder &amp;quot;mf:///path/to/files/*.png&amp;quot; -mf fps=15 -o out.avi # put -ovc here, see next lines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## for DivX - libavcodec MPEG 4 (DivX5), use:&lt;br /&gt;
-ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=1800 -ffourcc MP4S&lt;br /&gt;
## for XviD, use:&lt;br /&gt;
-ovc xvid -xvidencopts bitrate=1024 -xvidencopts pass=2 -xvidencopts cartoon&lt;br /&gt;
## for DivX4, use:&lt;br /&gt;
-ovc divx4 -divx4opts q=5&lt;br /&gt;
## for x264 use:&lt;br /&gt;
-ovc x264 -x264encopts pass=3 -x264encopts preset=veryslow -x264encopts tune=animation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Uses mplayer's encoder. Choose one of encoding formats and append to end &lt;br /&gt;
of &amp;quot;mencoder&amp;quot; line. Unfortunately only way to know quality settings is by &lt;br /&gt;
encoding, watching result and re-encoding with different params.&lt;br /&gt;
&lt;br /&gt;
Notice - by default encoding with lavc will set video fourcc to FMP4, that can be decoded with ffdshow. Option -ffourcc MP4S will change it to MPS4 (&amp;quot;official&amp;quot; MS fourcc for mpeg4) and video will be playable on Windows by standard MS mpeg4 decoder. It may lead to side effects, if MS mpeg4 decoder is buggy. More info: http://www.itdp.de/mplayer-users/2005-03/msg00069.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other guides:&lt;br /&gt;
* http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-enc-images.html&lt;br /&gt;
* http://electron.mit.edu/~gsteele/ffmpeg/&lt;br /&gt;
* http://www.stillhq.com/extracted/howto-jpeg2mpeg/output.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to construct high-quality WebM movies? ====&lt;br /&gt;
&lt;br /&gt;
A: {{wikipedia|WebM}} is the container for the {{wikipedia|VP8}} and {{wikipedia|VP9}} codecs. VP8 approaches H.264 in quality but differs from H.264 in that it is both patent + license free to use. Likewise, VP9 is an alternative to HEVC/H.265. The audio channel, if used, is encoded using the Ogg {{wikipedia|Vorbis}} codec for VP8 or Opus codec for VP9. Google has been promoting WebM as the standard fallback video format for HTML5 and is moving YouTube content to it. Firefox. Opera, and Google Chrome web browsers support WebM playback out of the box without need for extra plugins.&lt;br /&gt;
&lt;br /&gt;
; Encoding:&lt;br /&gt;
&lt;br /&gt;
First convert PNG or JPEG images to PPM format using the {{wikipedia|NetPBM}} tools.&lt;br /&gt;
: ''This step is pretty fast, I wouldn't worry about trying to parallelize it.''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for file in *.png ; do&lt;br /&gt;
   pngtopnm $file &amp;gt; `basename $file .png`.ppm&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
::or&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for file in *.jpg ; do&lt;br /&gt;
   jpegtopnm $file &amp;gt; `basename $file .jpg`.ppm&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next create a Y4M stream containing a concatenation of the raw PPM frames:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat *.ppm | ppmtoy4m -F 2:1 &amp;gt; all_frames.y4m&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''The &amp;quot;-F 2:1&amp;quot; option above sets the frame rate to 2 frames per second.''&lt;br /&gt;
* ''The &amp;lt;tt&amp;gt;ppmtoy4m&amp;lt;/tt&amp;gt; program comes from the mjpegtools package.''&lt;br /&gt;
* ''For a very high number of frames you may wish to skip this step and create a named FIFO or stdin pipe directly into &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt;, as the raw Y4M file can become extremely large.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, run the &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; encoder to create a high quality WebM video:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
vpxenc all_frames.y4m -o my_movie.webm \&lt;br /&gt;
  --passes=2 --threads=4 \&lt;br /&gt;
  --best --target-bitrate=2000 --end-usage=vbr \&lt;br /&gt;
  --auto-alt-ref=1 --verbose \&lt;br /&gt;
  --minsection-pct=5 --maxsection-pct=800 \&lt;br /&gt;
  --lag-in-frames=16 --kf-min-dist=0 --kf-max-dist=360 \&lt;br /&gt;
  --static-thresh=0 --drop-frame=0 \&lt;br /&gt;
  --min-q=0 --max-q=60&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''Set &amp;quot;--threads=&amp;quot; in the above command to the number of cores on your CPU. (or one less than the number of cores if you have many)''&lt;br /&gt;
* ''If you are encoding to VP8 (and not VP9) consider adding &amp;lt;tt&amp;gt;--token-parts=2&amp;lt;/tt&amp;gt;''&lt;br /&gt;
* ''If &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; complains about &amp;quot;Invalid image format&amp;quot; either add &amp;quot;-S 420jpeg&amp;quot; to the &amp;lt;tt&amp;gt;ppmtoy4m&amp;lt;/tt&amp;gt; options or add &amp;quot;--profile=1&amp;quot; to the &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; options.&lt;br /&gt;
* ''The &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; program comes from the vpx-tools package.''&lt;br /&gt;
* [http://www.webmproject.org/docs/encoder-parameters/#2-pass-best-quality-vbr-encoding Encoder parameters help page]&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to generate an animated GIF, FLI, or MNG? ====&lt;br /&gt;
&lt;br /&gt;
A: for animations of 300 frames or less, animated GIF, [http://woodshole.er.usgs.gov/operations/modeling/flc.html  FLI], or MNG formats are smaller files and better quality (i.e., frames stored as PNG not JPEG). Create with [http://www.lcdf.org/gifsicle/ gifsicle], [http://vento.pi.tu-berlin.de/fli.html ppm2fli], or for MNG use [http://www.imagemagick.org/script/convert.php ImageMagick's 'convert']. With more than 300 frames the players usually have memory issues. Animated GIFs are playable in any web browser of course and also in OpenOffice.&lt;br /&gt;
&lt;br /&gt;
 # with convert, many GIFs into one animated GIF:&lt;br /&gt;
 convert -verbose -delay 20 -loop 0 snapshot*.png animation.gif&lt;br /&gt;
&lt;br /&gt;
Notes: '-delay 20' means 20 hundreds of a second delay between each frame. The '-loop 0' flag lets it loop indefinitely. To loop only 3 times use '-loop 3' etc.&lt;br /&gt;
&lt;br /&gt;
Sample script to export PNGs in GRASS (generates tmean_001.png .. tmean_708.png):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
   export i=0&lt;br /&gt;
   for year in `seq 1950 2008` ; do&lt;br /&gt;
       for m in `seq 1 12` ; do&lt;br /&gt;
           i=`expr $i + 1`&lt;br /&gt;
           # awk trick to generate wildcard-correct file names:&lt;br /&gt;
           i=`echo $i | awk '{printf &amp;quot;%03d\n&amp;quot;, $1}'`&lt;br /&gt;
           r.out.png tmean_europe.$year.$m.avg out=tmean_$i.png&lt;br /&gt;
        done&lt;br /&gt;
    done&lt;br /&gt;
    convert -verbose -delay 20 -loop 0 tmean_*.png tmean_animation.gif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For presentations using a web browser, you can center the image on a blank white page, turn off any toolbars and go into full screen mode (F11 for Firefox or Chrome). Then Alt-Tab your way to the animation at the appropriate time and nobody knows you are using a web browser.&lt;br /&gt;
&lt;br /&gt;
Example HTML for centering image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;HTML&amp;gt;&lt;br /&gt;
&amp;lt;HEAD&amp;gt;&amp;lt;/HEAD&amp;gt;&lt;br /&gt;
&amp;lt;BODY&amp;gt;&lt;br /&gt;
 &amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
 &amp;lt;CENTER&amp;gt;&lt;br /&gt;
  &amp;lt;IMG SRC=&amp;quot;animation.gif&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/CENTER&amp;gt;&lt;br /&gt;
&amp;lt;/BODY&amp;gt;&lt;br /&gt;
&amp;lt;/HTML&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to create dynamic surface movies in NVIZ? ====&lt;br /&gt;
&lt;br /&gt;
A: See slides from the FOSS4G 2006 workshop:&lt;br /&gt;
: http://skagit.meas.ncsu.edu/~helena/grasswork/foss4g/FOSS4G06WKSVisual4anim.odp&lt;br /&gt;
&lt;br /&gt;
See also the example at the bottom of the [http://grass.osgeo.org/grass64/manuals/html64_user/nviz/nviz_panel_kanim.html NVIZ keyframe animator panel help page].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to animate a time series of raster maps? ====&lt;br /&gt;
&lt;br /&gt;
A: Use&lt;br /&gt;
* {{cmd|d.slide.show}} to view in a GRASS xmon (see {{cmd|d.mon}})&lt;br /&gt;
* {{cmd|r.out.mpeg}} to save to a MPEG-1 movie.&lt;br /&gt;
* GRASS GIS 6: {{cmd|xganim|version=64}} to view on screen in X-windows (with live start/stop/speed controls)&lt;br /&gt;
* GRASS GIS 7: {{cmd|g.gui.animation}} to view on screen in wxGUI (with live start/stop/speed controls)&lt;br /&gt;
: See also the wiki page for the [[wxGUI Animation Tool]]:&lt;br /&gt;
{{YouTube|Pi1ESk9iPwk|YouTube video introduction to the WxGUI Animation Tool}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to animate a series of maps, including decorations? ====&lt;br /&gt;
&lt;br /&gt;
A: Use the xmon drivers ({{cmd|d.mon}}) &lt;br /&gt;
to render the displays to a window via a shell script loop, then switch from the ''x0'' to ''PNG'' driver to save as a series of PNG or PPM images. Use a method answered in a FAQ above to combine those into a single animation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to create a screencast (for video tutorials etc)? ====&lt;br /&gt;
&lt;br /&gt;
; GNU/Linux:&lt;br /&gt;
* Easist way: [http://recordmydesktop.sourceforge.net/ recordmydesktop] (user interfaces are 'qt-recordmydesktop' and 'gtk-recordmydesktop')&lt;br /&gt;
:* when uploading videos to Youtube created by &amp;lt;tt&amp;gt;recordmydesktop&amp;lt;/tt&amp;gt; you need to encode the file eg. using &amp;lt;tt&amp;gt;mencoder&amp;lt;/tt&amp;gt;&lt;br /&gt;
:- No sound, just video screencast, as AVI file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;mencoder out.ogv -nosound -ovc lavc -o out.avi&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as AVI file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;mencoder out.ogv -ovc xvid -oac mp3lame -xvidencopts pass=1 -o out.avi&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as WebM file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;ffmpeg -i out.ogv -b:a 24k out.webm&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as MP4 file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;ffmpeg -i out.ogv -ar 44100 -ab 96k -coder ac -strict experimental -vcodec libx264 out.mp4&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [https://wiki.ubuntu.com/MeetingLogs/openweekfeisty/screencast Ubuntu discussion over screencast]&lt;br /&gt;
* [https://wiki.ubuntu.com/ScreencastTeam/RecordingScreencasts Ubuntu screencast how to]&lt;br /&gt;
* [http://www.unixuser.org/~euske/vnc2swf/ vnc2swf] to record a flash movie ([http://www-pool.math.tu-berlin.de/~soeren/grass/modules/screenshots/vnc2swf_usage.html short vnc2swf usage tutorial])&lt;br /&gt;
* [http://www.maartenbaert.be/simplescreenrecorder/ SimpleScreenRecorder]&lt;br /&gt;
&lt;br /&gt;
; MacOSX:&lt;br /&gt;
* [http://crschmidt.net/blog/archives/203/openlayers-screencast/ Chris Schmidt experience on MacOSX]&lt;br /&gt;
&lt;br /&gt;
; MS Windows:&lt;br /&gt;
* [http://camstudio.org/ Camstudio]&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
''Using the [http://grass.osgeo.org/download/data6.php Spearfish] sample dataset''&lt;br /&gt;
&lt;br /&gt;
===== Animate on screen =====&lt;br /&gt;
''Using a shell script''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
GRASS_WIDTH=640 GRASS_HEIGHT=500 \&lt;br /&gt;
  d.mon start=x0&lt;br /&gt;
&lt;br /&gt;
g.region rast=elevation.dem n=4927830 s=4912980&lt;br /&gt;
&lt;br /&gt;
for NUM in `seq 1 0.5 10` ; do&lt;br /&gt;
   d.rast elevation.dem --quiet&lt;br /&gt;
   d.vect roads&lt;br /&gt;
   d.vect bugsites icon=basic/circle col=black fcol=green size=`echo &amp;quot;21-($NUM * 2)&amp;quot; | bc`&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;symbol basic/arrow2 25 80 `echo &amp;quot;10*$NUM&amp;quot; | bc` 80:80:80 125:125:255&amp;quot; | d.graph&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;Spearfish, South Dakota&amp;quot; | d.text size=4.5 at=1,2.25&lt;br /&gt;
   d.barscale at=59.8,93.6 tcol=grey&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Animate to files =====&lt;br /&gt;
''Using [http://grass.osgeo.org/grass64/manuals/html64_user/pngdriver.html GRASS's PNG driver]''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
# set up base map&lt;br /&gt;
g.region rast=elevation.dem n=4927830 s=4912980&lt;br /&gt;
export GRASS_WIDTH=640&lt;br /&gt;
export GRASS_HEIGHT=500&lt;br /&gt;
export GRASS_PNGFILE=base.ppm&lt;br /&gt;
export GRASS_PNG_READ=FALSE&lt;br /&gt;
d.mon start=PNG&lt;br /&gt;
  d.rast elevation.dem&lt;br /&gt;
  d.vect roads&lt;br /&gt;
  echo &amp;quot;Spearfish, South Dakota&amp;quot; | d.text size=4.5 at=1,2.25&lt;br /&gt;
  d.barscale at=59.8,93.6 tcol=grey&lt;br /&gt;
d.mon stop=PNG&lt;br /&gt;
&lt;br /&gt;
# loop to draw variable parts as new frames&lt;br /&gt;
i=0&lt;br /&gt;
export GRASS_PNG_READ=TRUE&lt;br /&gt;
for NUM in `seq 1 0.5 10` ; do&lt;br /&gt;
   i=`expr $i + 1`&lt;br /&gt;
   FRAMENUM=`echo $i | awk '{printf(&amp;quot;%03d&amp;quot;, $1)}'`&lt;br /&gt;
   echo &amp;quot;Processing frame $FRAMENUM ...&amp;quot;&lt;br /&gt;
   export GRASS_PNGFILE=&amp;quot;ganim_${FRAMENUM}.ppm&amp;quot;&lt;br /&gt;
   cp base.ppm &amp;quot;$GRASS_PNGFILE&amp;quot;&lt;br /&gt;
   d.mon start=PNG --quiet&lt;br /&gt;
   d.vect bugsites icon=basic/circle col=black fcol=green \&lt;br /&gt;
      size=`echo &amp;quot;21-($NUM * 2)&amp;quot; | bc`&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;symbol basic/arrow2 25 80 `echo &amp;quot;10*$NUM&amp;quot; | bc` 80:80:80 125:125:255&amp;quot; | d.graph&lt;br /&gt;
   d.mon stop=PNG --quiet&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
# repeat the last frame a few times&lt;br /&gt;
for EXTRA in 1 2 3 ; do&lt;br /&gt;
 i=`expr $i + 1`&lt;br /&gt;
 FRAMENUM=`echo $i | awk '{printf(&amp;quot;%03d&amp;quot;, $1)}'`&lt;br /&gt;
 cp base.ppm &amp;quot;ganim_${FRAMENUM}.ppm&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
\rm base.ppm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as animated GIF =====&lt;br /&gt;
&lt;br /&gt;
* ''Using the [http://www.lcdf.org/gifsicle/ gifsicle] encoder''&lt;br /&gt;
* ''View in a web browser or with ImageMagick's [http://www.imagemagick.org/Usage/basics/#animate animate]''&lt;br /&gt;
* see [[Movies#Q:_How_to_generate_an_animated_GIF.2C_FLI.2C_or_MNG.3F]] above&lt;br /&gt;
&lt;br /&gt;
'''A) Using gifsicle:'''&lt;br /&gt;
&lt;br /&gt;
Advantage: the delay is coded in the animated GIF file and rendered properly e.g. in a Web browser.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
# Imagemagick's `convert` program may do a better job at &lt;br /&gt;
# 256 color quantization than NetPBM's &amp;lt;tt&amp;gt;ppmquant&amp;lt;/tt&amp;gt;.&lt;br /&gt;
for IMG in ganim*.ppm ; do   # convert each frame from PPM to GIF&lt;br /&gt;
   #ppmquant 256 $IMG | ppmtogif &amp;gt; &amp;quot;`basename $IMG .ppm`.gif&amp;quot;&lt;br /&gt;
   convert &amp;quot;$IMG&amp;quot; &amp;quot;`basename $IMG .ppm`.gif&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
gifsicle -O2 --delay 20 --no-loopcount --colors 256 ganim_*.gif &amp;gt; ganim.gif&lt;br /&gt;
&lt;br /&gt;
\rm ganim_0*.gif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''B) Using ImageMagick's convert and [http://www.imagemagick.org/Usage/basics/#animate animate]:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
# Generate &amp;quot;film&amp;quot; (create animated GIF, 750 millisec between frames):&lt;br /&gt;
convert -delay 75 lst_monthly_avg_film.00*.png lst_monthly_avg_2002_2012_zoom_film.gif&lt;br /&gt;
&lt;br /&gt;
# play animation (delay 500 millisec between frames, pause for 5 seconds at the end)&lt;br /&gt;
animate -delay 50 -pause 5 lst_monthly_avg_2002_2012_zoom_film.gif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as animated PNG (MNG) =====&lt;br /&gt;
* ''Using the [http://www.imagemagick.org ImageMagick] &amp;quot;convert&amp;quot; encoder''&lt;br /&gt;
* ''View with ImageMagick's &amp;quot;display&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
convert -delay 20 ganim_*.ppm ganim.mng&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as FLI =====&lt;br /&gt;
* ''Using the [http://vento.pi.tu-berlin.de/fli.html ppm2fli] encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer] or [http://xanim.polter.net xanim]''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
ls ganim_*.ppm &amp;gt; frames.txt&lt;br /&gt;
ppm2fli -g&amp;quot;${GRASS_WIDTH}x${GRASS_HEIGHT}&amp;quot; -O -s 15 frames.txt ganim.fli&lt;br /&gt;
\rm frames.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as Flash =====&lt;br /&gt;
&lt;br /&gt;
* ''Using the [http://www.swftools.org/ SWFTools] &amp;lt;tt&amp;gt;png2swf&amp;lt;/tt&amp;gt; encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer]''&lt;br /&gt;
&lt;br /&gt;
 png2swf -o outfile.swf *.png -r 1&lt;br /&gt;
&lt;br /&gt;
===== Encode as MPEG-4 Xvid =====&lt;br /&gt;
* ''Using the [http://www.mplayerhq.hu mencoder] encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer] or similar''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;&lt;br /&gt;
# doesn't like GRASS's PPMs, convert to PNG&lt;br /&gt;
for IMG in ganim*.ppm ; do&lt;br /&gt;
  pnmtopng $IMG &amp;gt; &amp;quot;`basename $IMG .ppm`.png&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
mencoder &amp;quot;mf://ganim_*.png&amp;quot; -mf &amp;quot;type=png:fps=5&amp;quot; -o ganim.avi \&lt;br /&gt;
   -ovc &amp;quot;xvid&amp;quot; -xvidencopts &amp;quot;bitrate=1024&amp;quot;&lt;br /&gt;
\rm ganim_0*.png&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Publish your cool videos in this Wiki ====&lt;br /&gt;
We have installed a Mediawiki widget extension and created a special template for including Youtube videos ([[Template:YouTube]]). See also [[WxGUI_Modeler#Video_tutorials|wxGUI Modeler]] page for the usage.&lt;br /&gt;
&lt;br /&gt;
The overall goal is to have many as possible '''[http://www.youtube.com/results?search_query=grass+gis GRASS GIS videos on YouTube]'''&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Visualization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Movies&amp;diff=28721</id>
		<title>Movies</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Movies&amp;diff=28721"/>
		<updated>2025-11-04T03:06:33Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Encode as animated GIF */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Q: How to construct high-quality MPEG-4 movies (animations) from a series of still frames? ====&lt;br /&gt;
&lt;br /&gt;
''Maris wrote'':&lt;br /&gt;
&lt;br /&gt;
Encode all .png files in directory to out.avi with 15 frames per second:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mencoder &amp;quot;mf:///path/to/files/*.png&amp;quot; -mf fps=15 -o out.avi # put -ovc here, see next lines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## for DivX - libavcodec MPEG 4 (DivX5), use:&lt;br /&gt;
-ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=1800 -ffourcc MP4S&lt;br /&gt;
## for XviD, use:&lt;br /&gt;
-ovc xvid -xvidencopts bitrate=1024 -xvidencopts pass=2 -xvidencopts cartoon&lt;br /&gt;
## for DivX4, use:&lt;br /&gt;
-ovc divx4 -divx4opts q=5&lt;br /&gt;
## for x264 use:&lt;br /&gt;
-ovc x264 -x264encopts pass=3 -x264encopts preset=veryslow -x264encopts tune=animation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Uses mplayer's encoder. Choose one of encoding formats and append to end &lt;br /&gt;
of &amp;quot;mencoder&amp;quot; line. Unfortunately only way to know quality settings is by &lt;br /&gt;
encoding, watching result and re-encoding with different params.&lt;br /&gt;
&lt;br /&gt;
Notice - by default encoding with lavc will set video fourcc to FMP4, that can be decoded with ffdshow. Option -ffourcc MP4S will change it to MPS4 (&amp;quot;official&amp;quot; MS fourcc for mpeg4) and video will be playable on Windows by standard MS mpeg4 decoder. It may lead to side effects, if MS mpeg4 decoder is buggy. More info: http://www.itdp.de/mplayer-users/2005-03/msg00069.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other guides:&lt;br /&gt;
* http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-enc-images.html&lt;br /&gt;
* http://electron.mit.edu/~gsteele/ffmpeg/&lt;br /&gt;
* http://www.stillhq.com/extracted/howto-jpeg2mpeg/output.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to construct high-quality WebM movies? ====&lt;br /&gt;
&lt;br /&gt;
A: {{wikipedia|WebM}} is the container for the {{wikipedia|VP8}} and {{wikipedia|VP9}} codecs. VP8 approaches H.264 in quality but differs from H.264 in that it is both patent + license free to use. Likewise, VP9 is an alternative to HEVC/H.265. The audio channel, if used, is encoded using the Ogg {{wikipedia|Vorbis}} codec for VP8 or Opus codec for VP9. Google has been promoting WebM as the standard fallback video format for HTML5 and is moving YouTube content to it. Firefox. Opera, and Google Chrome web browsers support WebM playback out of the box without need for extra plugins.&lt;br /&gt;
&lt;br /&gt;
; Encoding:&lt;br /&gt;
&lt;br /&gt;
First convert PNG or JPEG images to PPM format using the {{wikipedia|NetPBM}} tools.&lt;br /&gt;
: ''This step is pretty fast, I wouldn't worry about trying to parallelize it.''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for file in *.png ; do&lt;br /&gt;
   pngtopnm $file &amp;gt; `basename $file .png`.ppm&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
::or&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for file in *.jpg ; do&lt;br /&gt;
   jpegtopnm $file &amp;gt; `basename $file .jpg`.ppm&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next create a Y4M stream containing a concatenation of the raw PPM frames:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat *.ppm | ppmtoy4m -F 2:1 &amp;gt; all_frames.y4m&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''The &amp;quot;-F 2:1&amp;quot; option above sets the frame rate to 2 frames per second.''&lt;br /&gt;
* ''The &amp;lt;tt&amp;gt;ppmtoy4m&amp;lt;/tt&amp;gt; program comes from the mjpegtools package.''&lt;br /&gt;
* ''For a very high number of frames you may wish to skip this step and create a named FIFO or stdin pipe directly into &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt;, as the raw Y4M file can become extremely large.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, run the &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; encoder to create a high quality WebM video:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
vpxenc all_frames.y4m -o my_movie.webm \&lt;br /&gt;
  --passes=2 --threads=4 \&lt;br /&gt;
  --best --target-bitrate=2000 --end-usage=vbr \&lt;br /&gt;
  --auto-alt-ref=1 --verbose \&lt;br /&gt;
  --minsection-pct=5 --maxsection-pct=800 \&lt;br /&gt;
  --lag-in-frames=16 --kf-min-dist=0 --kf-max-dist=360 \&lt;br /&gt;
  --static-thresh=0 --drop-frame=0 \&lt;br /&gt;
  --min-q=0 --max-q=60&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''Set &amp;quot;--threads=&amp;quot; in the above command to the number of cores on your CPU. (or one less than the number of cores if you have many)''&lt;br /&gt;
* ''If you are encoding to VP8 (and not VP9) consider adding &amp;lt;tt&amp;gt;--token-parts=2&amp;lt;/tt&amp;gt;''&lt;br /&gt;
* ''If &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; complains about &amp;quot;Invalid image format&amp;quot; either add &amp;quot;-S 420jpeg&amp;quot; to the &amp;lt;tt&amp;gt;ppmtoy4m&amp;lt;/tt&amp;gt; options or add &amp;quot;--profile=1&amp;quot; to the &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; options.&lt;br /&gt;
* ''The &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; program comes from the vpx-tools package.''&lt;br /&gt;
* [http://www.webmproject.org/docs/encoder-parameters/#2-pass-best-quality-vbr-encoding Encoder parameters help page]&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to generate an animated GIF, FLI, or MNG? ====&lt;br /&gt;
&lt;br /&gt;
A: for animations of 300 frames or less, animated GIF, [http://woodshole.er.usgs.gov/operations/modeling/flc.html  FLI], or MNG formats are smaller files and better quality (i.e., frames stored as PNG not JPEG). Create with [http://www.lcdf.org/gifsicle/ gifsicle], [http://vento.pi.tu-berlin.de/fli.html ppm2fli], or for MNG use [http://www.imagemagick.org/script/convert.php ImageMagick's 'convert']. With more than 300 frames the players usually have memory issues. Animated GIFs are playable in any web browser of course and also in OpenOffice.&lt;br /&gt;
&lt;br /&gt;
 # with convert, many GIFs into one animated GIF:&lt;br /&gt;
 convert -verbose -delay 20 -loop 0 snapshot*.png animation.gif&lt;br /&gt;
&lt;br /&gt;
Notes: '-delay 20' means 20 hundreds of a second delay between each frame. The '-loop 0' flag lets it loop indefinitely. To loop only 3 times use '-loop 3' etc.&lt;br /&gt;
&lt;br /&gt;
Sample script to export PNGs in GRASS (generates tmean_001.png .. tmean_708.png):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
   export i=0&lt;br /&gt;
   for year in `seq 1950 2008` ; do&lt;br /&gt;
       for m in `seq 1 12` ; do&lt;br /&gt;
           i=`expr $i + 1`&lt;br /&gt;
           # awk trick to generate wildcard-correct file names:&lt;br /&gt;
           i=`echo $i | awk '{printf &amp;quot;%03d\n&amp;quot;, $1}'`&lt;br /&gt;
           r.out.png tmean_europe.$year.$m.avg out=tmean_$i.png&lt;br /&gt;
        done&lt;br /&gt;
    done&lt;br /&gt;
    convert -verbose -delay 20 -loop 0 tmean_*.png tmean_animation.gif&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For presentations using a web browser, you can center the image on a blank white page, turn off any toolbars and go into full screen mode (F11 for Firefox or Chrome). Then Alt-Tab your way to the animation at the appropriate time and nobody knows you are using a web browser.&lt;br /&gt;
&lt;br /&gt;
Example HTML for centering image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;HTML&amp;gt;&lt;br /&gt;
&amp;lt;HEAD&amp;gt;&amp;lt;/HEAD&amp;gt;&lt;br /&gt;
&amp;lt;BODY&amp;gt;&lt;br /&gt;
 &amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
 &amp;lt;CENTER&amp;gt;&lt;br /&gt;
  &amp;lt;IMG SRC=&amp;quot;animation.gif&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/CENTER&amp;gt;&lt;br /&gt;
&amp;lt;/BODY&amp;gt;&lt;br /&gt;
&amp;lt;/HTML&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to create dynamic surface movies in NVIZ? ====&lt;br /&gt;
&lt;br /&gt;
A: See slides from the FOSS4G 2006 workshop:&lt;br /&gt;
: http://skagit.meas.ncsu.edu/~helena/grasswork/foss4g/FOSS4G06WKSVisual4anim.odp&lt;br /&gt;
&lt;br /&gt;
See also the example at the bottom of the [http://grass.osgeo.org/grass64/manuals/html64_user/nviz/nviz_panel_kanim.html NVIZ keyframe animator panel help page].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to animate a time series of raster maps? ====&lt;br /&gt;
&lt;br /&gt;
A: Use&lt;br /&gt;
* {{cmd|d.slide.show}} to view in a GRASS xmon (see {{cmd|d.mon}})&lt;br /&gt;
* {{cmd|r.out.mpeg}} to save to a MPEG-1 movie.&lt;br /&gt;
* GRASS GIS 6: {{cmd|xganim|version=64}} to view on screen in X-windows (with live start/stop/speed controls)&lt;br /&gt;
* GRASS GIS 7: {{cmd|g.gui.animation}} to view on screen in wxGUI (with live start/stop/speed controls)&lt;br /&gt;
: See also the wiki page for the [[wxGUI Animation Tool]]:&lt;br /&gt;
{{YouTube|Pi1ESk9iPwk|YouTube video introduction to the WxGUI Animation Tool}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to animate a series of maps, including decorations? ====&lt;br /&gt;
&lt;br /&gt;
A: Use the xmon drivers ({{cmd|d.mon}}) &lt;br /&gt;
to render the displays to a window via a shell script loop, then switch from the ''x0'' to ''PNG'' driver to save as a series of PNG or PPM images. Use a method answered in a FAQ above to combine those into a single animation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to create a screencast (for video tutorials etc)? ====&lt;br /&gt;
&lt;br /&gt;
; GNU/Linux:&lt;br /&gt;
* Easist way: [http://recordmydesktop.sourceforge.net/ recordmydesktop] (user interfaces are 'qt-recordmydesktop' and 'gtk-recordmydesktop')&lt;br /&gt;
:* when uploading videos to Youtube created by &amp;lt;tt&amp;gt;recordmydesktop&amp;lt;/tt&amp;gt; you need to encode the file eg. using &amp;lt;tt&amp;gt;mencoder&amp;lt;/tt&amp;gt;&lt;br /&gt;
:- No sound, just video screencast, as AVI file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;mencoder out.ogv -nosound -ovc lavc -o out.avi&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as AVI file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;mencoder out.ogv -ovc xvid -oac mp3lame -xvidencopts pass=1 -o out.avi&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as WebM file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;ffmpeg -i out.ogv -b:a 24k out.webm&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as MP4 file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;ffmpeg -i out.ogv -ar 44100 -ab 96k -coder ac -strict experimental -vcodec libx264 out.mp4&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [https://wiki.ubuntu.com/MeetingLogs/openweekfeisty/screencast Ubuntu discussion over screencast]&lt;br /&gt;
* [https://wiki.ubuntu.com/ScreencastTeam/RecordingScreencasts Ubuntu screencast how to]&lt;br /&gt;
* [http://www.unixuser.org/~euske/vnc2swf/ vnc2swf] to record a flash movie ([http://www-pool.math.tu-berlin.de/~soeren/grass/modules/screenshots/vnc2swf_usage.html short vnc2swf usage tutorial])&lt;br /&gt;
* [http://www.maartenbaert.be/simplescreenrecorder/ SimpleScreenRecorder]&lt;br /&gt;
&lt;br /&gt;
; MacOSX:&lt;br /&gt;
* [http://crschmidt.net/blog/archives/203/openlayers-screencast/ Chris Schmidt experience on MacOSX]&lt;br /&gt;
&lt;br /&gt;
; MS Windows:&lt;br /&gt;
* [http://camstudio.org/ Camstudio]&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
''Using the [http://grass.osgeo.org/download/data6.php Spearfish] sample dataset''&lt;br /&gt;
&lt;br /&gt;
===== Animate on screen =====&lt;br /&gt;
''Using a shell script''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
GRASS_WIDTH=640 GRASS_HEIGHT=500 \&lt;br /&gt;
  d.mon start=x0&lt;br /&gt;
&lt;br /&gt;
g.region rast=elevation.dem n=4927830 s=4912980&lt;br /&gt;
&lt;br /&gt;
for NUM in `seq 1 0.5 10` ; do&lt;br /&gt;
   d.rast elevation.dem --quiet&lt;br /&gt;
   d.vect roads&lt;br /&gt;
   d.vect bugsites icon=basic/circle col=black fcol=green size=`echo &amp;quot;21-($NUM * 2)&amp;quot; | bc`&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;symbol basic/arrow2 25 80 `echo &amp;quot;10*$NUM&amp;quot; | bc` 80:80:80 125:125:255&amp;quot; | d.graph&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;Spearfish, South Dakota&amp;quot; | d.text size=4.5 at=1,2.25&lt;br /&gt;
   d.barscale at=59.8,93.6 tcol=grey&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Animate to files =====&lt;br /&gt;
''Using [http://grass.osgeo.org/grass64/manuals/html64_user/pngdriver.html GRASS's PNG driver]''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
# set up base map&lt;br /&gt;
g.region rast=elevation.dem n=4927830 s=4912980&lt;br /&gt;
export GRASS_WIDTH=640&lt;br /&gt;
export GRASS_HEIGHT=500&lt;br /&gt;
export GRASS_PNGFILE=base.ppm&lt;br /&gt;
export GRASS_PNG_READ=FALSE&lt;br /&gt;
d.mon start=PNG&lt;br /&gt;
  d.rast elevation.dem&lt;br /&gt;
  d.vect roads&lt;br /&gt;
  echo &amp;quot;Spearfish, South Dakota&amp;quot; | d.text size=4.5 at=1,2.25&lt;br /&gt;
  d.barscale at=59.8,93.6 tcol=grey&lt;br /&gt;
d.mon stop=PNG&lt;br /&gt;
&lt;br /&gt;
# loop to draw variable parts as new frames&lt;br /&gt;
i=0&lt;br /&gt;
export GRASS_PNG_READ=TRUE&lt;br /&gt;
for NUM in `seq 1 0.5 10` ; do&lt;br /&gt;
   i=`expr $i + 1`&lt;br /&gt;
   FRAMENUM=`echo $i | awk '{printf(&amp;quot;%03d&amp;quot;, $1)}'`&lt;br /&gt;
   echo &amp;quot;Processing frame $FRAMENUM ...&amp;quot;&lt;br /&gt;
   export GRASS_PNGFILE=&amp;quot;ganim_${FRAMENUM}.ppm&amp;quot;&lt;br /&gt;
   cp base.ppm &amp;quot;$GRASS_PNGFILE&amp;quot;&lt;br /&gt;
   d.mon start=PNG --quiet&lt;br /&gt;
   d.vect bugsites icon=basic/circle col=black fcol=green \&lt;br /&gt;
      size=`echo &amp;quot;21-($NUM * 2)&amp;quot; | bc`&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;symbol basic/arrow2 25 80 `echo &amp;quot;10*$NUM&amp;quot; | bc` 80:80:80 125:125:255&amp;quot; | d.graph&lt;br /&gt;
   d.mon stop=PNG --quiet&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
# repeat the last frame a few times&lt;br /&gt;
for EXTRA in 1 2 3 ; do&lt;br /&gt;
 i=`expr $i + 1`&lt;br /&gt;
 FRAMENUM=`echo $i | awk '{printf(&amp;quot;%03d&amp;quot;, $1)}'`&lt;br /&gt;
 cp base.ppm &amp;quot;ganim_${FRAMENUM}.ppm&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
\rm base.ppm&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as animated GIF =====&lt;br /&gt;
&lt;br /&gt;
* ''Using the [http://www.lcdf.org/gifsicle/ gifsicle] encoder''&lt;br /&gt;
* ''View in a web browser or with ImageMagick's [http://www.imagemagick.org/Usage/basics/#animate animate]''&lt;br /&gt;
* see [[Movies#Q:_How_to_generate_an_animated_GIF.2C_FLI.2C_or_MNG.3F]] above&lt;br /&gt;
&lt;br /&gt;
'''A) Using gifsicle:'''&lt;br /&gt;
&lt;br /&gt;
Advantage: the delay is coded in the animated GIF file and rendered properly e.g. in a Web browser.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
# Imagemagick's `convert` program may do a better job at &lt;br /&gt;
# 256 color quantization than NetPBM's &amp;lt;tt&amp;gt;ppmquant&amp;lt;/tt&amp;gt;.&lt;br /&gt;
for IMG in ganim*.ppm ; do   # convert each frame from PPM to GIF&lt;br /&gt;
   #ppmquant 256 $IMG | ppmtogif &amp;gt; &amp;quot;`basename $IMG .ppm`.gif&amp;quot;&lt;br /&gt;
   convert &amp;quot;$IMG&amp;quot; &amp;quot;`basename $IMG .ppm`.gif&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
gifsicle -O2 --delay 20 --no-loopcount --colors 256 ganim_*.gif &amp;gt; ganim.gif&lt;br /&gt;
&lt;br /&gt;
\rm ganim_0*.gif&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''B) Using ImageMagick's convert and [http://www.imagemagick.org/Usage/basics/#animate animate]:'''&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
# Generate &amp;quot;film&amp;quot; (create animated GIF, 750 millisec between frames):&lt;br /&gt;
convert -delay 75 lst_monthly_avg_film.00*.png lst_monthly_avg_2002_2012_zoom_film.gif&lt;br /&gt;
&lt;br /&gt;
# play animation (delay 500 millisec between frames, pause for 5 seconds at the end)&lt;br /&gt;
animate -delay 50 -pause 5 lst_monthly_avg_2002_2012_zoom_film.gif&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as animated PNG (MNG) =====&lt;br /&gt;
* ''Using the [http://www.imagemagick.org ImageMagick] &amp;quot;convert&amp;quot; encoder''&lt;br /&gt;
* ''View with ImageMagick's &amp;quot;display&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
convert -delay 20 ganim_*.ppm ganim.mng&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as FLI =====&lt;br /&gt;
* ''Using the [http://vento.pi.tu-berlin.de/fli.html ppm2fli] encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer] or [http://xanim.polter.net xanim]''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
ls ganim_*.ppm &amp;gt; frames.txt&lt;br /&gt;
ppm2fli -g&amp;quot;${GRASS_WIDTH}x${GRASS_HEIGHT}&amp;quot; -O -s 15 frames.txt ganim.fli&lt;br /&gt;
\rm frames.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as Flash =====&lt;br /&gt;
&lt;br /&gt;
* ''Using the [http://www.swftools.org/ SWFTools] &amp;lt;tt&amp;gt;png2swf&amp;lt;/tt&amp;gt; encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer]''&lt;br /&gt;
&lt;br /&gt;
 png2swf -o outfile.swf *.png -r 1&lt;br /&gt;
&lt;br /&gt;
===== Encode as MPEG-4 Xvid =====&lt;br /&gt;
* ''Using the [http://www.mplayerhq.hu mencoder] encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer] or similar''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
# doesn't like GRASS's PPMs, convert to PNG&lt;br /&gt;
for IMG in ganim*.ppm ; do&lt;br /&gt;
  pnmtopng $IMG &amp;gt; &amp;quot;`basename $IMG .ppm`.png&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
mencoder &amp;quot;mf://ganim_*.png&amp;quot; -mf &amp;quot;type=png:fps=5&amp;quot; -o ganim.avi \&lt;br /&gt;
   -ovc &amp;quot;xvid&amp;quot; -xvidencopts &amp;quot;bitrate=1024&amp;quot;&lt;br /&gt;
\rm ganim_0*.png&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Publish your cool videos in this Wiki ====&lt;br /&gt;
We have installed a Mediawiki widget extension and created a special template for including Youtube videos ([[Template:YouTube]]). See also [[WxGUI_Modeler#Video_tutorials|wxGUI Modeler]] page for the usage.&lt;br /&gt;
&lt;br /&gt;
The overall goal is to have many as possible '''[http://www.youtube.com/results?search_query=grass+gis GRASS GIS videos on YouTube]'''&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Visualization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=Movies&amp;diff=28720</id>
		<title>Movies</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=Movies&amp;diff=28720"/>
		<updated>2025-11-04T03:04:42Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Encode as animated GIF */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== Q: How to construct high-quality MPEG-4 movies (animations) from a series of still frames? ====&lt;br /&gt;
&lt;br /&gt;
''Maris wrote'':&lt;br /&gt;
&lt;br /&gt;
Encode all .png files in directory to out.avi with 15 frames per second:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mencoder &amp;quot;mf:///path/to/files/*.png&amp;quot; -mf fps=15 -o out.avi # put -ovc here, see next lines&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## for DivX - libavcodec MPEG 4 (DivX5), use:&lt;br /&gt;
-ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=1800 -ffourcc MP4S&lt;br /&gt;
## for XviD, use:&lt;br /&gt;
-ovc xvid -xvidencopts bitrate=1024 -xvidencopts pass=2 -xvidencopts cartoon&lt;br /&gt;
## for DivX4, use:&lt;br /&gt;
-ovc divx4 -divx4opts q=5&lt;br /&gt;
## for x264 use:&lt;br /&gt;
-ovc x264 -x264encopts pass=3 -x264encopts preset=veryslow -x264encopts tune=animation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Uses mplayer's encoder. Choose one of encoding formats and append to end &lt;br /&gt;
of &amp;quot;mencoder&amp;quot; line. Unfortunately only way to know quality settings is by &lt;br /&gt;
encoding, watching result and re-encoding with different params.&lt;br /&gt;
&lt;br /&gt;
Notice - by default encoding with lavc will set video fourcc to FMP4, that can be decoded with ffdshow. Option -ffourcc MP4S will change it to MPS4 (&amp;quot;official&amp;quot; MS fourcc for mpeg4) and video will be playable on Windows by standard MS mpeg4 decoder. It may lead to side effects, if MS mpeg4 decoder is buggy. More info: http://www.itdp.de/mplayer-users/2005-03/msg00069.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other guides:&lt;br /&gt;
* http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-enc-images.html&lt;br /&gt;
* http://electron.mit.edu/~gsteele/ffmpeg/&lt;br /&gt;
* http://www.stillhq.com/extracted/howto-jpeg2mpeg/output.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to construct high-quality WebM movies? ====&lt;br /&gt;
&lt;br /&gt;
A: {{wikipedia|WebM}} is the container for the {{wikipedia|VP8}} and {{wikipedia|VP9}} codecs. VP8 approaches H.264 in quality but differs from H.264 in that it is both patent + license free to use. Likewise, VP9 is an alternative to HEVC/H.265. The audio channel, if used, is encoded using the Ogg {{wikipedia|Vorbis}} codec for VP8 or Opus codec for VP9. Google has been promoting WebM as the standard fallback video format for HTML5 and is moving YouTube content to it. Firefox. Opera, and Google Chrome web browsers support WebM playback out of the box without need for extra plugins.&lt;br /&gt;
&lt;br /&gt;
; Encoding:&lt;br /&gt;
&lt;br /&gt;
First convert PNG or JPEG images to PPM format using the {{wikipedia|NetPBM}} tools.&lt;br /&gt;
: ''This step is pretty fast, I wouldn't worry about trying to parallelize it.''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for file in *.png ; do&lt;br /&gt;
   pngtopnm $file &amp;gt; `basename $file .png`.ppm&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
::or&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for file in *.jpg ; do&lt;br /&gt;
   jpegtopnm $file &amp;gt; `basename $file .jpg`.ppm&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next create a Y4M stream containing a concatenation of the raw PPM frames:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat *.ppm | ppmtoy4m -F 2:1 &amp;gt; all_frames.y4m&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''The &amp;quot;-F 2:1&amp;quot; option above sets the frame rate to 2 frames per second.''&lt;br /&gt;
* ''The &amp;lt;tt&amp;gt;ppmtoy4m&amp;lt;/tt&amp;gt; program comes from the mjpegtools package.''&lt;br /&gt;
* ''For a very high number of frames you may wish to skip this step and create a named FIFO or stdin pipe directly into &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt;, as the raw Y4M file can become extremely large.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, run the &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; encoder to create a high quality WebM video:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
vpxenc all_frames.y4m -o my_movie.webm \&lt;br /&gt;
  --passes=2 --threads=4 \&lt;br /&gt;
  --best --target-bitrate=2000 --end-usage=vbr \&lt;br /&gt;
  --auto-alt-ref=1 --verbose \&lt;br /&gt;
  --minsection-pct=5 --maxsection-pct=800 \&lt;br /&gt;
  --lag-in-frames=16 --kf-min-dist=0 --kf-max-dist=360 \&lt;br /&gt;
  --static-thresh=0 --drop-frame=0 \&lt;br /&gt;
  --min-q=0 --max-q=60&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''Set &amp;quot;--threads=&amp;quot; in the above command to the number of cores on your CPU. (or one less than the number of cores if you have many)''&lt;br /&gt;
* ''If you are encoding to VP8 (and not VP9) consider adding &amp;lt;tt&amp;gt;--token-parts=2&amp;lt;/tt&amp;gt;''&lt;br /&gt;
* ''If &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; complains about &amp;quot;Invalid image format&amp;quot; either add &amp;quot;-S 420jpeg&amp;quot; to the &amp;lt;tt&amp;gt;ppmtoy4m&amp;lt;/tt&amp;gt; options or add &amp;quot;--profile=1&amp;quot; to the &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; options.&lt;br /&gt;
* ''The &amp;lt;tt&amp;gt;vpxenc&amp;lt;/tt&amp;gt; program comes from the vpx-tools package.''&lt;br /&gt;
* [http://www.webmproject.org/docs/encoder-parameters/#2-pass-best-quality-vbr-encoding Encoder parameters help page]&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to generate an animated GIF, FLI, or MNG? ====&lt;br /&gt;
&lt;br /&gt;
A: for animations of 300 frames or less, animated GIF, [http://woodshole.er.usgs.gov/operations/modeling/flc.html  FLI], or MNG formats are smaller files and better quality (i.e., frames stored as PNG not JPEG). Create with [http://www.lcdf.org/gifsicle/ gifsicle], [http://vento.pi.tu-berlin.de/fli.html ppm2fli], or for MNG use [http://www.imagemagick.org/script/convert.php ImageMagick's 'convert']. With more than 300 frames the players usually have memory issues. Animated GIFs are playable in any web browser of course and also in OpenOffice.&lt;br /&gt;
&lt;br /&gt;
 # with convert, many GIFs into one animated GIF:&lt;br /&gt;
 convert -verbose -delay 20 -loop 0 snapshot*.png animation.gif&lt;br /&gt;
&lt;br /&gt;
Notes: '-delay 20' means 20 hundreds of a second delay between each frame. The '-loop 0' flag lets it loop indefinitely. To loop only 3 times use '-loop 3' etc.&lt;br /&gt;
&lt;br /&gt;
Sample script to export PNGs in GRASS (generates tmean_001.png .. tmean_708.png):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
   export i=0&lt;br /&gt;
   for year in `seq 1950 2008` ; do&lt;br /&gt;
       for m in `seq 1 12` ; do&lt;br /&gt;
           i=`expr $i + 1`&lt;br /&gt;
           # awk trick to generate wildcard-correct file names:&lt;br /&gt;
           i=`echo $i | awk '{printf &amp;quot;%03d\n&amp;quot;, $1}'`&lt;br /&gt;
           r.out.png tmean_europe.$year.$m.avg out=tmean_$i.png&lt;br /&gt;
        done&lt;br /&gt;
    done&lt;br /&gt;
    convert -verbose -delay 20 -loop 0 tmean_*.png tmean_animation.gif&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For presentations using a web browser, you can center the image on a blank white page, turn off any toolbars and go into full screen mode (F11 for Firefox or Chrome). Then Alt-Tab your way to the animation at the appropriate time and nobody knows you are using a web browser.&lt;br /&gt;
&lt;br /&gt;
Example HTML for centering image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;HTML&amp;gt;&lt;br /&gt;
&amp;lt;HEAD&amp;gt;&amp;lt;/HEAD&amp;gt;&lt;br /&gt;
&amp;lt;BODY&amp;gt;&lt;br /&gt;
 &amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
 &amp;lt;CENTER&amp;gt;&lt;br /&gt;
  &amp;lt;IMG SRC=&amp;quot;animation.gif&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/CENTER&amp;gt;&lt;br /&gt;
&amp;lt;/BODY&amp;gt;&lt;br /&gt;
&amp;lt;/HTML&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to create dynamic surface movies in NVIZ? ====&lt;br /&gt;
&lt;br /&gt;
A: See slides from the FOSS4G 2006 workshop:&lt;br /&gt;
: http://skagit.meas.ncsu.edu/~helena/grasswork/foss4g/FOSS4G06WKSVisual4anim.odp&lt;br /&gt;
&lt;br /&gt;
See also the example at the bottom of the [http://grass.osgeo.org/grass64/manuals/html64_user/nviz/nviz_panel_kanim.html NVIZ keyframe animator panel help page].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to animate a time series of raster maps? ====&lt;br /&gt;
&lt;br /&gt;
A: Use&lt;br /&gt;
* {{cmd|d.slide.show}} to view in a GRASS xmon (see {{cmd|d.mon}})&lt;br /&gt;
* {{cmd|r.out.mpeg}} to save to a MPEG-1 movie.&lt;br /&gt;
* GRASS GIS 6: {{cmd|xganim|version=64}} to view on screen in X-windows (with live start/stop/speed controls)&lt;br /&gt;
* GRASS GIS 7: {{cmd|g.gui.animation}} to view on screen in wxGUI (with live start/stop/speed controls)&lt;br /&gt;
: See also the wiki page for the [[wxGUI Animation Tool]]:&lt;br /&gt;
{{YouTube|Pi1ESk9iPwk|YouTube video introduction to the WxGUI Animation Tool}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to animate a series of maps, including decorations? ====&lt;br /&gt;
&lt;br /&gt;
A: Use the xmon drivers ({{cmd|d.mon}}) &lt;br /&gt;
to render the displays to a window via a shell script loop, then switch from the ''x0'' to ''PNG'' driver to save as a series of PNG or PPM images. Use a method answered in a FAQ above to combine those into a single animation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--------&lt;br /&gt;
&lt;br /&gt;
==== Q: How to create a screencast (for video tutorials etc)? ====&lt;br /&gt;
&lt;br /&gt;
; GNU/Linux:&lt;br /&gt;
* Easist way: [http://recordmydesktop.sourceforge.net/ recordmydesktop] (user interfaces are 'qt-recordmydesktop' and 'gtk-recordmydesktop')&lt;br /&gt;
:* when uploading videos to Youtube created by &amp;lt;tt&amp;gt;recordmydesktop&amp;lt;/tt&amp;gt; you need to encode the file eg. using &amp;lt;tt&amp;gt;mencoder&amp;lt;/tt&amp;gt;&lt;br /&gt;
:- No sound, just video screencast, as AVI file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;mencoder out.ogv -nosound -ovc lavc -o out.avi&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as AVI file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;mencoder out.ogv -ovc xvid -oac mp3lame -xvidencopts pass=1 -o out.avi&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as WebM file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;ffmpeg -i out.ogv -b:a 24k out.webm&amp;lt;/pre&amp;gt;&lt;br /&gt;
:- With audio track, as MP4 file:&lt;br /&gt;
::&amp;lt;pre&amp;gt;ffmpeg -i out.ogv -ar 44100 -ab 96k -coder ac -strict experimental -vcodec libx264 out.mp4&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [https://wiki.ubuntu.com/MeetingLogs/openweekfeisty/screencast Ubuntu discussion over screencast]&lt;br /&gt;
* [https://wiki.ubuntu.com/ScreencastTeam/RecordingScreencasts Ubuntu screencast how to]&lt;br /&gt;
* [http://www.unixuser.org/~euske/vnc2swf/ vnc2swf] to record a flash movie ([http://www-pool.math.tu-berlin.de/~soeren/grass/modules/screenshots/vnc2swf_usage.html short vnc2swf usage tutorial])&lt;br /&gt;
* [http://www.maartenbaert.be/simplescreenrecorder/ SimpleScreenRecorder]&lt;br /&gt;
&lt;br /&gt;
; MacOSX:&lt;br /&gt;
* [http://crschmidt.net/blog/archives/203/openlayers-screencast/ Chris Schmidt experience on MacOSX]&lt;br /&gt;
&lt;br /&gt;
; MS Windows:&lt;br /&gt;
* [http://camstudio.org/ Camstudio]&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
''Using the [http://grass.osgeo.org/download/data6.php Spearfish] sample dataset''&lt;br /&gt;
&lt;br /&gt;
===== Animate on screen =====&lt;br /&gt;
''Using a shell script''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
GRASS_WIDTH=640 GRASS_HEIGHT=500 \&lt;br /&gt;
  d.mon start=x0&lt;br /&gt;
&lt;br /&gt;
g.region rast=elevation.dem n=4927830 s=4912980&lt;br /&gt;
&lt;br /&gt;
for NUM in `seq 1 0.5 10` ; do&lt;br /&gt;
   d.rast elevation.dem --quiet&lt;br /&gt;
   d.vect roads&lt;br /&gt;
   d.vect bugsites icon=basic/circle col=black fcol=green size=`echo &amp;quot;21-($NUM * 2)&amp;quot; | bc`&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;symbol basic/arrow2 25 80 `echo &amp;quot;10*$NUM&amp;quot; | bc` 80:80:80 125:125:255&amp;quot; | d.graph&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;Spearfish, South Dakota&amp;quot; | d.text size=4.5 at=1,2.25&lt;br /&gt;
   d.barscale at=59.8,93.6 tcol=grey&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Animate to files =====&lt;br /&gt;
''Using [http://grass.osgeo.org/grass64/manuals/html64_user/pngdriver.html GRASS's PNG driver]''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
# set up base map&lt;br /&gt;
g.region rast=elevation.dem n=4927830 s=4912980&lt;br /&gt;
export GRASS_WIDTH=640&lt;br /&gt;
export GRASS_HEIGHT=500&lt;br /&gt;
export GRASS_PNGFILE=base.ppm&lt;br /&gt;
export GRASS_PNG_READ=FALSE&lt;br /&gt;
d.mon start=PNG&lt;br /&gt;
  d.rast elevation.dem&lt;br /&gt;
  d.vect roads&lt;br /&gt;
  echo &amp;quot;Spearfish, South Dakota&amp;quot; | d.text size=4.5 at=1,2.25&lt;br /&gt;
  d.barscale at=59.8,93.6 tcol=grey&lt;br /&gt;
d.mon stop=PNG&lt;br /&gt;
&lt;br /&gt;
# loop to draw variable parts as new frames&lt;br /&gt;
i=0&lt;br /&gt;
export GRASS_PNG_READ=TRUE&lt;br /&gt;
for NUM in `seq 1 0.5 10` ; do&lt;br /&gt;
   i=`expr $i + 1`&lt;br /&gt;
   FRAMENUM=`echo $i | awk '{printf(&amp;quot;%03d&amp;quot;, $1)}'`&lt;br /&gt;
   echo &amp;quot;Processing frame $FRAMENUM ...&amp;quot;&lt;br /&gt;
   export GRASS_PNGFILE=&amp;quot;ganim_${FRAMENUM}.ppm&amp;quot;&lt;br /&gt;
   cp base.ppm &amp;quot;$GRASS_PNGFILE&amp;quot;&lt;br /&gt;
   d.mon start=PNG --quiet&lt;br /&gt;
   d.vect bugsites icon=basic/circle col=black fcol=green \&lt;br /&gt;
      size=`echo &amp;quot;21-($NUM * 2)&amp;quot; | bc`&lt;br /&gt;
&lt;br /&gt;
   echo &amp;quot;symbol basic/arrow2 25 80 `echo &amp;quot;10*$NUM&amp;quot; | bc` 80:80:80 125:125:255&amp;quot; | d.graph&lt;br /&gt;
   d.mon stop=PNG --quiet&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
# repeat the last frame a few times&lt;br /&gt;
for EXTRA in 1 2 3 ; do&lt;br /&gt;
 i=`expr $i + 1`&lt;br /&gt;
 FRAMENUM=`echo $i | awk '{printf(&amp;quot;%03d&amp;quot;, $1)}'`&lt;br /&gt;
 cp base.ppm &amp;quot;ganim_${FRAMENUM}.ppm&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
\rm base.ppm&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as animated GIF =====&lt;br /&gt;
&lt;br /&gt;
* ''Using the [http://www.lcdf.org/gifsicle/ gifsicle] encoder''&lt;br /&gt;
* ''View in a web browser or with ImageMagick's [http://www.imagemagick.org/Usage/basics/#animate animate]''&lt;br /&gt;
* see [[Movies#Q:_How_to_generate_an_animated_GIF.2C_FLI.2C_or_MNG.3F]] above&lt;br /&gt;
&lt;br /&gt;
'''A) Using gifsicle:'''&lt;br /&gt;
&lt;br /&gt;
Advantage: the delay is coded in the animated GIF file and rendered properly e.g. in a Web browser.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
# Imagemagick's `convert` program may do a better job at &lt;br /&gt;
# 256 color quantization than NetPBM's &amp;lt;tt&amp;gt;ppmquant&amp;lt;/tt&amp;gt;.&lt;br /&gt;
for IMG in ganim*.ppm ; do   # convert each frame from PPM to GIF&lt;br /&gt;
   #ppmquant 256 $IMG | ppmtogif &amp;gt; &amp;quot;`basename $IMG .ppm`.gif&amp;quot;&lt;br /&gt;
   convert &amp;quot;$IMG&amp;quot; &amp;quot;`basename $IMG .ppm`.gif&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
gifsicle -O2 --delay 20 --no-loopcount --colors 256 ganim_*.gif &amp;gt; ganim.gif&lt;br /&gt;
&lt;br /&gt;
\rm ganim_0*.gif&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''B) Using ImageMagick's convert and [http://www.imagemagick.org/Usage/basics/#animate animate]:'''&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
# Generate &amp;quot;film&amp;quot; (create animated GIF):&lt;br /&gt;
convert lst_monthly_avg_film.00*.png lst_monthly_avg_2002_2012_zoom_film.gif&lt;br /&gt;
&lt;br /&gt;
# play animation (delay 50millisec between frames, pause for 5 seconds at the end)&lt;br /&gt;
animate -delay 50 -pause 5 lst_monthly_avg_2002_2012_zoom_film.gif&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as animated PNG (MNG) =====&lt;br /&gt;
* ''Using the [http://www.imagemagick.org ImageMagick] &amp;quot;convert&amp;quot; encoder''&lt;br /&gt;
* ''View with ImageMagick's &amp;quot;display&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
convert -delay 20 ganim_*.ppm ganim.mng&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as FLI =====&lt;br /&gt;
* ''Using the [http://vento.pi.tu-berlin.de/fli.html ppm2fli] encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer] or [http://xanim.polter.net xanim]''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
ls ganim_*.ppm &amp;gt; frames.txt&lt;br /&gt;
ppm2fli -g&amp;quot;${GRASS_WIDTH}x${GRASS_HEIGHT}&amp;quot; -O -s 15 frames.txt ganim.fli&lt;br /&gt;
\rm frames.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Encode as Flash =====&lt;br /&gt;
&lt;br /&gt;
* ''Using the [http://www.swftools.org/ SWFTools] &amp;lt;tt&amp;gt;png2swf&amp;lt;/tt&amp;gt; encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer]''&lt;br /&gt;
&lt;br /&gt;
 png2swf -o outfile.swf *.png -r 1&lt;br /&gt;
&lt;br /&gt;
===== Encode as MPEG-4 Xvid =====&lt;br /&gt;
* ''Using the [http://www.mplayerhq.hu mencoder] encoder''&lt;br /&gt;
* ''View with [http://www.mplayerhq.hu mplayer] or similar''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
# doesn't like GRASS's PPMs, convert to PNG&lt;br /&gt;
for IMG in ganim*.ppm ; do&lt;br /&gt;
  pnmtopng $IMG &amp;gt; &amp;quot;`basename $IMG .ppm`.png&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
mencoder &amp;quot;mf://ganim_*.png&amp;quot; -mf &amp;quot;type=png:fps=5&amp;quot; -o ganim.avi \&lt;br /&gt;
   -ovc &amp;quot;xvid&amp;quot; -xvidencopts &amp;quot;bitrate=1024&amp;quot;&lt;br /&gt;
\rm ganim_0*.png&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Publish your cool videos in this Wiki ====&lt;br /&gt;
We have installed a Mediawiki widget extension and created a special template for including Youtube videos ([[Template:YouTube]]). See also [[WxGUI_Modeler#Video_tutorials|wxGUI Modeler]] page for the usage.&lt;br /&gt;
&lt;br /&gt;
The overall goal is to have many as possible '''[http://www.youtube.com/results?search_query=grass+gis GRASS GIS videos on YouTube]'''&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Visualization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28719</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28719"/>
		<updated>2025-10-29T05:12:52Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Linke turbidity factor values */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. Note that this may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate ''and'' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Linke turbidity factor values ==&lt;br /&gt;
&lt;br /&gt;
* See Remund et al. (2003) appendix/table 1 for a list of monthly values for many sites around the world:&lt;br /&gt;
: https://www.researchgate.net/publication/42358500_Worldwide_Linke_turbidity_information&lt;br /&gt;
&lt;br /&gt;
* A good description and recipe for calculating it here:  (section 3.3.4, page 22)&lt;br /&gt;
: https://atmosphere.copernicus.eu/sites/default/files/2022-01/CAMS2_73_2021SC1_D3.2.1_2021_UserGuide_v1.pdf&lt;br /&gt;
&lt;br /&gt;
* Download 5' global dataset for all months of 2010 as LL/WGS84 GeoTIFF here:&lt;br /&gt;
: https://www.soda-pro.com/help/general-knowledge/linke-turbidity-factor&lt;br /&gt;
:: '''''&amp;quot;The Linke turbidity factor (TL, for an air mass equal to 2) is a very convenient approximation to model the atmospheric absorption and scattering of the solar radiation under clear skies. It describes the optical thickness of the atmosphere due to both the absorption by the water vapor and the absorption and scattering by the aerosol particles relative to a dry and clean atmosphere. It summarizes the turbidity of the atmosphere, and hence the attenuation of the direct beam solar radiation. The larger TL, the larger the attenuation of the radiation by the clear sky atmosphere.'''''&lt;br /&gt;
&lt;br /&gt;
:: '''''The TL denotes the transparency of the cloudless atmosphere. If the sky were perfectly dry and clean, TL would be equal to 1. When the sky is deep blue, the TL is just above 1 and still very small. In summer, in Europe, the water vapour is often large and the blue sky is close to white -- the TL is larger than 3. In turbid atmosphere, e.g. in polluted cities, the TL is close to 6 - 7.&amp;quot;'''''&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Minimum number of days needed to summarize a solar year ==&lt;br /&gt;
&lt;br /&gt;
You can get an estimated curve of daily irradiation throughout the year by running r.sun for e.g. just the middle day of each month, or just for the solstices, equinoxes, and half way between them.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Day of year for minimal annual summary&lt;br /&gt;
|-&lt;br /&gt;
! Day !! DOY !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| Feb 5th || 036 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Mar 21st || 080 || equinox&lt;br /&gt;
|-&lt;br /&gt;
| May 6th || 126 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Jun 21st || 172 ||  solstice&lt;br /&gt;
|-&lt;br /&gt;
| Aug 6th || 218 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Sept 21st || 264 ||  equinox&lt;br /&gt;
|-&lt;br /&gt;
| Nov 6th || 310 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Dec 21st || 355 ||  solstice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You may want to duplicate the results from Dec. 21st as day -10 when you fit the curve in your plot.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28718</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28718"/>
		<updated>2025-10-29T05:11:09Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Linke turbidity factor values */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. Note that this may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate ''and'' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Linke turbidity factor values ==&lt;br /&gt;
&lt;br /&gt;
* See Remund et al. (2003) appendix/table 1 for a list of monthly values for many sites around the world:&lt;br /&gt;
: https://www.researchgate.net/publication/42358500_Worldwide_Linke_turbidity_information&lt;br /&gt;
&lt;br /&gt;
* A good description and recipe for calculating it here:  (section 3.3.4, page 22)&lt;br /&gt;
: https://atmosphere.copernicus.eu/sites/default/files/2022-01/CAMS2_73_2021SC1_D3.2.1_2021_UserGuide_v1.pdf&lt;br /&gt;
&lt;br /&gt;
* Download 5' global dataset for all months of 2010 as LL/WGS84 GeoTIFF here:&lt;br /&gt;
: https://www.soda-pro.com/help/general-knowledge/linke-turbidity-factor&lt;br /&gt;
:: '''''&amp;quot;The Linke turbidity factor (TL, for an air mass equal to 2) is a very convenient approximation to model the atmospheric absorption and scattering of the solar radiation under clear skies. It describes the optical thickness of the atmosphere due to both the absorption by the water vapor and the absorption and scattering by the aerosol particles relative to a dry and clean atmosphere. It summarizes the turbidity of the atmosphere, and hence the attenuation of the direct beam solar radiation. The larger TL, the larger the attenuation of the radiation by the clear sky atmosphere.'''''&lt;br /&gt;
&lt;br /&gt;
:: '''''The TL denotes the transparency of the cloudless atmosphere. If the sky were perfectly dry and clean, TL would be equal to 1. When the sky is deep blue, the TL is just above 1 and still very small. In summer, in Europe, the water vapour is often large and the blue sky is close to white. The TL is larger than 3. In turbid atmosphere, e.g. in polluted cities, the TL is close to 6 - 7.&amp;quot;'''''&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Minimum number of days needed to summarize a solar year ==&lt;br /&gt;
&lt;br /&gt;
You can get an estimated curve of daily irradiation throughout the year by running r.sun for e.g. just the middle day of each month, or just for the solstices, equinoxes, and half way between them.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Day of year for minimal annual summary&lt;br /&gt;
|-&lt;br /&gt;
! Day !! DOY !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| Feb 5th || 036 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Mar 21st || 080 || equinox&lt;br /&gt;
|-&lt;br /&gt;
| May 6th || 126 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Jun 21st || 172 ||  solstice&lt;br /&gt;
|-&lt;br /&gt;
| Aug 6th || 218 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Sept 21st || 264 ||  equinox&lt;br /&gt;
|-&lt;br /&gt;
| Nov 6th || 310 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Dec 21st || 355 ||  solstice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You may want to duplicate the results from Dec. 21st as day -10 when you fit the curve in your plot.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28717</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28717"/>
		<updated>2025-10-29T05:10:12Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Linke turbidity factor values */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. Note that this may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate ''and'' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Linke turbidity factor values ==&lt;br /&gt;
&lt;br /&gt;
* See Remund et al. (2003) appendix/table 1 for a list of monthly values for many sites around the world:&lt;br /&gt;
: https://www.researchgate.net/publication/42358500_Worldwide_Linke_turbidity_information&lt;br /&gt;
&lt;br /&gt;
* A good description and recipe for calculating it here:  (section 3.3.4, page 22)&lt;br /&gt;
: https://atmosphere.copernicus.eu/sites/default/files/2022-01/CAMS2_73_2021SC1_D3.2.1_2021_UserGuide_v1.pdf&lt;br /&gt;
&lt;br /&gt;
* Download 5' global dataset for all months of 2010 as LL/WGS84 GeoTIFF here:&lt;br /&gt;
: https://www.soda-pro.com/help/general-knowledge/linke-turbidity-factor&lt;br /&gt;
:: '''''&amp;quot;The Linke turbidity factor (TL, for an air mass equal to 2) is a very convenient approximation to model the atmospheric absorption and scattering of the solar radiation under clear skies. It describes the optical thickness of the atmosphere due to both the absorption by the water vapor and the absorption and scattering by the aerosol particles relative to a dry and clean atmosphere. It summarizes the turbidity of the atmosphere, and hence the attenuation of the direct beam solar radiation. The larger TL, the larger the attenuation of the radiation by the clear sky atmosphere.&lt;br /&gt;
&lt;br /&gt;
The TL denotes the transparency of the cloudless atmosphere. If the sky were perfectly dry and clean, TL would be equal to 1. When the sky is deep blue, the TL is just above 1 and still very small. In summer, in Europe, the water vapour is often large and the blue sky is close to white. The TL is larger than 3. In turbid atmosphere, e.g. in polluted cities, the TL is close to 6 - 7.&amp;quot;'''''&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Minimum number of days needed to summarize a solar year ==&lt;br /&gt;
&lt;br /&gt;
You can get an estimated curve of daily irradiation throughout the year by running r.sun for e.g. just the middle day of each month, or just for the solstices, equinoxes, and half way between them.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Day of year for minimal annual summary&lt;br /&gt;
|-&lt;br /&gt;
! Day !! DOY !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| Feb 5th || 036 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Mar 21st || 080 || equinox&lt;br /&gt;
|-&lt;br /&gt;
| May 6th || 126 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Jun 21st || 172 ||  solstice&lt;br /&gt;
|-&lt;br /&gt;
| Aug 6th || 218 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Sept 21st || 264 ||  equinox&lt;br /&gt;
|-&lt;br /&gt;
| Nov 6th || 310 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Dec 21st || 355 ||  solstice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You may want to duplicate the results from Dec. 21st as day -10 when you fit the curve in your plot.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28716</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28716"/>
		<updated>2025-10-29T03:53:26Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Automation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. Note that this may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate ''and'' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Linke turbidity factor values ==&lt;br /&gt;
&lt;br /&gt;
* See Remund et al. (2003) appendix/table 1 for a list of monthly values for many sites around the world:&lt;br /&gt;
: https://www.researchgate.net/publication/42358500_Worldwide_Linke_turbidity_information&lt;br /&gt;
&lt;br /&gt;
* A good description and recipe for calculating it here:  (section 3.3.4, page 22)&lt;br /&gt;
: https://atmosphere.copernicus.eu/sites/default/files/2022-01/CAMS2_73_2021SC1_D3.2.1_2021_UserGuide_v1.pdf&lt;br /&gt;
&lt;br /&gt;
* Download 5' global dataset for all months of 2010 as LL/WGS84 GeoTIFF here:&lt;br /&gt;
: https://www.soda-pro.com/help/general-knowledge/linke-turbidity-factor&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Minimum number of days needed to summarize a solar year ==&lt;br /&gt;
&lt;br /&gt;
You can get an estimated curve of daily irradiation throughout the year by running r.sun for e.g. just the middle day of each month, or just for the solstices, equinoxes, and half way between them.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Day of year for minimal annual summary&lt;br /&gt;
|-&lt;br /&gt;
! Day !! DOY !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| Feb 5th || 036 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Mar 21st || 080 || equinox&lt;br /&gt;
|-&lt;br /&gt;
| May 6th || 126 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Jun 21st || 172 ||  solstice&lt;br /&gt;
|-&lt;br /&gt;
| Aug 6th || 218 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Sept 21st || 264 ||  equinox&lt;br /&gt;
|-&lt;br /&gt;
| Nov 6th || 310 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Dec 21st || 355 ||  solstice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You may want to duplicate the results from Dec. 21st as day -10 when you fit the curve in your plot.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28711</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28711"/>
		<updated>2025-09-29T05:08:48Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Minimum number of days needed to summarize a solar year */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. Note that this may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate ''and'' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Minimum number of days needed to summarize a solar year ==&lt;br /&gt;
&lt;br /&gt;
You can get an estimated curve of daily irradiation throughout the year by running r.sun for e.g. just the middle day of each month, or just for the solstices, equinoxes, and half way between them.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Day of year for minimal annual summary&lt;br /&gt;
|-&lt;br /&gt;
! Day !! DOY !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| Feb 5th || 036 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Mar 21st || 080 || equinox&lt;br /&gt;
|-&lt;br /&gt;
| May 6th || 126 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Jun 21st || 172 ||  solstice&lt;br /&gt;
|-&lt;br /&gt;
| Aug 6th || 218 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Sept 21st || 264 ||  equinox&lt;br /&gt;
|-&lt;br /&gt;
| Nov 6th || 310 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Dec 21st || 355 ||  solstice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You may want to duplicate the results from Dec. 21st as day -10 when you fit the curve in your plot.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28710</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28710"/>
		<updated>2025-09-29T05:06:37Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Tips */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. Note that this may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate ''and'' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Minimum number of days needed to summarize a solar year ==&lt;br /&gt;
&lt;br /&gt;
You can get a rough curve of daily irradiation throughout the year by running r.sun for e.g. just the middle day of each month, or just for the solstices, equinoxes, and half way between them.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Day of year for minimal annual summary&lt;br /&gt;
|-&lt;br /&gt;
! Day !! DOY !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| Feb 5th || 036 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Mar 21st || 080 || equinox&lt;br /&gt;
|-&lt;br /&gt;
| May 6th || 126 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Jun 21st || 172 ||  solstice&lt;br /&gt;
|-&lt;br /&gt;
| Aug 6th || 218 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Sept 21st || 264 ||  equinox&lt;br /&gt;
|-&lt;br /&gt;
| Nov 6th || 310 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Dec 21st || 355 ||  solstice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You may want to duplicate the results from Dec. 21st as day -10 when you fit the curve in your plot.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28709</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28709"/>
		<updated>2025-09-29T05:02:20Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Minimum number of days needed to summarize a solar year */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. This may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate ''and'' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Minimum number of days needed to summarize a solar year ==&lt;br /&gt;
&lt;br /&gt;
You can get a rough curve of daily irradiation throughout the year by running r.sun for e.g. just the middle day of each month, or just for the solstices, equinoxes, and half way between them.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Day of year for minimal annual summary&lt;br /&gt;
|-&lt;br /&gt;
! Day !! DOY !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| Feb 5th || 036 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Mar 21st || 080 || equinox&lt;br /&gt;
|-&lt;br /&gt;
| May 6th || 126 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Jun 21st || 172 ||  solstice&lt;br /&gt;
|-&lt;br /&gt;
| Aug 6th || 218 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Sept 21st || 264 ||  equinox&lt;br /&gt;
|-&lt;br /&gt;
| Nov 6th || 310 || ''mid''&lt;br /&gt;
|-&lt;br /&gt;
| Dec 21st || 355 ||  solstice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You may want to duplicate the results from Dec. 21st as day -10 when you fit the curve in your plot.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28708</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28708"/>
		<updated>2025-09-29T05:01:58Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Optional input maps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. This may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate ''and'' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Minimum number of days needed to summarize a solar year ==&lt;br /&gt;
&lt;br /&gt;
You can get a rough curve of daily irradiation throughout the year by running r.sun for e.g. just the middle day of each month, or just for the solstices, equinoxes, and half way between them.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Day of year for minimal annual summary&lt;br /&gt;
|-&lt;br /&gt;
! Day !! DOY !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| Feb 5th || 036 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Mar 21st || 080 || equinox&lt;br /&gt;
|-&lt;br /&gt;
| May 6th || 126 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Jun 21st || 172 ||  solstice&lt;br /&gt;
|-&lt;br /&gt;
| Aug 6th || 218 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Sept 21st || 264 ||  equinox&lt;br /&gt;
|-&lt;br /&gt;
| Nov 6th || 310 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Dec 21st || 355 ||  solstice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You may want to duplicate the results from Dec. 21st as day -10 when you fit the curve in your plot.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28707</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28707"/>
		<updated>2025-09-29T04:58:34Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Minimum number of days needed to summarize a solar year */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. This may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate 'and' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Minimum number of days needed to summarize a solar year ==&lt;br /&gt;
&lt;br /&gt;
You can get a rough curve of daily irradiation throughout the year by running r.sun for e.g. just the middle day of each month, or just for the solstices, equinoxes, and half way between them.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Day of year for minimal annual summary&lt;br /&gt;
|-&lt;br /&gt;
! Day !! DOY !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| Feb 5th || 036 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Mar 21st || 080 || equinox&lt;br /&gt;
|-&lt;br /&gt;
| May 6th || 126 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Jun 21st || 172 ||  solstice&lt;br /&gt;
|-&lt;br /&gt;
| Aug 6th || 218 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Sept 21st || 264 ||  equinox&lt;br /&gt;
|-&lt;br /&gt;
| Nov 6th || 310 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Dec 21st || 355 ||  solstice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You may want to duplicate the results from Dec. 21st as day -10 when you fit the curve in your plot.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28706</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28706"/>
		<updated>2025-09-29T04:57:58Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Overview of monthly maps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. This may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate 'and' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Minimum number of days needed to summarize a solar year ==&lt;br /&gt;
&lt;br /&gt;
You can get a rough curve of daily irradiation throughout the year by running r.sun for e.g. just the middle day of each month, or just for the solstices, equinoxes, and half way between them. For example:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Day of year for minimal annual summary&lt;br /&gt;
|-&lt;br /&gt;
! Day !! DOY !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| Feb 5th || 036 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Mar 21st || 080 || equinox&lt;br /&gt;
|-&lt;br /&gt;
| May 6th || 126 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Jun 21st || 172 ||  solstice&lt;br /&gt;
|-&lt;br /&gt;
| Aug 6th || 218 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Sept 21st || 264 ||  equinox&lt;br /&gt;
|-&lt;br /&gt;
| Nov 6th || 310 || mid&lt;br /&gt;
|-&lt;br /&gt;
| Dec 21st || 355 ||  solstice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
You may want to duplicate the results from Dec. 21st as day -10 when you fit the curve in your plot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28705</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28705"/>
		<updated>2025-09-29T04:43:48Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Seed maps */ clear up some misinformation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. This may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Optional input maps ==&lt;br /&gt;
&lt;br /&gt;
Using both input aspect and slope maps (generated from the input DEM) are necessary if you wish to include the effect of reflected light in the global output map.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: potentially buggy''. See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
Using horizon seed maps can (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results may not be as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.  Depends on the number of horizon maps. Note for accuracy you might want a large number of pre-calculated horizon maps, but that comes with the downside of it taking a long time and lots of memory to load them off the disk. Calculating horizons in real-time in the CPU may in fact be both more accurate 'and' faster. More tests are needed to clarify this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell. This is only needed if you are running r.sun in a simple XY location. If you are running in a normal session with a known map projection the lat/lon are calculated on the fly.&lt;br /&gt;
&lt;br /&gt;
: The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28704</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28704"/>
		<updated>2025-09-29T04:35:24Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Tips */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Counterpoint: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; maps are needed if you wish to include the effect of reflected light (seen in both the &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; and global radiation output maps). These two maps can be generated from your DEM or DSM with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt; maps are generally only needed if you are running r.sun from a simple XY location. In normal use with a known map projection they are not needed.&lt;br /&gt;
&lt;br /&gt;
If you are in a coastal area you can speed up processing by setting regions of water to NULL in the DEM input raster map. See the {{cmd|r.null}} module. This may reduce the amount of reflected light in the global and &amp;lt;tt&amp;gt;refl_rad&amp;lt;/tt&amp;gt; output maps. I suspect that r.sun does not model glint off water at low sun angles, although you may have luck setting water masses to a high albedo with the &amp;lt;tt&amp;gt;albedo&amp;lt;/tt&amp;gt; input raster if that is important to you.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Seed maps ==&lt;br /&gt;
&lt;br /&gt;
Using seed maps can greatly (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: currently buggy''. See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results not as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell.&lt;br /&gt;
The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28698</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28698"/>
		<updated>2025-09-11T06:39:36Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Overview of monthly maps */ fix dead link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Dissenting view: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.  The same may be true (or not) for the &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; pre-calculatated maps.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Testing ===&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Seed maps ==&lt;br /&gt;
&lt;br /&gt;
Using seed maps can greatly (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: currently buggy''. See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results not as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell.&lt;br /&gt;
The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [[Time_series#Common_legends_for_many_raster_maps|Common legends for many raster maps]]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28697</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28697"/>
		<updated>2025-09-11T04:20:28Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Tips */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Dissenting view: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.  The same may be true (or not) for the &amp;lt;tt&amp;gt;latin&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;longin&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;aspin&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;slopein&amp;lt;/tt&amp;gt; pre-calculatated maps.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Testing ===&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Seed maps ==&lt;br /&gt;
&lt;br /&gt;
Using seed maps can greatly (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: currently buggy''. See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results not as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell.&lt;br /&gt;
The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [http://grass.osgeo.org/wiki/Time_series#Common_legends_for_many_raster_maps Common legends for many raster maps]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28696</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28696"/>
		<updated>2025-09-11T04:17:01Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Time step */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Dissenting view: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Testing ===&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 '''step=0.5'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 '''step=0.25'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 '''step=0.05'''&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Seed maps ==&lt;br /&gt;
&lt;br /&gt;
Using seed maps can greatly (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: currently buggy''. See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results not as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell.&lt;br /&gt;
The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [http://grass.osgeo.org/wiki/Time_series#Common_legends_for_many_raster_maps Common legends for many raster maps]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28695</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28695"/>
		<updated>2025-09-11T04:16:29Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Time step */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Dissenting view: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Testing ===&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
: '''''step''' is measured in decimal hours''&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 step=0.5&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 step=0.25&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 step=0.05&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Seed maps ==&lt;br /&gt;
&lt;br /&gt;
Using seed maps can greatly (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: currently buggy''. See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results not as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell.&lt;br /&gt;
The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [http://grass.osgeo.org/wiki/Time_series#Common_legends_for_many_raster_maps Common legends for many raster maps]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28694</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28694"/>
		<updated>2025-09-11T04:14:05Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Tips */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of {{cmd|r.sun}} may be improved if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
: ''Dissenting view: modern CPUs are fast enough that the time it takes to read the horizon map off the hard drive may be more than just calculating the horizon on-the-fly, with the added advantage that the on-the-fly horizon is always at exactly the right azimuth. You will need to test to see if r.horizon is better or worse for your own use case.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Testing ===&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 step=0.5&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 step=0.25&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 step=0.05&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
== Seed maps ==&lt;br /&gt;
&lt;br /&gt;
Using seed maps can greatly (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: currently buggy''. See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results not as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell.&lt;br /&gt;
The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [http://grass.osgeo.org/wiki/Time_series#Common_legends_for_many_raster_maps Common legends for many raster maps]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
	<entry>
		<id>https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28693</id>
		<title>R.sun</title>
		<link rel="alternate" type="text/html" href="https://grasswiki.osgeo.org/w/index.php?title=R.sun&amp;diff=28693"/>
		<updated>2025-09-11T02:36:12Z</updated>

		<summary type="html">&lt;p&gt;Hamish: /* Automation */ fix broken link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Help page ==&lt;br /&gt;
&lt;br /&gt;
* {{cmd|r.sun}} manual page&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
&lt;br /&gt;
The speed of r.sun is much higher if {{cmd|r.horizon}} is used first and the resulting maps are given as input to r.sun. Background: the horizon needs to be computed only one time before, not in every step within r.sun. See the example at the end of the {{cmd|r.sun}} help page.&lt;br /&gt;
&lt;br /&gt;
=== Testing ===&lt;br /&gt;
&lt;br /&gt;
Create an artificial surface containing a Gaussian mound:&lt;br /&gt;
 {{AddonCmd|r.surf.volcano}} out=gauss method=gaussian kurtosis=1&lt;br /&gt;
&lt;br /&gt;
Overlay some 200m contours to show underlying topography:&lt;br /&gt;
 r.contour in=gauss out=gauss_200m_contours step=200&lt;br /&gt;
 d.vect gauss_200m_contours color=white&lt;br /&gt;
&lt;br /&gt;
Set map's color table to highlight detail:&lt;br /&gt;
 r.colors rad_test.day355.beam col=bcyr -e&lt;br /&gt;
 d.legend rad_test.day355.beam range=1300,1500&lt;br /&gt;
&lt;br /&gt;
=== Time step ===&lt;br /&gt;
&lt;br /&gt;
The following three images demonstrate the effects of using different time '''step''' parameters.&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.30minT&amp;quot; day=180 step=0.5&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_30min.png|400px|thumb|center|Default 30 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.15minT&amp;quot; day=180 step=0.25&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_15min.png|400px|thumb|center|15 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 r.sun -s elevin=&amp;quot;gauss&amp;quot; glob_rad=&amp;quot;rad.global.03minT&amp;quot; day=180 step=0.05&lt;br /&gt;
&lt;br /&gt;
[[File:Gauss_03min.png|400px|thumb|center|3 minute time step over a Gaussian mound.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The 3 minute time step takes roughly ten times as long to run as the 30 minute timestep.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Seed maps ==&lt;br /&gt;
&lt;br /&gt;
Using seed maps can greatly (?, unclear) speed up processing. This is especially important if you will batch process e.g. for every day of the year.&lt;br /&gt;
&lt;br /&gt;
* aspin= and slopein= options: create slope and aspect maps with the {{cmd|r.slope.aspect}} module.&lt;br /&gt;
: ''Caution: currently buggy''. See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* horizon= and horizonstep= options: Pre-calculate horizon shadows by creating a series of horizon rasters with the {{cmd|r.horizon}} module.&lt;br /&gt;
: Results not as smooth as without using this option?? See {{trac|498}}.&lt;br /&gt;
: Estimated speedup:  ?%.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* latin= and longin= options: Pre-calculate latitudes and longitudes for each raster cell.&lt;br /&gt;
The following script will create a raster containing latitude as the raster value:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create latitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=4 out=elevation.lat&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Creating the longitude map is exactly the same but use column 3 of the {{cmd|m.proj}} output instead of column 4:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 # create longitude map (WGS84)&lt;br /&gt;
 g.region rast=elevation.dem&lt;br /&gt;
 r.mapcalc one=1&lt;br /&gt;
 r.out.xyz one | \&lt;br /&gt;
   cut -f1,2 -d'|' | \&lt;br /&gt;
   m.proj -oed --quiet | \&lt;br /&gt;
   sed -e 's/[ \t]/|/g' | \&lt;br /&gt;
   cut -f1-4 -d'|' | \&lt;br /&gt;
   r.in.xyz in=- z=3 out=elevation.lon&lt;br /&gt;
 g.remove one&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Estimated speedup:  1.3% (in one test).&lt;br /&gt;
: See {{trac|498}}.&lt;br /&gt;
&lt;br /&gt;
The above assumes that your projection's ellipsoid is WGS84. If it isn't,  use other proj_out= terms with m.proj as required instead of the -o flag.&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
&lt;br /&gt;
It can be tedious to set up and run a long series of r.sun simulations for every day of the year. To automate this we can write a small shell script loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 for DAY in `seq 1 365` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
        beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
        refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
        insol_time=rad_insol_time.$DAY_STR&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://trac.osgeo.org/grass/browser/grass-addons/grass6/raster/r.sun.tools g.linke_by_day.py] is a small program which will return the Linke coefficient for any day of the year, interpolated from monthly values. You need to edit the script to fill in values appropriate for your study area.&lt;br /&gt;
&lt;br /&gt;
* If you have a multi-core CPU and you'd like to speed things up, here is a small Bourne shell script implementing a poor-man's multi-processing trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 ### r.sun mode 2 loop ###&lt;br /&gt;
 BEGIN=1&lt;br /&gt;
 END=365&lt;br /&gt;
 STEP=1&lt;br /&gt;
 NUM_CORES=4&lt;br /&gt;
&lt;br /&gt;
 for DAY in `seq $BEGIN $STEP $END` ; do&lt;br /&gt;
    DAY_STR=`echo $DAY | awk '{printf(&amp;quot;%.03d&amp;quot;, $1)}'`&lt;br /&gt;
    echo &amp;quot;Processing day $DAY_STR at `date` ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    LINKE=&amp;quot;`g.linke_by_day.py $DAY`&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    CMD=&amp;quot;r.sun -s elevin=elevation.dem day=$DAY lin=$LINKE step=0.05 \&lt;br /&gt;
         beam_rad=rad_beam.$DAY_STR diff_rad=rad_diffuse.$DAY_STR \&lt;br /&gt;
         refl_rad=rad_reflected.$DAY_STR glob_rad=rad_global.$DAY_STR \&lt;br /&gt;
         insol_time=rad_insol_time.$DAY_STR --quiet&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # poor man's multi-threading for a multi-core CPU&lt;br /&gt;
    MODULUS=`echo &amp;quot;$DAY $STEP $NUM_CORES&amp;quot; | awk '{print $1 % ($2 * $3)}'`&lt;br /&gt;
    if [ &amp;quot;$MODULUS&amp;quot; = &amp;quot;$STEP&amp;quot; ] || [ &amp;quot;$DAY&amp;quot; = &amp;quot;$END&amp;quot; ] ; then&lt;br /&gt;
       # stall to let the background jobs finish&lt;br /&gt;
       $CMD&lt;br /&gt;
       sleep 2&lt;br /&gt;
       wait&lt;br /&gt;
       #while [ `pgrep -c r.sun` -ne 0 ] ; do&lt;br /&gt;
       #   sleep 5&lt;br /&gt;
       #done&lt;br /&gt;
    else&lt;br /&gt;
       $CMD &amp;amp;&lt;br /&gt;
    fi&lt;br /&gt;
 done&lt;br /&gt;
 wait   # wait for background jobs to finish to avoid race conditions&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For a r.sun Mode 1 loop, see the [[Parallelizing Scripts]] page.&lt;br /&gt;
&lt;br /&gt;
== Overview of monthly maps ==&lt;br /&gt;
&lt;br /&gt;
Given there are mean monthly global irradiation maps calculated, an overview map of all 12 maps can be drawn along with their legends (see also [http://grass.osgeo.org/wiki/Time_series#Common_legends_for_many_raster_maps Common legends for many raster maps]). The script assumes a common naming convention for all 12 monthly average maps (i.e. global_rad_avg.jan, global_rad_avg.feb, global_rad_avg.mar, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
 #!/bash/sh&lt;br /&gt;
 # script to draw monthly (mean) global solar irradiation maps in a 3x4 matrix&lt;br /&gt;
 &lt;br /&gt;
 # set wide aspect ratio (16:9, e.g. 1366 width x 768 height)&lt;br /&gt;
 d.monsize setm=x0 setw=1366 seth=768&lt;br /&gt;
 &lt;br /&gt;
 # split in 12 frames&lt;br /&gt;
 d.split.frame frames=12&lt;br /&gt;
 &lt;br /&gt;
 # preferred font?&lt;br /&gt;
 d.font DroidSans&lt;br /&gt;
&lt;br /&gt;
 for FRAME in &amp;quot;uno dec December&amp;quot; &amp;quot;dos jan January&amp;quot; &amp;quot;tres feb February&amp;quot; \&lt;br /&gt;
 &amp;quot;cuatro mar March&amp;quot; &amp;quot;cinco apr April&amp;quot; &amp;quot;seis may May&amp;quot; \&lt;br /&gt;
 &amp;quot;siete jun June&amp;quot; &amp;quot;ocho jul July&amp;quot; &amp;quot;nueve aug August&amp;quot; \&lt;br /&gt;
 &amp;quot;diez sep September&amp;quot; &amp;quot;once oct October&amp;quot; &amp;quot;doce nov November&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 do&lt;br /&gt;
 &lt;br /&gt;
    # parse &amp;quot;${FRAMES_STR}&amp;quot; and set positional parameters&lt;br /&gt;
    set -- $FRAME ; echo $1 $2 $3&lt;br /&gt;
    &lt;br /&gt;
    # select FRAME&lt;br /&gt;
    d.frame -s &amp;quot;${1}&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # draw the map&lt;br /&gt;
    d.rast global_rad_avg.&amp;quot;${2}&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # draw label on the left and vertically&lt;br /&gt;
    d.text text=&amp;quot;${3}&amp;quot; size=10 color=50:50:50 at=9,25 rotation=90&lt;br /&gt;
 &lt;br /&gt;
    # draw legend&lt;br /&gt;
    d.legend global_rad_avg.&amp;quot;${2}&amp;quot; -s at=10,90,89,92&lt;br /&gt;
 &lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece.png|400px|thumb|center|Mean monthly global irradiation maps (n=38.918, s=38.531, w=21.793, e=22.436)]]&lt;br /&gt;
Same image also [http://grass.osgeo.org/grass-wiki/images/Mean_monthly_global_rad_maps_over_a_study_area_in_central_Greece_700px_height.jpg here (a bit of higher resolution)]&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
&lt;br /&gt;
* Ongoing trials documented in [https://trac.osgeo.org/grass/ticket/498 trac ticket #498]&lt;br /&gt;
&lt;br /&gt;
=== OpenCL ===&lt;br /&gt;
As part of the Google Summer of Code 2010 an {{wikipedia|OpenCL}} version has been written that allows ''r.sun'' to run on {{wikipedia|GPU}}s. This provides a massive speedup in processing time. The merging of this code into GRASS 7's r.sun is forthcoming (HB).&lt;br /&gt;
* To get your hands on the code now see http://github.com/mailseth/OpenCL-integration-for-GRASS---GDAL (functional prototype now available)&lt;br /&gt;
* To use OpenCL GPU functionality you'll want a graphics card like the ATI HD5770 or nVidia GTX260 or GTX460, or newer.&lt;br /&gt;
* OpenCL also allows for running on multi-core (or multi-processor) CPUs, for systems without GPUs. You can run OpenCL via multicore *or* GPU, but not both on the same job at the same time.&lt;br /&gt;
* Seth wrote: ''The OpenCL version of r.sun runs over 20x faster than the original version on my machine (2.26 GHz Mac Pro vs. GeForce GTX 285). However, it is hampered by the low memory on your GPU, so you may need to partition your raster.''&lt;br /&gt;
* You can now ./configure GRASS 7 with OpenCL support using:&lt;br /&gt;
 --with-opencl&lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
* Merge in OpenCL code&lt;br /&gt;
* Add support for [[OpenMP]] parallelization (if OpenCL doesn't make that redundant)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Usage of r.sun in the literature (selected references):&lt;br /&gt;
&lt;br /&gt;
* Agugiaro, G., Remondino, F., Stevanato, G., De Filippi, R., Furlanello, C., 2011. Estimation of solar radiation on building roofs in mountainous areas. International Archives of Photogrammetry 38. PDF: http://www.pf.bv.tum.de/isprs/pia11/pub/PIA11_Agugiaro_et_al.pdf&lt;br /&gt;
* H.T. Nguyen and J.M. Pearce, &amp;quot;[http://dx.doi.org/10.1016/j.solener.2010.02.009 Estimating Potential Photovoltaic Yield with r.sun and the Open Source Geographical Resources Analysis Support System]&amp;quot; Solar Energy 84, pp. 831-843, 2010. [http://mtu.academia.edu/JoshuaPearce/Papers/1540702/Estimating_Potential_Photovoltaic_Yield_with_r.sun_and_the_Open_Source_Geographical_Resources_Analysis_Support_System Open Access] (see also [http://www.appropedia.org/An_open_source_simulation_of_photovoltaic_yield_with_r.sun_over_large_regions Link to related external wiki page])&lt;br /&gt;
* Hofierka, J., Kanuk, J., 2009. Assessment of photovoltaic potential in urban areas using open-source solar radiation tools. Renewable Energy 34, 2206-2214.&lt;br /&gt;
* Huld, T.A., Šúri, M., Dunlop, E.D., Micale, F., 2006. Estimating average daytime and daily temperature profiles within Europe. Environmental Modelling &amp;amp; Software 21, 1650-1661.&lt;br /&gt;
* Šúri, M., Hofierka, J., 2004. A new GIS‐based solar radiation model and its application to photovoltaic assessments. Transactions in GIS 8, 175-190.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Documentation]]&lt;br /&gt;
[[Category: Parallelization]]&lt;/div&gt;</summary>
		<author><name>Hamish</name></author>
	</entry>
</feed>