inmost_data.h 44.4 KB
Newer Older
Kirill Terekhov's avatar
Kirill Terekhov committed
1 2 3 4 5 6 7
#ifndef INMOST_DATA_H_INCLUDED
#define INMOST_DATA_H_INCLUDED

#include "inmost_common.h"
#if defined(USE_AUTODIFF)
#include "inmost_expression.h"
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
8
#include "inmost_dense.h"
Kirill Terekhov's avatar
Kirill Terekhov committed
9 10 11 12 13 14

#if defined(USE_MESH)


namespace INMOST
{
Kirill Terekhov's avatar
Kirill Terekhov committed
15
	class Mesh;
Kirill Terekhov's avatar
Kirill Terekhov committed
16 17 18 19 20 21 22 23 24
	class Storage;
	class Element;
	class TagManager;
	class Node;
	class Edge;
	class Face;
	class Cell;
	class ElementSet;

Kirill Terekhov's avatar
Kirill Terekhov committed
25 26
	//////////////////////////////////////////////////////////////////////////////////////////////////
	// ElementType
Kirill Terekhov's avatar
Kirill Terekhov committed
27 28 29 30 31 32 33 34 35
  
	typedef INMOST_DATA_BULK_TYPE ElementType;
	static const ElementType NONE = 0x00;
	static const ElementType NODE = 0x01;
	static const ElementType EDGE = 0x02;
	static const ElementType FACE = 0x04;
	static const ElementType CELL = 0x08;
	static const ElementType ESET = 0x10;
	static const ElementType MESH = 0x20;
Kirill Terekhov's avatar
Kirill Terekhov committed
36
#define NUM_ELEMENT_TYPS 6
Kirill Terekhov's avatar
Kirill Terekhov committed
37

Kirill Terekhov's avatar
Kirill Terekhov committed
38
	__INLINE bool                         OneType             (ElementType t) {return t > 0 && (t & (t-1)) == 0;}
39 40 41 42 43 44 45 46 47 48 49
	__INLINE ElementType                  FirstElementType    () {return NODE;}
	__INLINE ElementType                  LastElementType     () {return MESH << 1;}
	__INLINE ElementType                  NextElementType     (ElementType etype) {return etype << 1;}
	__INLINE ElementType                  PrevElementType     (ElementType etype) {return etype >> 1;}
	__INLINE ElementType                  ElementTypeFromDim  (INMOST_DATA_INTEGER_TYPE dim) {return 1 << dim;}
	const char *                          ElementTypeName     (ElementType t); //mesh.cpp
	__INLINE INMOST_DATA_INTEGER_TYPE     ElementNum          (ElementType t)
	{
		unsigned int v = static_cast<unsigned int>(t);  // 32-bit value to find the log2 of 
		//static const unsigned int b[] = {0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000};
		static const unsigned int b[] = {0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0};
50
		unsigned int r = (v & b[0]) != 0;
51 52 53 54 55 56 57
		//r |= ((v & b[4]) != 0) << 4;
		//r |= ((v & b[3]) != 0) << 3;
		r |= ((v & b[2]) != 0) << 2;
		r |= ((v & b[1]) != 0) << 1;
		return static_cast<INMOST_DATA_INTEGER_TYPE>(r);
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
58 59
	//////////////////////////////////////////////////////////////////////////////////////////////////
	// MarkerType
Kirill Terekhov's avatar
Kirill Terekhov committed
60
  
Kirill Terekhov's avatar
Kirill Terekhov committed
61
	/// Low 8 bits - marker mask, rest high bits - position of marker.
Kirill Terekhov's avatar
Kirill Terekhov committed
62
	typedef INMOST_DATA_ENUM_TYPE         MarkerType; 
Kirill Terekhov's avatar
Kirill Terekhov committed
63
	/// Number of chars to hold all markers, total number (MarkerFields * bits_per_char).
Kirill Terekhov's avatar
Kirill Terekhov committed
64
	static const INMOST_DATA_ENUM_TYPE    MarkerFields        = 16;   
Kirill Terekhov's avatar
Kirill Terekhov committed
65 66 67 68 69
	/// Number of chars to hold all private markers, total number (MarkerFields * bits_per_char).
	static const INMOST_DATA_ENUM_TYPE    MarkerFieldsPrivate = 4;
	/// Last bit indicate whether the marker is private.
	static const INMOST_DATA_ENUM_TYPE    MarkerPrivateBit    = 1 << (sizeof(INMOST_DATA_ENUM_TYPE)*8-1); 
	/// Bit mask to obtain marker mask within MarkerType.
Kirill Terekhov's avatar
Kirill Terekhov committed
70
	static const INMOST_DATA_ENUM_TYPE    MarkerMask          = static_cast<INMOST_DATA_BULK_TYPE>(-1); 
Kirill Terekhov's avatar
Kirill Terekhov committed
71
	/// sizeof(char) * bits_per_char.
Kirill Terekhov's avatar
Kirill Terekhov committed
72
	static const INMOST_DATA_ENUM_TYPE    MarkerShift         = sizeof(INMOST_DATA_BULK_TYPE)*8;    
Kirill Terekhov's avatar
Kirill Terekhov committed
73
	__INLINE static bool                  isPrivate           (MarkerType n) {return (n & MarkerPrivateBit) == MarkerPrivateBit;}
74
	__INLINE static MarkerType            InvalidMarker       (){return ENUMUNDEF;}
Kirill Terekhov's avatar
Kirill Terekhov committed
75 76


Kirill Terekhov's avatar
Kirill Terekhov committed
77 78
	//////////////////////////////////////////////////////////////////////////////////////////////////
	// HandleType
Kirill Terekhov's avatar
Kirill Terekhov committed
79

Kirill Terekhov's avatar
Kirill Terekhov committed
80
	typedef INMOST_DATA_ENUM_TYPE         HandleType;
81 82 83 84
	static const INMOST_DATA_ENUM_TYPE    handle_etype_bits   = 3;
	static const INMOST_DATA_ENUM_TYPE    handle_etype_shift  = sizeof(HandleType)*8-handle_etype_bits;
	static const INMOST_DATA_ENUM_TYPE    handle_id_mask      = (1 << handle_etype_shift)-1;

Kirill Terekhov's avatar
Kirill Terekhov committed
85
	static const INMOST_DATA_ENUM_TYPE    chunk_bits_elems    = 13;
86 87 88 89
	static const INMOST_DATA_ENUM_TYPE    chunk_bits_empty    = 8;
	static const INMOST_DATA_ENUM_TYPE    chunk_bits_tags     = 6;
	static const INMOST_DATA_ENUM_TYPE    chunk_bits_dense    = 6;

Kirill Terekhov's avatar
Kirill Terekhov committed
90
	__INLINE HandleType                   InvalidHandle       () {return 0;}
91 92 93 94
	__INLINE INMOST_DATA_INTEGER_TYPE     GetHandleID         (HandleType h) {return (h & handle_id_mask)-1;}
	__INLINE INMOST_DATA_INTEGER_TYPE     GetHandleElementNum (HandleType h) {return h >> handle_etype_shift;}
	__INLINE ElementType                  GetHandleElementType(HandleType h) {return 1 << GetHandleElementNum(h);}
	__INLINE HandleType                   ComposeHandle       (ElementType etype, INMOST_DATA_INTEGER_TYPE ID) {return ID == -1 ? InvalidHandle() : ((ElementNum(etype) << handle_etype_shift) + (1+ID));}
Kirill Terekhov's avatar
Kirill Terekhov committed
95 96 97 98 99
	__INLINE HandleType                   ComposeCellHandle   (INMOST_DATA_INTEGER_TYPE ID) {return ID == -1 ? InvalidHandle() : ((ElementNum(CELL) << handle_etype_shift) + (1+ID));}
	__INLINE HandleType                   ComposeFaceHandle   (INMOST_DATA_INTEGER_TYPE ID) {return ID == -1 ? InvalidHandle() : ((ElementNum(FACE) << handle_etype_shift) + (1+ID));}
	__INLINE HandleType                   ComposeEdgeHandle   (INMOST_DATA_INTEGER_TYPE ID) {return ID == -1 ? InvalidHandle() : ((ElementNum(EDGE) << handle_etype_shift) + (1+ID));}
	__INLINE HandleType                   ComposeNodeHandle   (INMOST_DATA_INTEGER_TYPE ID) {return ID == -1 ? InvalidHandle() : ((ElementNum(NODE) << handle_etype_shift) + (1+ID));}
	__INLINE HandleType                   ComposeSetHandle    (INMOST_DATA_INTEGER_TYPE ID) {return ID == -1 ? InvalidHandle() : ((ElementNum(ESET) << handle_etype_shift) + (1+ID));}
100 101 102
	__INLINE HandleType                   ComposeHandleNum    (INMOST_DATA_INTEGER_TYPE etypenum, INMOST_DATA_INTEGER_TYPE ID) {return ID == -1 ? InvalidHandle() : ((etypenum << handle_etype_shift) + (1+ID));}
	__INLINE bool                         isValidHandle       (HandleType h) {return h != 0;}

Kirill Terekhov's avatar
Kirill Terekhov committed
103 104
	//////////////////////////////////////////////////////////////////////////////////////////////////
	// RemoteElementType
105

Kirill Terekhov's avatar
Kirill Terekhov committed
106 107 108 109 110
	typedef std::pair<Mesh*,HandleType>   RemoteHandleType;
	/// Construct an object of type Element, hande cannot be modified.
	Element                               MakeElement         (const RemoteHandleType & rh); //storage.cpp
	/// Construct an object of type Element, hande can be modified.
	Element                               MakeElementRef      (RemoteHandleType & rh); //storage.cpp
Kirill Terekhov's avatar
Kirill Terekhov committed
111 112
	

Kirill Terekhov's avatar
Kirill Terekhov committed
113

Kirill Terekhov's avatar
Kirill Terekhov committed
114
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
115
	typedef array<variable>               inner_variable_array;
Kirill Terekhov's avatar
Kirill Terekhov committed
116
#endif
117 118
	typedef array<INMOST_DATA_REAL_TYPE>  inner_real_array;
	typedef array<INMOST_DATA_INTEGER_TYPE> 
Kirill Terekhov's avatar
Kirill Terekhov committed
119
		                                  inner_integer_array;
120 121
	typedef array<INMOST_DATA_BULK_TYPE>  inner_bulk_array;
	typedef array<HandleType>             inner_reference_array;
Kirill Terekhov's avatar
Kirill Terekhov committed
122
	typedef array<RemoteHandleType>       inner_remote_reference_array;
Kirill Terekhov's avatar
Kirill Terekhov committed
123 124 125

	enum DataType
	{
126 127 128 129
		DATA_REAL                           = 0, 
		DATA_INTEGER                        = 1, 
		DATA_BULK                           = 2,
		DATA_REFERENCE                      = 3,
Kirill Terekhov's avatar
Kirill Terekhov committed
130
		DATA_REMOTE_REFERENCE               = 4,
Kirill Terekhov's avatar
Kirill Terekhov committed
131
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
132
		DATA_VARIABLE                       = 5
Kirill Terekhov's avatar
Kirill Terekhov committed
133 134 135
#endif
	};

Kirill Terekhov's avatar
Kirill Terekhov committed
136
	///Returns a name of the data type as a string.
137
	const char *                          DataTypeName        (DataType t);
Kirill Terekhov's avatar
Kirill Terekhov committed
138

Kirill Terekhov's avatar
Kirill Terekhov committed
139 140 141 142

	///This class is a data container for class Tag, contains all the necessery information to access
	/// mesh data in class TagManager. It is never exposed to the user directly, should be accessed 
	/// through interface class Tag. Functions are implemented in tag.cpp.
Kirill Terekhov's avatar
Kirill Terekhov committed
143 144 145
	class TagMemory 
	{
	public:
Kirill Terekhov's avatar
Kirill Terekhov committed
146 147 148 149
		///Destructor should not do anything.
		~TagMemory() {}
		///Copy constructor, copies all the data except for m_link. Main purpose is to create an exact 
		/// copy for different mesh, whenever another mesh is created.
Kirill Terekhov's avatar
Kirill Terekhov committed
150
		TagMemory(Mesh * m, const TagMemory & other);
Kirill Terekhov's avatar
Kirill Terekhov committed
151
		///Assignment operator should not be ever used, but is here for convinience.
Kirill Terekhov's avatar
Kirill Terekhov committed
152 153
		TagMemory & operator =(TagMemory const & other);
	private:
Kirill Terekhov's avatar
Kirill Terekhov committed
154
		///Common constructor shouldn't be called from outside.
Kirill Terekhov's avatar
Kirill Terekhov committed
155
		TagMemory();
Kirill Terekhov's avatar
Kirill Terekhov committed
156
		///Position of data in memory for each type of element.
Kirill Terekhov's avatar
Kirill Terekhov committed
157
		INMOST_DATA_ENUM_TYPE pos[NUM_ELEMENT_TYPS]; 
Kirill Terekhov's avatar
Kirill Terekhov committed
158
		///Type of represented data.
Kirill Terekhov's avatar
Kirill Terekhov committed
159
		DataType dtype; 
Kirill Terekhov's avatar
Kirill Terekhov committed
160
		///Specified name for the data.
Kirill Terekhov's avatar
Kirill Terekhov committed
161
		std::string tagname; 
Kirill Terekhov's avatar
Kirill Terekhov committed
162
		///Associated MPI-type for communication.
Kirill Terekhov's avatar
Kirill Terekhov committed
163
		INMOST_MPI_Type bulk_data_type; 
Kirill Terekhov's avatar
Kirill Terekhov committed
164 165
		///Number of entries in each record of the type.
		///May be set to ENUMUNDEF to represent variable-sized arrays.
Kirill Terekhov's avatar
Kirill Terekhov committed
166
		INMOST_DATA_ENUM_TYPE size;
Kirill Terekhov's avatar
Kirill Terekhov committed
167 168 169 170
		///Number of bytes used to represent data type in memory.
		INMOST_DATA_ENUM_TYPE bytes_size;
		///Indicates whether the data is represented as sparse
		/// on certain elements of the mesh.
Kirill Terekhov's avatar
Kirill Terekhov committed
171
		bool sparse[NUM_ELEMENT_TYPS];
Kirill Terekhov's avatar
Kirill Terekhov committed
172
		///Number of bytes used to store data for one element. It is size times bytes_size for data of 
173
		/// fixed size or number of bytes for the structure used to represent data of variable size.
Kirill Terekhov's avatar
Kirill Terekhov committed
174
		INMOST_DATA_ENUM_TYPE record_size;
175 176 177 178 179 180 181
		///Print this tag to files.
		/// Temporary solution for compatibility with external packages.
		/// @see Mesh::SetPrint
		/// @see Mesh::GetPrint
		/// \todo The general solution:
		/// @see Mesh::file_options
		bool print_tag;
Kirill Terekhov's avatar
Kirill Terekhov committed
182
		///Link to the mesh.
Kirill Terekhov's avatar
Kirill Terekhov committed
183
		Mesh * m_link;
184
		///Provide access to interface.
Kirill Terekhov's avatar
Kirill Terekhov committed
185
		friend class Tag;
186
		///For debug purposes only.
Kirill Terekhov's avatar
Kirill Terekhov committed
187 188 189
		friend class Storage;
	};

190 191
	
	///This class provides the access to the individual mesh datum and general information about it.
Kirill Terekhov's avatar
Kirill Terekhov committed
192 193 194
	class Tag //implemented in tag.cpp
	{
	private:
Kirill Terekhov's avatar
Kirill Terekhov committed
195
		///A link to the data for the current instance of the class Tag.
Kirill Terekhov's avatar
Kirill Terekhov committed
196
		TagMemory * mem;
Kirill Terekhov's avatar
Kirill Terekhov committed
197
		///The use of this privite constructor is reserved for TagManager::CreateTag function.
Kirill Terekhov's avatar
Kirill Terekhov committed
198 199 200 201 202 203 204 205
		Tag (Mesh * m,std::string name, DataType _dtype, INMOST_DATA_ENUM_TYPE size); 
		__INLINE INMOST_DATA_ENUM_TYPE GetRecordSize() const;
		__INLINE void SetSize(INMOST_DATA_ENUM_TYPE size);
		__INLINE void SetPosition(INMOST_DATA_ENUM_TYPE pos, ElementType type);
		__INLINE INMOST_DATA_ENUM_TYPE GetPosition(ElementType type) const;
		__INLINE void SetSparse(ElementType type);
		__INLINE INMOST_DATA_ENUM_TYPE GetPositionByDim(INMOST_DATA_ENUM_TYPE typenum) const;
	public:
Kirill Terekhov's avatar
Kirill Terekhov committed
206 207 208
		~Tag();
		Tag();
		Tag(const Tag & other);
Kirill Terekhov's avatar
Kirill Terekhov committed
209 210 211 212 213 214 215
		__INLINE bool operator <(const Tag & other) const;
		__INLINE bool operator >(const Tag & other) const;
		__INLINE bool operator ==(const Tag & other) const;
		__INLINE bool operator !=(const Tag & other) const;
		__INLINE Tag & operator =(Tag const & other);
		__INLINE DataType GetDataType() const;
		__INLINE INMOST_MPI_Type GetBulkDataType() const;
216 217 218
		/// Amount of bytes necessery to support one record
		/// referred by the tag on one element. Used internally
		/// to allocate, manage and copy data of the mesh.
Kirill Terekhov's avatar
Kirill Terekhov committed
219
		__INLINE INMOST_DATA_ENUM_TYPE GetBytesSize() const;
220 221 222
		/// Amount of bytes necessery for one record in packed
		/// form that is used in GetData.
		INMOST_DATA_ENUM_TYPE GetPackedBytesSize() const;
Kirill Terekhov's avatar
Kirill Terekhov committed
223 224 225 226 227 228 229 230 231
		__INLINE INMOST_DATA_ENUM_TYPE GetSize() const;
		__INLINE std::string GetTagName() const;
		__INLINE bool isDefined(ElementType type) const;
		__INLINE bool isSparse(ElementType type) const;
		__INLINE bool isValid() const;
		__INLINE Mesh * GetMeshLink() const;
		__INLINE bool isSparseByDim(INMOST_DATA_INTEGER_TYPE typenum)const;
		__INLINE bool isDefinedByDim(INMOST_DATA_INTEGER_TYPE typenum)const;
		__INLINE void SetBulkDataType(INMOST_MPI_Type type);
232 233
        __INLINE void SetPrint(bool print);
        __INLINE bool GetPrint() const;
Kirill Terekhov's avatar
Kirill Terekhov committed
234 235 236 237
		friend class TagManager;
		friend class Storage;
		friend class Mesh;
	};
Kirill Terekhov's avatar
Kirill Terekhov committed
238 239
	
	
Kirill Terekhov's avatar
Kirill Terekhov committed
240

Kirill Terekhov's avatar
Kirill Terekhov committed
241
	class TagManager //implemented in tag.cpp
Kirill Terekhov's avatar
Kirill Terekhov committed
242 243
	{
	protected:
Kirill Terekhov's avatar
Kirill Terekhov committed
244
		TagManager();
Kirill Terekhov's avatar
Kirill Terekhov committed
245 246 247 248 249
		TagManager(const TagManager & other);
		TagManager & operator = (TagManager const & other);
		typedef chunk_array<INMOST_DATA_ENUM_TYPE,chunk_bits_empty>    empty_data;
		typedef chunk_array<Tag, chunk_bits_tags>                      tag_array_type;
		typedef chunk_bulk_array<chunk_bits_elems>                     dense_sub_type;
250
		typedef chunk_array<dense_sub_type,chunk_bits_dense>           dense_data_array_type;
Kirill Terekhov's avatar
Kirill Terekhov committed
251 252 253 254 255 256 257 258 259
		typedef struct{void * tag, * rec;}                             sparse_sub_record;
		typedef array< sparse_sub_record >                             sparse_sub_type;
		typedef chunk_array< sparse_sub_type,chunk_bits_elems>         sparse_data_array_type;
		typedef chunk_array<INMOST_DATA_INTEGER_TYPE,chunk_bits_elems> back_links_type;
		//typedef std::vector<INMOST_DATA_INTEGER_TYPE>                  back_links_type;
	public:
		typedef tag_array_type::iterator iteratorTag;
	public:
		virtual ~TagManager();
Kirill Terekhov's avatar
Kirill Terekhov committed
260
		/// Check existance of a data tag by it's name.
Kirill Terekhov's avatar
Kirill Terekhov committed
261
		bool HaveTag(std::string name) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
262
		/// Retrive a data tag by it's name.
Kirill Terekhov's avatar
Kirill Terekhov committed
263
		Tag GetTag(std::string name) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
264
		/// Retrive names for all the tags present on the mesh.
Kirill Terekhov's avatar
Kirill Terekhov committed
265
		void ListTagNames(std::vector<std::string> & list) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
266
		/// Create tag with prescribed attributes.
Kirill Terekhov's avatar
Kirill Terekhov committed
267
		Tag CreateTag(Mesh * m, std::string name, DataType dtype, ElementType etype, ElementType sparse, INMOST_DATA_ENUM_TYPE size = ENUMUNDEF); 
Kirill Terekhov's avatar
Kirill Terekhov committed
268
		/// Delete tag from certain elements.
Kirill Terekhov's avatar
Kirill Terekhov committed
269
		virtual Tag DeleteTag(Tag tag, ElementType mask); 
Kirill Terekhov's avatar
Kirill Terekhov committed
270
		/// Check that the tag was defined on certain elements.
Kirill Terekhov's avatar
Kirill Terekhov committed
271 272
		bool ElementDefined(Tag const & tag, ElementType etype) const;
	protected:
Kirill Terekhov's avatar
Kirill Terekhov committed
273
		/// Shrink or enlarge arrays for a dense data.
Kirill Terekhov's avatar
Kirill Terekhov committed
274
		void ReallocateData(const Tag & t, INMOST_DATA_INTEGER_TYPE etypenum,INMOST_DATA_ENUM_TYPE new_size);
Kirill Terekhov's avatar
Kirill Terekhov committed
275
		/// Reallocate all the data for all the tags.
Kirill Terekhov's avatar
Kirill Terekhov committed
276
		void ReallocateData(INMOST_DATA_INTEGER_TYPE etypenum, INMOST_DATA_ENUM_TYPE new_size);
Kirill Terekhov's avatar
Kirill Terekhov committed
277
		///Retrive substructure for representation of the sparse data without permission for modification.
Kirill Terekhov's avatar
Kirill Terekhov committed
278
		__INLINE sparse_sub_type const & GetSparseData(int etypenum, int local_id) const {return sparse_data[etypenum][local_id];}
Kirill Terekhov's avatar
Kirill Terekhov committed
279
		///Retrive substructure for representation of the sparse data.
Kirill Terekhov's avatar
Kirill Terekhov committed
280
		__INLINE sparse_sub_type & GetSparseData(int etypenum, int local_id) {return sparse_data[etypenum][local_id];}
Kirill Terekhov's avatar
Kirill Terekhov committed
281
		///Retrive substructure for representation of the dense data without permission for modification.
Kirill Terekhov's avatar
Kirill Terekhov committed
282
		__INLINE dense_sub_type const & GetDenseData(int pos) const {return dense_data[pos];}
Kirill Terekhov's avatar
Kirill Terekhov committed
283
		///Retrive substructure for representation of the dense data.
Kirill Terekhov's avatar
Kirill Terekhov committed
284
		__INLINE dense_sub_type & GetDenseData(int pos) {return dense_data[pos];}
Kirill Terekhov's avatar
Kirill Terekhov committed
285
		///Copy data from one element to another.
Kirill Terekhov's avatar
Kirill Terekhov committed
286
		static void CopyData(const Tag & t, void * adata, const void * bdata);
Kirill Terekhov's avatar
Kirill Terekhov committed
287
		///Destroy data that represents array of variable size.
Kirill Terekhov's avatar
Kirill Terekhov committed
288 289
		static void DestroyVariableData(const Tag & t, void * adata);
	protected:
Kirill Terekhov's avatar
Kirill Terekhov committed
290 291
		typedef tag_array_type::iterator       tag_iterator; //< Use this type to iterate over tags of the mesh.
		typedef tag_array_type::const_iterator tag_const_iterator; //< Use this type to iterate over tags of the mesh without right for modification.
Kirill Terekhov's avatar
Kirill Terekhov committed
292 293 294 295 296 297 298 299
	protected:
		tag_array_type         tags;
		empty_data             empty_dense_data;
		dense_data_array_type  dense_data;
		sparse_data_array_type sparse_data[NUM_ELEMENT_TYPS];
		back_links_type        back_links[NUM_ELEMENT_TYPS];
	};

Kirill Terekhov's avatar
Kirill Terekhov committed
300
	/// Base class for Mesh, Element, and ElementSet classes.
Kirill Terekhov's avatar
Kirill Terekhov committed
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
	/// This base class is used for the Mesh class, as well as Element classes, and ElementSet class.
	/// 
	/// Storage class is used for representing different data objects in memory.
	/// Each data object is associated with corresponding Tag.
	class Storage //implemented in storage.cpp
	{
	public:
		/// Storage type for representing real values.
		typedef INMOST_DATA_REAL_TYPE       real; 
		/// Storage type for representing integer values.
		typedef INMOST_DATA_INTEGER_TYPE    integer;
		/// Storage type for representing one byte of abstact data.
		typedef INMOST_DATA_BULK_TYPE       bulk;
		/// type for representing unsigned integer values.
		typedef INMOST_DATA_ENUM_TYPE       enumerator;
		/// Storage type for representing references to Element.
		typedef HandleType                  reference;
Kirill Terekhov's avatar
Kirill Terekhov committed
318 319
		/// Storage type for representing references to Element in another Mesh.
		typedef RemoteHandleType            remote_reference;
Kirill Terekhov's avatar
Kirill Terekhov committed
320 321 322 323 324 325 326
		/// Storage type for representing arrays of real values.
		typedef shell<real>                 real_array;
		/// Storage type for representing arrays of integer values.
		typedef shell<integer>              integer_array;
		/// Storage type for representing abstact data as a series of bytes.
		typedef shell<bulk>                 bulk_array;
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
327 328 329 330
		/// Storage type for representing real value with vector of variations
		typedef variable                    var;
		/// Storage type for representing array of values with vectors of variations
		typedef shell<variable>             var_array;
Kirill Terekhov's avatar
Kirill Terekhov committed
331 332
#endif
		/// Storage type for representing arrays of Element references.
333
		class reference_array : public shell<reference>
Kirill Terekhov's avatar
Kirill Terekhov committed
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
		{
			Mesh * m;
		public:
			reference_array() : m(NULL) {}
			reference_array(Mesh * m, inner_reference_array & arr) : shell<reference>(arr), m(m) {} 
			reference_array(Mesh * m, reference * arr, size_type size) : shell<reference>(arr,size), m(m) {}
			~reference_array() {}
			void push_back(const Storage & elem);
			void push_back(HandleType h) {shell<reference>::push_back(h);} //is it needed?
			Element operator[] (size_type n);
			Element operator[] (size_type n) const;
			class iterator : public shell<HandleType>::iterator
			{
				Mesh * m;
			public:
Kirill Terekhov's avatar
Kirill Terekhov committed
349
				iterator() :shell<HandleType>::iterator() {}
Kirill Terekhov's avatar
Kirill Terekhov committed
350 351 352 353 354 355 356 357 358 359 360 361 362
				iterator(Mesh * m, const shell<HandleType>::iterator & other) : shell<HandleType>::iterator(other), m(m) {}
				iterator(const iterator & other) : shell<HandleType>::iterator(other), m(other.m) {}
				iterator & operator =(iterator const & other) {m = other.m; shell<HandleType>::iterator::operator=(other); return *this;}
				iterator & operator ++() {shell<HandleType>::iterator::operator++(); return *this;}
				iterator   operator ++(int) {iterator ret(*this); shell<HandleType>::iterator::operator++(); return ret;}
				iterator & operator --() {shell<HandleType>::iterator::operator--(); return *this;}
				iterator   operator --(int) {iterator ret(*this); shell<HandleType>::iterator::operator--(); return ret;}
				Element operator->();
			};
			class const_iterator : public shell<HandleType>::const_iterator
			{
				Mesh * m;
			public:
Kirill Terekhov's avatar
Kirill Terekhov committed
363
				const_iterator() :shell<HandleType>::const_iterator() {}
Kirill Terekhov's avatar
Kirill Terekhov committed
364 365 366 367 368 369 370 371 372 373 374 375 376
				const_iterator(Mesh * m, const shell<HandleType>::const_iterator & other) : shell<HandleType>::const_iterator(other) , m(m) {}
				const_iterator(const const_iterator & other) : shell<HandleType>::const_iterator(other), m(other.m) {}
				const_iterator & operator =(const_iterator const & other) {m = other.m; shell<HandleType>::const_iterator::operator=(other); return *this;}
				const_iterator & operator ++() {shell<HandleType>::const_iterator::operator++(); return *this;}
				const_iterator   operator ++(int) {const_iterator ret(*this); shell<HandleType>::const_iterator::operator++(); return ret;}
				const_iterator & operator --() {shell<HandleType>::const_iterator::operator--(); return *this;}
				const_iterator   operator --(int) {const_iterator ret(*this); shell<HandleType>::const_iterator::operator--(); return ret;}
				Element operator->();
			};
			class reverse_iterator : public shell<HandleType>::reverse_iterator
			{
				Mesh * m;
			public:
Kirill Terekhov's avatar
Kirill Terekhov committed
377
				reverse_iterator() :shell<HandleType>::reverse_iterator() {}
Kirill Terekhov's avatar
Kirill Terekhov committed
378 379 380 381 382 383 384 385 386 387 388 389 390
				reverse_iterator(Mesh * m, const shell<HandleType>::reverse_iterator & other) : shell<HandleType>::reverse_iterator(other), m(m) {}
				reverse_iterator(const reverse_iterator & other) : shell<HandleType>::reverse_iterator(other), m(other.m)  {}
				reverse_iterator & operator =(reverse_iterator const & other) {m = other.m; shell<HandleType>::reverse_iterator::operator=(other); return *this;}
				reverse_iterator & operator ++() {shell<HandleType>::reverse_iterator::operator++(); return *this;}
				reverse_iterator   operator ++(int) {reverse_iterator ret(*this); shell<HandleType>::reverse_iterator::operator++(); return ret;}
				reverse_iterator & operator --() {shell<HandleType>::reverse_iterator::operator--(); return *this;}
				reverse_iterator   operator --(int) {reverse_iterator ret(*this); shell<HandleType>::reverse_iterator::operator--(); return ret;}
				Element operator->();
			};
			class const_reverse_iterator : public shell<HandleType>::const_reverse_iterator
			{
				Mesh * m;
			public:
Kirill Terekhov's avatar
Kirill Terekhov committed
391
				const_reverse_iterator() :shell<HandleType>::const_reverse_iterator() {}
Kirill Terekhov's avatar
Kirill Terekhov committed
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
				const_reverse_iterator(Mesh * m, const shell<HandleType>::const_reverse_iterator & other) : shell<HandleType>::const_reverse_iterator(other), m(m) {}
				const_reverse_iterator(const const_reverse_iterator & other) : shell<HandleType>::const_reverse_iterator(other), m(other.m) {}
				const_reverse_iterator & operator =(const_reverse_iterator const & other) {m = other.m; shell<HandleType>::const_reverse_iterator::operator=(other); return *this;}
				const_reverse_iterator & operator ++() {shell<HandleType>::const_reverse_iterator::operator++(); return *this;}
				const_reverse_iterator   operator ++(int) {const_reverse_iterator ret(*this); shell<HandleType>::const_reverse_iterator::operator++(); return ret;}
				const_reverse_iterator & operator --() {shell<HandleType>::const_reverse_iterator::operator--(); return *this;}
				const_reverse_iterator   operator --(int) {const_reverse_iterator ret(*this); shell<HandleType>::const_reverse_iterator::operator--(); return ret;}
				Element operator->();
			};
			iterator begin() {return iterator(m,shell<HandleType>::begin());}
			const_iterator begin() const {return const_iterator(m,shell<HandleType>::begin());}
			reverse_iterator rbegin() {return reverse_iterator(m,shell<HandleType>::rbegin());}
			const_reverse_iterator rbegin() const {return const_reverse_iterator(m,shell<HandleType>::rbegin());}
			iterator end() {return iterator(m,shell<HandleType>::end());}
			const_iterator end() const {return const_iterator(m,shell<HandleType>::end());}
			reverse_iterator rend() {return reverse_iterator(m,shell<HandleType>::rend());}
			const_reverse_iterator rend() const {return const_reverse_iterator(m,shell<HandleType>::rend());}
			void SetMeshLink(Mesh * new_m) {m = new_m;}
Kirill Terekhov's avatar
Kirill Terekhov committed
410 411 412 413
			Element back();
			Element back() const;
			Element front();
			Element front() const;
Kirill Terekhov's avatar
Kirill Terekhov committed
414
		};
Kirill Terekhov's avatar
Kirill Terekhov committed
415
		/// Storage type for representing arrays of Element references on another Mesh.
416 417 418
		class remote_reference_array : public shell<remote_reference>
		{
		public:
Kirill Terekhov's avatar
Kirill Terekhov committed
419 420 421 422
			remote_reference_array() :shell<remote_reference>() {}
			remote_reference_array(const shell<remote_reference> & other) :shell<remote_reference>(other) {}
			remote_reference_array(const remote_reference_array & other) :shell<remote_reference>(other) {}
			remote_reference_array(remote_reference * pntr, shell<remote_reference>::size_type psize) : shell<remote_reference>(pntr,psize) {}
423 424 425 426 427
			void push_back(const Storage & elem);
			void push_back(Mesh * m, HandleType h) {shell<remote_reference>::push_back(RemoteHandleType(m,h));} //is it needed?
			Element operator[] (size_type n);
			Element operator[] (size_type n) const;
			class iterator : public shell<remote_reference>::iterator 
Kirill Terekhov's avatar
Kirill Terekhov committed
428
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
429
			public:
Kirill Terekhov's avatar
Kirill Terekhov committed
430 431
				iterator() :shell<remote_reference>::iterator() {}
				iterator(const shell<remote_reference>::iterator & other) : shell<remote_reference>::iterator(other) {}
432
				iterator(const iterator & other) : shell<remote_reference>::iterator(other) {}
Kirill Terekhov's avatar
Kirill Terekhov committed
433 434
				Element operator->();
			};
435
			class const_iterator : public shell<remote_reference>::const_iterator 
Kirill Terekhov's avatar
Kirill Terekhov committed
436
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
437
			public:
Kirill Terekhov's avatar
Kirill Terekhov committed
438 439
				const_iterator() :shell<remote_reference>::const_iterator() {}
				const_iterator(const shell<remote_reference>::const_iterator & other) : shell<remote_reference>::const_iterator(other) {}
440
				const_iterator(const const_iterator & other) : shell<remote_reference>::const_iterator(other) {}
Kirill Terekhov's avatar
Kirill Terekhov committed
441 442
				Element operator->();
			};
443
			class reverse_iterator : public shell<remote_reference>::reverse_iterator 
Kirill Terekhov's avatar
Kirill Terekhov committed
444
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
445
			public:
Kirill Terekhov's avatar
Kirill Terekhov committed
446 447
				reverse_iterator() :shell<remote_reference>::reverse_iterator() {}
				reverse_iterator(const shell<remote_reference>::reverse_iterator & other) : shell<remote_reference>::reverse_iterator(other) {}
448
				reverse_iterator(const reverse_iterator & other) : shell<remote_reference>::reverse_iterator(other) {}
Kirill Terekhov's avatar
Kirill Terekhov committed
449 450
				Element operator->();
			};
451
			class const_reverse_iterator : public shell<remote_reference>::const_reverse_iterator 
Kirill Terekhov's avatar
Kirill Terekhov committed
452
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
453
			public:
Kirill Terekhov's avatar
Kirill Terekhov committed
454 455
				const_reverse_iterator() :shell<remote_reference>::const_reverse_iterator() {}
				const_reverse_iterator(const shell<remote_reference>::const_reverse_iterator & other) : shell<remote_reference>::const_reverse_iterator(other) {}
456
				const_reverse_iterator(const const_reverse_iterator & other) : shell<remote_reference>::const_reverse_iterator(other) {}
Kirill Terekhov's avatar
Kirill Terekhov committed
457 458 459 460 461 462
				Element operator->();
			};
			Element back();
			Element back() const;
			Element front();
			Element front() const;
