-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCreateGrid.hpp
155 lines (126 loc) · 4.76 KB
/
CreateGrid.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#ifndef ASU_CREATEGRID
#define ASU_CREATEGRID
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
/***********************************************************
* This C++ template returns the 1D grid meshing results.
*
* input(s):
* const double &lowerbound ---- Grid lower bound.
* const double &upperbound ---- Grid upper bound.
* const double &Para ---- meaning-changing parameter.
* it's meaning depends on which mode:
*
* const int &mode ---- select mode.
* Define the meaning of Para and return vector.
*
* 0: Para means number of gird points.
* Return a vector (ans) of size Para:
*
* ans.size()=Para;
* ans[0]=lowerbound;
* ans[Para-1]=upperbound;
*
* 1: Para means grid increment.
* Last grid point is less equal to higherbound.
* Return a vector (ans) of calculated size:
*
* ans[0]=lowerbound;
* ans[1]-ans[0]=Para;
* upperbound-Para<ans.back();
* ans.back()<=upperbound;
*
* -1: Same as 1. Will only return the grid property:
*
* ans.size()=2;
* ans[0] = calculated grid size.
* ans[1] = adjusted upperbound.
*
*
* 2: Para means an estimation of grid increment.
* The calculated grid increment (Para*) is (possibly)
* sightly adjusted such that the higherbound is meet.
* Return a vector (ans) of calculated size:
*
* ans[0]=lowerbound;
* ans[1]-ans[0]=Para* (<=Para);
* ans.back()=upperbound;
*
* -2: Same as 2. Will only return the grid property:
*
* ans.size()=2;
* ans[0] = calculated grid size.
* ans[1] = adjusted Para (Para*).
*
* return(s):
* vector<double> ans ---- Created grid or grid properties, depending on mode.
*
* Shule Yu
* Jan 23 2018
*
* Key words: creating grid.
***********************************************************/
std::vector<double> CreateGrid(const double &lowerbound, const double &upperbound,
const double &Para, const int mode){
double upperBound=upperbound, lowerBound=lowerbound;
bool reverseAns=false;
// check lower and upper bound.
if (upperBound<lowerBound) {
std::swap(upperBound,lowerBound);
reverseAns=true;
}
if (mode==0){
int N=Para;
if (N<=0) throw std::runtime_error("NPTS < 0 ...\n");
double Inc = 1.0 * (upperBound - lowerBound) / (N - 1);
std::vector<double> ans(N, lowerBound);
for (int i = 1 ; i < N; ++i) {
ans[i] = ans[i-1] + Inc;
}
ans[N - 1] = upperBound;
if (reverseAns) {
std::reverse(ans.begin(), ans.end());
}
return ans;
}
if (mode==1 || mode==-1){
double Inc=fabs(Para);
if (mode==-1) {
double N=1+floor(1.0*(upperBound-lowerBound)/Inc);
if (fabs((upperBound-lowerBound-N*Inc))<Inc*1e-6) // float number rounding error?
N+=1;
return {N,lowerBound+(N-1)*Inc};
}
std::vector<double> ans;
double Cur=lowerBound;
while (Cur<=upperBound || Cur-upperBound<Inc*1e-6) {
ans.push_back(Cur);
Cur+=Inc;
}
if (reverseAns) std::reverse(ans.begin(),ans.end());
return ans;
}
if (mode==2 || mode==-2){
double Inc=fabs(Para);
int N=1+(int)round((upperBound-lowerBound)/Inc);
Inc=1.0*(upperBound-lowerBound)/(N-1);
if (mode==-2) {
return {1.0*N,Inc};
}
std::vector<double> ans;
double Cur=lowerBound;
for (int i=0;i<N;++i) {
ans.push_back(Cur);
Cur+=Inc;
}
// Round-off errors eliminator!
ans.back()=upperBound;
if (reverseAns) std::reverse(ans.begin(),ans.end());
return ans;
}
std::cerr << "Error in " << __func__ << ": mode error ..." << std::endl;
return {};
}
#endif