gctl_toolkits/archive/TetraGM/Tetra_G.h
2024-09-10 20:25:18 +08:00

1124 lines
29 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef _TETRA_G_H
#define _TETRA_G_H
#include "Data_Func.h"
#include "res_reg.h"
class Tetra_G
{
public:
Tetra_G();
~Tetra_G();
int info_taker_run(int,string,string,string);//读入必要参数
int info_taker_run(int,string,double*,string,double *);//读入必要参数
int info_taker_run(int,string,double*,string);
int info_taker_run(int,string,string,string,double *);
int readnode(string);//读取.node文件并保存至结构体vertex
int readele(string);//读取.ele文件并保存至结构体tetrahedron
int readele(string,double *);//读取.ele文件并保存至结构体tetrahedron
int readmsh(string,double *);//读取.msh文件
int field_reader(int,string);//读取观测面信息保存至结构体point3d
int manual_input(int,double *);//手工输入计算信息保存至结构体field_point只适用于水平观测面
int cal_tetra_info();//计算四面体属性
double cal_tetra_gc(point3d);//计算四面体网络在单个观测点的重力异常值
int cal_tetra_ggc(point3d,double &,double &,double &);
double cal_tetra_gs(point3d,sphere_point);//计算四面体网络在单个观测点的重力异常值
int cal_tetra_ggs(point3d,sphere_point,double &,double &,double &);
int cal_total_g(int,string);//计算所有四面体重力异常并利用res_reg类进行保存
private:
double once_time;//一次四面体到计算值的所用时间
clock_t start,finish;
//info_taker_run
string nodename;
string elename;
string mshname;
//readnode&&readmsh
int vertex_sum;
vertex *vert;
int edge_sum;
edge *edg;
int face_sum;
face *fac;
//readele&&readmsh
int tetra_sum;
tetra *tet;
//readmsh
int element_sum;
//field_reader&&manual_input
int fie_sum;
point3d *fie;
sphere_point *s_point;
//cal_total_g
double *_Obdata;
double *_Obdata2;
double *_Obdata3;
};
/************************************************************************/
Tetra_G::Tetra_G()
{
once_time=2e-7;//通过实验计算得到单次计算耗时
vert = NULL;
edg = NULL;
fac = NULL;
tet = NULL;
fie = NULL;
s_point = NULL;
_Obdata = NULL;
_Obdata2 = NULL;
_Obdata3 = NULL;
}
Tetra_G::~Tetra_G()
{
if(tet!=NULL)
{
for(int i=0;i<tetra_sum;i++)
{
if(tet[i].attribute) delete []tet[i].attribute;
}
delete []tet;
}
if(vert!=NULL) delete []vert;
if(edg!=NULL) delete []edg;
if(fac!=NULL) delete []fac;
if(fie!=NULL) delete []fie;
if(s_point!=NULL) delete []s_point;
if(_Obdata!=NULL) delete []_Obdata;
if(_Obdata2!=NULL) delete []_Obdata2;
if(_Obdata3!=NULL) delete []_Obdata3;
}
/************************************************************************/
int Tetra_G::info_taker_run(int calculate_type,string meshname,double *ob_info,string savename,double *attri)
{
elename = meshname + ".ele";
nodename = meshname + ".node";
mshname = meshname + ".msh";
if(access(elename.c_str(),F_OK)&&access(nodename.c_str(),F_OK)&&access(mshname.c_str(),F_OK)){
cout<<"No surpported file exist!";
return 1;
}
if(!access(elename.c_str(),F_OK)&&!access(nodename.c_str(),F_OK))
{
readnode(nodename);
readele(elename,attri);
}
else if(!access(mshname.c_str(),F_OK))
{
readmsh(mshname,attri);
}
if(manual_input(calculate_type,ob_info)) return 1;
cal_tetra_info();
cal_total_g(calculate_type,savename);
return 0;
}
int Tetra_G::info_taker_run(int calculate_type,string meshname,string fiename,string savename)
{
elename = meshname + ".ele";
nodename = meshname + ".node";
if(access(elename.c_str(),F_OK)&&access(nodename.c_str(),F_OK)){
cout<<"No surpported file exist!";
return 1;
}
readnode(nodename);
readele(elename);
if(field_reader(calculate_type,fiename)) return 1;
cal_tetra_info();
cal_total_g(calculate_type,savename);
return 0;
}
int Tetra_G::info_taker_run(int calculate_type,string meshname,double *ob_info,string savename)
{
elename = meshname + ".ele";
nodename = meshname + ".node";
if(access(elename.c_str(),F_OK)&&access(nodename.c_str(),F_OK)){
cout<<"No surpported file exist!";
return 1;
}
readnode(nodename);
readele(elename);
if(manual_input(calculate_type,ob_info)) return 1;
cal_tetra_info();
cal_total_g(calculate_type,savename);
return 0;
}
int Tetra_G::info_taker_run(int calculate_type,string meshname,string fiename,string savename,double *attri)
{
elename = meshname + ".ele";
nodename = meshname + ".node";
mshname = meshname + ".msh";
if(access(elename.c_str(),F_OK)&&access(nodename.c_str(),F_OK)&&access(mshname.c_str(),F_OK)){
cout<<"No surpported file exist!";
return 1;
}
if(!access(elename.c_str(),F_OK)&&!access(nodename.c_str(),F_OK))
{
readnode(nodename);
readele(elename,attri);
}
else if(!access(mshname.c_str(),F_OK))
{
readmsh(mshname,attri);
}
if(field_reader(calculate_type,fiename)) return 1;
cal_tetra_info();
cal_total_g(calculate_type,savename);
return 0;
}
/************************************************************************/
int Tetra_G::readnode(string filename)
{
cout<<"reading "<<filename<<"... ";
start = clock();
const char* openname = filename.c_str();
ifstream nodein(openname);
int temp,first_No;
nodein>>vertex_sum>>temp>>temp>>temp>>first_No;
nodein.seekg(-1,ios::cur);
vert = new vertex [vertex_sum];
if(first_No==1)
{
for(int i=0;i<vertex_sum;i++)
{
nodein>>vert[i].No>>vert[i].vt.x>>vert[i].vt.y>>vert[i].vt.z;
vert[i].No = i;
}
finish=clock();
cout<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
}
else
{
for(int i=0;i<vertex_sum;i++)
{
nodein>>vert[i].No>>vert[i].vt.x>>vert[i].vt.y>>vert[i].vt.z;
}
finish=clock();
cout<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
}
nodein.close();
/*ofstream testout("testout.txt");
for(int i=0;i<vertex_sum;i++)
{
testout<<vert[i].vt.x<<" "<<vert[i].vt.y<<" "<<vert[i].vt.z<<endl;
}
testout.close();*/
return 0;
}
int Tetra_G::readele(string filename)
{
cout<<"reading "<<filename<<"... ";
start = clock();
const char* openname = filename.c_str();
ifstream elein(openname);
int vertex_num,attribute_sum,first_No;
elein>>tetra_sum>>vertex_num>>attribute_sum>>first_No;
elein.seekg(-1,ios::cur);
tet = new tetra [tetra_sum];
if(first_No==1)
{
for(int i=0;i<tetra_sum;i++)
{
tet[i].attribute = new double [attribute_sum];
}
for(int i=0;i<tetra_sum;i++)
{
elein>>tet[i].No>>tet[i].ver[0]>>tet[i].ver[1]>>tet[i].ver[2]>>tet[i].ver[3];
for(int j=0;j<attribute_sum;j++)
{
elein>>tet[i].attribute[j];
}
tet[i].No = i;
tet[i].ver[0] -= 1;
tet[i].ver[1] -= 1;
tet[i].ver[2] -= 1;
tet[i].ver[3] -= 1;
}
finish=clock();
cout<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
}
else
{
for(int i=0;i<tetra_sum;i++)
{
tet[i].attribute = new double [attribute_sum];
}
for(int i=0;i<tetra_sum;i++)
{
elein>>tet[i].No>>tet[i].ver[0]>>tet[i].ver[1]>>tet[i].ver[2]>>tet[i].ver[3];
for(int j=0;j<attribute_sum;j++)
{
elein>>tet[i].attribute[j];
}
}
finish=clock();
cout<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
}
elein.close();
return 0;
}
int Tetra_G::readele(string filename,double *attri)
{
cout<<"reading "<<filename<<"... ";
start = clock();
const char* openname = filename.c_str();
ifstream elein(openname);//声明模型读入文件流
int vertex_num,attribute_sum,first_No;//此处并未应用vertex_num这个值
elein>>tetra_sum>>vertex_num>>attribute_sum>>first_No;
elein.seekg(-1,ios::cur);
tet = new tetra [tetra_sum];
if(first_No==1)
{
for(int i=0;i<tetra_sum;i++)
{
tet[i].attribute = new double [1];
tet[i].attribute[0] = *(attri);
}
for(int i=0;i<tetra_sum;i++)
{
elein>>tet[i].No>>tet[i].ver[0]>>tet[i].ver[1]>>tet[i].ver[2]>>tet[i].ver[3];
tet[i].No = i;
tet[i].ver[0] -= 1;
tet[i].ver[1] -= 1;
tet[i].ver[2] -= 1;
tet[i].ver[3] -= 1;
}
finish=clock();
cout<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
}
else
{
for(int i=0;i<tetra_sum;i++)
{
tet[i].attribute = new double [1];
tet[i].attribute[0] = *attri;
}
for(int i=0;i<tetra_sum;i++)
{
elein>>tet[i].No>>tet[i].ver[0]>>tet[i].ver[1]>>tet[i].ver[2]>>tet[i].ver[3];
}
finish=clock();
cout<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
}
elein.close();
/*ofstream testout("testout2.txt");
for(int i=0;i<tetra_sum;i++)
{
testout<<tet[i].ver[0]<<" "<<tet[i].ver[1]<<" "<<tet[i].ver[2]<<" "<<tet[i].ver[3]<<" "<<tet[i].attribute[0]<<endl;
}
testout.close();*/
return 0;
}
int Tetra_G::readmsh(string filename,double *attri)
{
double version;
int format,precision;
int element_order,element_type;
int itemp;
int count;
string temp;
stringstream stemp;
edge E1;
edge_list EdgList;
edge_list::iterator ie;
face F1;
face_list FacList;
face_list::iterator ifac;
tetra T1;
tetra_list TetList;
tetra_list::iterator it;
cout<<"reading "<<filename<<"... ";
const char* openname = filename.c_str();
ifstream mshin(openname);
start = clock();
while (getline(mshin,temp))
{
if(temp=="$MeshFormat")//读入.msh文件版本信息虽然对我们来说没什么用
{
getline(mshin,temp);
stemp.clear();
stemp.str(temp);
stemp>>version>>format>>precision;
}
else if(temp=="$Nodes")//读入node信息
{
getline(mshin,temp);
stemp.clear();
stemp.str(temp);
stemp>>vertex_sum;
vert = new vertex [vertex_sum];
for(int i=0;i<vertex_sum;i++)
{
getline(mshin,temp);
stemp.clear();
stemp.str(temp);
stemp>>vert[i].No>>vert[i].vt.x>>vert[i].vt.y>>vert[i].vt.z;
vert[i].No-=1;//.msh文件中点的编号是从1开始的
}
}
else if(temp=="$Elements")//读入元素信息,保存到相应的链表
{
getline(mshin,temp);
stemp.clear();
stemp.str(temp);
stemp>>element_sum;
for(int i=0;i<element_sum;i++)
{
getline(mshin,temp);
stemp.clear();
stemp.str(temp);
stemp>>element_order>>element_type;
if(element_type==4)//四面体元素
{
stemp>>itemp>>itemp>>itemp>>T1.ver[0]>>T1.ver[1]>>T1.ver[2]>>T1.ver[3];
T1.ver[0]-=1;
T1.ver[1]-=1;
T1.ver[2]-=1;
T1.ver[3]-=1;
TetList.push_back(T1);
}
else if(element_type==1)//边元素
{
stemp>>itemp>>itemp>>itemp>>E1.ver[0]>>E1.ver[1];
E1.ver[0]-=1;
E1.ver[1]-=1;
EdgList.push_back(E1);
}
else if(element_type==2)//三角形元素
{
stemp>>itemp>>itemp>>itemp>>F1.ver[0]>>F1.ver[1]>>F1.ver[2];
F1.ver[0]-=1;
F1.ver[1]-=1;
F1.ver[2]-=1;
FacList.push_back(F1);
}
else continue;
}
}
}
mshin.close();
tetra_sum = TetList.size();
edge_sum = EdgList.size();
face_sum = FacList.size();
tet = new tetra [tetra_sum];
edg = new edge [edge_sum];
fac = new face [face_sum];
count=0;
for(it=TetList.begin();it!=TetList.end();++it)
{
T1 = *it;
T1.No = count;
tet[count] = T1;
count++;
}
TetList.clear();
count=0;
for(ie=EdgList.begin();ie!=EdgList.end();++ie)
{
E1 = *ie;
E1.No = count;
edg[count] = E1;
count++;
}
EdgList.clear();
count=0;
for(ifac=FacList.begin();ifac!=FacList.end();++ifac)
{
F1 = *ifac;
F1.No = count;
fac[count] = F1;
count++;
}
FacList.clear();
for(int i=0;i<tetra_sum;i++)
{
tet[i].attribute = new double [1];
tet[i].attribute[0] = *attri;
}
finish=clock();
cout<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
return 0;
}
int Tetra_G::field_reader(int cal_type,string filename)
{
filename+= ".fie";
if(access(filename.c_str(),F_OK)){
cout<<filename<<" not found!"<<endl;
return 1;
}
cout<<"reading "<<filename<<"... ";
start = clock();
const char* openname = filename.c_str();
ifstream fiein(openname);
fiein>>fie_sum;
fie = new point3d [fie_sum];
if(cal_type==1||cal_type==2)
{
for(int i=0;i<fie_sum;i++)
{
fiein>>fie[i].x>>fie[i].y>>fie[i].z;
}
}
else
{
s_point = new sphere_point [fie_sum];
for(int i=0;i<fie_sum;i++)
{
fiein>>s_point[i].phi>>s_point[i].thet>>s_point[i].radius;
fie[i]=SCS2CCS(s_point[i]);
}
}
finish=clock();
cout<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
fiein.close();
return 0;
}
int Tetra_G::manual_input(int cal_type,double *ob_info)
{
int M,N;
double _ob[7];
cout<<"calculating observing points... ";
start = clock();
for(int i=0;i<7;i++)
{
_ob[i]=*(ob_info+i);
}
N=int (_ob[5]-_ob[3])/_ob[4]+1;
M=int (_ob[2]-_ob[0])/_ob[1]+1;
_ob[2]=_ob[0]+(M-1)*_ob[1];
_ob[5]=_ob[3]+(N-1)*_ob[4];
fie_sum = M*N;
fie = new point3d [fie_sum];
if(cal_type==1||cal_type==2)
{
for(int i=0;i<fie_sum;i++)
{
fie[i].y = _ob[4]*(i%N)+_ob[3];
fie[i].x = _ob[1]*(i/N)+_ob[0];
fie[i].z = _ob[6];
}
}
else
{
if(_ob[0]<-90||_ob[2]>90||_ob[3]<-180||_ob[5]>180||_ob[6]<=0)
{
cout<<"coordinate out of range! function fail...";
return 1;
}
s_point = new sphere_point [fie_sum];
for(int i=0;i<fie_sum;i++)
{
s_point[i].phi = _ob[4]*(i%N)+_ob[3];
s_point[i].thet = _ob[1]*(i/N)+_ob[0];
s_point[i].radius = _ob[6];
fie[i]=SCS2CCS(s_point[i]);
}
}
finish=clock();
cout<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
/*
ofstream testout("testout.txt");
for(int i=0;i<fie_sum;i++)
{
testout<<fie[i].x<<" "<<fie[i].y<<" "<<fie[i].z<<endl;
}
testout.close();
*/
return 0;
}
/************************************************************************/
int Tetra_G::cal_tetra_info()
{
point3d refer_vertex,plane_vertex[3],nf,nor_f;
int t1,t2;
point3d v1,v2,ref1,ref2,edge12,edge21;
point3d n12,nor_n12,nA,nor_nA;
point3d n21,nor_n21,nB,nor_nB;
double nor_nAn12[3][3],nor_nBn21[3][3];
int count;
cout<<"calculating tetrahedrons' parameters... ";
start = clock();
for(int i=0;i<tetra_sum;i++)
{
for(int f=0;f<4;f++)
{
refer_vertex=vert[tet[i].ver[f]].vt;
plane_vertex[0]=vert[tet[i].ver[(f+1)%4]].vt;
plane_vertex[1]=vert[tet[i].ver[(f+2)%4]].vt;
plane_vertex[2]=vert[tet[i].ver[(f+3)%4]].vt;
if(re_order(refer_vertex,plane_vertex[0],plane_vertex[1],plane_vertex[2]))
{
tet[i].ordered_ver[f][0]=tet[i].ver[(f+1)%4];
tet[i].ordered_ver[f][1]=tet[i].ver[(f+3)%4];
tet[i].ordered_ver[f][2]=tet[i].ver[(f+2)%4];
}
else
{
tet[i].ordered_ver[f][0]=tet[i].ver[(f+1)%4];
tet[i].ordered_ver[f][1]=tet[i].ver[(f+2)%4];
tet[i].ordered_ver[f][2]=tet[i].ver[(f+3)%4];
}
nf=cross(plane_vertex[1]-plane_vertex[0],plane_vertex[2]-plane_vertex[0]);
nor_f=nor_point3d(nf);
/*
for(int h=0;h<3;h++)
{
for(int l=0;l<3;l++)
{
//tet[i].F_kron[f].kron[h][l] = *(kron_v(nor_f,nor_f)+h*3+l);
tet[i].F_kron[f].kron[h][l] = 0.1;
}
}
*/
tet[i].F_kron[f].kron[0][0]=nor_f.x*nor_f.x; tet[i].F_kron[f].kron[0][1]=nor_f.x*nor_f.y; tet[i].F_kron[f].kron[0][2]=nor_f.x*nor_f.z;
tet[i].F_kron[f].kron[1][0]=nor_f.y*nor_f.x; tet[i].F_kron[f].kron[1][1]=nor_f.y*nor_f.y; tet[i].F_kron[f].kron[1][2]=nor_f.y*nor_f.z;
tet[i].F_kron[f].kron[2][0]=nor_f.z*nor_f.x; tet[i].F_kron[f].kron[2][1]=nor_f.z*nor_f.y; tet[i].F_kron[f].kron[2][2]=nor_f.z*nor_f.z;
}
count=0;
for(int e=0;e<3;e++)
{
for(int e2=e+1;e2<4;e2++)
{
v1=vert[tet[i].ver[e]].vt;
v2=vert[tet[i].ver[e2]].vt;
find_left(t1,t2,e,e2);
ref1=vert[tet[i].ver[t1]].vt;
ref2=vert[tet[i].ver[t2]].vt;
re_order2(v1,v2,ref1,ref2);
tet[i].E_len[count] = Dis_point3d(v1,v2);
edge12 = v2-v1;
edge21 = v1-v2;
nA=cross(edge12,ref1-v1); nor_nA=nor_point3d(nA);
n12=cross(edge12,nA); nor_n12=nor_point3d(n12);
nB=cross(edge21,ref2-v2); nor_nB=nor_point3d(nB);
n21=cross(edge21,nB); nor_n21=nor_point3d(n21);
/*
for(int g=0;g<3;g++)
{
for(int j=0;j<3;j++)
{
//nor_nAn12 = *(kron_v(nor_nA,nor_n12)+g*3+j);
//nor_nBn21 = *(kron_v(nor_nB,nor_n21)+g*3+j);
//tet[i].E_kron[count].kron[g][j] = nor_nAn12 + nor_nBn21;
tet[i].E_kron[count].kron[g][j] = 0.1;
}
}
*/
nor_nAn12[0][0]=nor_nA.x*nor_n12.x; nor_nAn12[0][1]=nor_nA.x*nor_n12.y; nor_nAn12[0][2]=nor_nA.x*nor_n12.z;
nor_nAn12[1][0]=nor_nA.y*nor_n12.x; nor_nAn12[1][1]=nor_nA.y*nor_n12.y; nor_nAn12[1][2]=nor_nA.y*nor_n12.z;
nor_nAn12[2][0]=nor_nA.z*nor_n12.x; nor_nAn12[2][1]=nor_nA.z*nor_n12.y; nor_nAn12[2][2]=nor_nA.z*nor_n12.z;
nor_nBn21[0][0]=nor_nB.x*nor_n21.x; nor_nBn21[0][1]=nor_nB.x*nor_n21.y; nor_nBn21[0][2]=nor_nB.x*nor_n21.z;
nor_nBn21[1][0]=nor_nB.y*nor_n21.x; nor_nBn21[1][1]=nor_nB.y*nor_n21.y; nor_nBn21[1][2]=nor_nB.y*nor_n21.z;
nor_nBn21[2][0]=nor_nB.z*nor_n21.x; nor_nBn21[2][1]=nor_nB.z*nor_n21.y; nor_nBn21[2][2]=nor_nB.z*nor_n21.z;
for(int g=0;g<3;g++)
{
for(int j=0;j<3;j++)
{
tet[i].E_kron[count].kron[g][j] = nor_nAn12[g][j] + nor_nBn21[g][j];
}
}
count++;
}
}
}
finish=clock();
cout<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
/*ofstream testout("testout2.txt");
for(int i=0;i<tetra_sum;i++)
{
testout<<tet[i].ver[0]<<" "<<tet[i].ver[1]<<" "<<tet[i].ver[2]<<" "<<tet[i].ver[3]<<" "<<tet[i].attribute[0]<<endl;
for(int j=0;j<6;j++)
{
testout<<tet[i].E_len[j]<<" ";
}testout<<endl;
for(int m=0;m<4;m++)
{
for(int p=0;p<3;p++)
{
for(int q=0;q<3;q++)
{
testout<<tet[i].F_kron[m].kron[p][q]<<" ";
}
testout<<endl;
}
testout<<endl;
}
testout<<"**********************************"<<endl;
for(int m=0;m<6;m++)
{
for(int p=0;p<3;p++)
{
for(int q=0;q<3;q++)
{
testout<<tet[i].E_kron[m].kron[p][q]<<" ";
}
testout<<endl;
}
testout<<endl;
}
}
testout.close();*/
return 0;
}
/************************************************************************/
double Tetra_G::cal_tetra_gc(point3d ob_posi)
{
int count;
double cal_data;
double Le,wf,face_sum,edge_sum;
double Dv1,Dv2;
point3d re;
point3d r_ijk[3];
double L_ijk[3];
cal_data=0;
for(int i=0;i<tetra_sum;i++)
{
if(tet[i].attribute[0]==0.0) cal_data += 0.0;
else
{
face_sum=0;
for(int f=0;f<4;f++)
{
r_ijk[0]=vert[tet[i].ordered_ver[f][0]].vt - ob_posi;
r_ijk[1]=vert[tet[i].ordered_ver[f][1]].vt - ob_posi;
r_ijk[2]=vert[tet[i].ordered_ver[f][2]].vt - ob_posi;
L_ijk[0]=L_point3d(r_ijk[0]);
L_ijk[1]=L_point3d(r_ijk[1]);
L_ijk[2]=L_point3d(r_ijk[2]);
wf =2*atan2(dot(r_ijk[0],cross(r_ijk[1],r_ijk[2])),
L_ijk[0]*L_ijk[1]*L_ijk[2]+L_ijk[0]*dot(r_ijk[1],r_ijk[2])+L_ijk[1]*dot(r_ijk[2],r_ijk[0])+L_ijk[2]*dot(r_ijk[0],r_ijk[1]));
face_sum+= (tet[i].F_kron[f].kron[2][0]*r_ijk[0].x+tet[i].F_kron[f].kron[2][1]*r_ijk[0].y+tet[i].F_kron[f].kron[2][2]*r_ijk[0].z)*wf;
}
edge_sum=0;
count=0;
for(int e=0;e<3;e++)
{
for(int e2=e+1;e2<4;e2++)
{
Dv1=Dis_point3d(vert[tet[i].ver[e]].vt,ob_posi);
Dv2=Dis_point3d(vert[tet[i].ver[e2]].vt,ob_posi);
re=vert[tet[i].ver[e]].vt-ob_posi;
Le=log((Dv1+Dv2+tet[i].E_len[count])/(Dv1+Dv2-tet[i].E_len[count]));
edge_sum+= (tet[i].E_kron[count].kron[2][0]*re.x+tet[i].E_kron[count].kron[2][1]*re.y+tet[i].E_kron[count].kron[2][2]*re.z)*Le;
count++;
}
}
cal_data += G0*tet[i].attribute[0]*(face_sum-edge_sum);
}
}
return cal_data;
}
int Tetra_G::cal_tetra_ggc(point3d ob_posi,double& temp_data,double& temp_data2,double& temp_data3)
{
int count;
double cal_data[3];
double Le,wf,face_sum[3],edge_sum[3];
double Dv1,Dv2;
point3d re;
point3d r_ijk[3];
double L_ijk[3];
cal_data[0]=0;
cal_data[1]=0;
cal_data[2]=0;
for(int i=0;i<tetra_sum;i++)
{
if(tet[i].attribute[0]==0.0){
cal_data[0] += 0.0;
cal_data[1] += 0.0;
cal_data[2] += 0.0;
}
else
{
face_sum[0]=0;
face_sum[1]=0;
face_sum[2]=0;
for(int f=0;f<4;f++)
{
r_ijk[0]=vert[tet[i].ordered_ver[f][0]].vt - ob_posi;
r_ijk[1]=vert[tet[i].ordered_ver[f][1]].vt - ob_posi;
r_ijk[2]=vert[tet[i].ordered_ver[f][2]].vt - ob_posi;
L_ijk[0]=L_point3d(r_ijk[0]);
L_ijk[1]=L_point3d(r_ijk[1]);
L_ijk[2]=L_point3d(r_ijk[2]);
wf =2*atan2(dot(r_ijk[0],cross(r_ijk[1],r_ijk[2])),
L_ijk[0]*L_ijk[1]*L_ijk[2]+L_ijk[0]*dot(r_ijk[1],r_ijk[2])+L_ijk[1]*dot(r_ijk[2],r_ijk[0])+L_ijk[2]*dot(r_ijk[0],r_ijk[1]));
face_sum[0]+=tet[i].F_kron[f].kron[2][0]*wf;
face_sum[1]+=tet[i].F_kron[f].kron[2][1]*wf;
face_sum[2]+=tet[i].F_kron[f].kron[2][2]*wf;
}
edge_sum[0]=0;
edge_sum[1]=0;
edge_sum[2]=0;
count=0;
for(int e=0;e<3;e++)
{
for(int e2=e+1;e2<4;e2++)
{
Dv1=Dis_point3d(vert[tet[i].ver[e]].vt,ob_posi);
Dv2=Dis_point3d(vert[tet[i].ver[e2]].vt,ob_posi);
re=vert[tet[i].ver[e]].vt-ob_posi;
Le=log((Dv1+Dv2+tet[i].E_len[count])/(Dv1+Dv2-tet[i].E_len[count]));
edge_sum[0]+=tet[i].E_kron[count].kron[2][0]*Le;
edge_sum[1]+=tet[i].E_kron[count].kron[2][1]*Le;
edge_sum[2]+=tet[i].E_kron[count].kron[2][2]*Le;
count++;
}
}
cal_data[0] += 1e+4*G0*tet[i].attribute[0]*(edge_sum[0]-face_sum[0]);
cal_data[1] += 1e+4*G0*tet[i].attribute[0]*(edge_sum[1]-face_sum[1]);
cal_data[2] += 1e+4*G0*tet[i].attribute[0]*(edge_sum[2]-face_sum[2]);
}
}
temp_data=cal_data[0];
temp_data2=cal_data[1];
temp_data3=cal_data[2];
return 0;
}
double Tetra_G::cal_tetra_gs(point3d ob_posi,sphere_point ob_posi_s)
{
int count;
double cal_data;
double Le,wf,face_sum,edge_sum;
double Dv1,Dv2;
point3d re;
point3d r_ijk[3];
double L_ijk[3];
cal_data=0;
for(int i=0;i<tetra_sum;i++)
{
if(tet[i].attribute[0]==0.0) cal_data += 0.0;
else
{
face_sum=0;
for(int f=0;f<4;f++)
{
r_ijk[0]=vert[tet[i].ordered_ver[f][0]].vt - ob_posi;
r_ijk[1]=vert[tet[i].ordered_ver[f][1]].vt - ob_posi;
r_ijk[2]=vert[tet[i].ordered_ver[f][2]].vt - ob_posi;
L_ijk[0]=L_point3d(r_ijk[0]);
L_ijk[1]=L_point3d(r_ijk[1]);
L_ijk[2]=L_point3d(r_ijk[2]);
wf =2*atan2(dot(r_ijk[0],cross(r_ijk[1],r_ijk[2])),
L_ijk[0]*L_ijk[1]*L_ijk[2]+L_ijk[0]*dot(r_ijk[1],r_ijk[2])+L_ijk[1]*dot(r_ijk[2],r_ijk[0])+L_ijk[2]*dot(r_ijk[0],r_ijk[1]));
face_sum+= (martix_point3d(r_ijk[0],tet[i].F_kron[f].kron[0]).x*sin((0.5-ob_posi_s.thet/180)*pi)*cos((2+ob_posi_s.phi/180)*pi)+
martix_point3d(r_ijk[0],tet[i].F_kron[f].kron[0]).y*sin((0.5-ob_posi_s.thet/180)*pi)*sin((2+ob_posi_s.phi/180)*pi)+
martix_point3d(r_ijk[0],tet[i].F_kron[f].kron[0]).z*cos((0.5-ob_posi_s.thet/180)*pi))*wf;
}
edge_sum=0;
count=0;
for(int e=0;e<3;e++)
{
for(int e2=e+1;e2<4;e2++)
{
Dv1=Dis_point3d(vert[tet[i].ver[e]].vt,ob_posi);
Dv2=Dis_point3d(vert[tet[i].ver[e2]].vt,ob_posi);
re=vert[tet[i].ver[e]].vt-ob_posi;
Le=log((Dv1+Dv2+tet[i].E_len[count])/(Dv1+Dv2-tet[i].E_len[count]));
edge_sum+= (martix_point3d(re,tet[i].E_kron[count].kron[0]).x*sin((0.5-ob_posi_s.thet/180)*pi)*cos((2+ob_posi_s.phi/180)*pi)+
martix_point3d(re,tet[i].E_kron[count].kron[0]).y*sin((0.5-ob_posi_s.thet/180)*pi)*sin((2+ob_posi_s.phi/180)*pi)+
martix_point3d(re,tet[i].E_kron[count].kron[0]).z*cos((0.5-ob_posi_s.thet/180)*pi))*Le;
count++;
}
}
cal_data += G0*tet[i].attribute[0]*(edge_sum-face_sum);
}
}
return cal_data;
}
int Tetra_G::cal_tetra_ggs(point3d ob_posi,sphere_point ob_posi_s,double& temp_data,double& temp_data2,double& temp_data3)
{
int count;
double* face_temp;
double* edge_temp;
double R[3][3];
double cal_data[3];
double Le,wf,face_sum[3],edge_sum[3];
double Dv1,Dv2;
point3d re;
point3d r_ijk[3];
double L_ijk[3];
R[0][0] = sin((0.5-ob_posi_s.thet/180)*pi)*cos((2+ob_posi_s.phi/180)*pi); R[0][1] = sin((0.5-ob_posi_s.thet/180)*pi)*sin((2+ob_posi_s.phi/180)*pi); R[0][2] = cos((0.5-ob_posi_s.thet/180)*pi);
R[1][0] = cos((0.5-ob_posi_s.thet/180)*pi)*cos((2+ob_posi_s.phi/180)*pi); R[1][1] = cos((0.5-ob_posi_s.thet/180)*pi)*sin((2+ob_posi_s.phi/180)*pi); R[1][2] = -1*sin((0.5-ob_posi_s.thet/180)*pi);
R[2][0] = -1*sin((2+ob_posi_s.phi/180)*pi); R[2][1] = cos((2+ob_posi_s.phi/180)*pi); R[2][2] = 0;
cal_data[0]=0;
cal_data[1]=0;
cal_data[2]=0;
for(int i=0;i<tetra_sum;i++)
{
if(tet[i].attribute[0]==0.0){
cal_data[0] += 0.0;
cal_data[1] += 0.0;
cal_data[2] += 0.0;
}
else
{
face_sum[0]=0;
face_sum[1]=0;
face_sum[2]=0;
for(int f=0;f<4;f++)
{
r_ijk[0]=vert[tet[i].ordered_ver[f][0]].vt - ob_posi;
r_ijk[1]=vert[tet[i].ordered_ver[f][1]].vt - ob_posi;
r_ijk[2]=vert[tet[i].ordered_ver[f][2]].vt - ob_posi;
L_ijk[0]=L_point3d(r_ijk[0]);
L_ijk[1]=L_point3d(r_ijk[1]);
L_ijk[2]=L_point3d(r_ijk[2]);
wf =2*atan2(dot(r_ijk[0],cross(r_ijk[1],r_ijk[2])),
L_ijk[0]*L_ijk[1]*L_ijk[2]+L_ijk[0]*dot(r_ijk[1],r_ijk[2])+L_ijk[1]*dot(r_ijk[2],r_ijk[0])+L_ijk[2]*dot(r_ijk[0],r_ijk[1]));
face_temp = martix_martix(martix_martix(R[0],tet[i].F_kron[f].kron[0]),martix_T(R[0]));
face_sum[0]+= *(face_temp) * wf;
face_sum[1]+= *(face_temp+1) * wf;
face_sum[2]+= *(face_temp+2) * wf;
}
edge_sum[0]=0;
edge_sum[1]=0;
edge_sum[2]=0;
count=0;
for(int e=0;e<3;e++)
{
for(int e2=e+1;e2<4;e2++)
{
Dv1=Dis_point3d(vert[tet[i].ver[e]].vt,ob_posi);
Dv2=Dis_point3d(vert[tet[i].ver[e2]].vt,ob_posi);
re=vert[tet[i].ver[e]].vt-ob_posi;
Le=log((Dv1+Dv2+tet[i].E_len[count])/(Dv1+Dv2-tet[i].E_len[count]));
edge_temp = martix_martix(martix_martix(R[0],tet[i].E_kron[count].kron[0]),martix_T(R[0]));
edge_sum[0]+= *(edge_temp) * Le;
edge_sum[1]+= *(edge_temp+1) * Le;
edge_sum[2]+= *(edge_temp+2) * Le;
count++;
}
}
cal_data[0] += 1e+4*G0*tet[i].attribute[0]*(edge_sum[0]-face_sum[0]);
cal_data[1] += 1e+4*G0*tet[i].attribute[0]*(edge_sum[1]-face_sum[1]);
cal_data[2] += 1e+4*G0*tet[i].attribute[0]*(edge_sum[2]-face_sum[2]);
}
}
temp_data=cal_data[0];
temp_data2=cal_data[1];
temp_data3=cal_data[2];
return 0;
}
/************************************************************************/
int Tetra_G::cal_total_g(int cal_type,string filename)
{
int i;
cout<<"calculating gravity or magnetic filed, expected time-consuming: "<<once_time*tetra_sum*fie_sum<<" s...";
start = clock();
if(cal_type==1)
{
res_reg Res(fie_sum);
_Obdata = new double [fie_sum];
#pragma omp parallel for private(i) schedule(runtime)//对四面体网络在不同测点的计算值执行并行计算
for(i=0;i<fie_sum;i++)
{
_Obdata[i]=cal_tetra_gc(fie[i]);
}
finish=clock();
cout<<"done! "<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
Res.res_add(_Obdata,fie_sum);
if(Res.check(fie_sum))
{
system("pause");
exit(0);
}
if(Res.savedat(filename,fie_sum,fie))
{
system("pause");
exit(0);
}
}
else if(cal_type==2)
{
res_reg Res(fie_sum);
res_reg Res2(fie_sum);
res_reg Res3(fie_sum);
_Obdata = new double [fie_sum];
_Obdata2 = new double [fie_sum];
_Obdata3 = new double [fie_sum];
#pragma omp parallel for private(i) schedule(runtime)//对四面体网络在不同测点的计算值执行并行计算
for(i=0;i<fie_sum;i++)
{
cal_tetra_ggc(fie[i],_Obdata[i],_Obdata2[i],_Obdata3[i]);
}
finish=clock();
cout<<"done! "<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
Res.res_add(_Obdata,fie_sum);
Res2.res_add(_Obdata2,fie_sum);
Res3.res_add(_Obdata3,fie_sum);
if(Res.check(fie_sum)||Res2.check(fie_sum)||Res3.check(fie_sum))
{
system("pause");
exit(0);
}
if(Res.savedat(filename + "_gx",fie_sum,fie)||Res2.savedat(filename + "_gy",fie_sum,fie)||Res3.savedat(filename + "_gz",fie_sum,fie))
{
system("pause");
exit(0);
}
}
else if(cal_type==3)
{
res_reg Res(fie_sum);
_Obdata = new double [fie_sum];
#pragma omp parallel for private(i) schedule(runtime)//对四面体网络在不同测点的计算值执行并行计算
for(i=0;i<fie_sum;i++)
{
_Obdata[i]=cal_tetra_gs(fie[i],s_point[i]);
}
finish=clock();
cout<<"done! "<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
Res.res_add(_Obdata,fie_sum);
if(Res.check(fie_sum))
{
system("pause");
exit(0);
}
if(Res.savedat(filename,fie_sum,s_point))
{
system("pause");
exit(0);
}
}
else if(cal_type==4)
{
res_reg Res(fie_sum);
res_reg Res2(fie_sum);
res_reg Res3(fie_sum);
_Obdata = new double [fie_sum];
_Obdata2 = new double [fie_sum];
_Obdata3 = new double [fie_sum];
#pragma omp parallel for private(i) schedule(runtime)//对四面体网络在不同测点的计算值执行并行计算
for(i=0;i<fie_sum;i++)
{
cal_tetra_ggs(fie[i],s_point[i],_Obdata[i],_Obdata2[i],_Obdata3[i]);
}
finish=clock();
cout<<"done! "<<(double)(finish-start)/CLOCKS_PER_SEC<<" s"<<endl;
Res.res_add(_Obdata,fie_sum);
Res2.res_add(_Obdata2,fie_sum);
Res3.res_add(_Obdata3,fie_sum);
if(Res.check(fie_sum)||Res2.check(fie_sum)||Res3.check(fie_sum))
{
system("pause");
exit(0);
}
if(Res.savedat(filename + "_gr",fie_sum,s_point)||Res2.savedat(filename + "_gthet",fie_sum,s_point)||Res3.savedat(filename + "_gphi",fie_sum,s_point))
{
system("pause");
exit(0);
}
}
return 0;
}
#endif