463
		};
Kirill Terekhov's avatar
Kirill Terekhov committed
464 465 466 467 468 469 470 471 472 473 474 475 476 477
		//typedef shell<reference>          reference_array;
	protected:
		HandleType                          handle;
		HandleType *                        handle_link;
	private:
		Mesh *                              m_link;
	public:
		Storage(const Storage & other) : handle(other.handle), handle_link(other.handle_link), m_link(other.m_link) {}
		Storage(Mesh * mesh, HandleType handle) : handle(handle), handle_link(NULL), m_link(mesh) {}
		/// This constructor allows for remote handle modification
		Storage(Mesh * mesh, HandleType * handle) : handle(*handle), handle_link(handle), m_link(mesh) {}
		/// If there is a link to handle provided (automatically by ElementArray and reference_array),
		/// then remote handle value will be modified
		Storage &                           operator =          (Storage const & other); 
Kirill Terekhov's avatar
Kirill Terekhov committed
478 479 480 481 482 483 484 485 486 487
		__INLINE bool                       operator <          (const Storage & other) const {return handle < other.handle;}
		__INLINE bool                       operator >          (const Storage & other) const {return handle > other.handle;}
		__INLINE bool                       operator <=         (const Storage & other) const {return handle <= other.handle;}
		__INLINE bool                       operator >=         (const Storage & other) const {return handle >= other.handle;}
		__INLINE bool                       operator ==         (const Storage & other) const {return handle == other.handle;}
		__INLINE bool                       operator !=         (const Storage & other) const {return handle != other.handle;}
		__INLINE Storage *                  operator->          () {return this;}
		__INLINE const Storage *            operator->          () const {return this;}
		__INLINE Storage &                  self                () {return *this;}
		__INLINE const Storage &            self                () const {return *this;}
