[Dart-dev] [4850] DART/trunk/location/threed_sphere/location_mod.html: Add Jeff' s discussion of computing the minimium longitudes at any given

nancy at ucar.edu nancy at ucar.edu
Fri Apr 8 16:33:23 MDT 2011


Revision: 4850
Author:   nancy
Date:     2011-04-08 16:33:23 -0600 (Fri, 08 Apr 2011)
Log Message:
-----------
Add Jeff's discussion of computing the minimium longitudes at any given
latitude which are within a given radius.  Also fix a typo in an href
down in the namelist.  minor other reformatting, remove extra </P>, etc.

Modified Paths:
--------------
    DART/trunk/location/threed_sphere/location_mod.html

-------------- next part --------------
Modified: DART/trunk/location/threed_sphere/location_mod.html
===================================================================
--- DART/trunk/location/threed_sphere/location_mod.html	2011-04-06 15:19:43 UTC (rev 4849)
+++ DART/trunk/location/threed_sphere/location_mod.html	2011-04-08 22:33:23 UTC (rev 4850)
@@ -43,12 +43,11 @@
 read and write location information to files.
 DART isolates all this location information into separate modules 
 so that the main algorithms can operate with the same code independent
-of whether the model uses latitude/longitude/height, one-d unit
+of whether the model uses latitude/longitude/height, 1D unit
 sphere coordinates, cylindrical coordinates, etc.  DART provides
 about half a dozen possible coordinate systems, and others can be added.  
 The most common one for geophysical models is this one: threed_sphere.
-</P>
-<P>
+</P> <P>
 This location module provides a representation of a physical location 
 on a 3-D spherical shell, using latitude and longitude plus a vertical
 component with choices of vertical coordinate type such as pressure or 
@@ -69,8 +68,7 @@
 is controlled by which source file name is specified 
 in the <em class=file>path_names_xxx</em> file, which is used by
 the <em class=file>mkmf_xxx</em> scripts.
-</P>
-<P>
+</P> <P>
 All types of location modules define the same Fortran 90 derived type
 <em class=code>location_type</em>.
 Programs that need to pass location information to subroutines
@@ -92,8 +90,7 @@
 a single observation and items in the state vector, and also between a single
 observation and other nearby observations.
 However, any source for locations is supported.
-</P>
-<P>
+</P> <P>
 In simpler location modules (like the <em class=file>oned</em> version)
 there is no need for anything other than a brute force search between
 the base location and all available state vector locations.  However in
@@ -103,7 +100,7 @@
 The location code pre-processes all locations into a set of <em>bins</em>
 and then only needs to search the lists of locations in nearby bins when looking
 for locations that are within a specified distance.
-
+</P> <P>
 The expected calling sequence of the <em class=code>get_close</em> routines 
 is as follows:
 <pre>
@@ -124,15 +121,13 @@
 compute the exact separation distance from the reference location.
 The last routine deallocates the space.  See the documentation 
 below for the specific details for each routine.
-</P>
-<P>
+</P> <P>
 All 4 of these routines must be present in every location module
 but in most other versions
 all but <em class=code>get_close_obs()</em> are stubs.
 In this <em class=file>threed_sphere</em> version
 of the locations module all are fully implemented.
 </P>
-</P>
 <H4>Interaction with model_mod.f90 code</H4>
 <A NAME="ModelMod"></A>
 <P>
@@ -146,8 +141,7 @@
 from the <em class=code>location_mod</em> module.
 Thus they 'pass through' the model_mod but the user does
 not need to provide a subroutine or any code for them.
-</P>
-<P>
+</P> <P>
 However, if the model interface code wants to intercept and alter
 the default behavior of the get_close routines, it is able to.
 Typically the model_mod still calls the location_mod routines and
@@ -171,8 +165,7 @@
 through to the code in the location_mod, but the model_mod must supply
 a get_close_obs() subroutine.  When it wants to call the code in the 
 location_mod it calls <em class=code>location_get_close_obs()</em>.
-</P>
-<P>
+</P> <P>
 One use pattern is for the model_mod to call the location get_close_obs()
 routine without the <em class=code>dist</em> argument.  This returns a list
 of any potentially close locations without computing the exact distance
@@ -190,57 +183,34 @@
 particular unit type, this is the place where the conversion to that
 vertical unit should be done.
 </P>
