Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
interpolation.cpp
Go to the documentation of this file.
1 #include "interpolation.h"
2 
3 
4 /*
5  * Get cell (rectangle) around target point
6  */
7 vector<int> Interpolate::getCell( points *pTarget, points *pSource, int rTargetPointNumber, int rClosestPointNumber ){
8 
9  //Retrieve the actual points
10  pnt tgt_pnt = pTarget->get_point( rTargetPointNumber );
11  pnt closest_pnt = pSource->get_point( rClosestPointNumber );
12 
13  //Initialize the storage vector
14  //Stores point indices of the source points that surround the target point
15  vector<int> grid_points;
16 
17  grid_points.push_back(-1);
18  grid_points.push_back(-1);
19  grid_points.push_back(-1);
20  grid_points.push_back(-1);
21 
22  //Get points closest to the source point that's nearest the target point
23  std::vector<int> near_pts = pSource->get_connected_points(rClosestPointNumber);
24 
25  //Find triangles using the closest points
26  std::list<int*> tri_str;
27 
28  int tris = 0;
29  for(int j=0; j<near_pts.size(); j++){
30  for(int k=j; k<near_pts.size(); k++){
31  if(k == j)
32  continue;
33 
34  //Test if the target point is in the triangle specified
35  //by the two current points and the closest point
36  if(pnt_in_tri(tgt_pnt, pSource->get_point( near_pts[j] ),
37  pSource->get_point( near_pts[k] ),
38  closest_pnt ) ){
39 
40  //If so, store the two points
41  int *t_add = new int[2];
42  t_add[0] = near_pts[j];
43  t_add[1] = near_pts[k];
44 
45  tri_str.push_back(t_add);
46 
47  tris++;
48  }
49  }
50  }
51 
52  //Check for two common points
53  //There should be two triangles (which form a rectangle around the target point)
54  //Find the two points common between the triangles
55  for(list<int*>::iterator it = tri_str.begin(); it != tri_str.end(); it++){
56 
57  std::vector<int> near_pts_x = pSource->get_connected_points( (*it)[0] );
58  std::vector<int> near_pts_y = pSource->get_connected_points( (*it)[1] );
59 
60  int matched_pts = 0;
61 
62  int mp_str[2];
63 
64  for(int j=0; j<near_pts_x.size(); j++){
65  for(int k=0; k<near_pts_y.size(); k++){
66 
67  if( near_pts_x[j] == near_pts_y[k] ){
68  if(matched_pts < 2)
69  mp_str[matched_pts] = near_pts_x[j];
70 
71  matched_pts++;
72  }
73  }
74  }
75 
76  if(matched_pts == 2
77  && mp_str[0] != mp_str[1] //){
78  && mp_str[0] != (*it)[0] //Detect Triangles
79  && mp_str[0] != (*it)[1]
80  && mp_str[1] != (*it)[0]
81  && mp_str[1] != (*it)[1] ){
82 
83  grid_points[0] = (*it)[0];
84  grid_points[1] = (*it)[1];
85  grid_points[2] = mp_str[0];
86  grid_points[3] = mp_str[1];
87 
88  break;
89  }
90  }
91 
92  for(list<int*>::iterator it = tri_str.begin(); it != tri_str.end(); it++){
93  delete[] (*it);
94  }
95 
96  //Return final 4 points
97  return grid_points;
98 }
99 
100 /*
101  * Sort the given points from the given dataset in clockwise order from bottom left
102  */
103 vector<int> Interpolate::sortPoints( points *pSource, vector<int> rGridPoints ){
104 
105  vector< int > sorted_points;
106 
107  //Check input
108  if(pSource == NULL || rGridPoints.size() != 4)
109  return sorted_points;
110 
111  //Sort independent var 0 values
112  while( rGridPoints.size() > 0 ){
113 
114  //Pop a point
115  int curr_point = rGridPoints.back();
116  rGridPoints.pop_back();
117 
118  pnt to_insert = pSource->get_point(curr_point);
119 
120  vector<int>::iterator it;
121 
122  for(it = sorted_points.begin(); it < sorted_points.end(); it++){
123  pnt curr_sorted = pSource->get_point(*it);
124 
125  if(to_insert.vals[0] < curr_sorted.vals[0]){
126  sorted_points.insert(it, curr_point);
127  break;
128  }
129  }
130 
131  //Insert the point at the end if it hasn't already been inserted
132  if(it == sorted_points.end())
133  sorted_points.push_back(curr_point);
134 
135  }
136 
137  //Sort independent var 1 values
138  if(pSource->get_point(sorted_points[0]).vals[1] > pSource->get_point(sorted_points[1]).vals[1]){
139  int zero = sorted_points[0];
140  sorted_points[0] = sorted_points[1];
141  sorted_points[1] = zero;
142  }
143 
144  if(pSource->get_point(sorted_points[2]).vals[1] < pSource->get_point(sorted_points[3]).vals[1]){
145  int two = sorted_points[2];
146  sorted_points[2] = sorted_points[3];
147  sorted_points[3] = two;
148  }
149 
150  return sorted_points;
151 }
152 
153 /*
154  * Return interpolated values of dataset "source" at the points of dataset "target"
155  */
156 points * Interpolate::bilinear( points *pTarget, points *pSource, int rTargetVariable, int rSourceVariable ){
157 
158  //Sanity checks
159  if( pTarget == NULL || pSource == NULL )
160  return NULL;
161 
162  if( rTargetVariable >= pTarget->get_num_vars() || rSourceVariable >= pSource->get_num_vars() )
163  return NULL;
164 
165  //Bilinear interpolation only works with
166  //plane data (2 dimensions, 3rd dimension = value)
167  if( pTarget->get_num_indep_vars() != 2 ||
168  pSource->get_num_indep_vars() != 2 ){
169 
170  return NULL;
171  }
172 
173  //Create data structure for return value
174  points *interp = pTarget->clone();
175 
176  int dropped_points = 0;
177 
178  //Loop over all points
179  for(int i=0; i<pTarget->get_num_points(); i++){
180 
181  //Get point coordinates
182  long double *coord = new long double[pTarget->get_num_indep_vars()];
183  pnt tgt_pnt = pTarget->get_point(i);
184 
185  for(int m=0; m<pTarget->get_num_indep_vars(); m++){
186  coord[m] = tgt_pnt.vals[m];
187  }
188 
189 
190  //Get nearest point in the source mesh
191  int closest = pSource->get_closest(coord);
192  delete[] coord;
193 
194  pnt closest_pnt = pSource->get_point(closest);
195 
196  //Get cell
197  vector<int> grid_points = getCell( pTarget, pSource, i, closest );
198 
199  //TODO
200  //Handle case where less than 4 points can be established
201  //IE: the point is off the grid
202  if( grid_points[0] < 0 || grid_points[1] < 0 ||
203  grid_points[2] < 0 || grid_points[3] < 0 ){
204 
205  dropped_points++;
206  interp->set_point_val(i, rTargetVariable, nan());
207  continue;
208  }
209 
210 
211  //Extract specific grid information
212  vector<int> sorted_points = sortPoints(pSource, grid_points);
213 
214  long double bot_right_0 = pSource->get_point(sorted_points[3]).vals[0];
215  long double bot_left_0 = pSource->get_point(sorted_points[0]).vals[0];
216  long double top_left_1 = pSource->get_point(sorted_points[1]).vals[1];
217  long double bot_left_1 = pSource->get_point(sorted_points[0]).vals[1];
218 
219  long double source_vals[4];
220 
221  //0 = Bottom Left Point
222  //1 = Top Left Point
223  //2 = Top Right Point
224  //3 = Bottom Right Point
225 
226  for(int sp_num = 0; sp_num < sorted_points.size(); sp_num++){
227  source_vals[sp_num] = pSource->get_point(sorted_points[sp_num]).vals[rSourceVariable];
228  }
229 
230  //Calculate square distances
231  long double dist_0 = bot_right_0 - bot_left_0;
232  long double dist_1 = top_left_1 - bot_left_1;
233 
234  //Correct locations
235  long double tgt_0 = tgt_pnt.vals[0];
236  long double tgt_1 = tgt_pnt.vals[1];
237 
238  long double t = (tgt_0 - bot_left_0) / dist_0;
239  long double u = (tgt_1 - bot_left_1) / dist_1;
240 
241  long double interp_val = (1-t)*(1-u)*source_vals[0] + t*(1-u)*source_vals[1];
242  interp_val += t*u*source_vals[2] + (1-t)*u*source_vals[3];
243 
244  //Store interpolated value
245  interp->set_point_val(i, rTargetVariable, interp_val);
246  }
247 
248  return interp;
249 }
250 
int get_num_vars()
Definition: points.cpp:121
virtual std::vector< int > get_connected_points(int point_num)
Definition: points.cpp:196
j indices k indices k
Definition: Indexing.h:6
long double nan()
static vector< int > sortPoints(points *pSource, vector< int > rGridPoints)
Sort points (rGridPoints) from pSouce into a vector where 0 - Bottom Left 1 - Top Left 2 - Top Right ...
Definition: points.h:30
int coord[NPANE][NROW *NCOL][3]
Definition: blastest.C:86
long double * vals
Definition: datatypedef.h:69
void set_point_val(int point_number, int var, long double val)
Definition: points.cpp:129
pnt get_point(int n)
Definition: points.cpp:183
Point object that represents a single point.
Definition: datatypedef.h:68
blockLoc i
Definition: read.cpp:79
j indices j
Definition: Indexing.h:6
static points * bilinear(points *pTarget, points *pSource, int rTargetVariable, int rSourceVariable)
Performs bilinear interpolation to find values from source mesh at the target points.
int get_num_indep_vars()
Definition: points.cpp:125
virtual int get_closest(long double *coord)
Definition: points.cpp:192
bool pnt_in_tri(pnt test, pnt p1, pnt p2, pnt p3)
static vector< int > getCell(points *pTarget, points *pSource, int rTargetPointNumber, int rClosestPointNumber)
Get a points surrounding a target point in a mesh.
int get_num_points()
Definition: points.cpp:117
virtual points * clone()
Definition: points.cpp:80