// BrickMesh.h
// Class for brick meshes
// James Liu, ColoState; 2007/01--2017/02

#ifndef BrickMesh_H
#define BrickMesh_H

#include "cell3d.h"
#include "PtVec3d.h"

class BrickMesh {
private: 
  int NumNds, NumFcs, NumEms, NumBndryPcs;
  int BgnLblNd, BgnLblFc, BgnLblEm, BgnLblBndry;
  int *IsBndryNd, *NumNdsNd, **LblNdNd, *NumEmsNd, **LblNdEm;
  int *IsBndryFc, (*LblFcNd)[4], (*LblFcFc)[11], (*LblFcEm)[2];
  int (*LblEmNd)[8], (*LblEmFc)[6];
  int flag;  // 1,2,3 for hierarchy
  int NX, NY, NZ;
  double XA, XB, YC, YD, ZE, ZF;
  double *X, *Y, *Z;
  PtVec3d *nd, *OutNmlBndry;
public:
  BrickMesh();  // Default constructor
  BrickMesh(double xa, double xb, int nx,   // A constructor:
            double yc, double yd, int ny,   // generating a uniform
            double ze, double zf, int nz);  // brick mesh
  // BrickMesh(char *filename);  // A constructor based on reading a data file
  //
  ~BrickMesh();  // Destructor
  void enrich1();  // Enriching to Type I for CG methods
  //
  int numberNodes() const {return NumNds;}
  int numberFaces() const {return NumFcs;}
  int numberElements() const {return NumEms;}
  //
  int beginLabelNode() const {return BgnLblNd;}
  int beginLabelFace() const {return BgnLblFc;}
  int beginLabelElement() const {return BgnLblEm;}
  int endLabelNode() const {return BgnLblNd+NumNds-1;}
  int endLabelFace() const {return BgnLblFc+NumFcs-1;}
  int endLabelElement() const {return BgnLblEm+NumEms-1;}
  //
  int isBoundaryNode(int labeld) const {return IsBndryNd[labeld-BgnLblNd];}
  int isBoundaryFace(int labelc) const {return IsBndryFc[labelc-BgnLblFc];}
  //
  int numberNbrNodesNode(int labeld) const {return NumNdsNd[labeld-BgnLblNd];}
  int numberNbrElementsNode(int labeld) const {return NumEmsNd[labeld-BgnLblNd];}
  //
  PtVec3d node(int labeld) const {return nd[labeld-BgnLblNd];}
  Rect3d face(int labelc) const;
  Brick element(int labele) const;
  PtVec3d outerNormalBoundary(int labelc) const {return OutNmlBndry[labelc-1];}
  //
  void getNodeNode(int labeld, int *labelNode) const;
  void getNodeElement(int labeld, int *labelElement) const;
  //
  void getFaceNode(int labelc, int labelNode[4]) const;
  void getFaceFace(int labelc, int labelFace[11]) const;
  void getFaceElement(int labelc, int &labelElementA, int &labelElementB) const;
  //
  void getElementNode(int labele, int labelNode[8]) const;
  void getElementFace(int labele, int labelFace[6]) const;
  //
  // double maxSize() const;
  // double minSize() const;
  void save2file(char *filename) const;
  double xa() const {return XA;}
  double xb() const {return XB;}
  double yc() const {return YC;}
  double yd() const {return YD;}
  double ze() const {return ZE;}
  double zf() const {return ZF;}
  int nx() const {return NX;}
  int ny() const {return NY;}
  int nz() const {return NZ;}
  double xCrd(int i) const {return X[i];}
  double yCrd(int j) const {return Y[j];}
  double zCrd(int k) const {return Z[k];}
};

#endif  // BrickMesh_H
// BrickMesh.h 