GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
N_geom.c
Go to the documentation of this file.
00001 
00002 /*****************************************************************************
00003 *
00004 * MODULE:       Grass PDE Numerical Library
00005 * AUTHOR(S):    Soeren Gebbert, Berlin (GER) Dec 2006
00006 *               soerengebbert <at> gmx <dot> de
00007 *               
00008 * PURPOSE:      part of the gpde library
00009 *               allocation, destroing and initializing the geometric struct
00010 *
00011 * COPYRIGHT:    (C) 2000 by the GRASS Development Team
00012 *
00013 *               This program is free software under the GNU General Public
00014 *               License (>=v2). Read the file COPYING that comes with GRASS
00015 *               for details.
00016 *
00017 *****************************************************************************/
00018 
00019 
00020 #include "grass/N_pde.h"
00021 
00022 /* *************************************************************** * 
00023  * *********** Konstruktor *************************************** * 
00024  * *************************************************************** */
00030 N_geom_data *N_alloc_geom_data(void)
00031 {
00032     N_geom_data *geom = (N_geom_data *) G_calloc(1, sizeof(N_geom_data));
00033 
00034     geom->area = NULL;
00035     geom->planimetric = 1;
00036     geom->dim = 0;
00037 
00038     return geom;
00039 }
00040 
00041 /* *************************************************************** * 
00042  * *********** Destruktor **************************************** * 
00043  * *************************************************************** */
00050 void N_free_geom_data(N_geom_data * geom)
00051 {
00052     if (geom->area != NULL)
00053         G_free(geom->area);
00054 
00055     G_free(geom);
00056     return;
00057 }
00058 
00059 /* *************************************************************** * 
00060  * *************************************************************** * 
00061  * *************************************************************** */
00073 N_geom_data *N_init_geom_data_3d(G3D_Region * region3d, N_geom_data * geodata)
00074 {
00075     N_geom_data *geom = geodata;
00076 
00077     struct Cell_head region2d;
00078 
00079 #pragma omp critical
00080     {
00081 
00082         G_debug(2,
00083                 "N_init_geom_data_3d: initializing the geometry structure");
00084 
00085         if (geom == NULL)
00086             geom = N_alloc_geom_data();
00087 
00088         geom->dz = region3d->tb_res * G_database_units_to_meters_factor();      /*this function is not thread safe */
00089         geom->depths = region3d->depths;
00090         geom->dim = 3;
00091 
00092         /*convert the 3d into a 2d region and begin the area calculation */
00093         G_get_set_window(&region2d);    /*this function is not thread safe */
00094         G3d_regionToCellHead(region3d, &region2d);
00095     }
00096 
00097     return N_init_geom_data_2d(&region2d, geom);
00098 }
00099 
00100 
00101 /* *************************************************************** * 
00102  * *************************************************************** * 
00103  * *************************************************************** */
00115 N_geom_data *N_init_geom_data_2d(struct Cell_head * region,
00116                                  N_geom_data * geodata)
00117 {
00118     N_geom_data *geom = geodata;
00119 
00120     struct Cell_head backup;
00121 
00122     double meters;
00123 
00124     short ll = 0;
00125 
00126     int i;
00127 
00128 
00129     /*create an openmp lock to assure that only one thread at a time will access this function */
00130 #pragma omp critical
00131     {
00132         G_debug(2,
00133                 "N_init_geom_data_2d: initializing the geometry structure");
00134 
00135         /*make a backup from this region */
00136         G_get_set_window(&backup);      /*this function is not thread safe */
00137         /*set the current region */
00138         G_set_window(region);   /*this function is not thread safe */
00139 
00140         if (geom == NULL)
00141             geom = N_alloc_geom_data();
00142 
00143         meters = G_database_units_to_meters_factor();   /*this function is not thread safe */
00144 
00145         /*set the dim to 2d if it was not initiated with 3, thats a bit ugly :( */
00146         if (geom->dim != 3)
00147             geom->dim = 2;
00148 
00149         geom->planimetric = 1;
00150         geom->rows = region->rows;
00151         geom->cols = region->cols;
00152         geom->dx = region->ew_res * meters;
00153         geom->dy = region->ns_res * meters;
00154         geom->Az = geom->dy * geom->dx; /*square meters in planimetric proj */
00155         /*depths and dz are initialized with a 3d region */
00156 
00157         /*Begin the area calculation */
00158         ll = G_begin_cell_area_calculations();  /*this function is not thread safe */
00159 
00160         /*if the projection is not planimetric, calc the area for each row */
00161         if (ll == 2) {
00162             G_debug(2,
00163                     "N_init_geom_data_2d: calculating the areas for non parametric projection");
00164             geom->planimetric = 0;
00165 
00166             if (geom->area != NULL) {
00167                 G_free(geom->area);
00168                 geom->area = G_calloc(geom->rows, sizeof(double));
00169             } else {
00170                 geom->area = G_calloc(geom->rows, sizeof(double));
00171             }
00172 
00173             /*fill the area vector */
00174             for (i = 0; i < geom->rows; i++) {
00175                 geom->area[i] = G_area_of_cell_at_row(i);       /*square meters */
00176             }
00177         }
00178 
00179         /*restore the old region */
00180         G_set_window(&backup);  /*this function is not thread safe */
00181     }
00182 
00183     return geom;
00184 }
00185 
00186 /* *************************************************************** * 
00187  * *************************************************************** * 
00188  * *************************************************************** */
00199 double N_get_geom_data_area_of_cell(N_geom_data * geom, int row)
00200 {
00201     if (geom->planimetric) {
00202         G_debug(6, "N_get_geom_data_area_of_cell: %g", geom->Az);
00203         return geom->Az;
00204     }
00205     else {
00206         G_debug(6, "N_get_geom_data_area_of_cell: %g", geom->area[row]);
00207         return geom->area[row];
00208     }
00209 
00210     return 0.0;
00211 }