|
GRASS Programmer's Manual
6.5.svn(2012)-r51648
|
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(®ion2d); /*this function is not thread safe */ 00094 G3d_regionToCellHead(region3d, ®ion2d); 00095 } 00096 00097 return N_init_geom_data_2d(®ion2d, 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 }