123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- /*****************************************************************************
- *
- * MODULE: Grass PDE Numerical Library
- * AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
- * soerengebbert <at> gmx <dot> de
- *
- * PURPOSE: part of the gpde library
- * allocation, destroying and initializing the geometric struct
- *
- * COPYRIGHT: (C) 2000 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public
- * License (>=v2). Read the file COPYING that comes with GRASS
- * for details.
- *
- *****************************************************************************/
- #include <grass/N_pde.h>
- /* *************************************************************** *
- * *********** Konstruktor *************************************** *
- * *************************************************************** */
- /*!
- * \brief Allocate the pde geometry data structure and return a pointer to the new allocated structure
- *
- * \return N_geom_data *
- * */
- N_geom_data *N_alloc_geom_data(void)
- {
- N_geom_data *geom = (N_geom_data *) G_calloc(1, sizeof(N_geom_data));
- geom->area = NULL;
- geom->planimetric = 1;
- geom->dim = 0;
- return geom;
- }
- /* *************************************************************** *
- * *********** Destruktor **************************************** *
- * *************************************************************** */
- /*!
- * \brief Release memory of a pde geometry data structure
- *
- * \param geom N_geom_data *
- * \return void
- * */
- void N_free_geom_data(N_geom_data * geom)
- {
- if (geom->area != NULL)
- G_free(geom->area);
- G_free(geom);
- return;
- }
- /* *************************************************************** *
- * *************************************************************** *
- * *************************************************************** */
- /*!
- * \brief Initiate a pde geometry data structure with a 3d region
- *
- * If the projection is not planimetric, a double array will be created based on the
- * number of rows of the provided region
- *
- * \param region3d RASTER3D_Region *
- * \param geodata N_geom_data * - if a NULL pointer is given, a new structure will be allocatet and returned
- *
- * \return N_geom_data *
- * */
- N_geom_data *N_init_geom_data_3d(RASTER3D_Region * region3d, N_geom_data * geodata)
- {
- N_geom_data *geom = geodata;
- struct Cell_head region2d;
- #pragma omp critical
- {
- G_debug(2,
- "N_init_geom_data_3d: initializing the geometry structure");
- if (geom == NULL)
- geom = N_alloc_geom_data();
- geom->dz = region3d->tb_res * G_database_units_to_meters_factor(); /*this function is not thread safe */
- geom->depths = region3d->depths;
- geom->dim = 3;
- /*convert the 3d into a 2d region and begin the area calculation */
- G_get_set_window(®ion2d); /*this function is not thread safe */
- Rast3d_region_to_cell_head(region3d, ®ion2d);
- }
- return N_init_geom_data_2d(®ion2d, geom);
- }
- /* *************************************************************** *
- * *************************************************************** *
- * *************************************************************** */
- /*!
- * \brief Initiate a pde geometry data structure with a 2d region
- *
- * If the projection is not planimetric, a double array will be created based on the
- * number of rows of the provided region storing all computed areas for each row
- *
- * \param region sruct Cell_head *
- * \param geodata N_geom_data * - if a NULL pointer is given, a new structure will be allocatet and returned
- *
- * \return N_geom_data *
- * */
- N_geom_data *N_init_geom_data_2d(struct Cell_head * region,
- N_geom_data * geodata)
- {
- N_geom_data *geom = geodata;
- struct Cell_head backup;
- double meters;
- short ll = 0;
- int i;
- /*create an openmp lock to assure that only one thread at a time will access this function */
- #pragma omp critical
- {
- G_debug(2,
- "N_init_geom_data_2d: initializing the geometry structure");
- /*make a backup from this region */
- G_get_set_window(&backup); /*this function is not thread safe */
- /*set the current region */
- Rast_set_window(region); /*this function is not thread safe */
- if (geom == NULL)
- geom = N_alloc_geom_data();
- meters = G_database_units_to_meters_factor(); /*this function is not thread safe */
- /*set the dim to 2d if it was not initiated with 3, that's a bit ugly :( */
- if (geom->dim != 3)
- geom->dim = 2;
- geom->planimetric = 1;
- geom->rows = region->rows;
- geom->cols = region->cols;
- geom->dx = region->ew_res * meters;
- geom->dy = region->ns_res * meters;
- geom->Az = geom->dy * geom->dx; /*square meters in planimetric proj */
- /*depths and dz are initialized with a 3d region */
- /*Begin the area calculation */
- ll = G_begin_cell_area_calculations(); /*this function is not thread safe */
- /*if the projection is not planimetric, calc the area for each row */
- if (ll == 2) {
- G_debug(2,
- "N_init_geom_data_2d: calculating the areas for non parametric projection");
- geom->planimetric = 0;
- if (geom->area != NULL)
- G_free(geom->area);
- else
- geom->area = G_calloc(geom->rows, sizeof(double));
- /*fill the area vector */
- for (i = 0; i < geom->rows; i++) {
- geom->area[i] = G_area_of_cell_at_row(i); /*square meters */
- }
- }
- /*restore the old region */
- Rast_set_window(&backup); /*this function is not thread safe */
- }
- return geom;
- }
- /* *************************************************************** *
- * *************************************************************** *
- * *************************************************************** */
- /*!
- * \brief Get the areay size in square meter of one cell (x*y) at row
- *
- * This function works for two and three dimensions
- *
- * \param geom N_geom_data *
- * \param row int
- * \return area double
- *
- * */
- double N_get_geom_data_area_of_cell(N_geom_data * geom, int row)
- {
- if (geom->planimetric) {
- G_debug(6, "N_get_geom_data_area_of_cell: %g", geom->Az);
- return geom->Az;
- }
- else {
- G_debug(6, "N_get_geom_data_area_of_cell: %g", geom->area[row]);
- return geom->area[row];
- }
- return 0.0;
- }
|