text: // This file is a part of nla3d project. For information about authors and
  // licensing go to project's repository on github:
  // https://github.com/dmitryikh/nla3d 
  
  #pragma once
  #include "sys.h"
  
  namespace nla3d {
  
  class DofCollection;
  // class for Degree of Freedom informations 
  // (is it fixed boundary condition, what its number in equation system, ..)
  class Dof {
    public:
      enum dofType {
        UX = 0,
        UY,
        UZ,
        ROTX,
        ROTY,
        ROTZ,
        HYDRO_PRESSURE,
        TEMP,
        UNDEFINED // should be last
      };
  
      Dof(dofType t) : eqNumber(0), isConstrained(false), type(t) { }
  
      uint32 eqNumber = 0; // 0 - not use
      bool isConstrained = false; // is this DOF defined by B.C.
      dofType type;
  
      static const char* const dofTypeLabels[];
      static const uint16 numberOfDofTypes;
      static dofType label2dofType (const std::string& label);
      static const char* dofType2label (const dofType t);
  };
  
  inline const char* Dof::dofType2label(const Dof::dofType t) {
    assert(t < Dof::UNDEFINED);
    return dofTypeLabels[t];
  }
  
  
  class DofCollection {
    public:
      uint32 getNumberOfUsedDofs();
      uint32 getNumberOfEntities();
  
      // return a poiner to Dof class for Entity n and for type dof
      Dof* getDof(uint32 n, Dof::dofType dof);
  
      // return begin and end iterator of Dofs for Entity n
      std::pair<std::vector<Dof>::iterator,
                std::vector<Dof>::iterator> getEntityDofs(uint32 n);
  
      void initDofTable(uint32 _numberOfEntities);
      void addDof(uint32 n, std::initializer_list<Dof::dofType> _dofs);
      void clearDofTable();
      bool isDofUsed(uint32 n, Dof::dofType dof);
  
      std::set<Dof::dofType> getUniqueDofTypes();
  
    private:
      uint32 numberOfUsedDofs = 0;
      uint32 numberOfEntities = 0;
  
      // vector of Dof objects 
      std::vector<Dof> dofs;
      // array of indexes to find where dofs for particular entity is located in dofs
      // Dof for entity n will be located from dofPos[n-1] included to dofPos[n] excluded 
      std::vector<uint32> dofPos;
      // set of unique dofs used in collection
      std::set<Dof::dofType> uniqueDofTypes;
  };
  
  
  inline uint32 DofCollection::getNumberOfUsedDofs() {
    return numberOfUsedDofs;
  }
  
  
  inline uint32 DofCollection::getNumberOfEntities() {
    return numberOfEntities;
  }
  
  
  inline std::pair<std::vector<Dof>::iterator,
                   std::vector<Dof>::iterator> DofCollection::getEntityDofs(uint32 n) {
    assert(n > 0);
    assert(n <= numberOfEntities);
    assert(dofPos.size() > 0);
  
    return std::make_pair(dofs.begin() + dofPos[n-1], dofs.begin() + dofPos[n]);
  }
  
  
  } // namespace nla3d 
  