-
-<!--=====================================================================-->
-<!--===================== DESCRIPTION OF A NAMELIST =====================-->
-<!--=====================================================================-->
-
-<A NAME="Namelist"></A>
-<HR>
-<H2>NAMELIST</H2>
-<P>We adhere to the F90 standard of starting a namelist with an ampersand
-'&amp;' and terminating with a slash '/' for all our namelist input.
-Consider yourself forewarned that character strings that contain a '/' must be
-enclosed in quotes to prevent them from prematurely terminating the namelist.
-The namelist declaration (i.e. what follows) has a different syntax, naturally.
-</P>
-<div class=namelist>
-<pre>
-<em class=call>namelist / location_nml / </em> &amp;
-   horiz_dist_only, vert_normalization_pressure, vert_normalization_height, &amp;
-   vert_normalization_level, vert_normalization_scale_height, &amp;
-   approximate_distance, nlon, nlat, output_box_info, maintain_original_vert
-</pre>
-</div>
-
-<div class=indent1>
-<!-- Description -->
-
+<H4>Horizontal Distance Only</H4>
 <P>
-Items in this namelist either control the way in which distances 
-are computed and/or influence the code performance.
-<br><br>
-If <em>horiz_distance_only</em> is .false.
+If <em>horiz_distance_only</em> is .true. in the namelist, then the
+vertical coordinate is ignored and only the great-circle distance
+between the two locations is computed, as if they were both on the
+surface of the sphere. 
+</P> <P>
+If <em>horiz_distance_only</em> is .false. in the namelist
 then the appropriate normalization constant determines the relative impact of
 vertical and horizontal separation.  Since only a single localization
 distance is specified, and the vertical scales might have very different
 distance characteristics, the vert_normalization_xxx values can be used
 to scale the vertical appropriately to control the desired influence 
 of observations in the vertical.
-<br><br>
+</P>
+<H4>Precomputation for Run-time Search Efficiency</H4>
+<P>
 For search efficiency all locations are pre-binned. The surface of the
 sphere is divided up into <em>nlon</em> by <em>nlat</em> boxes and the
 index numbers of all items (both state vector entries and observations)
 are stored in the appropriate box.  
 To locate all points close to a given location, only the locations
 listed in the boxes within the search radius must be checked.  
-<!--   Does this really clarify anything?  is it right?
 This speeds up the computations, for example, when localization controls
 which state vector items are impacted by any given observation.  The search
 radius is the localization distance and only those state vector items
 in boxes closer than the radius to the observation location are processed.
--->
-<br><br>
+</P> <P>
 The default values have given good performance on many of our
 existing model runs, but for tuning purposes the box counts
 have been added to the namelist to allow adjustment.  
@@ -260,7 +230,7 @@
 distributed across boxes. 
 The absolute numbers for best performance will certainly
 vary from case to case.
-<br><br>
+</P> <P>
 For latitude, the <em>nlat</em> boxes are distributed evenly across the
 actual extents of the data. (Locations are in radians, so the
 maximum limits are the poles at -PI/2 and +PI/2).   
@@ -280,7 +250,91 @@
 across the entire surface of the sphere.  
 For local or regional models, the boxes
 are distributed only across the the extent of the local grid.
