#ifndef  _M3D_H
#define  _M3D_H

// C++ includes
#include <vector>
#include <cassert>
#include <cmath>
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

#include "node.h"
#include "tet.h"
#include "grid.h"

class M3D 
{
 public:
  M3D(Tet& tet, Point r);

  void V(double& v);
  void B(Point& b);
  void T(double tb[3][3]);

  double sgn(const double m);
  void set(double a[3][3], double b);
  void compute_1_R(unsigned int i, double &k0); 
  void compute_grad_1_R(unsigned int i, Point &k1); 
  void compute_grad_grad_1_R(unsigned int i, double k2[3][3]);
  void compute_1_R3(unsigned int i,  double &k3);
  const double TOL;
  const double Cm ; 
  double get_tri_size(std::vector<Point>& T);

 private:
  // variables for edges 
  double    Rij_minus[4][3]; // equation (15)
  double    Rij_plus [4][3]; // equation (14)
  double    Sij_minus[4][3]; // equation (8)
  double    Sij_plus [4][3]; // equation (9)
  double    Rij0     [4][3]; // equation (13)
  double    mij0     [4][3]; // mij0 is constant along edge eij
  Point     mij      [4][3]; // mij is the outgoing normal vector of edge eij
  Point     tij      [4][3]; // tij is the tangential normal vector of edge eij
  // variables for facets
  Point     ni       [4];    // ni is the outgoing normal vector of surface Ti
  double   wi0       [4];    // equation (8)
  Point     oi       [4];    // oi is the projection point of site r on surface Ti
  // observation site and source element
  Tet&               tet;    // a tetrahedron
  Point              r;      // an observation site
}; 


#endif // _M3D_H


