initial upload
This commit is contained in:
36
archive/sh2xyz/.gitignore
vendored
Normal file
36
archive/sh2xyz/.gitignore
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.ex
|
||||
|
||||
# Pdf documents
|
||||
*.pdf
|
21
archive/sh2xyz/CMakeLists.txt
Normal file
21
archive/sh2xyz/CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
#Uncomment the following two lines to compile the sources as an individual cmake porject. Change the <project_name> as you wanted.
|
||||
#cmake_minimum_required(VERSION 3.15.2)
|
||||
#project(<project_name>)
|
||||
|
||||
#Set executable name here
|
||||
set(name sh2xyz)
|
||||
|
||||
aux_source_directory(. "${name}_src")
|
||||
add_executable(${name} ${${name}_src})
|
||||
set_target_properties(${name} PROPERTIES CXX_STANDARD 11)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
install(TARGETS ${name} RUNTIME DESTINATION sbin)
|
||||
|
||||
#Find and link openmp library
|
||||
find_package(OpenMP REQUIRED)
|
||||
if (OpenMP_CXX_FOUND)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
|
||||
endif()
|
||||
|
||||
target_link_libraries(${name} PUBLIC OpenMP::OpenMP_CXX)
|
143
archive/sh2xyz/NALF-SFCM.h
Normal file
143
archive/sh2xyz/NALF-SFCM.h
Normal file
@@ -0,0 +1,143 @@
|
||||
// Fully normalized associated Legendre functions calculated by standard forward column methods
|
||||
// Holmes, S. A., & Featherstone, W. E. (2002).
|
||||
// A unified approach to the Clenshaw summation and the recursive computation of very high degree and order normalised associated Legendre functions.
|
||||
// Journal of Geodesy, 76(5), 279–299. https://doi.org/10.1007/s00190-002-0216-2
|
||||
// Author: Yi Zhang (zhangyi.cugwuhan@gmail.com)
|
||||
#ifndef _NALF_SFCM_H
|
||||
#define _NALF_SFCM_H
|
||||
#include "sysDefine.h"
|
||||
//计算向前列推的系数 避免重复计算 这里不要使用vector at() 速度比较慢 直接使用[] 注意调用size()函数也会降低执行效率
|
||||
_2dArray get_a_nm_array(int MaxOrder)
|
||||
{
|
||||
int i,j;
|
||||
_2dArray cs;
|
||||
cs.resize(MaxOrder);
|
||||
for (i = 0; i < MaxOrder; i++)
|
||||
cs[i].resize(i+1);
|
||||
//向下列推计算
|
||||
#pragma omp parallel for private(i,j) schedule(guided)
|
||||
for (j = 0; j < MaxOrder; j++)
|
||||
{
|
||||
cs[j][j] = 0; //对角线上的值直接给0 反正用不到
|
||||
for (i = j+1; i < MaxOrder; i++)
|
||||
{
|
||||
cs[i][j] = sqrt(((2.0*i-1)*(2.0*i+1))/((i-j)*(i+j)));
|
||||
}
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
_2dArray get_b_nm_array(int MaxOrder)
|
||||
{
|
||||
int i,j;
|
||||
_2dArray cs;
|
||||
cs.resize(MaxOrder);
|
||||
for (i = 0; i < MaxOrder; i++)
|
||||
cs[i].resize(i+1);
|
||||
//向下列推计算
|
||||
#pragma omp parallel for private(i,j) schedule(guided)
|
||||
for (j = 0; j < MaxOrder; j++)
|
||||
{
|
||||
cs[j][j] = 0; //对角线上的值直接给0 反正用不到
|
||||
for (i = j+1; i < MaxOrder; i++)
|
||||
{
|
||||
cs[i][j] = sqrt(((2.0*i+1)*(i+j-1)*(i-j-1))/((i-j)*(i+j)*(2.0*i-3)));
|
||||
}
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
// 计算标准前向列推法计算规格化的勒让德多项式 输入参数为需要计算的最大阶次MaxOrder 余纬度theta(度) 返回一个下半三角二维数组
|
||||
// 最大维度为MaxOrder+1,二维数组中行数代表阶数列数为次数
|
||||
_2dArray NALF_SFCM(int MaxOrder,_2dArray a_nm,_2dArray b_nm,double theta)
|
||||
{
|
||||
//声明数组 初始化一个下半三角二维数组
|
||||
_2dArray nalf;
|
||||
nalf.resize(MaxOrder);
|
||||
for (int i = 0; i < MaxOrder; i++)
|
||||
nalf.at(i).resize(i+1);
|
||||
|
||||
//赋初值给前两个对角线上的值
|
||||
nalf.at(0).at(0) = 1.0;
|
||||
nalf.at(1).at(1) = sqrt(3.0)*sin(theta*pi/180.0);
|
||||
//计算对角线上的值 递归计算 不能并行
|
||||
for (int i = 2; i < nalf.size(); i++)
|
||||
nalf.at(i).at(i) = sin(theta*pi/180.0)*sqrt(0.5*(2.0*i+1)/i)*nalf.at(i-1).at(i-1);
|
||||
|
||||
//声明系数和迭代变量
|
||||
int i,j;
|
||||
double Pn_2m,Pn_1m; //Pn-1,m Pn-2,m
|
||||
//这里可以使用并行加速计算外层循环 内层计算因为是递归计算因此不能并行
|
||||
#pragma omp parallel for private(i,j,Pn_2m,Pn_1m) schedule(guided)
|
||||
for (j = 0; j < nalf.size()-1; j++)
|
||||
{
|
||||
Pn_2m = 0;
|
||||
Pn_1m = nalf.at(j).at(j);
|
||||
for (i = j+1; i < nalf.size(); i++)
|
||||
{
|
||||
nalf.at(i).at(j) = a_nm.at(i).at(j)*cos(theta*pi/180.0)*Pn_1m - b_nm.at(i).at(j)*Pn_2m;
|
||||
|
||||
Pn_2m = nalf.at(i-1).at(j);
|
||||
Pn_1m = nalf.at(i).at(j);
|
||||
}
|
||||
}
|
||||
return nalf;
|
||||
}
|
||||
|
||||
// 计算标准前向列推法计算规格化的勒让德多项式 输入参数 一个下半三角二维矩阵 余纬度theta(度) 无返回值
|
||||
// 二维数组中行数代表阶数列数为次数
|
||||
void NALF_SFCM2(_2dArray& nalf,_2dArray a_nm,_2dArray b_nm,double theta)
|
||||
{
|
||||
//赋初值给前两个对角线上的值
|
||||
nalf.at(0).at(0) = 1.0;
|
||||
nalf.at(1).at(1) = sqrt(3.0)*sin(theta*pi/180.0);
|
||||
//计算对角线上的值 递归计算 不能并行
|
||||
for (int i = 2; i < nalf.size(); i++)
|
||||
nalf.at(i).at(i) = sin(theta*pi/180.0)*sqrt(0.5*(2.0*i+1)/i)*nalf.at(i-1).at(i-1);
|
||||
|
||||
//声明系数和迭代变量
|
||||
int i,j;
|
||||
double Pn_2m,Pn_1m; //Pn-1,m Pn-2,m
|
||||
//这里可以使用并行加速计算外层循环 内层计算因为是递归计算因此不能并行
|
||||
#pragma omp parallel for private(i,j,Pn_2m,Pn_1m) schedule(guided)
|
||||
for (j = 0; j < nalf.size()-1; j++)
|
||||
{
|
||||
Pn_2m = 0;
|
||||
Pn_1m = nalf.at(j).at(j);
|
||||
for (i = j+1; i < nalf.size(); i++)
|
||||
{
|
||||
nalf.at(i).at(j) = a_nm.at(i).at(j)*cos(theta*pi/180.0)*Pn_1m - b_nm.at(i).at(j)*Pn_2m;
|
||||
|
||||
Pn_2m = nalf.at(i-1).at(j);
|
||||
Pn_1m = nalf.at(i).at(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NALF_SFCM3(_2dArray& nalf,_2dArray a_nm,_2dArray b_nm,int maxOrder,double theta,double norSum)
|
||||
{
|
||||
//赋初值给前两个对角线上的值
|
||||
//norSum为1时第一个值为1/sqrt(4.0*pi),归一化值为1, norSum为4.0*pi时第一个值为4.0*pi/sqrt(4.0*pi)=1,归一化值为4.0*pi
|
||||
nalf[0][0] = sqrt(norSum)/sqrt(4.0*pi);
|
||||
nalf[1][1] = sqrt(3.0)*sin(theta*pi/180.0);
|
||||
//计算对角线上的值 递归计算 不能并行
|
||||
for (int i = 2; i < maxOrder; i++)
|
||||
nalf[i][i] = sin(theta*pi/180.0)*sqrt(0.5*(2.0*i+1)/i)*nalf[i-1][i-1];
|
||||
|
||||
//计算次对角线(m+1,m)上的值 递归计算 不能并行
|
||||
for (int i = 0; i < maxOrder-1; i++)
|
||||
nalf[i+1][i] = cos(theta*pi/180.0)*sqrt(2.0*i+3)*nalf[i][i];
|
||||
|
||||
//声明系数和迭代变量
|
||||
int i,j;
|
||||
//这里可以使用并行加速计算外层循环 内层计算因为是递归计算因此不能并行
|
||||
#pragma omp parallel for private(i,j) schedule(guided)
|
||||
for (j = 0; j < maxOrder-1; j++)
|
||||
{
|
||||
for (i = j+2; i < maxOrder; i++)
|
||||
{
|
||||
nalf[i][j] = a_nm[i][j]*cos(theta*pi/180.0)*nalf[i-1][j] - b_nm[i][j]*nalf[i-2][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
71
archive/sh2xyz/README.md
Normal file
71
archive/sh2xyz/README.md
Normal file
@@ -0,0 +1,71 @@
|
||||
## Forward calculation of topographic or gravitational data using spherical harmonic coefficients
|
||||
|
||||
### Introduction
|
||||
|
||||
### Files and folders
|
||||
|
||||
1. **CMakeLists.txt** CMake project file;
|
||||
2. **\*.h and \*.cpp** Source files;
|
||||
3. **README.md** This file;
|
||||
4. **example** Example files.
|
||||
|
||||
#### Source file lists
|
||||
|
||||
```shell
|
||||
main.cpp
|
||||
NALF-SFCM.h
|
||||
progressBar_imp.h
|
||||
sh2xyz.h
|
||||
sysDefine.h
|
||||
```
|
||||
|
||||
### Installation
|
||||
|
||||
This program is a toolkit of a [software collection](https://gitee.com/yizhangss/toolkits) that is developed and maintained by Dr. Yi Zhang (zhangyiss@icloud.com) , which could be compiled and installed using the [CMake](https://cmake.org) software. Follow the three step instructions bellow, if you want to compile this program out of the collection.
|
||||
|
||||
1. Uncomment the first two lines in the `CMakeLists.txt` file,
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.15.2)
|
||||
project(<project_name>)
|
||||
```
|
||||
|
||||
1. Compile the program as
|
||||
|
||||
```shell
|
||||
mkdir build && cd build && make
|
||||
```
|
||||
|
||||
3. Move or symlink the executable file to any directory included in your $PATH, for instance, `/usr/local/bin`.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
sph2xyz -t<table> -r<lonmin>/<lonmax>/<latmin>/<latmax>[/<altitude>] -i<dlon>/<dlat> -d<type> -f<ln>/<lm>/<hn>/<hm> [-p<loc-file>] [-s<refr>/<refR>] [-g<GM>/<R>] [-n<type>] [-c<col1>,<col2>,<col3>,<col4>] [-z<alti-file>[+d<col1>,<col2>,<col3>]] [-h] > out-file
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
+ __-t__: Input filename of the coefficients.
|
||||
+ __-r__: Initialize the range of observation points. Altitude of the points is optional (will be 0 if no set).
|
||||
+ __-i__: Intervals of the observation points.
|
||||
+ __-d__: Types of forward calculation.
|
||||
+ __-f__: Starting and ending order/degree that will be used for calculation.
|
||||
+ __-p__: Interpolate the forward calculated data to spherical locations read from the file.
|
||||
+ __-s__: short and long semi-radius of the reference coordinate system.
|
||||
+ __-g__: Model parameters of gravity models. This option must be set if we are calculating gravitational data.
|
||||
+ __-n__: Normalization type of the Associated Legendre Function.
|
||||
+ __-c__: Select input columns of the coefficients.
|
||||
+ __-z__: Initialize the observation's altitudes from the a input file.
|
||||
+ __-h__: Show help information.
|
||||
|
||||
### Examples
|
||||
|
||||
To forward calculating an `example.SHcoeffs` which maximal degree/order are both 360.
|
||||
|
||||
```bash
|
||||
sh2xyz -t example.SHcoeffs -r -180/180/-90/90/0 -i 0.5/0.5 -f 0/0/360/360 -s 10000/10000 > example.txt
|
||||
```
|
||||
|
||||
The calculated data is shown as below:
|
||||

|
65343
archive/sh2xyz/example/example.SHcoeffs
Normal file
65343
archive/sh2xyz/example/example.SHcoeffs
Normal file
File diff suppressed because it is too large
Load Diff
10316
archive/sh2xyz/example/example.eps
Normal file
10316
archive/sh2xyz/example/example.eps
Normal file
File diff suppressed because it is too large
Load Diff
BIN
archive/sh2xyz/example/example.nc
Normal file
BIN
archive/sh2xyz/example/example.nc
Normal file
Binary file not shown.
BIN
archive/sh2xyz/example/example.png
Normal file
BIN
archive/sh2xyz/example/example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 409 KiB |
260283
archive/sh2xyz/example/example.txt
Normal file
260283
archive/sh2xyz/example/example.txt
Normal file
File diff suppressed because it is too large
Load Diff
154
archive/sh2xyz/main.cpp
Normal file
154
archive/sh2xyz/main.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#include "sh2xyz.h"
|
||||
|
||||
void disp_help()
|
||||
{
|
||||
cout << "sh2xyz - v0.1 calculated spherical harmonic coefficients to table data" << endl
|
||||
<< "Author: zhangyi.cugwuhan@gmail.com" << endl << endl
|
||||
<< "usage: sh2xyz -t<table> -r<lonmin>/<lonmax>/<latmin>/<latmax>[/<altitude>] -i<dlon>/<dlat> -d<type> -f<ln>/<lm>/<hn>/<hm> [-p<loc-file>] [-s<refr>/<refR>] [-g<GM>/<R>] [-n<type>] [-c<col1>,<col2>,<col3>,<col4>] [-z<alti-file>[+d<col1>,<col2>,<col3>]] [-h] > out-file" << endl
|
||||
<< "-t\tinput spherical harmonic coefficients, four columns are needed at least" << endl
|
||||
<< "-r\tcalculation range" << endl
|
||||
<< "-i\tcalculation intervals" << endl
|
||||
<< "-d\tcalculation types, \n\tt for topography (default)\n\td for gravity disturbance\n\tg for gravity anomaly and\n\tp for geo-potential\n\tr for radial gravity gradient" << endl
|
||||
<< "-s\treference system" << endl
|
||||
<< "-p\tinterpolating locations indicated by a input file, every line of the file has a longitudinal and a latitudinal value" << endl
|
||||
<< "-g\tGM and R parameters for gravitational data's calculation" << endl
|
||||
<< "-n\tnormalized sum of associated Legendre functions\n\tm for mathematic normalization which equal 1\n\tg for geodetic normalization which equal 4*pi (default)" << endl
|
||||
<< "-f\tstart and end orders and degrees used for calculation" << endl
|
||||
<< "-c\tselect data columns of the input table data. the default is 0,1,2,3" << endl
|
||||
<< "-z\tprovide a input file for observations' altitudes. use +d to select input data columns, the default is 0,1,2" << endl
|
||||
<< "-h\tshow this info" << endl;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char infilename[1024] = "NULL";
|
||||
char interfilename[1024] = "NULL";
|
||||
char range[1024] = "NULL";
|
||||
char interval[1024] = "NULL";
|
||||
char type[1024] = "t";
|
||||
char referSystem[1024] = "NULL";
|
||||
char coffPara[1024] = "NULL";
|
||||
char columns[1024] = "0,1,2,3";
|
||||
char gravPara[1024] = "NULL";
|
||||
char norType[1024] = "g";
|
||||
char altiFile[1024] = "NULL";
|
||||
|
||||
opterr = 0; //内置参数 若不为0则会在发生遭遇错误时输出一条信息到屏幕
|
||||
|
||||
int curr;
|
||||
/*循环拾取参数 最后一个参数为-1 需要变量的参数后跟一个冒号 可有可无参数跟两个冒号*/
|
||||
while((curr = getopt(argc,argv,"ht:r:i:s:f:c:d:g:n:p:z:")) != -1)
|
||||
{
|
||||
/*匹配命令*/
|
||||
switch (curr)
|
||||
{
|
||||
case 'h': //显示帮助信息
|
||||
disp_help();
|
||||
break;
|
||||
case 't':
|
||||
if (1!=sscanf(optarg,"%s",infilename))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
if (1!=sscanf(optarg,"%s",range))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
if (1!=sscanf(optarg,"%s",interval))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if (1!=sscanf(optarg,"%s",type))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
if (1!=sscanf(optarg,"%s",interfilename))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if (1!=sscanf(optarg,"%s",referSystem))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
if (1!=sscanf(optarg,"%s",gravPara))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
if (1!=sscanf(optarg,"%s",norType))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
if (1!=sscanf(optarg,"%s",coffPara))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
if (1!=sscanf(optarg,"%s",columns))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case 'z':
|
||||
if (1!=sscanf(optarg,"%s",altiFile))
|
||||
{
|
||||
cout << "error ==> wrong format of " << optarg << endl;
|
||||
}
|
||||
break;
|
||||
case '?': //处理未定义或错误参数
|
||||
if (optopt == 't' || optopt == 'r' || optopt == 'i' || optopt == 's' || optopt == 'f' || optopt == 'c' || optopt == 'p' || optopt == 'z')
|
||||
{
|
||||
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
|
||||
return -1;
|
||||
}
|
||||
else if (isprint(optopt))
|
||||
{
|
||||
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr,"Unknown option character `\\x%x'.\n",optopt);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
sh2xyz sx;
|
||||
//读入球谐系数文件
|
||||
if(sx.readSHC(infilename,coffPara,columns)) return 0;
|
||||
//初始化观测点位置
|
||||
if(sx.initObs(range,interval,referSystem)) return 0;
|
||||
//重定位观测点高程
|
||||
if(sx.relocateAltitude(altiFile)) return 0;
|
||||
//初始化矩阵
|
||||
sx.initMatrix(type,gravPara,norType,altiFile);
|
||||
//计算
|
||||
if (!strcmp(altiFile,"NULL"))
|
||||
{
|
||||
sx.calSolution();
|
||||
}
|
||||
else sx.calSolution2(type);
|
||||
//输出
|
||||
sx.outObs(interfilename);
|
||||
return 0;
|
||||
}
|
15
archive/sh2xyz/makefile
Normal file
15
archive/sh2xyz/makefile
Normal file
@@ -0,0 +1,15 @@
|
||||
CC = g++-8
|
||||
PROM = /usr/local/sbin/sh2xyz
|
||||
CFLAGS = -I.
|
||||
DEPS = $(shell find . -name "*.h")
|
||||
SRC = $(shell find . -name "*.cpp")
|
||||
OBJ = $(SRC:%.cpp=%.o)
|
||||
|
||||
$(PROM): $(OBJ)
|
||||
$(CC) -o $(PROM) $(OBJ) $(CFLAGS) -fopenmp -O2
|
||||
|
||||
%.o:%.cpp $(DEPS)
|
||||
$(CC) -c $< -o $@ $(CFLAGS) -fopenmp -O2
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ)
|
154
archive/sh2xyz/progressBar_imp.h
Normal file
154
archive/sh2xyz/progressBar_imp.h
Normal file
@@ -0,0 +1,154 @@
|
||||
#ifndef _PROGRESS_BAR_
|
||||
#define _PROGRESS_BAR_
|
||||
|
||||
//#ifdef _WINDOWS
|
||||
//#include <windows.h>
|
||||
//#else
|
||||
//#include <sys/ioctl.h>
|
||||
//#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
#define TOTAL_PERCENTAGE 100.0
|
||||
#define CHARACTER_WIDTH_PERCENTAGE 4
|
||||
|
||||
class ProgressBar
|
||||
{
|
||||
public:
|
||||
|
||||
ProgressBar();
|
||||
ProgressBar(unsigned long n_, const char *description_="", std::ostream& out_=std::cerr);
|
||||
|
||||
void SetFrequencyUpdate(unsigned long frequency_update_);
|
||||
void SetStyle(const char* unit_bar_, const char* unit_space_);
|
||||
|
||||
void Progressed(unsigned long idx_);
|
||||
|
||||
private:
|
||||
|
||||
unsigned long n;
|
||||
unsigned int desc_width;
|
||||
unsigned long frequency_update;
|
||||
std::ostream* out;
|
||||
|
||||
const char *description;
|
||||
const char *unit_bar;
|
||||
const char *unit_space;
|
||||
|
||||
void ClearBarField();
|
||||
int GetConsoleWidth();
|
||||
int GetBarLength();
|
||||
|
||||
};
|
||||
|
||||
ProgressBar::ProgressBar() {}
|
||||
|
||||
ProgressBar::ProgressBar(unsigned long n_, const char* description_, std::ostream& out_){
|
||||
|
||||
n = n_;
|
||||
frequency_update = n_;
|
||||
description = description_;
|
||||
out = &out_;
|
||||
|
||||
unit_bar = "\u2588";
|
||||
unit_space = "-";
|
||||
desc_width = std::strlen(description); // character width of description field
|
||||
|
||||
}
|
||||
|
||||
void ProgressBar::SetFrequencyUpdate(unsigned long frequency_update_){
|
||||
|
||||
if(frequency_update_ > n){
|
||||
frequency_update = n; // prevents crash if freq_updates_ > n_
|
||||
}
|
||||
else{
|
||||
frequency_update = frequency_update_;
|
||||
}
|
||||
}
|
||||
|
||||
void ProgressBar::SetStyle(const char* unit_bar_, const char* unit_space_){
|
||||
|
||||
unit_bar = unit_bar_;
|
||||
unit_space = unit_space_;
|
||||
}
|
||||
|
||||
int ProgressBar::GetConsoleWidth(){
|
||||
|
||||
int width;
|
||||
|
||||
#ifdef _WINDOWS
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
|
||||
width = csbi.srWindow.Right - csbi.srWindow.Left;
|
||||
#else
|
||||
struct winsize win;
|
||||
ioctl(0, TIOCGWINSZ, &win);
|
||||
width = win.ws_col;
|
||||
#endif
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
int ProgressBar::GetBarLength(){
|
||||
|
||||
// get console width and according adjust the length of the progress bar
|
||||
|
||||
int bar_length = static_cast<int>((GetConsoleWidth() - desc_width - CHARACTER_WIDTH_PERCENTAGE) / 2.);
|
||||
|
||||
return bar_length;
|
||||
}
|
||||
|
||||
void ProgressBar::ClearBarField(){
|
||||
|
||||
for(int i=0;i<GetConsoleWidth();++i){
|
||||
*out << " ";
|
||||
}
|
||||
*out << "\r" << std::flush;
|
||||
}
|
||||
|
||||
void ProgressBar::Progressed(unsigned long idx_)
|
||||
{
|
||||
try{
|
||||
if(idx_ > n) throw idx_;
|
||||
|
||||
// determines whether to update the progress bar from frequency_update
|
||||
if ((idx_ != n-1) && ((idx_+1) % (n/frequency_update) != 0)) return;
|
||||
|
||||
// calculate the size of the progress bar
|
||||
int bar_size = GetBarLength();
|
||||
|
||||
// calculate percentage of progress
|
||||
double progress_percent = idx_* TOTAL_PERCENTAGE/(n-1);
|
||||
|
||||
// calculate the percentage value of a unit bar
|
||||
double percent_per_unit_bar = TOTAL_PERCENTAGE/bar_size;
|
||||
|
||||
// display progress bar
|
||||
*out << " " << description << " |";
|
||||
|
||||
for(int bar_length=0;bar_length<=bar_size-1;++bar_length){
|
||||
if(bar_length*percent_per_unit_bar<progress_percent){
|
||||
*out << unit_bar;
|
||||
}
|
||||
else{
|
||||
*out << unit_space;
|
||||
}
|
||||
}
|
||||
|
||||
if(idx_ == n-1)
|
||||
*out << "|" << std::setw(CHARACTER_WIDTH_PERCENTAGE + 1) << std::setprecision(1) << std::fixed << progress_percent << "%\r" << std::flush << std::endl;
|
||||
else *out << "|" << std::setw(CHARACTER_WIDTH_PERCENTAGE + 1) << std::setprecision(1) << std::fixed << progress_percent << "%\r" << std::flush;
|
||||
}
|
||||
catch(unsigned long e){
|
||||
ClearBarField();
|
||||
std::cerr << "PROGRESS_BAR_EXCEPTION: _idx (" << e << ") went out of bounds, greater than n (" << n << ")." << std::endl << std::flush;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
535
archive/sh2xyz/sh2xyz.h
Normal file
535
archive/sh2xyz/sh2xyz.h
Normal file
@@ -0,0 +1,535 @@
|
||||
#ifndef _FUNC_H
|
||||
#define _FUNC_H
|
||||
#include "sysDefine.h"
|
||||
#include "NALF-SFCM.h"
|
||||
#include "progressBar_imp.h"
|
||||
// 命令规则 n为阶数 m为次数
|
||||
class sh2xyz
|
||||
{
|
||||
public:
|
||||
sh2xyz(){}
|
||||
~sh2xyz(){}
|
||||
int readSHC(char*,char*,char*); //读入球谐系数
|
||||
int initMatrix(char*,char*,char*,char*); //初始化相关的矩阵大小
|
||||
int initObs(char*,char*,char*); //初始化观测点 如只有范围参数则只初始化经纬度位置
|
||||
int relocateAltitude(char*); //根据输入文件重新确定计算高程
|
||||
int outObs(char*); //输出计算结果 如果有文件指定的位置则插值
|
||||
int calSolution(); //计算球谐结果 同一高程观测值
|
||||
int calSolution2(char*); //计算不同高程的观测值
|
||||
private:
|
||||
_2dArray Anm;
|
||||
_2dArray Bnm;
|
||||
_2dArray Pnm; //伴随勒让德函数系数 这个函数只和观测位置的纬度/余纬度相关 同一纬度只需要计算一次
|
||||
_2dArray mCos; //不同次数cos函数值 这个值只和观测位置的经度相关 行数为不同经度位置 列数为不同次数 矩阵维度即为经度个数*阶次 一般估算在1000*1000级别
|
||||
_2dArray mSin; //不同次数sin函数值 其他与上同
|
||||
_2dArray coff_S; //球谐系数sin参数
|
||||
_2dArray coff_C; //球谐系数cos参数
|
||||
_2dArray multi_array; //乘子矩阵
|
||||
sphArray obsPoint; //计算地形是的观测位置 即计算半径值
|
||||
sphArray outPoint; //输出计算值
|
||||
|
||||
double norSum;
|
||||
double GM,R; //球谐系数中重力常数与质量的乘积 单位为SI标准 g 与 m
|
||||
double multi_factor; // 乘子系数
|
||||
int NN_size; //系数矩阵大小
|
||||
int lon_size,lat_size;
|
||||
double refr,refR,altitude;
|
||||
double lonmin,lonmax,dlon;
|
||||
double latmin,latmax,dlat;
|
||||
};
|
||||
//读取球谐参数文件 文件名 起止阶次 列序列
|
||||
int sh2xyz::readSHC(char* filename,char* para,char* orders)
|
||||
{
|
||||
ifstream infile;
|
||||
if (open_infile(infile,filename)) return -1;
|
||||
|
||||
int n_start,m_start,n_end,m_end;
|
||||
if (4 != sscanf(para,"%d/%d/%d/%d",&n_start,&m_start,&n_end,&m_end))
|
||||
{
|
||||
cerr << BOLDRED << "error ==> " << RESET << "wrong parameter: " << para << endl;
|
||||
return -1;
|
||||
}
|
||||
//识别列次序
|
||||
int order[4];
|
||||
if (4 != sscanf(orders,"%d,%d,%d,%d",&order[0],&order[1],&order[2],&order[3]))
|
||||
{
|
||||
cerr << BOLDRED << "error ==> " << RESET << "wrong parameter: " << orders << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//按照最大阶数初始化下半三角矩阵
|
||||
NN_size = n_end + 1;
|
||||
//对于二维vector来说 对行初始化的时候需要使用resize 而对于列的初始化而言使用reserve效率更高
|
||||
coff_C.resize(NN_size);
|
||||
coff_S.resize(NN_size);
|
||||
for (int i = 0; i < NN_size; i++)
|
||||
{
|
||||
coff_C[i].resize(i+1,0.0);
|
||||
coff_S[i].resize(i+1,0.0);
|
||||
}
|
||||
|
||||
int n,m; //行列号
|
||||
double temp_d,temp_c,temp_s;
|
||||
_1dArray temp_row; temp_row.reserve(100); //出现初始化100个double的空间 这样读文件更快
|
||||
string temp_str;
|
||||
stringstream temp_ss;
|
||||
while (getline(infile,temp_str))
|
||||
{
|
||||
if (*(temp_str.begin()) == '#') continue;
|
||||
if (!temp_row.empty()) temp_row.clear();
|
||||
temp_ss.str("");
|
||||
temp_ss.clear();
|
||||
temp_ss << temp_str;
|
||||
while (temp_ss >> temp_d)
|
||||
temp_row.push_back(temp_d);
|
||||
|
||||
n = int(temp_row[order[0]]);
|
||||
m = int(temp_row[order[1]]);
|
||||
temp_c = temp_row[order[2]];
|
||||
temp_s = temp_row[order[3]];
|
||||
|
||||
if (n >= n_start && n <= n_end && m >= m_start && m <= m_end)
|
||||
{
|
||||
coff_C[n][m] = temp_c;
|
||||
coff_S[n][m] = temp_s;
|
||||
}
|
||||
}
|
||||
infile.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sh2xyz::initObs(char* r_para,char* i_para,char* refsys)
|
||||
{
|
||||
//解析参考球
|
||||
if (!strcmp(refsys,"NULL"))
|
||||
{
|
||||
refr = refR = 0.0;
|
||||
}
|
||||
else if (!strcmp(refsys,"WGS84"))
|
||||
{
|
||||
refr = WGS84_PoleRadius;
|
||||
refR = WGS84_EquatorRadius;
|
||||
}
|
||||
else if (!strcmp(refsys,"EarthRadius"))
|
||||
{
|
||||
refr = EarthRadius;
|
||||
refR = EarthRadius;
|
||||
}
|
||||
else if (!strcmp(refsys,"MoonRadius"))
|
||||
{
|
||||
refr = MoonRadius;
|
||||
refR = MoonRadius;
|
||||
}
|
||||
else if (2 != sscanf(refsys,"%lf/%lf",&refr,&refR))
|
||||
{
|
||||
cerr << BOLDRED << "error ==> " << RESET << "wrong parameter: " << refsys << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//解析经纬度范围 按规则网络初始化观测点位置
|
||||
if (5 != sscanf(r_para,"%lf/%lf/%lf/%lf/%lf",&lonmin,&lonmax,&latmin,&latmax,&altitude))
|
||||
{
|
||||
if (4 != sscanf(r_para,"%lf/%lf/%lf/%lf",&lonmin,&lonmax,&latmin,&latmax))
|
||||
{
|
||||
cerr << BOLDRED << "error ==> " << RESET << "wrong parameter: " << r_para << endl;
|
||||
return -1;
|
||||
}
|
||||
else altitude = 0.0;
|
||||
}
|
||||
|
||||
//解析间隔
|
||||
if (2 != sscanf(i_para,"%lf/%lf",&dlon,&dlat))
|
||||
{
|
||||
cerr << BOLDRED << "error ==> " << RESET << "wrong parameter: " << i_para << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
spoint temp_spoint;
|
||||
double lon,lat;
|
||||
lon_size = floor((lonmax-lonmin)/dlon) + 1;
|
||||
lat_size = floor((latmax-latmin)/dlat) + 1;
|
||||
obsPoint.reserve(lon_size*lat_size);
|
||||
for (int i = 0; i < lat_size; i++)
|
||||
{
|
||||
for (int j = 0; j < lon_size; j++)
|
||||
{
|
||||
lat = latmin + i*dlat; lon = lonmin + j*dlon;
|
||||
temp_spoint.lon = lon; temp_spoint.lat = lat;
|
||||
temp_spoint.ref = refRadius(temp_spoint.lat,refr,refR);
|
||||
temp_spoint.alti = altitude;
|
||||
temp_spoint.rad = temp_spoint.ref + temp_spoint.alti;
|
||||
temp_spoint.val = 0.0;
|
||||
obsPoint.push_back(temp_spoint);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sh2xyz::relocateAltitude(char* filepara)
|
||||
{
|
||||
char filename[1024];
|
||||
int orders[3] = {0,1,2}; //默认的读入的数据列为前三列
|
||||
|
||||
if(!strcmp(filepara,"NULL")) return 0;
|
||||
|
||||
//解析文件名中是否含有+d标示 如果有则将+d以前解释为filename 之后为需要读入的数据列 默认为逗号分隔
|
||||
//否则将filepara赋值为filename
|
||||
if (4 != sscanf(filepara,"%[^+]+d%d,%d,%d",filename,&orders[0],&orders[1],&orders[2]))
|
||||
strcpy(filename,filepara);
|
||||
|
||||
ifstream infile;
|
||||
if (open_infile(infile,filename)) return -1;
|
||||
|
||||
int numM,numN,tempM,tempN;
|
||||
string temp_str;
|
||||
stringstream temp_ss;
|
||||
double temp_d,temp_lon,temp_lat,temp_alti;
|
||||
_1dArray temp_row;
|
||||
|
||||
numM = floor((latmax-latmin)/dlat)+1;
|
||||
numN = floor((lonmax-lonmin)/dlon)+1;
|
||||
while(getline(infile,temp_str))
|
||||
{
|
||||
if (*(temp_str.begin()) == '#') continue;
|
||||
|
||||
temp_ss.str(""); temp_ss.clear(); temp_ss << temp_str;
|
||||
if(!temp_row.empty()) temp_row.clear();
|
||||
while(temp_ss >> temp_d)
|
||||
temp_row.push_back(temp_d);
|
||||
|
||||
temp_lon = temp_row[orders[0]];
|
||||
temp_lat = temp_row[orders[1]];
|
||||
temp_alti = temp_row[orders[2]];
|
||||
|
||||
tempM = round((temp_lat-latmin)/dlat);
|
||||
tempN = round((temp_lon-lonmin)/dlon);
|
||||
obsPoint[tempM*numN+tempN].alti = temp_alti;
|
||||
obsPoint[tempM*numN+tempN].rad = obsPoint[tempM*numN+tempN].ref + temp_alti;
|
||||
}
|
||||
infile.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//初始化矩阵
|
||||
int sh2xyz::initMatrix(char* type,char* para,char* norType,char* zfile)
|
||||
{
|
||||
//初始化GM与R
|
||||
if (strcmp(para,"NULL")) //如果para不为NULL则识别参数 否则将GM与R初始化为MAX_BDL
|
||||
{
|
||||
if (2 != sscanf(para,"%lf/%lf",&GM,&R))
|
||||
{
|
||||
cerr << BOLDRED << "error ==> " << RESET << "wrong parameter: " << para << endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else GM = R = MAX_BDL;
|
||||
//初始化归一化类型
|
||||
if (!strcmp(norType,"g")) norSum = 4.0*pi;
|
||||
else if (!strcmp(norType,"m")) norSum = 1.0;
|
||||
else
|
||||
{
|
||||
cerr << BOLDRED << "error ==> " << RESET << "wrong parameter: " << norType << endl;
|
||||
return -1;
|
||||
}
|
||||
//初始化伴随勒让德函数矩阵
|
||||
Pnm.resize(NN_size);
|
||||
for (int i = 0; i < NN_size; i++)
|
||||
Pnm.at(i).resize(i+1,0.0);
|
||||
//初始化sin和cos矩阵
|
||||
mCos.resize(lon_size);
|
||||
mSin.resize(lon_size);
|
||||
for (int i = 0; i < lon_size; i++)
|
||||
{
|
||||
mCos[i].reserve(NN_size);
|
||||
mSin[i].reserve(NN_size);
|
||||
}
|
||||
//计算mCos和mSin的值
|
||||
int i,j;
|
||||
double lon;
|
||||
#pragma omp parallel for private(i,j,lon) schedule(guided)
|
||||
for (i = 0; i < lon_size; i++)
|
||||
{
|
||||
lon = lonmin + i*dlon;
|
||||
for (j = 0; j < NN_size; j++)
|
||||
{
|
||||
mCos[i].push_back(cos(j*lon*pi/180.0));
|
||||
mSin[i].push_back(sin(j*lon*pi/180.0));
|
||||
}
|
||||
}
|
||||
//计算勒让德函数系数
|
||||
Anm = get_a_nm_array(NN_size);
|
||||
Bnm = get_b_nm_array(NN_size);
|
||||
//计算乘子参数
|
||||
if(!strcmp(type,"t")) //topography
|
||||
multi_factor = 1.0;
|
||||
else if (!strcmp(type,"d") || !strcmp(type,"g")) //gravity disturbance
|
||||
multi_factor = 1e+5*GM/(R*R);
|
||||
else if (!strcmp(type,"r")) //gravity disturbance
|
||||
multi_factor = 1e+9*GM/(R*R);
|
||||
else if (!strcmp(type,"p"))
|
||||
multi_factor = 1e+5*GM/R;
|
||||
else
|
||||
{
|
||||
cerr << BOLDRED << "error ==> " << RESET << "unknown calculation type of " << type << endl;
|
||||
return -1;
|
||||
}
|
||||
//初始化乘子矩阵
|
||||
multi_array.resize(lat_size);
|
||||
for (i = 0; i < lat_size; i++)
|
||||
{
|
||||
multi_array[i].resize(NN_size,1.0); //初始化乘子矩阵为1 适用于地形等直接计算的类型
|
||||
}
|
||||
//如果计算高程不在同一高程 则不能使用multi_array 同时应该使用calSolution2()函数
|
||||
if (strcmp(zfile,"NULL"))
|
||||
return 0;
|
||||
//如果计算类型不是地形等直接计算类型则需要检验-g选项是否已经设置
|
||||
if (strcmp(type,"t"))
|
||||
{
|
||||
if (GM == MAX_BDL || R == MAX_BDL)
|
||||
{
|
||||
cerr << BOLDRED << "error ==> " << RESET << "-g option must be set for gravitational calculation" << endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//根据不同类型计算乘子参数和乘子矩阵
|
||||
if (!strcmp(type,"d")) //gravity disturbance
|
||||
{
|
||||
#pragma omp parallel for private(i,j) shared(R,lon_size) schedule(guided)
|
||||
for (i = 0; i < lat_size; i++)
|
||||
{
|
||||
for (j = 0; j < NN_size; j++)
|
||||
{
|
||||
multi_array[i][j] = pow(R/obsPoint[i*lon_size].rad,j+2)*(j+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(type,"r")) //gravity gradient
|
||||
{
|
||||
#pragma omp parallel for private(i,j) shared(R,lon_size) schedule(guided)
|
||||
for (i = 0; i < lat_size; i++)
|
||||
{
|
||||
for (j = 0; j < NN_size; j++)
|
||||
{
|
||||
multi_array[i][j] = pow(R/obsPoint[i*lon_size].rad,j+2)*(j+1)*(j+2)/obsPoint[i*lon_size].rad;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(type,"g")) //gravity anomaly
|
||||
{
|
||||
#pragma omp parallel for private(i,j) shared(R,lon_size) schedule(guided)
|
||||
for (i = 0; i < lat_size; i++)
|
||||
{
|
||||
for (j = 0; j < NN_size; j++)
|
||||
{
|
||||
multi_array[i][j] = pow(R/obsPoint[i*lon_size].rad,j+2)*(j-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(type,"p")) //geo-potential
|
||||
{
|
||||
#pragma omp parallel for private(i,j) shared(R,lon_size) schedule(guided)
|
||||
for (i = 0; i < lat_size; i++)
|
||||
{
|
||||
for (j = 0; j < NN_size; j++)
|
||||
{
|
||||
multi_array[i][j] = pow(R/obsPoint[i*lon_size].rad,j+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sh2xyz::outObs(char* filename)
|
||||
{
|
||||
if (!strcmp(filename,"NULL")) //没有输入文件 直接输出规则网计算结果
|
||||
{
|
||||
cout << "# NaN value = 1e+30" << endl;
|
||||
cout << "# lon(deg) lat(deg) reference-radius(m) altitude(m) topography(m)|gravitational-field(mGal)" << endl;
|
||||
for (int i = 0; i < obsPoint.size(); i++)
|
||||
{
|
||||
obsPoint[i].info();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ifstream infile;
|
||||
if(open_infile(infile,filename)) return -1;
|
||||
|
||||
spoint temp_sp;
|
||||
string temp_str;
|
||||
stringstream temp_ss;
|
||||
while (getline(infile,temp_str))
|
||||
{
|
||||
if(*(temp_str.begin()) == '#') continue;
|
||||
|
||||
temp_ss.str("");
|
||||
temp_ss.clear();
|
||||
temp_ss << temp_str;
|
||||
temp_ss >> temp_sp.lon >> temp_sp.lat;
|
||||
temp_sp.ref = refRadius(temp_sp.lat,refr,refR);
|
||||
temp_sp.alti = altitude;
|
||||
outPoint.push_back(temp_sp);
|
||||
}
|
||||
infile.close();
|
||||
|
||||
int numM,numN,tempM,tempN;
|
||||
double lon1,lon2,lat1,lat2;
|
||||
|
||||
numM = floor((latmax-latmin)/dlat)+1;
|
||||
numN = floor((lonmax-lonmin)/dlon)+1;
|
||||
for (int i = 0; i < outPoint.size(); i++)
|
||||
{
|
||||
tempM = floor((outPoint[i].lat-latmin)/dlat);
|
||||
tempN = floor((outPoint[i].lon-lonmin)/dlon);
|
||||
|
||||
if (tempM == (numM-1))
|
||||
tempM -= 1;
|
||||
if (tempN == (numN-1))
|
||||
tempN -= 1;
|
||||
|
||||
if (tempM >= 0 && tempN >= 0 && tempM <= numM-2 && tempN <= numN-2)
|
||||
{
|
||||
lon1 = lonmin+tempN*dlon;
|
||||
lon2 = lonmin+(tempN+1)*dlon;
|
||||
lat1 = latmin+tempM*dlat;
|
||||
lat2 = latmin+(tempM+1)*dlat;
|
||||
outPoint[i].val = SphBiInterp_deg(lat1,lat2,lon1,lon2,
|
||||
outPoint[i].lat,outPoint[i].lon,
|
||||
obsPoint[tempM*numN+tempN].val,
|
||||
obsPoint[tempM*numN+tempN+1].val,
|
||||
obsPoint[(tempM+1)*numN+tempN].val,
|
||||
obsPoint[(tempM+1)*numN+tempN+1].val);
|
||||
}
|
||||
}
|
||||
|
||||
cout << "# NaN value = 1e+30" << endl;
|
||||
cout << "# lon(deg) lat(deg) reference-radius(m) altitude(m) topography(m)|gravitational-field(mGal)" << endl;
|
||||
for (int i = 0; i < outPoint.size(); i++)
|
||||
{
|
||||
outPoint[i].info();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sh2xyz::calSolution()
|
||||
{
|
||||
//计算
|
||||
int i,j,n,m;
|
||||
double temp_d,lat;
|
||||
|
||||
ProgressBar *bar = new ProgressBar(lat_size,"Process");
|
||||
for (i = 0; i < lat_size; i++)
|
||||
{
|
||||
bar->Progressed(i);
|
||||
lat = latmin + dlat*i;
|
||||
//计算伴随勒让德函数 对于同一个纬度只需要计算一次
|
||||
NALF_SFCM3(Pnm,Anm,Bnm,NN_size,90.0-lat,norSum);
|
||||
//这里可以使用并行加速计算外层循环 内层计算因为是递归计算因此不能并行
|
||||
//一种并行方案更快一些
|
||||
#pragma omp parallel for private(j,n,m,temp_d) shared(i,multi_factor) schedule(guided)
|
||||
for (j = 0; j < lon_size; j++)
|
||||
{
|
||||
temp_d = 0;
|
||||
for (n = 0; n < NN_size; n++)
|
||||
{
|
||||
for (m = 0; m < n+1; m++)
|
||||
{
|
||||
temp_d += multi_array[i][n]*Pnm[n][m]*(coff_C[n][m]*mCos[j][m]+coff_S[n][m]*mSin[j][m]);
|
||||
}
|
||||
}
|
||||
obsPoint[i*lon_size+j].val = multi_factor*temp_d;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sh2xyz::calSolution2(char* type)
|
||||
{
|
||||
//计算
|
||||
int i,j,n,m;
|
||||
double temp_d,lat;
|
||||
|
||||
ProgressBar *bar = new ProgressBar(lat_size,"Process");
|
||||
if (!strcmp(type,"d"))
|
||||
{
|
||||
for (i = 0; i < lat_size; i++)
|
||||
{
|
||||
bar->Progressed(i);
|
||||
lat = latmin + dlat*i;
|
||||
//计算伴随勒让德函数 对于同一个纬度只需要计算一次
|
||||
NALF_SFCM3(Pnm,Anm,Bnm,NN_size,90.0-lat,norSum);
|
||||
//这里可以使用并行加速计算外层循环 内层计算因为是递归计算因此不能并行
|
||||
//一种并行方案更快一些
|
||||
#pragma omp parallel for private(j,n,m,temp_d) shared(i,multi_factor,lon_size) schedule(guided)
|
||||
for (j = 0; j < lon_size; j++)
|
||||
{
|
||||
temp_d = 0;
|
||||
for (n = 0; n < NN_size; n++)
|
||||
{
|
||||
for (m = 0; m < n+1; m++)
|
||||
{
|
||||
//pow(R/obsPoint[i*lon_size+j].rad,n+2)*(n+1)
|
||||
temp_d += pow(R/obsPoint[i*lon_size+j].rad,n+2)*(n+1)*Pnm[n][m]*(coff_C[n][m]*mCos[j][m]+coff_S[n][m]*mSin[j][m]);
|
||||
}
|
||||
}
|
||||
obsPoint[i*lon_size+j].val = multi_factor*temp_d;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(type,"g"))
|
||||
{
|
||||
for (i = 0; i < lat_size; i++)
|
||||
{
|
||||
bar->Progressed(i);
|
||||
lat = latmin + dlat*i;
|
||||
//计算伴随勒让德函数 对于同一个纬度只需要计算一次
|
||||
NALF_SFCM3(Pnm,Anm,Bnm,NN_size,90.0-lat,norSum);
|
||||
//这里可以使用并行加速计算外层循环 内层计算因为是递归计算因此不能并行
|
||||
//一种并行方案更快一些
|
||||
#pragma omp parallel for private(j,n,m,temp_d) shared(i,multi_factor,lon_size) schedule(guided)
|
||||
for (j = 0; j < lon_size; j++)
|
||||
{
|
||||
temp_d = 0;
|
||||
for (n = 0; n < NN_size; n++)
|
||||
{
|
||||
for (m = 0; m < n+1; m++)
|
||||
{
|
||||
//pow(R/obsPoint[i*lon_size+j].rad,n+2)*(n-1)
|
||||
temp_d += pow(R/obsPoint[i*lon_size+j].rad,n+2)*(n-1)*Pnm[n][m]*(coff_C[n][m]*mCos[j][m]+coff_S[n][m]*mSin[j][m]);
|
||||
}
|
||||
}
|
||||
obsPoint[i*lon_size+j].val = multi_factor*temp_d;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(type,"p"))
|
||||
{
|
||||
for (i = 0; i < lat_size; i++)
|
||||
{
|
||||
bar->Progressed(i);
|
||||
lat = latmin + dlat*i;
|
||||
//计算伴随勒让德函数 对于同一个纬度只需要计算一次
|
||||
NALF_SFCM3(Pnm,Anm,Bnm,NN_size,90.0-lat,norSum);
|
||||
//这里可以使用并行加速计算外层循环 内层计算因为是递归计算因此不能并行
|
||||
//一种并行方案更快一些
|
||||
#pragma omp parallel for private(j,n,m,temp_d) shared(i,multi_factor,lon_size) schedule(guided)
|
||||
for (j = 0; j < lon_size; j++)
|
||||
{
|
||||
temp_d = 0;
|
||||
for (n = 0; n < NN_size; n++)
|
||||
{
|
||||
for (m = 0; m < n+1; m++)
|
||||
{
|
||||
//pow(R/obsPoint[i*lon_size+j].rad,n+1)
|
||||
temp_d += pow(R/obsPoint[i*lon_size+j].rad,n+1)*Pnm[n][m]*(coff_C[n][m]*mCos[j][m]+coff_S[n][m]*mSin[j][m]);
|
||||
}
|
||||
}
|
||||
obsPoint[i*lon_size+j].val = multi_factor*temp_d;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
106
archive/sh2xyz/sysDefine.h
Normal file
106
archive/sh2xyz/sysDefine.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef _SYSDEFINE_H
|
||||
#define _SYSDEFINE_H
|
||||
#include "iostream"
|
||||
#include "fstream"
|
||||
#include "sstream"
|
||||
#include "iomanip"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "unistd.h"
|
||||
#include "string.h"
|
||||
#include "cmath"
|
||||
#include "vector"
|
||||
#include "omp.h"
|
||||
|
||||
#define pi (4.0*atan(1.0))
|
||||
#define MAX_BDL 1e+30
|
||||
#define WGS84_PoleRadius 6356752.314//WGS84椭球极半径
|
||||
#define WGS84_EquatorRadius 6378137//WGS84椭球长半径
|
||||
#define EarthRadius 6371000
|
||||
#define MoonRadius 1738000
|
||||
|
||||
#define BOLDRED "\033[1m\033[31m"
|
||||
#define BOLDGREEN "\033[1m\033[32m"
|
||||
#define BOLDBLUE "\033[1m\033[34m"
|
||||
#define UNDERLINE "\033[1m\033[4m"
|
||||
#define RESET "\033[0m"
|
||||
#define MOVEUP(x) printf("\033[%dA", (x))
|
||||
#define MOVEDOWN(x) printf("\033[%dB", (x))
|
||||
#define MOVELEFT(x) printf("\033[%dD", (x))
|
||||
#define MOVERIGHT(x) printf("\033[%dC", (x))
|
||||
#define MOVETO(y,x) printf("\033[%d;%dH", (y), (x))
|
||||
#define CLEARLINE "\033[K"
|
||||
#define CLEARALL "\033[2J"
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef vector<double> _1dArray;
|
||||
typedef vector<vector<double> > _2dArray;
|
||||
|
||||
struct spoint
|
||||
{
|
||||
double lon,lat,ref,alti,rad,val;
|
||||
spoint()
|
||||
{
|
||||
lon = lat = ref = alti = rad = val = MAX_BDL;
|
||||
}
|
||||
void info()
|
||||
{
|
||||
cout << setprecision(16) << lon << " " << lat << " " << ref << " " << alti << " " << val << endl;
|
||||
}
|
||||
};
|
||||
typedef vector<spoint> sphArray;
|
||||
|
||||
//计算一个参考椭球或者参考球在纬度位置的半径
|
||||
double refRadius(double lati,double refr,double refR)
|
||||
{
|
||||
return refr*refR/sqrt(pow(refr,2)*pow(cos((double) lati*pi/180.0),2)+pow(refR,2)*pow(sin((double) lati*pi/180.0),2));
|
||||
}
|
||||
//测试打开输入文件 如果成功则返回0并输出信息 否则返回1
|
||||
int open_infile(ifstream &infile,char* filename)
|
||||
{
|
||||
infile.open(filename);
|
||||
if (!infile)
|
||||
{
|
||||
cout << BOLDRED << "error ==> " << RESET << "file not found: " << filename << endl;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//测试打开输出文件 如果成功则返回0并输出信息 否则返回1
|
||||
int open_outfile(ofstream &outfile,char* filename)
|
||||
{
|
||||
outfile.open(filename);
|
||||
if (!outfile)
|
||||
{
|
||||
cout << BOLDRED << "error ==> " << RESET << "fail to create the file: " << filename << endl;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
double cosd(double deg)
|
||||
{
|
||||
return (cos(deg*pi/180.0));
|
||||
}
|
||||
/*
|
||||
lat
|
||||
|
|
||||
|
|
||||
h21----h22
|
||||
| |
|
||||
| |
|
||||
h11----h12----> lon
|
||||
*/
|
||||
// 球面双线性插值函数 以度为单位的版本 注意纬度为余纬度
|
||||
double SphBiInterp_deg(double CoLat1,double CoLat2,double Lon1,double Lon2,double CoLat0,double Lon0,double h11,double h12,double h21,double h22)
|
||||
{
|
||||
double Delta=(Lon2-Lon1)*(cosd(CoLat2)-cosd(CoLat1));
|
||||
double A=(Lon1*(h12-h22)+Lon2*(h21-h11))/Delta;
|
||||
double B=(cosd(CoLat1)*(h21-h22)+cosd(CoLat2)*(h12-h11))/Delta;
|
||||
double C=(h11+h22-h21-h12)/Delta;
|
||||
double D=(Lon2*cosd(CoLat2)*h11-Lon2*cosd(CoLat1)*h21+Lon1*cosd(CoLat1)*h22-Lon1*cosd(CoLat2)*h12)/Delta;
|
||||
double h0=A*cosd(CoLat0)+B*Lon0+C*Lon0*cosd(CoLat0)+D;
|
||||
return h0;
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user