-<br><br>
+</P> <P>
+For efficiency in the case where the boxes span less than half the globe,
+the 3D location module needs to be able to determine the greatest longitude 
+difference between a base point at latitude <tt>&phi;<sub>s</sub></tt>
+and all points that are separated from that point by a central 
+angle of <tt>&theta;</tt>. 
+We might also want to know the latitude, <tt>&phi;<sub>f</sub></tt> , 
+at which the largest separation occurs. Note also that an intermediate 
+form below allows the computation of the maximum longitude difference 
+at a particular latitude.
+</P> <P>
+The central angle between a point at latitude <tt>&phi;<sub>s</sub></tt>
+and a second point at latitude <tt>&phi;<sub>f</sub></tt> that are separated 
+in longitude by <tt>&Delta;&lambda;</tt> is <br> <br>
+<tt>
+&nbsp;&nbsp;&theta = cos<sup>-1</sup>(sin&phi;<sub>s</sub>sin&phi;<sub>f</sub> + 
+   cos&phi;<sub>s</sub>cos&phi<sub>f</sub>cos&Delta;&lambda;) 
+</tt> <br> <br>
+Taking the cos of both sides gives <br> <br>
+<tt>
+&nbsp;&nbsp;cos&theta; = (sin&phi;<sub>s</sub>sin&phi;<sub>f</sub> +
+   cos&phi;<sub>s</sub>cos&phi;<sub>f</sub>cos&Delta;&lambda;)
+</tt> <br> <br>
+Solving for <tt>cos&Delta;&lambda;</tt> gives <br> <br>
+<tt>
+&nbsp;&nbsp;cos&Delta;&lambda; 
+    = <sup>(<i>a</i> - <i>b</i>&nbsp;sin&phi<sub>f</sub>)</sup><big>/</big><sub>(<i>c</i>&nbsp;cos&phi;<sub>f</sub>)</sub>
+    = <sup><i>a</i></sup><big>/</big><sub><i>c</i></sub>&nbsp;sec&phi;<sub>f</sub> - 
+      <sup><i>b</i></sup><big>/</big><sub><i>c</i></sub>&nbsp;tan&phi;<sub>f</sub> 
+</tt> <br> <br>
+where <tt><i>a</i> = cos&theta;</tt> , 
+<tt><i>b</i> = sin&phi;<sub>s</sub></tt> , 
+and <tt><i>c</i> = cos&phi<sub>s</sub></tt> . 
+We want to maximize <tt>&Delta;&lambda;</tt> which implies minimizing   
+<tt>cos&Delta;&lambda;</tt> subject to constraints. Taking the 
+derivative with respect to <tt>&phi;<sub>f</sub></tt> gives  <br> <br>
+<tt>
+&nbsp;&nbsp;<i><sup>(d</i>&nbsp;cos&Delta;&lambda;)</sup><big>/</big><sub>(<i>d</i>&phi;<sub>f</sub>)</sub> = 
+   <sup><i>a</i></sup><big>/</big><sub><i>c</i></sub>&nbsp;sec&phi;<sub>f</sub>&nbsp;tan&phi;<sub>f</sub>
+ - <sup><i>b</i></sup><big>/</big><sub><i>c</i></sub>&nbsp;sec<sup>2</sup>&phi;<sub>f</sub> = 0
+</tt> <br> <br>
+Factoring out <tt>sec&phi;<sub>f</sub></tt> which can never be 0 and using the
+definitions of <tt>sec</tt> and <tt>tan</tt> gives <br> <br>
+<tt>
+&nbsp;&nbsp;<sup>(<i>a</i>&nbsp;sin&phi;<sub>f</sub>)</sup><big>/</big><sub>(<i>c</i>&nbsp;cos&phi;<sub>f</sub>)</sub> -
+<sup><i>b</i></sup><big>/</big><sub>(<i>c</i>&nbsp;cos&phi;<sub>f</sub>)</sub> = 0
+</tt> <br> <br>
+Solving in the constrained range from 0 to PI/2 gives <br> <br>
+<tt>
+&nbsp;&nbsp; sin&phi;<sub>f</sub> = <sup><i>b</i></sup><big>/</big><sub><i>a</i></sub> = 
+   <sup>sin&phi;<sub>s</sub></sup><big>/</big><sub>cos&theta;</sub>
+</tt> <br> <br>
+Note that if the angle between the base point and a pole is less than 
+or equal to the central angle, all longitude differences will occur 
+as the pole is approached.
+</P>
+
+<!--=====================================================================-->
+<!--===================== DESCRIPTION OF A NAMELIST =====================-->
+<!--=====================================================================-->
+
+<A NAME="Namelist"></A>
+<HR>
+<H2>NAMELIST</H2>
+<P>We adhere to the F90 standard of starting a namelist with an ampersand
+'&amp;' and terminating with a slash '/' for all our namelist input.
+Consider yourself forewarned that character strings that contain a '/' must be
+enclosed in quotes to prevent them from prematurely terminating the namelist.
+The namelist declaration (i.e. what follows) has a different syntax, naturally.
+</P>
+<div class=namelist>
+<pre>
+<em class=call>namelist / location_nml / </em> &amp;
+   horiz_dist_only, vert_normalization_pressure, vert_normalization_height, &amp;
+   vert_normalization_level, vert_normalization_scale_height, &amp;
+   approximate_distance, nlon, nlat, output_box_info, maintain_original_vert
+</pre>
+</div>
+
+<div class=indent1>
+<!-- Description -->
+
+<P>
+Items in this namelist either control the way in which distances 
+are computed and/or influence the code performance.
 This namelist is read in a file called <em class=file>input.nml</em> .
 </P>
 
@@ -311,7 +365,7 @@
 <TR><!--contents--><TD valign=top>maintain_original_vert</TD>
     <!--  type  --><TD valign=top>logical</TD>
     <!--descript--><TD>If using per-type specialized localization distances
-                (see <a href="../../assim_tools/assim_tools_mod.html#Namelist>assim_tools_mod</a>
+                (see <a href="../../assim_tools/assim_tools_mod.html#Namelist">assim_tools_mod</a>)
                 by default the vertical distances are altered also.  To maintain
                 the original vertical scaling while changing the horizontal, set this
                 to true.  Default: .false.</TD></TR>


More information about the Dart-dev mailing list