/*! * \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); }
/* *************************************************************** */ int test_matrix_assemble_3d(void) { N_geom_data *geom; N_les *les; N_les_callback_3d *call; N_array_3d *status; N_array_3d *start_val; /*set the callback to default */ call = N_alloc_les_callback_3d(); status = create_status_array_3d(); start_val = create_value_array_3d(); geom = N_alloc_geom_data(); geom->dx = 1; geom->dy = 1; geom->dz = 1; geom->Az = 1; geom->depths = TEST_N_NUM_DEPTHS; geom->rows = TEST_N_NUM_ROWS; geom->cols = TEST_N_NUM_COLS; /*Assemble the matrix */ les = N_assemble_les_3d(N_SPARSE_LES, geom, status, start_val, NULL, call); N_free_les(les); les = N_assemble_les_3d_active(N_SPARSE_LES, geom, status, start_val, NULL, call); N_free_les(les); les = N_assemble_les_3d_dirichlet(N_SPARSE_LES, geom, status, start_val, NULL, call); N_les_integrate_dirichlet_3d(les, geom, status, start_val); N_free_les(les); les = N_assemble_les_3d(N_NORMAL_LES, geom, status, start_val, NULL, call); N_free_les(les); les = N_assemble_les_3d_active(N_NORMAL_LES, geom, status, start_val, NULL, call); N_free_les(les); les = N_assemble_les_3d_dirichlet(N_NORMAL_LES, geom, status, start_val, NULL, call); N_les_integrate_dirichlet_3d(les, geom, status, start_val); N_free_les(les); G_free(geom); G_free(call); return 0; }
/* ************************************************************************* */ int test_geom_data(void) { struct Cell_head region2d; G3D_Region region3d; N_geom_data *geom = NULL; int sum = 0, i; double area = 0; G_get_set_window(®ion2d); /*Set the defaults */ G3d_initDefaults(); /*get the current region */ G3d_getWindow(®ion3d); geom = N_alloc_geom_data(); if (!geom) { G_warning("error in N_alloc_geom_data"); return 1; } N_free_geom_data(geom); geom = NULL; /* ************ 2d region *************** */ geom = N_init_geom_data_2d(®ion2d, geom); if (!geom) { G_warning("error in N_init_geom_data_2d"); return 2; } geom = N_init_geom_data_2d(®ion2d, geom); if (!geom) { G_warning("error in N_init_geom_data_2d"); return 3; } if (geom->dim != 2) sum++; if (geom->planimetric == 0 && geom->area == NULL) sum++; if (geom->planimetric == 1 && geom->area != NULL) sum++; /*get areas */ area = 0.0; if (geom->planimetric == 0) { for (i = 0; i < geom->rows; i++) area += N_get_geom_data_area_of_cell(geom, i); if (area == 0) { G_warning("Wrong area calculation in N_init_geom_data_2d"); sum++; } } area = 0.0; if (geom->planimetric == 1) { for (i = 0; i < geom->rows; i++) area += N_get_geom_data_area_of_cell(geom, i); if (area == 0) { G_warning ("Wrong area calculation in N_get_geom_data_area_of_cell"); sum++; } } N_free_geom_data(geom); geom = NULL; /* ************ 3d region *************** */ geom = N_init_geom_data_3d(®ion3d, geom); if (!geom) { G_warning("error in N_init_geom_data_3d"); return 2; } geom = N_init_geom_data_3d(®ion3d, geom); if (!geom) { G_warning("error in N_init_geom_data_3d"); return 3; } if (geom->dim != 3) sum++; if (geom->planimetric == 0 && geom->area == NULL) sum++; if (geom->planimetric == 1 && geom->area != NULL) sum++; /*get areas */ area = 0.0; if (geom->planimetric == 0) { for (i = 0; i < geom->rows; i++) area += N_get_geom_data_area_of_cell(geom, i); if (area == 0) { G_warning ("Wrong area calculation in N_get_geom_data_area_of_cell"); sum++; } } area = 0.0; if (geom->planimetric == 1) { for (i = 0; i < geom->rows; i++) area += N_get_geom_data_area_of_cell(geom, i); if (area == 0) { G_warning ("Wrong area calculation in N_get_geom_data_area_of_cell"); sum++; } } return sum; }
/* *************************************************************** */ int test_solute_transport_2d(void) { N_solute_transport_data2d *data = NULL; N_geom_data *geom = NULL; N_les *les = NULL; N_les_callback_2d *call = NULL; N_array_2d *pot, *relax = NULL; N_gradient_field_2d *field = NULL; int i, j; /*set the callback */ call = N_alloc_les_callback_2d(); N_set_les_callback_2d_func(call, (*N_callback_solute_transport_2d)); pot = N_alloc_array_2d(TEST_N_NUM_COLS_LOCAL, TEST_N_NUM_ROWS_LOCAL, 1, DCELL_TYPE); relax = N_alloc_array_2d(TEST_N_NUM_COLS_LOCAL, TEST_N_NUM_ROWS_LOCAL, 1, DCELL_TYPE); data = create_solute_transport_data_2d(); data->dt = 600; geom = N_alloc_geom_data(); geom->dx = 10; geom->dy = 15; geom->Az = 150; geom->rows = TEST_N_NUM_ROWS_LOCAL; geom->cols = TEST_N_NUM_COLS_LOCAL; for (j = 0; j < TEST_N_NUM_ROWS_LOCAL; j++) { for (i = 0; i < TEST_N_NUM_COLS_LOCAL; i++) { N_put_array_2d_d_value(pot, i, j, j); N_put_array_2d_d_value(relax, i, j, 1); } } field = N_compute_gradient_field_2d(pot, relax, relax, geom, NULL); N_copy_gradient_field_2d(field, data->grad); N_free_gradient_field_2d(field); N_compute_gradient_field_2d(pot, relax, relax, geom, data->grad); /*The dispersivity tensor */ N_calc_solute_transport_disptensor_2d(data); /*Assemble the matrix */ /* */ /*Jacobi */ les = N_assemble_les_2d(N_SPARSE_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_jacobi(les, 100, 1, 0.1e-8); N_print_les(les); N_free_les(les); /*jacobi */ les = N_assemble_les_2d(N_NORMAL_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_jacobi(les, 100, 1, 0.1e-8); N_print_les(les); N_free_les(les); /*SOR*/ les = N_assemble_les_2d(N_SPARSE_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_SOR(les, 100, 1, 0.1e-8); N_print_les(les); N_free_les(les); /*SOR*/ les = N_assemble_les_2d(N_NORMAL_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_SOR(les, 100, 1, 0.1e-8); N_print_les(les); N_free_les(les); /*BICG*/ les = N_assemble_les_2d(N_SPARSE_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_bicgstab(les, 100, 0.1e-8); N_print_les(les); N_free_les(les); /*BICG*/ les = N_assemble_les_2d(N_NORMAL_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_bicgstab(les, 100, 0.1e-8); N_print_les(les); N_free_les(les); /*GAUSS*/ les = N_assemble_les_2d(N_NORMAL_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_gauss(les); N_print_les(les); N_free_les(les); /*LU*/ les = N_assemble_les_2d(N_NORMAL_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_lu(les); N_print_les(les); N_free_les(les); N_free_solute_transport_data2d(data); G_free(geom); G_free(call); return 0; }
/* *************************************************************** */ int test_solute_transport_3d(void) { N_solute_transport_data3d *data; N_geom_data *geom; N_les *les; N_les_callback_3d *call; call = N_alloc_les_callback_3d(); N_set_les_callback_3d_func(call, (*N_callback_solute_transport_3d)); /*solute_transport 3d */ data = create_solute_transport_data_3d(); N_calc_solute_transport_disptensor_3d(data); data->dt = 86400; geom = N_alloc_geom_data(); geom->dx = 10; geom->dy = 15; geom->dz = 3; geom->Az = 150; geom->depths = TEST_N_NUM_DEPTHS_LOCAL; geom->rows = TEST_N_NUM_ROWS_LOCAL; geom->cols = TEST_N_NUM_COLS_LOCAL; /*Assemble the matrix */ /* */ /*Jacobi */ les = N_assemble_les_3d(N_SPARSE_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_jacobi(les, 100, 1, 0.1e-8); N_print_les(les); N_free_les(les); /*jacobi */ les = N_assemble_les_3d(N_NORMAL_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_jacobi(les, 100, 1, 0.1e-8); N_print_les(les); N_free_les(les); /*SOR*/ les = N_assemble_les_3d(N_SPARSE_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_SOR(les, 100, 1, 0.1e-8); N_print_les(les); N_free_les(les); /*SOR*/ les = N_assemble_les_3d(N_NORMAL_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_SOR(les, 100, 1, 0.1e-8); N_print_les(les); N_free_les(les); /*BICG*/ les = N_assemble_les_3d(N_SPARSE_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_bicgstab(les, 100, 0.1e-8); N_print_les(les); N_free_les(les); /*BICG*/ les = N_assemble_les_3d(N_NORMAL_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_bicgstab(les, 100, 0.1e-8); N_print_les(les); N_free_les(les); /*GUASS*/ les = N_assemble_les_3d(N_NORMAL_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_gauss(les); N_print_les(les); N_free_les(les); /*LU*/ les = N_assemble_les_3d(N_NORMAL_LES, geom, data->status, data->c_start, (void *)data, call); N_solver_lu(les); N_print_les(les); N_free_les(les); N_free_solute_transport_data3d(data); G_free(geom); G_free(call); return 0; }
/*! * \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; }