Skip to content
Snippets Groups Projects
grid-id.h 7.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • Debolskiy Andrey's avatar
    Debolskiy Andrey committed
    #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);
    }
    // -------------------------------------------------------------------------------------------- //