#pragma once // [grid-id.h]: grid data identifier // // -------------------------------------------------------------------------------------------- // #include "nse-sys.h" #include "mpi-com.h" #include <string.h> #ifdef USE_CXX_11 #include <initializer_list> #endif //#define _USE_DEPRECATED_WST_FORMAT namespace nse { enum maskType { solidCell = 0, fluidCell = 1, externalCell = 2 }; template< typename T > class GridId { public: GridId(); GridId(const GridId& id); ~GridId(); void init(); // initialize id // set: void set_grid_type(const int grid_type); void set_dim_num(const int ndim); void set_domain_dim(const int dim, const T x, const T length); void set_grid_dim(const int dim, const int nx, const int gcx); void reset_data_type_size(); // to: [sizeof(T)] // set specs: #ifdef USE_CXX_11 void set_domain_specs(const std::initializer_list<T> specs); void set_grid_specs(const std::initializer_list<int> specs); #else void set_domain_specs(int nspecs, const T* specs); void set_grid_specs(int nspecs, const int* specs); #endif // header: int key() const; int grid_type() const; int dim_num() const; int data_type_size() const; // get grid, domain by dim: void domain_dim(const int dim, T* x, T* length) const; void grid_dim(const int dim, int* nx, int* gcx) const; // get specs: T domain_spec(int idx) const; int grid_spec(int idx) const; // check id based on header values and input num dims bool check(const int ndim) const; // broadcast GridId object on communicator void mpi_broadcast(const int host, const MPI_Comm comm); // ------------------------------------------------------------------------------------ // // static constants // ------------------------------------------------------------------------------------ // static const int max_dim = 3; // using <3> to comply with WST-format static const int hsize = 4; static const int dsize = 24; static const int gsize = 24; static const int id_byte_size = hsize * sizeof(int) + dsize * sizeof(T) + gsize * sizeof(int); // static constants (read 3D data only), switch: comply with WST-format // ------------------------------------------------------------------------------------ // #ifndef _USE_DEPRECATED_WST_FORMAT static const int hsize_r3d = hsize; static const int dsize_r3d = dsize; static const int gsize_r3d = gsize; #else static const int hsize_r3d = 4; static const int dsize_r3d = 7; static const int gsize_r3d = 6; #endif static const int id_byte_size_r3d = hsize_r3d * sizeof(int) + dsize_r3d * sizeof(T) + gsize_r3d * sizeof(int); public: // data triple [header,domain,grid] // ------------------------------------------------------------------------------------ // int header[hsize]; T domain[dsize]; int grid[gsize]; }; } // Implementation // -------------------------------------------------------------------------------------------- // template< typename T > nse::GridId<T>::GridId() { memset(header, 0, GridId<T>::hsize * sizeof(int)); memset(domain, 0, GridId<T>::dsize * sizeof(T)); memset(grid, 0, GridId<T>::gsize * sizeof(int)); } template< typename T > nse::GridId<T>::GridId(const GridId& id) { memcpy(header, id.header, GridId<T>::hsize * sizeof(int)); memcpy(domain, id.domain, GridId<T>::dsize * sizeof(T)); memcpy(grid, id.grid, GridId<T>::gsize * sizeof(int)); } template< typename T > nse::GridId<T>::~GridId() { } template< typename T > void nse::GridId<T>::init() { memset(header, 0, GridId<T>::hsize * sizeof(int)); memset(domain, 0, GridId<T>::dsize * sizeof(T)); memset(grid, 0, GridId<T>::gsize * sizeof(int)); header[0] = 'n' + 's' + 'e'; // file identifier // header[3] = sizeof(T); // data type size // } template< typename T > void nse::GridId<T>::set_grid_type(const int grid_type) { if (grid_type >= 0) header[1] = grid_type; } template< typename T > void nse::GridId<T>::set_dim_num(const int ndim) { if ((ndim <= 0) || (ndim > max_dim)) return; header[2] = ndim; } template< typename T > void nse::GridId<T>::set_domain_dim(const int dim, const T x, const T length) { if ((dim <= 0) || (dim > dim_num())) return; domain[dim - 1] = x; domain[max_dim + dim - 1] = length; } template< typename T > void nse::GridId<T>::set_grid_dim(const int dim, const int nx, const int gcx) { if ((dim <= 0) || (dim > dim_num())) return; grid[dim - 1] = nx; grid[max_dim + dim - 1] = gcx; } template< typename T > void nse::GridId<T>::reset_data_type_size() { header[3] = sizeof(T); } #ifdef USE_CXX_11 template< typename T > void nse::GridId<T>::set_domain_specs(const std::initializer_list<T> specs) { int ptr = 2 * max_dim; for (auto sp : specs) { domain[ptr] = sp; ptr++; if (ptr >= GridId<T>::dsize) break; } } template< typename T > void nse::GridId<T>::set_grid_specs(const std::initializer_list<int> specs) { int ptr = 2 * max_dim; for (auto sp : specs) { grid[ptr] = sp; ptr++; if (ptr >= GridId<T>::gsize) break; } } #else template< typename T > void nse::GridId<T>::set_domain_specs(int nspecs, const T* specs) { const int ptr = 2 * max_dim; for (int k = 0; k < nspecs; k++) { if (ptr + k >= GridId<T>::dsize) break; domain[ptr + k] = specs[k]; } } template< typename T > void nse::GridId<T>::set_grid_specs(int nspecs, const int* specs) { const int ptr = 2 * max_dim; for (int k = 0; k < nspecs; k++) { if (ptr + k >= GridId<T>::gsize) break; grid[ptr + k] = specs[k]; } } #endif template< typename T > inline int nse::GridId<T>::key() const { return header[0]; } template< typename T > inline int nse::GridId<T>::grid_type() const { return header[1]; } template< typename T > inline int nse::GridId<T>::dim_num() const { return header[2]; } template< typename T > inline int nse::GridId<T>::data_type_size() const { return header[3]; } template< typename T > void nse::GridId<T>::domain_dim(const int dim, T* x, T* length) const { if ((dim <= 0) || (dim > dim_num())) return; (*x) = domain[dim - 1]; (*length) = domain[max_dim + dim - 1]; } template< typename T > void nse::GridId<T>::grid_dim(const int dim, int* nx, int* gcx) const { if ((dim <= 0) || (dim > dim_num())) return; (*nx) = grid[dim - 1]; (*gcx) = grid[max_dim + dim - 1]; } template< typename T > T nse::GridId<T>::domain_spec(int idx) const { return domain[2 * max_dim + idx]; } template< typename T > int nse::GridId<T>::grid_spec(int idx) const { return grid[2 * max_dim + idx]; } template< typename T > bool nse::GridId<T>::check(const int ndim) const { return ( (key() == 'n' + 's' + 'e') && // file identifier (dim_num() == ndim) && // dims - strict ((data_type_size() == sizeof(float)) || (data_type_size() == sizeof(double))) // appropriate data type ); } template< typename T > void nse::GridId<T>::mpi_broadcast(const int host, const MPI_Comm comm) { nse::mpi_broadcast(header, GridId<T>::hsize, host, comm); nse::mpi_broadcast(domain, GridId<T>::dsize, host, comm); nse::mpi_broadcast(grid, GridId<T>::gsize, host, comm); } // -------------------------------------------------------------------------------------------- //