Kirill Terekhov's avatar
Kirill Terekhov committed
488 489
		virtual ~Storage() {}
	public:
490
		/// Retrieve real value associated with Tag. Implemented in inmost_mesh.h.
Kirill Terekhov's avatar
Kirill Terekhov committed
491
		/// @param tag instance of class Tag that represent asking datum. 
Kirill Terekhov's avatar
Kirill Terekhov committed
492
		__INLINE real &                     Real                (const Tag & tag) const;
493
		/// Retrieve integer value associated with Tag. Implemented in inmost_mesh.h.
Kirill Terekhov's avatar
Kirill Terekhov committed
494
		/// @param tag instance of class Tag that represent asking datum. 
Kirill Terekhov's avatar
Kirill Terekhov committed
495
		__INLINE integer &                  Integer             (const Tag & tag) const;
496
		/// Retrieve one byte of abstract data associated with Tag. Implemented in inmost_mesh.h.
Kirill Terekhov's avatar
Kirill Terekhov committed
497
		/// @param tag instance of class Tag that represent asking datum. 
Kirill Terekhov's avatar
Kirill Terekhov committed
498
		__INLINE bulk &                     Bulk                (const Tag & tag) const;
499
		/// Retrieve Element reference associated with Tag. Implemented in inmost_mesh.h.
