429 lines
13 KiB
C++
429 lines
13 KiB
C++
/*
|
||
TetraGM4.0 四面体网络正演程序
|
||
2015/11/12
|
||
为避免之前版本中的冗余计算过程,在4.0版本中我们将对程序的数据结构做出调整(大改)。
|
||
通过模型对比实验,程序的计算效率有了质的提升。同时4.0版本更适合与并行计算的要求。调整后
|
||
的程序结构任未达到最优化状态,但进一步的优化需要获取更多的网络信息(每一条边的索引、每
|
||
一个面的索引)。准备从其他格式的网络文件(如.msh文件)中寻找突破口。
|
||
2015/11/13
|
||
今天在程序中加入了并行执行的命令,程序的运行效率有了进一步的提升。在i5,4G内存平台上
|
||
提升率约为原计算效率的两倍。相信在更高主频的平台能取得更好的成绩。
|
||
|
||
程序数据结构:调整后基本数据结构如下。
|
||
point3d(矢量结构):矢量的坐标(x,y,z)
|
||
sphere_point(球面点/地理坐标系):顶点的经纬值与球坐标半径
|
||
vertex(顶点结构):顶点的索引号,点坐标
|
||
edge(边结构体):边的编号,边的顶点索引,边的属性,边的长度,边的张量积E
|
||
face(面结构体):面的编号,面的顶点索引,面的属性,面的张量积F
|
||
tetra(四面体结构体):四面体的索引号、
|
||
四面体四个顶点的索引号、
|
||
重新排序后的四组三角形的索引号(记录排序后信息有利于后续的利用,避免函数的重复调用)
|
||
四个面的张量积F、
|
||
六条边的张量积E与边的长度(F、E与边长四面体是的固有属性,首先计算出来可以有效减少冗余计算)
|
||
四面体属性值
|
||
程序文件结构:Data_Func.h文件定义了数据类型与需要使用到的矢量运算函数
|
||
Commond_Line.h文件定义了程序中规定的命令行操作符
|
||
res_reg.h文件定义了计算结果的暂存与写入文件函数
|
||
Tetra_G.h文件定义了重力场正演类
|
||
Tetra_M.h文件定义了磁场正演类
|
||
main.cpp识别命令行指令,调取相应函数响应
|
||
*/
|
||
|
||
#include "Tetra_G.h"
|
||
#include "Commond_Line.h"
|
||
|
||
int caltype = NULL;//计算目标
|
||
int fietype = NULL;//观测点类型
|
||
int attritype = NULL;//元属性类型
|
||
int elementtype = NULL;//计算元类型
|
||
int space_num;//字符串中空格的个数
|
||
double attri[3];//元属性
|
||
double ob_info[7];//自定义观测面信息
|
||
string _attri;
|
||
string meshname;
|
||
string fiename;
|
||
string savename;
|
||
stringstream stemp;
|
||
|
||
void disp_info()
|
||
{
|
||
cout<<"tetragm 0.5.0 - forward modeling of gravity and magnetic data and their gradient data based on unstructured grid"<<endl<<endl
|
||
<<"usage: tetragm -gc|ggc|gs|ggs|mc|ms|mgc|mgs -a[<para1>/<para2>/<para3>/<para4>] -v<mesh-file>|s<mesh-file>"<<endl
|
||
<<" -F<fie-file>|M[<xmin>/<dx>/<xmax>/<ymin>/<dy>/<ymax>/<altitude>][<lati_min>/<d_lati>/<lati_max>/"<<endl
|
||
<<" <longi_min>/<d_longi>/<longi_max>/<radius>] -o<output-file>"<<endl
|
||
<<" -gc forward modeling gravity data in Cartesian coordinate"<<endl
|
||
<<" -ggc forward modeling gravity gradient data in Cartesian coordinate"<<endl
|
||
<<" -gs forward modeling gravity data in spherical coordinate"<<endl
|
||
<<" -ggs forward modeling gravity gradient data in spherical coordinate"<<endl
|
||
<<" -mc forward modeling magnetic data in Cartesian coordinate"<<endl
|
||
<<" -mgc forward modeling magnetic gradient data in Cartesian coordinate"<<endl
|
||
<<" -ms forward modeling magnetic data in spherical coordinate"<<endl
|
||
<<" -mgs forward modeling magnetic gradient data in spherical coordinate"<<endl
|
||
<<" -a define cells' physical attributes. If no arguments are followed behind -a, it means that the cells'"<<endl
|
||
<<" attributes are defined by the mesh-file individually. For forward modeling gravity and its gradient"<<endl
|
||
<<" data, density is the only parameter the program need. In this case, you just need to specify 'para1'."<<endl
|
||
<<" For example '1.0///'. For forward modeling magnetic and its gradient data. Parameters are as follow"<<endl
|
||
<<" para1 "<<endl
|
||
<<"-Vstring: use volume element, followed by mesh file's name"<<endl
|
||
<<"-Sstring: use surface element, followed by mesh file's name"<<endl
|
||
<<"-Fstring: read observation points from a .fie file, followed by file name"<<endl
|
||
<<"-Mdouble/double/double/double/double/double/double: user defined observation points, format:"<<endl
|
||
<<"xmin/dx/xmax/ymin/dy/ymax/altitude"<<endl
|
||
<<"lati_min/d_lati/lati_max/longi_min/d_longi/longi_max/radius"<<endl
|
||
<<"-Ostring: Output file, followed by file name"<<endl;
|
||
}
|
||
|
||
int typeget(char *str, const char* str2,string &str3)
|
||
{
|
||
char* strp = strstr(str, str2); // 从字符串str中查找str2,
|
||
if (strp == NULL)
|
||
{
|
||
return 0; // 如果没有找到,返回
|
||
}
|
||
string temp = str;
|
||
str3=temp.substr(strlen(str2));//提出除str2外的子句
|
||
return 1;
|
||
}
|
||
|
||
string& replace_all(string& str,const string& old_value,const string& new_value,int &num) //替换str中所有lod_value为new_value,返回被替换的lod_value的个数
|
||
{
|
||
int count = 0;
|
||
for(string::size_type pos(0);pos!=string::npos;pos+=new_value.length()){
|
||
if((pos=str.find(old_value,pos))!=string::npos){
|
||
str.replace(pos,old_value.length(),new_value);
|
||
count++;
|
||
}
|
||
else break;
|
||
}
|
||
num = count;
|
||
return str;
|
||
}
|
||
|
||
/*
|
||
caltype -GC:1 -GGC:2 -GS:3 -GGS:4 -MC:5 -MGC:6 -MS:7 -MGS:8
|
||
elementtype -V:1 -S:2
|
||
attritype -F:1 -M:2
|
||
*/
|
||
struct Call_func
|
||
{
|
||
int callback_func(int caltype,int elementtype,string filename,string fiename,string savename)
|
||
{
|
||
switch (caltype)
|
||
{
|
||
case 1:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,fiename,savename)) return 1;
|
||
}break;
|
||
case 2:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,fiename,savename)) return 1;
|
||
}break;
|
||
case 3:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,fiename,savename)) return 1;
|
||
}break;
|
||
case 4:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,fiename,savename)) return 1;
|
||
}break;
|
||
case 5:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 6:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 7:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 8:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
default:{
|
||
cout<<"An error picked at 'callback_func()', program stopped...";
|
||
exit(0);
|
||
}break;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int callback_func(int caltype,int elementtype,string filename,double* ob_info,string savename)
|
||
{
|
||
switch (caltype)
|
||
{
|
||
case 1:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,ob_info,savename)) return 1;
|
||
}break;
|
||
case 2:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,ob_info,savename)) return 1;
|
||
}break;
|
||
case 3:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,ob_info,savename)) return 1;
|
||
}break;
|
||
case 4:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,ob_info,savename)) return 1;
|
||
}break;
|
||
case 5:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 6:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 7:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 8:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
default:{
|
||
cout<<"An error picked at 'callback_func()', program stopped...";
|
||
exit(0);
|
||
}break;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int callback_func(int caltype,int elementtype,string filename,string fiename,string savename,double* attri)
|
||
{
|
||
switch (caltype)
|
||
{
|
||
case 1:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,fiename,savename,attri)) return 1;
|
||
}break;
|
||
case 2:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,fiename,savename,attri)) return 1;
|
||
}break;
|
||
case 3:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,fiename,savename,attri)) return 1;
|
||
}break;
|
||
case 4:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,fiename,savename,attri)) return 1;
|
||
}break;
|
||
case 5:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 6:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 7:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 8:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
default:{
|
||
cout<<"An error picked at 'callback_func()', program stopped...";
|
||
exit(0);
|
||
}break;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int callback_func(int caltype,int elementtype,string filename,double* ob_info,string savename,double* attri)
|
||
{
|
||
switch (caltype)
|
||
{
|
||
case 1:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,ob_info,savename,attri)) return 1;
|
||
}break;
|
||
case 2:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,ob_info,savename,attri)) return 1;
|
||
}break;
|
||
case 3:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,ob_info,savename,attri)) return 1;
|
||
}break;
|
||
case 4:{
|
||
Tetra_G _Project;
|
||
if(_Project.info_taker_run(caltype,filename,ob_info,savename,attri)) return 1;
|
||
}break;
|
||
case 5:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 6:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 7:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
case 8:{
|
||
cout<<"Unfished!"<<endl;
|
||
}break;
|
||
default:{
|
||
cout<<"An error picked at 'callback_func()', program stopped...";
|
||
exit(0);
|
||
}break;
|
||
}
|
||
return 0;
|
||
}
|
||
};
|
||
|
||
int main(int argc,char* argv[])
|
||
{
|
||
if(argc==1){
|
||
disp_info();
|
||
}
|
||
else{
|
||
Call_func Call;
|
||
|
||
for(int i=1;i<=argc-1;i++){
|
||
//解析计算目标
|
||
if(!strcmp(argv[i],ForGC)) caltype=1;
|
||
else if(!strcmp(argv[i],ForGGC)) caltype=2;
|
||
else if(!strcmp(argv[i],ForGS)) caltype=3;
|
||
else if(!strcmp(argv[i],ForGGS)) caltype=4;
|
||
else if(!strcmp(argv[i],ForMC)) caltype=5;
|
||
else if(!strcmp(argv[i],ForMGC)) caltype=6;
|
||
else if(!strcmp(argv[i],ForMS)) caltype=7;
|
||
else if(!strcmp(argv[i],ForMGS)) caltype=8;
|
||
|
||
//解析元属性,需要滞后
|
||
if(typeget(argv[i],ATTRI,_attri)){
|
||
if(_attri!=""){
|
||
attritype=2;
|
||
replace_all(_attri,"/"," ",space_num);
|
||
stemp.clear();
|
||
stemp.str(_attri);
|
||
if(space_num==3){
|
||
for(int i=0;i<4;i++)
|
||
{
|
||
if(!(stemp>>attri[i])){
|
||
attri[i]=DBL_MAX;
|
||
}
|
||
}
|
||
}
|
||
else{
|
||
cout<<"Insufficient attributes information, program stoped...";//自定义观测面信息错误或不完整,程序停止
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
|
||
}
|
||
else attritype=1;//若无给定元信息
|
||
}
|
||
|
||
//解析元类型与网络文件名
|
||
if(typeget(argv[i],VolumeElement,meshname)){
|
||
elementtype = 1;
|
||
if(meshname==""){
|
||
cout<<"No mesh file name, program stoped...";//无网络文件名,程序停止
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
else if(typeget(argv[i],SurfaceElement,meshname)){
|
||
elementtype = 2;
|
||
if(meshname==""){
|
||
cout<<"No mesh file name, program stoped...";//无网络文件名,程序停止
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
|
||
//解析观测信息
|
||
if(typeget(argv[i],FILE,fiename)){
|
||
fietype=1;
|
||
if(fiename==""){
|
||
cout<<"No observation points' information, program stoped...";//无观测点文件,程序停止
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
else if(typeget(argv[i],MANUAL,fiename)){
|
||
fietype=2;
|
||
if(fiename==""){
|
||
cout<<"No observation points' information, program stoped...";//无自定义观测面信息,程序停止
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
else{
|
||
replace_all(fiename,"/"," ",space_num);
|
||
stemp.clear();
|
||
stemp.str(fiename);
|
||
if(space_num==6){
|
||
for(int i=0;i<7;i++)
|
||
{
|
||
if(!(stemp>>ob_info[i])){
|
||
ob_info[i]=DBL_MAX;
|
||
}
|
||
}
|
||
for(int i=0;i<7;i++)
|
||
{
|
||
if(ob_info[i]==DBL_MAX){
|
||
cout<<"Wrong observation points' information, program stoped...";//自定义观测面信息错误或不完整,程序停止
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
if(ob_info[1]<0||ob_info[4]<0||ob_info[0]>ob_info[2]||ob_info[3]>ob_info[5]||(ob_info[0]+ob_info[1])>ob_info[2]||(ob_info[3]+ob_info[4])>ob_info[5]){
|
||
cout<<"Wrong observation points' information, program stoped...";//自定义观测面信息错误或不完整,程序停止
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
else{
|
||
cout<<"Wrong observation points' information, program stoped...";//自定义观测面信息错误或不完整,程序停止
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
//解析输出文件名
|
||
if(typeget(argv[i],OUTFILE,savename)){
|
||
if(savename==""){
|
||
cout<<"No output file name, program stoped...";//无输出文件名,程序停止
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
}
|
||
|
||
if(caltype==NULL||fietype==NULL||attritype==NULL||elementtype==NULL||savename==""){
|
||
cout<<"Wrong commond line, program stoped...";
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
|
||
if(fietype==1&&attritype==1){
|
||
if(Call.callback_func(caltype,elementtype,meshname,fiename,savename)){
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
else if(fietype==1&&attritype==2){
|
||
if(Call.callback_func(caltype,elementtype,meshname,fiename,savename,attri)){
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
else if(fietype==2&&attritype==1){
|
||
if(Call.callback_func(caltype,elementtype,meshname,ob_info,savename)){
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
else if(fietype==2&&attritype==2){
|
||
if(Call.callback_func(caltype,elementtype,meshname,ob_info,savename,attri)){
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
else{
|
||
cout<<"A program error is detected, program stopped...";
|
||
system("pause");
|
||
exit(0);
|
||
}
|
||
}
|
||
return 0;
|
||
} |