diff options
Diffstat (limited to 'src/patch/patch_system.cc')
-rw-r--r-- | src/patch/patch_system.cc | 702 |
1 files changed, 684 insertions, 18 deletions
diff --git a/src/patch/patch_system.cc b/src/patch/patch_system.cc index 98974e6..bbd29f7 100644 --- a/src/patch/patch_system.cc +++ b/src/patch/patch_system.cc @@ -30,6 +30,8 @@ // // patch_system::set_gridfn_to_constant // patch_system::gridfn_copy +// patch_system::ghosted_gridfn_copy +// patch_system::add_to_gridfn // patch_system::add_to_ghosted_gridfn // patch_system::gridfn_norms // patch_system::ghosted_gridfn_norms @@ -39,9 +41,11 @@ // // patch_system::patch_containing_local_xyz // patch_system::radius_in_local_xyz_direction +// patch_system::radii_in_local_xyz_directions // // patch_system::print_unknown_gridfn // patch_system::read_unknown_gridfn +// patch_system::output_unknown_gridfn // // patch_system::synchronize // patch_system::compute_synchronize_Jacobian @@ -51,20 +55,37 @@ /// patch_system::ghost_zone_Jacobian // +#include <assert.h> #include <stdio.h> #include <math.h> #include <string.h> #include <assert.h> #include <limits.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <vector> +#include <sstream> +#include <string> #include "cctk.h" +#include "CactusBase/IOUtil/src/ioGH.h" #include "config.h" #include "stdc.h" +#include "../gr/gfns.hh" #include "../jtutil/util.hh" #include "../jtutil/array.hh" #include "../jtutil/cpm_map.hh" #include "../jtutil/linear_map.hh" +using jtutil::error_exit; + +#ifdef CCTK_HDF5 +// Some macros to fix compatibility issues as long as 1.8.0 is in beta +// phase +# define H5_USE_16_API 1 +# include <hdf5.h> +#endif #include "coords.hh" #include "grid.hh" @@ -80,7 +101,6 @@ // all the code in this file is inside this namespace namespace AHFinderDirect { -using jtutil::error_exit; //****************************************************************************** //****************************************************************************** @@ -325,12 +345,13 @@ delete[] ghosted_gridfn_storage_; delete[] gridfn_storage_; delete[] ghosted_starting_gpn_; delete[] starting_gpn_; -delete[] all_patches_; for (int pn = N_patches()-1 ; pn >= 0 ; --pn) { delete &ith_patch(pn); } + +delete[] all_patches_; } //****************************************************************************** @@ -342,6 +363,8 @@ delete[] all_patches_; // of this patch system. This function also correctly sets // N_grid_points_ // N_ghosted_grid_points_ +// max_N_additional_points_ +// N_additional_points_ // all_patches_[] // starting_gpn_[] // ghosted_starting_gpn_[] @@ -353,6 +376,9 @@ void patch_system::create_patches(const struct patch_info patch_info_in[], int N_zones_per_right_angle, bool print_msg_flag) { +max_N_additional_points_ = 1; +// N_additional_points_ = 0; +N_additional_points_ = 1; N_grid_points_ = 0; ghosted_N_grid_points_ = 0; for (int pn = 0 ; pn < N_patches() ; ++pn) @@ -461,8 +487,8 @@ const int N_gridfns_in = jtutil::how_many_in_range(min_gfn_in, max_gfn_in); const int ghosted_N_gridfns_in = jtutil::how_many_in_range(ghosted_min_gfn_in, ghosted_max_gfn_in); -const int gfn_stride = N_grid_points(); -const int ghosted_gfn_stride = ghosted_N_grid_points(); +const int gfn_stride = N_grid_points() + max_N_additional_points(); +const int ghosted_gfn_stride = ghosted_N_grid_points() + max_N_additional_points(); const int N_storage = gfn_stride * N_gridfns_in; const int ghosted_N_storage = ghosted_gfn_stride * ghosted_N_gridfns_in; @@ -531,7 +557,7 @@ const patch& plast = ith_patch(N_patches()-1); const fp* const gfn1_first_ptr = & pfirst.gridfn(gfn+1, pfirst.min_irho(), pfirst.min_isigma()); - if (! (gfn1_first_ptr == gfn_last_ptr+1)) + if (! (gfn1_first_ptr == gfn_last_ptr+max_N_additional_points()+1)) then error_exit(PANIC_EXIT, "***** patch_system::setup_gridfn_storage():\n" " nominal-grid gridfns don't partition overall storage array!" @@ -561,7 +587,7 @@ const patch& plast = ith_patch(N_patches()-1); = & pfirst.ghosted_gridfn(ghosted_gfn+1, pfirst.ghosted_min_irho(), pfirst.ghosted_min_isigma()); - if (! (ghosted_gfn1_first_ptr == ghosted_gfn_last_ptr+1)) + if (! (ghosted_gfn1_first_ptr == ghosted_gfn_last_ptr+max_N_additional_points()+1)) then error_exit(PANIC_EXIT, "***** patch_system::setup_gridfn_storage():\n" " ghosted-grid gridfns don't partition overall storage array!" @@ -635,7 +661,7 @@ const patch& plast = ith_patch(N_patches()-1); if (! (p1_first_ptr == p_last_ptr+1)) then error_exit(PANIC_EXIT, "***** patch_system::setup_gridfn_storage():\n" -" nominal-grid patches gridfns don't partition storage for gfn=%d!\n" +" ghosted-grid patches gridfns don't partition storage for gfn=%d!\n" " (this should never happen!)\n" " %s patch (pn=%d) last point at p_last_ptr=%p\n" " %s patch (pn=%d) first point at p1_first_ptr=%p\n" @@ -1489,6 +1515,29 @@ void patch_system::set_gridfn_to_constant(fp a, int dst_gfn) //****************************************************************************** // +// This function sets a ghosted gridfn to a constant value. +// +void patch_system::set_ghosted_gridfn_to_constant(fp a, int ghosted_dst_gfn) +{ + for (int pn = 0 ; pn < N_patches() ; ++pn) + { + patch& p = ith_patch(pn); + for (int irho = p.ghosted_min_irho() ; + irho <= p.ghosted_max_irho() ; ++irho) + { + for (int isigma = p.ghosted_min_isigma() ; + isigma <= p.ghosted_max_isigma() ; + ++isigma) + { + p.ghosted_gridfn(ghosted_dst_gfn, irho,isigma) = a; + } + } + } +} + +//****************************************************************************** + +// // This function copies one (nominal-grid) gridfn to another. // void patch_system::gridfn_copy(int src_gfn, int dst_gfn) @@ -1511,6 +1560,78 @@ void patch_system::gridfn_copy(int src_gfn, int dst_gfn) //****************************************************************************** // +// This function copies one ghosted gridfn to another. +// +void patch_system::ghosted_gridfn_copy(int ghosted_src_gfn, + int ghosted_dst_gfn) +{ + for (int pn = 0 ; pn < N_patches() ; ++pn) + { + patch& p = ith_patch(pn); + for (int irho = p.ghosted_min_irho() ; + irho <= p.ghosted_max_irho() ; ++irho) + { + for (int isigma = p.ghosted_min_isigma() ; + isigma <= p.ghosted_max_isigma() ; + ++isigma) + { + p.ghosted_gridfn(ghosted_dst_gfn, irho,isigma) + = p.ghosted_gridfn(ghosted_src_gfn, irho,isigma); + } + } + } +} + +//****************************************************************************** + +// +// This function copies a ghosted gridfn to a nominal gridfn. +// +void patch_system::ghosted_gridfn_copy_to_nominal(int ghosted_src_gfn, + int dst_gfn) +{ + for (int pn = 0 ; pn < N_patches() ; ++pn) + { + patch& p = ith_patch(pn); + for (int irho = p.min_irho() ; irho <= p.max_irho() ; ++irho) + { + for (int isigma = p.min_isigma() ; isigma <= p.max_isigma() ; + ++isigma) + { + p.gridfn(dst_gfn, irho,isigma) + = p.ghosted_gridfn(ghosted_src_gfn, irho,isigma); + } + } + } +} + +//****************************************************************************** + +// +// This function adds a scalar to a (nominal-grid) gridfn. +// +void patch_system::add_to_gridfn(fp delta, int dst_gfn) +{ + for (int pn = 0 ; pn < N_patches() ; ++pn) + { + patch& p = ith_patch(pn); + for (int irho = p.min_irho() ; + irho <= p.max_irho() ; + ++irho) + { + for (int isigma = p.min_isigma() ; + isigma <= p.max_isigma() ; + ++isigma) + { + p.gridfn(dst_gfn, irho,isigma) += delta; + } + } + } +} + +//****************************************************************************** + +// // This function adds a scalar to a ghosted gridfn. // void patch_system::add_to_ghosted_gridfn(fp delta, int ghosted_dst_gfn) @@ -1535,6 +1656,30 @@ void patch_system::add_to_ghosted_gridfn(fp delta, int ghosted_dst_gfn) //****************************************************************************** // +// This function scales a ghosted gridfn with a scalar. +// +void patch_system::scale_ghosted_gridfn(fp factor, int ghosted_dst_gfn) +{ + for (int pn = 0 ; pn < N_patches() ; ++pn) + { + patch& p = ith_patch(pn); + for (int irho = p.ghosted_min_irho() ; + irho <= p.ghosted_max_irho() ; + ++irho) + { + for (int isigma = p.ghosted_min_isigma() ; + isigma <= p.ghosted_max_isigma() ; + ++isigma) + { + p.ghosted_gridfn(ghosted_dst_gfn, irho,isigma) *= factor; + } + } + } +} + +//****************************************************************************** + +// // This function computes norms of a nominal-grid gridfn. // void patch_system::gridfn_norms(int src_gfn, jtutil::norm<fp>& norms) @@ -1757,6 +1902,69 @@ default: return integral; } +fp patch_system::integrate_gridpoint(int unknown_src_gfn, + int ghosted_radius_gfn, + int g_xx_gfn, int g_xy_gfn, int g_xz_gfn, + int g_yy_gfn, int g_yz_gfn, + int g_zz_gfn, + enum patch::integration_method method, + int pn, int irho, int isigma) + const +{ +const patch& p = ith_patch(pn); +const fp val = p.integrate_gridpoint(unknown_src_gfn, + ghosted_radius_gfn, + g_xx_gfn, g_xy_gfn, g_xz_gfn, + g_yy_gfn, g_yz_gfn, + g_zz_gfn, + method, + irho, isigma); + +return val; +} +fp patch_system::integrate_correction(bool src_gfn_is_even_across_xy_plane, + bool src_gfn_is_even_across_xz_plane, + bool src_gfn_is_even_across_yz_plane) + const +{ +fp integral = 1.0; +// +// correct the integral +// for the fact that the patch system may not cover the full 2-sphere +// +switch (type()) + { +case patch_system__full_sphere: + break; +case patch_system__plus_z_hemisphere: + integral *= src_gfn_is_even_across_xy_plane ? 2.0 : 0.0; + break; +case patch_system__plus_xy_quadrant_mirrored: +case patch_system__plus_xy_quadrant_rotating: + integral *= src_gfn_is_even_across_xz_plane ? 2.0 : 0.0; + integral *= src_gfn_is_even_across_yz_plane ? 2.0 : 0.0; + break; +case patch_system__plus_xz_quadrant_mirrored: +case patch_system__plus_xz_quadrant_rotating: + integral *= src_gfn_is_even_across_xy_plane ? 2.0 : 0.0; + integral *= src_gfn_is_even_across_yz_plane ? 2.0 : 0.0; + break; +case patch_system__plus_xyz_octant_mirrored: +case patch_system__plus_xyz_octant_rotating: + integral *= src_gfn_is_even_across_xy_plane ? 2.0 : 0.0; + integral *= src_gfn_is_even_across_xz_plane ? 2.0 : 0.0; + integral *= src_gfn_is_even_across_yz_plane ? 2.0 : 0.0; + break; +default: + error_exit(PANIC_EXIT, +"***** patch_system::integrate_gridfn(): bad patch system type()=(int)%d!\n" +" (this should never happen!)\n", + int(type())); /*NOTREACHED*/ + } + +return integral; +} + //****************************************************************************** //****************************************************************************** //****************************************************************************** @@ -1814,7 +2022,6 @@ else error_exit(ERROR_EXIT, // patch-system symmetries. If the point coincides with the local origin, // we return the dummy value 1.0. // -// Bugs: // Due to the surface-interpolator overhead, repeatedly calling this // function is rather inefficient. // @@ -1940,13 +2147,177 @@ if (status < 0) , status, double(x), double(y), double(z), - p.name(), rho, sigma, + p.name(), double(rho), double(sigma), double(p.drho_of_rho(rho)), double(p.dsigma_of_sigma(sigma))); /*NOTREACHED*/ return xyz_radius; } +struct perpatch { + std::vector<int> n; + std::vector<fp> rho, sigma; + std::vector<fp> radii; + void reserve (int const npoints) + { + n.reserve (npoints); + rho.reserve (npoints); + sigma.reserve (npoints); + radii.reserve (npoints); + } + void addpoint (int const n_, fp const rho_, fp const sigma_) + { + n .push_back (n_); + rho .push_back (rho_); + sigma.push_back (sigma_); + radii.push_back (fp (0.0)); + } +}; + +void patch_system::radii_in_local_xyz_directions(int const ghosted_radius_gfn, + int const npoints, + fp const * const xp, + fp const * const yp, + fp const * const zp, + fp * const radii) + const +{ + std::vector<perpatch> patchpoints (N_patches()); + for (int pn=0; pn<N_patches(); ++pn) { + patchpoints.at(pn).reserve (npoints); + } + + for (int n=0; n<npoints; ++n) { + fp x = xp[n]; + fp y = yp[n]; + fp z = zp[n]; + + if ((x == 0.0) && (y == 0.0) && (z == 0.0)) { + radii[n] = 1.0; + } else { + // + // apply symmetries to map (x,y,z) into that part of the + // 2-sphere which is covered by the patch system + // + switch (type()) + { + case patch_system__full_sphere: + break; + case patch_system__plus_z_hemisphere: + z = fabs(z); + break; + case patch_system__plus_xy_quadrant_mirrored: + case patch_system__plus_xy_quadrant_rotating: + x = fabs(x); + y = fabs(y); + break; + case patch_system__plus_xz_quadrant_mirrored: + case patch_system__plus_xz_quadrant_rotating: + x = fabs(x); + z = fabs(z); + break; + case patch_system__plus_xyz_octant_mirrored: + case patch_system__plus_xyz_octant_rotating: + x = fabs(x); + y = fabs(y); + z = fabs(z); + break; + default: + error_exit(PANIC_EXIT, +"***** patch_system::radii_in_local_xyz_directions():\n" +" unknown patch system type()=(int)%d!\n" +" (this should never happen!)\n", + int(type())); /*NOTREACHED*/ + } + + const patch* p_ptr = patch_containing_local_xyz(x, y, z); + if (p_ptr == NULL) + then error_exit(ERROR_EXIT, +"***** patch_system::radius_in_local_xyz_direction():\n" +" can't find containing patch!\n" +" (this should never happen!)\n" +" [local] (x,y,z)=(%g,%g,%g)\n" + , + double(x), double(y), double(z)); /*NOTREACHED*/ + + const patch& p = *p_ptr; + const fp rho = p. rho_of_xyz(x,y,z); + const fp sigma = p.sigma_of_xyz(x,y,z); + + patchpoints.at(p.patch_number()).addpoint (n, rho, sigma); + } + } // for n + + for (int pn=0; pn<N_patches(); ++pn) { + const patch& p = ith_patch(pn); + perpatch& localpatchpoints = patchpoints.at(pn); + + // Set up the surface interpolator to interpolate the surface + // radius gridfn to the (rho,sigma) coordinates: + // + // Notes on the interpolator setup: + // * The interpolator assumes Fortran subscripting, so we take the + // coordinates in the order (sigma,rho) to match our C + // subscripting in the patch system. + // * To avoid having to set up min/max array subscripts in the + // parameter table, we treat the patch as using 0-origin + // (integer) array subscripts (irho - ghosted_min_irho(), isigma + // - ghosted_min_isigma()). However, we use the usual + // floating-point coordinates. + // + + const int N_dims = 2; + const CCTK_REAL coord_origin[N_dims] + = { p.ghosted_min_sigma(), p.ghosted_min_rho() }; + const CCTK_REAL coord_delta[N_dims] + = { p.delta_sigma(), p.delta_rho() }; + + const int N_interp_points = localpatchpoints.radii.size(); + const int interp_coords_type_code = CCTK_VARIABLE_REAL; + const void* const interp_coords[N_dims] + = { static_cast<const void*>(& localpatchpoints.sigma.front()), + static_cast<const void*>(& localpatchpoints.rho .front()) }; + + const int N_input_arrays = 1; + const CCTK_INT input_array_dims[N_dims] + = { p.ghosted_N_isigma(), p.ghosted_N_irho() }; + const CCTK_INT input_array_type_codes[N_input_arrays] + = { CCTK_VARIABLE_REAL }; + const void* const input_arrays[N_input_arrays] + = { static_cast<const void*> + (p.ghosted_gridfn_data_array(ghosted_radius_gfn)) }; + + const int N_output_arrays = 1; + const CCTK_INT output_array_type_codes[N_output_arrays] + = { CCTK_VARIABLE_REAL }; + void* const output_arrays[N_output_arrays] + = { static_cast<void*>(& localpatchpoints.radii.front()) }; + + const int status = CCTK_InterpLocalUniform + (N_dims, + surface_interp_handle_, + surface_interp_par_table_handle_, + coord_origin, coord_delta, + N_interp_points, + interp_coords_type_code, interp_coords, + N_input_arrays, + input_array_dims, input_array_type_codes, input_arrays, + N_output_arrays, + output_array_type_codes, output_arrays); + if (status < 0) + then error_exit(ERROR_EXIT, +"***** patch_system::radii_in_local_xyz_directions():\n" +" error return (status=%d) from surface interpolator!\n" + , + status); /*NOTREACHED*/ + + for (size_t nn=0; nn<localpatchpoints.radii.size(); ++nn) { + radii[localpatchpoints.n.at(nn)] = localpatchpoints.radii.at(nn); + } + + } // for p +} + //****************************************************************************** //****************************************************************************** //****************************************************************************** @@ -2034,8 +2405,9 @@ fprintf(output_fp, "\n"); const fp dpy = p.dpy_of_rho_sigma(rho, sigma); fprintf(output_fp, "%g\t%g\t%#.15g", - dpx, dpy, p.unknown_gridfn(ghosted_flag, - unknown_gfn, irho,isigma)); + double(dpx), double(dpy), + double(p.unknown_gridfn(ghosted_flag, + unknown_gfn, irho,isigma))); if (print_xyz_flag) then { const fp r = p.unknown_gridfn(radius_is_ghosted_flag, @@ -2049,7 +2421,8 @@ fprintf(output_fp, "\n"); const fp global_z = origin_z() + local_z; fprintf(output_fp, "\t%#.10g\t%#.10g\t%#.10g", - global_x, global_y, global_z); + double(global_x), double(global_y), + double(global_z)); } fprintf(output_fp, "\n"); } @@ -2122,12 +2495,13 @@ int line_number = 1; " dpx=%g dpy=%g\n" , p.name(), unknown_gfn, - irho, p.effective_min_irho(want_ghost_zones), - p.effective_max_irho(want_ghost_zones), - isigma, + int(irho), + p.effective_min_irho(want_ghost_zones), + p.effective_max_irho(want_ghost_zones), + int(isigma), p.effective_min_isigma(want_ghost_zones), p.effective_max_isigma(want_ghost_zones), - dpx, dpy); /*NOTREACHED*/ + double(dpx), double(dpy)); /*NOTREACHED*/ ++line_number; } while ((buffer[0] == '#') || (buffer[0] == '\n')); @@ -2150,8 +2524,8 @@ int line_number = 1; , p.name(), unknown_gfn, line_number, - dpx, dpy, - read_dpx, read_dpy); /*NOTREACHED*/ + double(dpx), double(dpy), + double(read_dpx), double(read_dpy)); /*NOTREACHED*/ p.unknown_gridfn(ghosted_flag, unknown_gfn, irho,isigma) = read_gridfn_value; @@ -2164,6 +2538,298 @@ fclose(input_fp); } //****************************************************************************** + +#ifdef CCTK_HDF5 + +static void WriteAttribute (const hid_t dataset, const char* name, char value); +static void WriteAttribute (const hid_t dataset, const char* name, const char* values); +static void WriteAttribute (const hid_t dataset, const char* name, const char* values, int nvalues); + +static void WriteAttribute (const hid_t dataset, const char* const name, const char value) +{ + WriteAttribute (dataset, name, &value, 1); +} + +static void WriteAttribute (const hid_t dataset, const char* const name, const char* const values) +{ + WriteAttribute (dataset, name, values, strlen(values)); +} + +static void WriteAttribute (const hid_t dataset, const char* const name, const char* const values, const int nvalues) +{ + assert (dataset>=0); + assert (name); + assert (values); + assert (nvalues>=0); + + herr_t herr; + + const hid_t dataspace = H5Screate (H5S_SCALAR); + assert (dataspace>=0); + + const hid_t datatype = H5Tcopy (H5T_C_S1); + assert (datatype>=0); + herr = H5Tset_size (datatype, nvalues); + assert (!herr); + + const hid_t attribute = H5Acreate (dataset, name, datatype, dataspace, H5P_DEFAULT); + assert (attribute>=0); + herr = H5Awrite (attribute, datatype, values); + assert (!herr); + herr = H5Aclose (attribute); + assert (!herr); + + herr = H5Tclose (datatype); + assert (!herr); + + herr = H5Sclose (dataspace); + assert (!herr); +} + +#endif + +// +// This function output an unknown-grid gridfn in HDF5 format to a +// named output file. +// +void patch_system::output_unknown_gridfn + (bool ghosted_flag, int unknown_gfn, + const char gfn_name[], const cGH *cctkGH, + bool output_xyz_flag, bool radius_is_ghosted_flag, + int unknown_radius_gfn, + const char output_file_name[], bool want_ghost_zones) + const +{ +if (want_ghost_zones && !ghosted_flag) + then error_exit(PANIC_EXIT, +"***** patch_system::output_unknown_gridfn(unknown_gfn=%d):\n" +" can't have want_ghost_zones && !ghosted_flag !\n" +, + unknown_gfn); /*NOTREACHED*/ +if (want_ghost_zones && output_xyz_flag && !radius_is_ghosted_flag) + then error_exit(PANIC_EXIT, +"***** patch_system::output_unknown_gridfn(unknown_gfn=%d):\n" +" can't have want_ghost_zones && output_xyz_flag\n" +" && !radius_is_ghosted_flag!\n" +" unknown_radius_gfn=%d\n" +, + unknown_gfn, + unknown_radius_gfn); /*NOTREACHED*/ + +#ifdef CCTK_HDF5 + + using std::ostringstream; + using std::string; + using std::vector; + + herr_t herr; + + hid_t writer; + + // Get grid hierarchy extentsion from IOUtil + const ioGH * const iogh = (const ioGH *)CCTK_GHExtension (cctkGH, "IO"); + assert (iogh); + + struct stat fileinfo; + if (! iogh->recovered || stat(output_file_name, &fileinfo) != 0) { + writer = H5Fcreate (output_file_name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + } else { + writer = H5Fopen (output_file_name, H5F_ACC_RDWR, H5P_DEFAULT); + } + assert (writer >= 0); + + hid_t datatype; + if (sizeof(fp) == sizeof(float)) { + datatype = H5T_NATIVE_FLOAT; + } else if (sizeof(fp) == sizeof(double)) { + datatype = H5T_NATIVE_DOUBLE; + } else if (sizeof(fp) == sizeof(long double)) { + datatype = H5T_NATIVE_LDOUBLE; + } else { + assert (0); + } + assert (datatype >= 0); + + for (int pn=0; pn<N_patches(); ++pn) { + const patch& p = ith_patch(pn); + + hsize_t shape[2]; + shape[0] = p.effective_N_isigma(want_ghost_zones); + shape[1] = p.effective_N_irho(want_ghost_zones); + + hid_t dataspace = H5Screate_simple (2, shape, NULL); + assert (dataspace >= 0); + + + + ostringstream datasetnamebuf; + datasetnamebuf << gfn_name + << " it=" << cctkGH->cctk_iteration + << " patch=" << pn; + string datasetnamestr = datasetnamebuf.str(); + assert (datasetnamestr.size() <= 256); // limit dataset name length + const char * const datasetname = datasetnamestr.c_str(); + assert (datasetname); + + ostringstream datasetnamebufx; + datasetnamebufx << "x" + << " it=" << cctkGH->cctk_iteration + << " patch=" << pn; + string datasetnamestrx = datasetnamebufx.str(); + assert (datasetnamestrx.size() <= 256); // limit dataset name length + const char * const datasetnamex = datasetnamestrx.c_str(); + assert (datasetnamex); + + ostringstream datasetnamebufy; + datasetnamebufy << "y" + << " it=" << cctkGH->cctk_iteration + << " patch=" << pn; + string datasetnamestry = datasetnamebufy.str(); + assert (datasetnamestry.size() <= 256); // limit dataset name length + const char * const datasetnamey = datasetnamestry.c_str(); + assert (datasetnamey); + + ostringstream datasetnamebufz; + datasetnamebufz << "z" + << " it=" << cctkGH->cctk_iteration + << " patch=" << pn; + string datasetnamestrz = datasetnamebufz.str(); + assert (datasetnamestrz.size() <= 256); // limit dataset name length + const char * const datasetnamez = datasetnamestrz.c_str(); + assert (datasetnamez); + + + + hid_t dataset = H5Dcreate (writer, datasetname, datatype, dataspace, H5P_DEFAULT); + assert (dataset >= 0); + + hid_t datasetx; + hid_t datasety; + hid_t datasetz; + if (output_xyz_flag) { + + datasetx = H5Dcreate (writer, datasetnamex, datatype, dataspace, H5P_DEFAULT); + assert (datasetx >= 0); + + datasety = H5Dcreate (writer, datasetnamey, datatype, dataspace, H5P_DEFAULT); + assert (datasety >= 0); + + datasetz = H5Dcreate (writer, datasetnamez, datatype, dataspace, H5P_DEFAULT); + assert (datasetz >= 0); + + } // if output_xyf_flag + + + + vector<fp> tmpdata; + vector<fp> tmpx, tmpy, tmpz; + tmpdata.resize (shape[0] * shape[1]); + if (output_xyz_flag) { + tmpx.resize (shape[0] * shape[1]); + tmpy.resize (shape[0] * shape[1]); + tmpz.resize (shape[0] * shape[1]); + } + + int elt = 0; + for (int irho = p.effective_min_irho(want_ghost_zones); + irho <= p.effective_max_irho(want_ghost_zones); + ++irho) + { + for (int isigma = p.effective_min_isigma(want_ghost_zones); + isigma <= p.effective_max_isigma(want_ghost_zones); + ++isigma) + { + + tmpdata.at(elt) = p.unknown_gridfn (ghosted_flag, unknown_gfn, irho,isigma); + if (output_xyz_flag) { + const fp r = p.unknown_gridfn(radius_is_ghosted_flag, + unknown_radius_gfn, + irho,isigma); + const fp rho = p.rho_of_irho(irho); + const fp sigma = p.sigma_of_isigma(isigma); + fp local_x, local_y, local_z; + p.xyz_of_r_rho_sigma(r,rho,sigma, + local_x,local_y,local_z); + const fp global_x = origin_x() + local_x; + const fp global_y = origin_y() + local_y; + const fp global_z = origin_z() + local_z; + tmpx.at(elt) = global_x; + tmpy.at(elt) = global_y; + tmpz.at(elt) = global_z; + } + ++elt; + + } + } + + + + herr = H5Dwrite (dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &tmpdata.front()); + assert (! herr); + + WriteAttribute (dataset, "name", gfn_name); + + herr = H5Dclose (dataset); + assert (! herr); + + + + if (output_xyz_flag) { + + herr = H5Dwrite (datasetx, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &tmpx.front()); + assert (! herr); + + WriteAttribute (datasetx, "name", "x"); + + herr = H5Dclose (datasetx); + assert (! herr); + + + + herr = H5Dwrite (datasety, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &tmpy.front()); + assert (! herr); + + WriteAttribute (datasety, "name", "y"); + + herr = H5Dclose (datasety); + assert (! herr); + + + + herr = H5Dwrite (datasetz, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &tmpz.front()); + assert (! herr); + + WriteAttribute (datasetz, "name", "z"); + + herr = H5Dclose (datasetz); + assert (! herr); + + } // if output_xyz_flag + + + + herr = H5Sclose (dataspace); + assert (! herr); + + } // for pn + + + + herr = H5Fclose (writer); + assert (! herr); + +#else + error_exit(ERROR_EXIT, +"***** patch_system::output_unknown_gridfn(unknown_gfn=%d):\n" +" no HDF5 support compiled in. Cannot write output file \"%s\"\n!" +, + unknown_gfn, + output_file_name); /*NOTREACHED*/ + +#endif +} + +//****************************************************************************** //****************************************************************************** //****************************************************************************** |