#pragma once
#ifndef _ELAS_
#define _ELAS_
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<string>
#include<unistd.h>
#include<functional>
#include"../include/tools.h"
#include"../include/outcar.h"
#include"../include/structure_operator.h"
#include"../include/read_write.h"
#include"../include/spglib/spglib.h"
using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::function;
namespace elas
{
	enum LAUE
	{
		C,
		H,
		R1,
		R2,
		T1,
		T2,
		O,
		M,
		N
	};
	class elastic
	{
	public:
		elastic(vector<double> strain = { -0.005, -0.003, -0.001, 0.000, 0.001, 0.003, 0.005 }, const char file[] = "INPOS");
		void generatefile(const char filename[], vector<vector<double> > matrix);
		void getstress(const char file[] = "Stress_Strain");
		void generate();
		void calculate();
		void PrintElasticProperty(const char file[] = "Elastic.dat");
		void PrintCelas(FILE* fp);
		void cal_cub();
		void cal_hexa();
		void cal_trig1();
		void cal_trig2();
		void cal_tetra1();
		void cal_tetra2();
		void cal_ortho();
		void cal_mono();
		void cal_tric();
		vector<function<void(elastic*)> > cal_method;
	private:
		POSCAR pos;
		LAUE Laue;
		vector<double> strain;
		vector<vector<vector<double> > > stress;
		vector<vector<double> > coeff;
		vector<vector<double> > Celas;
		vector<int> lists;
	};
};
#endif