Kirill Terekhov's avatar
Kirill Terekhov committed
500
		/// @param tag instance of class Tag that represent asking datum. 
Kirill Terekhov's avatar
Kirill Terekhov committed
501
		__INLINE reference &                Reference           (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
502 503
		/// Retrieve remote Element reference associated with Tag. Implemented in inmost_mesh.h.
		/// @param tag instance of class Tag that represent asking datum. 
504 505
		__INLINE remote_reference &         RemoteReference     (const Tag & tag) const;
		/// Retrieve array of real values associated with Tag. Implemented in inmost_mesh.h.
Kirill Terekhov's avatar
Kirill Terekhov committed
506
		/// @param tag instance of class Tag that represent asking datum. 
Kirill Terekhov's avatar
Kirill Terekhov committed
507
		__INLINE real_array                 RealArray           (const Tag & tag) const;
508
		/// Retrieve array of integer values associated with Tag. Implemented in inmost_mesh.h.
Kirill Terekhov's avatar
Kirill Terekhov committed
509
		/// @param tag instance of class Tag that represent asking datum. 
Kirill Terekhov's avatar
Kirill Terekhov committed
510 511
		__INLINE integer_array              IntegerArray        (const Tag & tag) const;
		/// Retrieve abstract data associated with Tag as a series of bytes. 
Kirill Terekhov's avatar
Kirill Terekhov committed
512 513
		/// Implemented in inmost_mesh.h.
		/// @param tag instance of class Tag that represent asking datum. 
Kirill Terekhov's avatar
Kirill Terekhov committed
514 515
		__INLINE bulk_array                 BulkArray           (const Tag & tag) const;
		/// Retrieve array of Element references associated with Tag. 
Kirill Terekhov's avatar
Kirill Terekhov committed
516 517
		/// Implemented in inmost_mesh.h.
		/// @param tag instance of class Tag that represent asking datum. 
Kirill Terekhov's avatar
Kirill Terekhov committed
518
		__INLINE reference_array            ReferenceArray      (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
519 520 521
		/// Retrieve array of Element references associated with Tag. 
		/// Implemented in inmost_mesh.h.
		/// @param tag instance of class Tag that represent asking datum. 
522
		__INLINE remote_reference_array     RemoteReferenceArray(const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
523 524 525 526 527 528
    
		//optimized data requests for dense data with fixed size
		__INLINE real_array                 RealArrayDF         (const Tag & tag) const;
		__INLINE integer_array              IntegerArrayDF      (const Tag & tag) const;
		__INLINE bulk_array                 BulkArrayDF         (const Tag & tag) const;
		__INLINE reference_array            ReferenceArrayDF    (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
529
		__INLINE remote_reference_array     RemoteReferenceArrayDF(const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
530 531 532 533
		__INLINE real      &                RealDF              (const Tag & tag) const;
		__INLINE integer   &                IntegerDF           (const Tag & tag) const;
		__INLINE bulk      &                BulkDF              (const Tag & tag) const;
		__INLINE reference &                ReferenceDF         (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
534
		__INLINE remote_reference &         RemoteReferenceDF   (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
535 536 537 538 539 540
		
		//optimized data requests for dense data with variable size
		__INLINE real_array                 RealArrayDV         (const Tag & tag) const;
		__INLINE integer_array              IntegerArrayDV      (const Tag & tag) const;
		__INLINE bulk_array                 BulkArrayDV         (const Tag & tag) const;
		__INLINE reference_array            ReferenceArrayDV    (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
541
		__INLINE remote_reference_array     RemoteReferenceArrayDV(const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
542 543 544 545
		__INLINE real      &                RealDV              (const Tag & tag) const;
		__INLINE integer   &                IntegerDV           (const Tag & tag) const;
		__INLINE bulk      &                BulkDV              (const Tag & tag) const;
		__INLINE reference &                ReferenceDV         (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
546
		__INLINE remote_reference &         RemoteReferenceDV   (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
547
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
548
		/// Retrieve variable reference associated with Tag.
Kirill Terekhov's avatar
Kirill Terekhov committed
549
		__INLINE var &                      Variable            (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
550 551 552 553
		__INLINE var &                      VariableDF          (const Tag & tag) const;
		__INLINE var &                      VariableDV          (const Tag & tag) const;
		/// Retrieve array of variables associated with Tag.
		__INLINE var_array                  VariableArray       (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
554
		__INLINE var_array                  VariableArrayDF     (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
555
		__INLINE var_array                  VariableArrayDV     (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
556 557 558 559
#endif
		
		/// Return the data length associated with Tag.
		/// For abstract data return the number of bytes, otherwise return the length of associated array. 
Kirill Terekhov's avatar
Kirill Terekhov committed
560
		/// @param tag tag that represents the data
Kirill Terekhov's avatar
Kirill Terekhov committed
561
		/// @see Storage::SetDataSize
Kirill Terekhov's avatar
Kirill Terekhov committed
562
		/// @see Mesh::GetDataSize
Kirill Terekhov's avatar
Kirill Terekhov committed
563
		__INLINE INMOST_DATA_ENUM_TYPE      GetDataSize         (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
564 565 566 567 568 569
		/// Return the size of the structure required to represent the data on current element.
		/// This is equal to GetDataSize times Tag::GetBytesSize for all the data types,
		/// except for DATA_VARIABLE, that requires a larger structure to accomodate derivatives.
		/// @param tag tag that represents the data
		/// @see Mesh::GetDataCapacity
		__INLINE INMOST_DATA_ENUM_TYPE      GetDataCapacity     (const Tag & tag) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
570 571 572 573
		/// Set the length of  data associated with Tag.
		/// @param tag Identifying Tag.
		/// @param new_size The number of bytes for abstract data, otherwise the length of the array.
		/// @see Storage::GetDataSize
Kirill Terekhov's avatar
Kirill Terekhov committed
574
		/// @see Mesh::SetDataSize
Kirill Terekhov's avatar
Kirill Terekhov committed
575 576 577 578 579 580
		__INLINE void                       SetDataSize         (const Tag & tag,
                                                             INMOST_DATA_ENUM_TYPE new_size) const;
		/// Extract part of the data associated with Tag.
		/// Copy part of the associated array or data to the destination memory.
		/// @param tag Identifying Tag.
		/// @param shift Starting position of the copied data.
581
        /// For abstact data - number of bytes to skip, otherwise number of values to skip.
Kirill Terekhov's avatar
Kirill Terekhov committed
582
		/// @param size Number of elements to copy.
583
        /// For abstact data - number of bytes to copy, otherwise number of values to copy.
Kirill Terekhov's avatar
Kirill Terekhov committed
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
		/// @param data Destination position to copy data to.
		/// @see Storage::SetData
		__INLINE void                       GetData             (const Tag & tag, 
                                                             INMOST_DATA_ENUM_TYPE shift, 
                                                             INMOST_DATA_ENUM_TYPE size, 
                                                             void * data) const;
		__INLINE void                       SetData             (const Tag & tag, 
                                                             INMOST_DATA_ENUM_TYPE shift, 
                                                             INMOST_DATA_ENUM_TYPE size, 
                                                             const void * data) const;
		__INLINE void                       DelData             (const Tag & tag) const;
		/// Deallocates space allocated for sparse data, frees variable array if necessary
		__INLINE void                       DelSparseData       (const Tag & tag) const;
		/// Frees variable array or fills field with zeroes
		__INLINE void                       DelDenseData        (const Tag & tag) const;
		/// Check if any data is associated with Tag.
		__INLINE bool                       HaveData            (const Tag & tag) const;
		__INLINE ElementType                GetElementType      () const;
		__INLINE integer                    GetElementNum       () const;
		__INLINE void                       SetMarker           (MarkerType n) const;
		__INLINE bool                       GetMarker           (MarkerType n) const;
		__INLINE void                       RemMarker           (MarkerType n) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
606
		__INLINE void                       SetPrivateMarker    (MarkerType n) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
607 608 609 610 611 612 613 614 615 616 617 618
		__INLINE bool                       GetPrivateMarker    (MarkerType n) const;
		__INLINE void                       RemPrivateMarker    (MarkerType n) const;
		__INLINE void                       ClearMarkerSpace    () const;
		__INLINE void                       GetMarkerSpace      (bulk copy[MarkerFields]) const;
		__INLINE void                       SetMarkerSpace      (bulk source[MarkerFields]) const;
		__INLINE integer                    LocalID             () const;
		/// This number is guaranteed to be between 0 and Mesh::NumberOf(type of element)
		/// after Mesh::ReorderEmpty
		__INLINE integer                    DataLocalID         () const;
		__INLINE bool                       isValid             () const;
		__INLINE Mesh *                     GetMeshLink         () const;
		__INLINE HandleType                 GetHandle           () const;
Kirill Terekhov's avatar
Kirill Terekhov committed
619 620
	    __INLINE Element                    getAsElement        () const;
		__INLINE Node                       getAsNode           () const;
Kirill Terekhov's avatar
Kirill Terekhov committed
621 622 623 624 625 626
		__INLINE Edge                       getAsEdge           () const;
		__INLINE Face                       getAsFace           () const;
		__INLINE Cell                       getAsCell           () const;
		__INLINE ElementSet                 getAsSet            () const;
		friend class Mesh;
	};
Kirill Terekhov's avatar
Kirill Terekhov committed
627 628 629 630 631 632 633 634 635 636 637 638 639
	
	//////////////////////////////////////////////////////////////////////
	/// Helper classes for class Tag                                    //
	//////////////////////////////////////////////////////////////////////
	
	class TagReal : public Tag
	{
	public:
		TagReal() : Tag() {}
		TagReal(const TagReal & b) : Tag(b) {}
		TagReal(const Tag & b) : Tag(b) {}
		TagReal & operator = (TagReal const & b) {Tag::operator =(b); return *this;}
		TagReal & operator = (Tag const & b) {Tag::operator =(b); return *this;}
640 641
		__INLINE Storage::real & operator [](const Storage & arg) const {return arg.Real(*static_cast<const Tag*>(this));}
		__INLINE Storage::real & operator [](HandleType h) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
642 643 644 645 646 647 648 649 650 651
	};
	
	class TagInteger : public Tag
	{
	public:
		TagInteger() : Tag() {}
		TagInteger(const TagInteger & b) : Tag(b) {}
		TagInteger(const Tag & b) : Tag(b) {}
		TagInteger & operator = (TagInteger const & b) {Tag::operator =(b); return *this;}
		TagInteger & operator = (Tag const & b) {Tag::operator =(b); return *this;}
652 653
		__INLINE Storage::integer & operator [](const Storage & arg) const {return arg.Integer(*static_cast<const Tag*>(this));}
		__INLINE Storage::integer & operator [](HandleType h) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
654 655 656 657 658 659 660 661 662 663
	};
	
	class TagBulk : public Tag
	{
	public:
		TagBulk() : Tag() {}
		TagBulk(const TagBulk & b) : Tag(b) {}
		TagBulk(const Tag & b) : Tag(b) {}
		TagBulk & operator = (TagBulk const & b) {Tag::operator =(b); return *this;}
		TagBulk & operator = (Tag const & b) {Tag::operator =(b); return *this;}
664 665
		__INLINE Storage::bulk & operator [](const Storage & arg) const {return arg.Bulk(*static_cast<const Tag*>(this));}
		__INLINE Storage::bulk & operator [](HandleType h) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
666 667 668 669 670 671 672 673 674 675
	};
	
	class TagReference : public Tag
	{
	public:
		TagReference() : Tag() {}
		TagReference(const TagReference & b) : Tag(b) {}
		TagReference(const Tag & b) : Tag(b) {}
		TagReference & operator = (TagReference const & b) {Tag::operator =(b); return *this;}
		TagReference & operator = (Tag const & b) {Tag::operator =(b); return *this;}
676 677
		__INLINE Storage::reference & operator [](const Storage & arg) const {return arg.Reference(*static_cast<const Tag*>(this));}
		__INLINE Storage::reference & operator [](HandleType h) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
678 679 680 681 682 683 684 685 686 687 688
	};
	
	
	class TagRealArray : public Tag
	{
	public:
		TagRealArray() : Tag() {}
		TagRealArray(const TagRealArray & b) : Tag(b) {}
		TagRealArray(const Tag & b) : Tag(b) {}
		TagRealArray & operator = (TagRealArray const & b) {Tag::operator =(b); return *this;}
		TagRealArray & operator = (Tag const & b) {Tag::operator =(b); return *this;}
689 690
		__INLINE Storage::real_array operator [](const Storage & arg) const {return arg.RealArray(*static_cast<const Tag*>(this));}
		__INLINE Storage::real_array operator [](HandleType h) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
691 692 693 694 695 696 697
		__INLINE Matrix<Storage::real,Storage::real_array> operator()(const Storage & arg, int n, int m) const
		{
			Storage::real_array data = arg.RealArray(*static_cast<const Tag*>(this));
			assert(data.size() == n*m);
			return Matrix<Storage::real,Storage::real_array>(data,n,m);
		}
		__INLINE Matrix<Storage::real,Storage::real_array> operator()(HandleType h, int n, int m) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
698 699 700 701 702 703 704 705 706 707
	};
	
	class TagIntegerArray : public Tag
	{
	public:
		TagIntegerArray() : Tag() {}
		TagIntegerArray(const TagIntegerArray & b) : Tag(b) {}
		TagIntegerArray(const Tag & b) : Tag(b) {}
		TagIntegerArray & operator = (TagIntegerArray const & b) {Tag::operator =(b); return *this;}
		TagIntegerArray & operator = (Tag const & b) {Tag::operator =(b); return *this;}
708 709
		__INLINE Storage::integer_array operator [](const Storage & arg) const {return arg.IntegerArray(*static_cast<const Tag*>(this));}
		__INLINE Storage::integer_array operator [](HandleType h) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
710 711 712 713 714 715 716 717 718 719
	};
	
	class TagBulkArray : public Tag
	{
	public:
		TagBulkArray() : Tag() {}
		TagBulkArray(const TagBulkArray & b) : Tag(b) {}
		TagBulkArray(const Tag & b) : Tag(b) {}
		TagBulkArray & operator = (TagBulkArray const & b) {Tag::operator =(b); return *this;}
		TagBulkArray & operator = (Tag const & b) {Tag::operator =(b); return *this;}
720 721
		__INLINE Storage::bulk_array operator [](const Storage & arg) const {return arg.BulkArray(*static_cast<const Tag*>(this));}
		__INLINE Storage::bulk_array operator [](HandleType h) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
722 723 724 725 726 727 728 729 730 731
	};
	
	class TagReferenceArray : public Tag
	{
	public:
		TagReferenceArray() : Tag() {}
		TagReferenceArray(const TagReferenceArray & b) : Tag(b) {}
		TagReferenceArray(const Tag & b) : Tag(b) {}
		TagReferenceArray & operator = (TagReferenceArray const & b) {Tag::operator =(b); return *this;}
		TagReferenceArray & operator = (Tag const & b) {Tag::operator =(b); return *this;}
732 733
		__INLINE Storage::reference_array operator [](const Storage & arg) const {return arg.ReferenceArray(*static_cast<const Tag*>(this));}
		__INLINE Storage::reference_array operator [](HandleType h) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
734 735
	};
	
Kirill Terekhov's avatar
Kirill Terekhov committed
736 737 738 739 740 741 742 743 744
#if defined(USE_AUTODIFF)
	class TagVariable : public Tag
	{
	public:
		TagVariable() : Tag() {}
		TagVariable(const TagVariable & b) : Tag(b) {}
		TagVariable(const Tag & b) : Tag(b) {}
		TagVariable & operator = (TagVariable const & b) {Tag::operator =(b); return *this;}
		TagVariable & operator = (Tag const & b) {Tag::operator =(b); return *this;}
745 746
		__INLINE Storage::var & operator [](const Storage & arg) const {return arg.Variable(*static_cast<const Tag*>(this));}
		__INLINE Storage::var & operator [](HandleType h) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
747 748
	};
	
Kirill Terekhov's avatar
Kirill Terekhov committed
749 750 751 752 753 754 755 756
	class TagVariableArray : public Tag
	{
	public:
		TagVariableArray() : Tag() {}
		TagVariableArray(const TagVariableArray & b) : Tag(b) {}
		TagVariableArray(const Tag & b) : Tag(b) {}
		TagVariableArray & operator = (TagVariableArray const & b) {Tag::operator =(b); return *this;}
		TagVariableArray & operator = (Tag const & b) {Tag::operator =(b); return *this;}
757 758
		__INLINE Storage::var_array operator [](const Storage & arg) const {return arg.VariableArray(*static_cast<const Tag*>(this));}
		__INLINE Storage::var_array operator [](HandleType h) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
759 760 761 762 763 764 765
		__INLINE Matrix<Storage::var,Storage::var_array> operator()(const Storage & arg, int n, int m) const
		{
			Storage::var_array data = arg.VariableArray(*static_cast<const Tag*>(this));
			assert(data.size() == n*m);
			return Matrix<Storage::var,Storage::var_array>(data,n,m);
		}
		__INLINE Matrix<Storage::var,Storage::var_array> operator()(HandleType h, int n, int m) const;
Kirill Terekhov's avatar
Kirill Terekhov committed
766
	};
Kirill Terekhov's avatar
Kirill Terekhov committed
767
#endif //USE_AUTODIFF
Kirill Terekhov's avatar
Kirill Terekhov committed
768

Kirill Terekhov's avatar
Kirill Terekhov committed
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799
	//////////////////////////////////////////////////////////////////////
	/// Inline functions for class Tag                                  //
	//////////////////////////////////////////////////////////////////////

	__INLINE INMOST_DATA_ENUM_TYPE  Tag::GetRecordSize() const 
	{
		return mem->record_size;
	}

	__INLINE void Tag::SetSize(INMOST_DATA_ENUM_TYPE size) 
	{
		mem->size = size;
	}

	__INLINE void Tag::SetPosition(INMOST_DATA_ENUM_TYPE pos, 
		ElementType type) 
	{
		mem->pos[ElementNum(type)] = pos;
	}

	__INLINE INMOST_DATA_ENUM_TYPE Tag::GetPosition(ElementType type) const 
	{
		assert(mem != NULL); 
		return mem->pos[ElementNum(type)];
	}

	__INLINE void Tag::SetSparse(ElementType type) 
	{
		mem->sparse[ElementNum(type)] = true;
	}

800 801 802 803 804 805 806 807 808 809
	__INLINE void Tag::SetPrint(bool print)
	{
		mem->print_tag = print;
	}

	__INLINE bool Tag::GetPrint() const
	{
		return mem->print_tag;
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
	__INLINE INMOST_DATA_ENUM_TYPE Tag::GetPositionByDim(INMOST_DATA_ENUM_TYPE typenum) const 
	{
		return mem->pos[typenum];
	}

	__INLINE bool Tag::operator <(const Tag & other) const 
	{
		return mem < other.mem;
	}

	__INLINE bool Tag::operator >(const Tag & other) const 
	{
		return mem > other.mem;
	}

	__INLINE bool Tag::operator ==(const Tag & other) const 
	{
		return mem == other.mem;
	}

	__INLINE bool Tag::operator !=(const Tag & other) const 
	{
		return mem != other.mem;
	}

	__INLINE Tag & Tag::operator =(Tag const & other) 
	{
		mem = other.mem; 
		return *this;	
	}

	__INLINE DataType Tag::GetDataType() const 
	{
		assert(mem!=NULL); 
		return mem->dtype;
	}

	__INLINE INMOST_MPI_Type Tag::GetBulkDataType() const 
	{
		assert(mem!=NULL); 
		return mem->bulk_data_type;
	}

	__INLINE INMOST_DATA_ENUM_TYPE Tag::GetBytesSize() const 
	{
		assert(mem!=NULL); 
		return mem->bytes_size;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
858
	__INLINE INMOST_DATA_ENUM_TYPE Tag::GetSize() const 
Kirill Terekhov's avatar
Kirill Terekhov committed
859 860 861 862
	{
		assert(mem!=NULL); 
		return mem->size;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
863
	__INLINE std::string Tag::GetTagName() const 
Kirill Terekhov's avatar
Kirill Terekhov committed
864 865 866 867
	{
		assert(mem!=NULL); 
		return mem->tagname;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
868
	__INLINE bool Tag::isDefined(ElementType type) const 
Kirill Terekhov's avatar
Kirill Terekhov committed
869 870 871 872 873
	{
		assert(mem!=NULL);
		assert(OneType(type)); 
		return GetPosition(type) != ENUMUNDEF;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
874
	__INLINE bool Tag::isSparse(ElementType type) const 
Kirill Terekhov's avatar
Kirill Terekhov committed
875 876 877 878 879
	{
		assert(mem!=NULL);
		assert(OneType(type)); 
		return mem->sparse[ElementNum(type)];
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
880
	__INLINE bool Tag::isValid() const 
Kirill Terekhov's avatar
Kirill Terekhov committed
881 882 883
	{
		return mem != NULL;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
884
	__INLINE Mesh * Tag::GetMeshLink() const 
Kirill Terekhov's avatar
Kirill Terekhov committed
885 886 887 888
	{
		assert(mem!=NULL); 
		return mem->m_link;
	}		
Kirill Terekhov's avatar
Kirill Terekhov committed
889
	__INLINE bool Tag::isSparseByDim(INMOST_DATA_INTEGER_TYPE typenum) const 
Kirill Terekhov's avatar
Kirill Terekhov committed
890 891 892 893
	{
		assert(mem!=NULL); 
		return mem->sparse[typenum];
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
894
	__INLINE bool Tag::isDefinedByDim(INMOST_DATA_INTEGER_TYPE typenum) const 
Kirill Terekhov's avatar
Kirill Terekhov committed
895 896 897 898
	{
		assert(mem!=NULL); 
		return GetPositionByDim(typenum) != ENUMUNDEF;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
899
	__INLINE void Tag::SetBulkDataType(INMOST_MPI_Type type) 
Kirill Terekhov's avatar
Kirill Terekhov committed
900 901 902 903 904 905
	{
		assert(mem!=NULL);
		assert(mem->dtype == DATA_BULK ); 
		mem->bulk_data_type = type;
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
906 907
}

Kirill Terekhov's avatar
Kirill Terekhov committed
908
//Implementation of inlined functions
igor's avatar
igor committed
909
//#include "../Data/tag_inline.hpp"
Kirill Terekhov's avatar
Kirill Terekhov committed
910 911 912 913 914 915


#endif



916
#endif //INMOST_DATA_H_INCLUDED