Ice Sheet System Model  4.18
Code documentation
InterpFromGridToMeshx.cpp
Go to the documentation of this file.
1 
5 #ifdef HAVE_CONFIG_H
6  #include <config.h>
7 #else
8 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
9 #endif
10 
11 #include <cstring>
13 #include "../../shared/shared.h"
14 #include "../../shared/io/io.h"
15 
16 /*InterpFromGridToMeshx{{{*/
17 int InterpFromGridToMeshx(IssmSeqVec<IssmPDouble>** pdata_mesh,double* x_in, int x_rows, double* y_in, int y_rows, double* data, int M, int N, double* x_mesh, double* y_mesh, int nods,double default_value,const char* interptype){
18 
19  /*output: */
20  IssmSeqVec<IssmPDouble>* data_mesh=NULL;
21 
22  /*Intermediary*/
23  double* x=NULL;
24  double* y=NULL;
25  int i;
26 
27  /*Some checks on arguments: */
28  if ((M<2) || (N<2) || (nods<=0)){
29  _error_("nothing to be done according to the dimensions of input matrices and vectors.");
30  }
31  if (x_in[1]-x_in[0]<0){
32  _error_("x coordinate vector should be increasing.\n use Matlab's command x=flipud(x), also flip the data matrix data=fliplr(data)");
33  }
34  if (y_in[1]-y_in[0]<0){
35  _error_("y coordinate vector should be increasing.\n use Matlab's command y=flipud(y), also flip the data matrix data=flipud(data)");
36  }
37 
38  /*Allocate output vector: */
39  data_mesh=new IssmSeqVec<IssmPDouble>(nods);
40 
41  /*Find out what kind of coordinates (x_in,y_in) have been given is input*/
42  if(N==(x_rows-1) && M==(y_rows-1)){
43 
44  /*The coordinates given in input describe the contour of each pixel. Take the center of each pixel*/
45  x=xNew<double>(N);
46  y=xNew<double>(M);
47  for(i=0;i<N;i++) x[i]=(x_in[i]+x_in[i+1])/2.;
48  for(i=0;i<M;i++) y[i]=(y_in[i]+y_in[i+1])/2.;
49  x_rows=x_rows-1;
50  y_rows=y_rows-1;
51  }
52  else if (N==x_rows && M==y_rows){
53 
54  /*The coordinates given in input describe the center each pixel. Keep them*/
55  x=xNew<double>(N);
56  y=xNew<double>(M);
57  for(i=0;i<N;i++) x[i]=x_in[i];
58  for(i=0;i<M;i++) y[i]=y_in[i];
59  }
60  else{
61  _error_("x and y vectors length should be 1 or 0 more than data number of rows.");
62  }
63 
64  /*initialize thread parameters: */
66  gate.x_mesh = x_mesh;
67  gate.y_mesh = y_mesh;
68  gate.x_rows = x_rows;
69  gate.y_rows = y_rows;
70  gate.x = x;
71  gate.y = y;
72  gate.nods = nods;
73  gate.data_mesh = data_mesh;
74  gate.data = data;
75  gate.default_value = default_value;
76  gate.interp = interptype;
77  gate.M = M;
78  gate.N = N;
79 
80  /*launch the thread manager with InterpFromGridToMeshxt as a core: */
81  LaunchThread(InterpFromGridToMeshxt,(void*)&gate,_NUMTHREADS_);
82  //_printf_("\r interpolation progress: "<<fixed<<setw(6)<<setprecision(2)<<100.<<"% \n");
83 
84  /*Assign output pointers:*/
85  *pdata_mesh=data_mesh;
86  return 1;
87 }
88 /*}}}*/
89 /*InterpFromGridToMeshxt {{{*/
90 void* InterpFromGridToMeshxt(void* vpthread_handle){
91 
92  /*gate variables :*/
94  pthread_handle *handle = NULL;
95  int my_thread;
96  int num_threads;
97  int i0,i1;
98 
99  /*intermediary: */
100  int i,m,n;
101  double x_grid;
102  double y_grid;
103  double data_value;
104  double x1,x2,y1,y2;
105  double Q11,Q12,Q21,Q22;
106 
107  /*recover handle and gate: */
108  handle=(pthread_handle*)vpthread_handle;
110  my_thread=handle->id;
111  num_threads=handle->num;
112 
113  /*recover parameters :*/
114  double *x_mesh = gate->x_mesh;
115  double *y_mesh = gate->y_mesh;
116  int x_rows = gate->x_rows;
117  int y_rows = gate->y_rows;
118  double *x = gate->x;
119  double *y = gate->y;
120  int nods = gate->nods;
121  IssmSeqVec<IssmPDouble>*data_mesh = gate->data_mesh;
122  double *data = gate->data;
123  double default_value = gate->default_value;
124  const char* interptype = gate->interp;
125  int M = gate->M;
126  int N = gate->N;
127 
128  bool debug = M*N>1? true:false;
129 
130  /*partition loop across threads: */
131  PartitionRange(&i0,&i1,nods,num_threads,my_thread);
132  for (i=i0;i<i1;i++) {
133 
134  //if(debug && my_thread==0) _printf_("\r interpolation progress: "<<setw(6)<<setprecision(2)<<double(i-i0)/double(i1-i0)*100<<"% ");
135  x_grid=*(x_mesh+i);
136  y_grid=*(y_mesh+i);
137 
138  /*Find indices m and n into y and x, for which y(m)<=y_grids<=y(m+1) and x(n)<=x_grid<=x(n+1)*/
139  if(findindices(&n,&m,x,x_rows, y,y_rows, x_grid,y_grid)){
140 
141  /* Q12 Q22
142  * y2 x---------+-----x
143  * | | |
144  * | |P |
145  * |---------+-----|
146  * | | |
147  * | | |
148  * y1 x---------+-----x Q21
149  * x1 x2
150  *
151  */
152  x1=x[n]; x2=x[n+1];
153  y1=y[m]; y2=y[m+1];
154  Q11=data[m*N+n];
155  Q12=data[(m+1)*N+n];
156  Q21=data[m*N+n+1];
157  Q22=data[(m+1)*N+n+1];
158 
159  if(strcmp(interptype,"triangle")==0){
160  data_value=triangleinterp(x1,x2,y1,y2,Q11,Q12,Q21,Q22,x_grid,y_grid);
161  }
162  else if(strcmp(interptype,"bilinear")==0){
163  data_value=bilinearinterp(x1,x2,y1,y2,Q11,Q12,Q21,Q22,x_grid,y_grid);
164  }
165  else if(strcmp(interptype,"nearest")==0){
166  data_value=nearestinterp(x1,x2,y1,y2, Q11,Q12,Q21,Q22,x_grid,y_grid);
167  }
168  else{
169  _printf_("Interpolation " << interptype << " not supported yet (supported intepolations are: triangle, bilinear and nearest)\n");
170  return NULL; /*WARNING: no error because it would blow up the multithreading!*/
171  }
172  if(xIsNan<IssmPDouble>(data_value)) data_value=default_value;
173  }
174  else{
175  data_value=default_value;
176  }
177 
178  data_mesh->SetValue(i,data_value,INS_VAL);
179  }
180 
181  return NULL;
182 }/*}}}*/
183 
184 /*findindices {{{*/
185 bool findindices(int* pn,int* pm,double* x,int x_rows, double* y,int y_rows, double xgrid,double ygrid){
186 
187  bool foundx=false,foundy=false;
188  int m=-1,n=-1;
189  int i;
190 
191  for (i=0;i<x_rows-1;i++){
192  if ((x[i]<=xgrid) && (xgrid<x[i+1])){
193  n=i;
194  foundx=true;
195  break;
196  }
197  }
198  if(xgrid==x[x_rows-1]){
199  n=x_rows-2;
200  foundx=true;
201  }
202 
203  for (i=0;i<y_rows-1;i++){
204  if ((y[i]<=ygrid) && (ygrid<y[i+1])){
205  m=i;
206  foundy=true;
207  break;
208  }
209  }
210  if(ygrid==y[y_rows-1]){
211  m=y_rows-2;
212  foundy=true;
213  }
214 
215  /*Assign output pointers:*/
216  *pm=m; *pn=n;
217  return (foundx && foundy);
218 }/*}}}*/
219 /*triangleinterp{{{*/
220 double triangleinterp(double x1,double x2,double y1,double y2,double Q11,double Q12,double Q21,double Q22,double x,double y){
221  /*split the rectangle in 2 triangle and
222  * use Lagrange P1 interpolation
223  *
224  * +3----+2,3' Q12----Q22
225  * | /| | /|
226  * | / | | / |
227  * | / | | / |
228  * | / | | / |
229  * |/ | |/ |
230  * 1-----2' Q11---Q21 */
231 
232  /*Intermediaries*/
233  double area,area_1,area_2,area_3;
234 
235  /*Checks*/
236  _assert_(x2>x1 && y2>y1);
237  _assert_(x<=x2 && x>=x1 && y<=y2 && y>=y1);
238 
239  /*area of the rectangle*/
240  area=(x2-x1)*(y2-y1);
241 
242  /*is it the upper left triangle?*/
243  if ((x-x1)/(x2-x1)<(y-y1)/(y2-y1)){
244 
245  area_1=((y2-y)*(x2-x1))/area;
246  area_2=((x-x1)*(y2-y1))/area;
247  area_3=1-area_1-area_2;
248 
249  return area_1*Q11+area_2*Q22+area_3*Q12;
250  }
251  else {
252 
253  area_1=((y-y1)*(x2-x1))/area;
254  area_2=((x2-x)*(y2-y1))/area;
255  area_3=1-area_1-area_2;
256 
257  return area_1*Q22+area_2*Q11+area_3*Q21;
258  }
259 }/*}}}*/
260 /*bilinearinterp{{{*/
261 double bilinearinterp(double x1,double x2,double y1,double y2,double Q11,double Q12,double Q21,double Q22,double x,double y){
262  /*Bilinear interpolation: (http://en.wikipedia.org/wiki/Bilinear_interpolation) */
263 
264  /* Q12 R2 Q22
265  * y2 x------x---------x
266  * | | |
267  * | | |
268  * | +P |
269  * | | |
270  * |Q11 R1 Q21
271  * y1 x------x---------x
272  * x1 x2
273  *
274  */
275 
276  /*Checks*/
277  _assert_(x2>x1 && y2>y1);
278  _assert_(x<=x2 && x>=x1 && y<=y2 && y>=y1);
279 
280  return
281  +Q11*(x2-x)*(y2-y)/((x2-x1)*(y2-y1))
282  +Q21*(x-x1)*(y2-y)/((x2-x1)*(y2-y1))
283  +Q12*(x2-x)*(y-y1)/((x2-x1)*(y2-y1))
284  +Q22*(x-x1)*(y-y1)/((x2-x1)*(y2-y1));
285 }
286 /*}}}*/
287 /*nearestinterp{{{*/
288 double nearestinterp(double x1,double x2,double y1,double y2,double Q11,double Q12,double Q21,double Q22,double x,double y){
289  /*Nearest neighbor interpolation*/
290 
291  /* Q12 Q22
292  * y2 x--------x---------x
293  * | | |
294  * | | xP |
295  * ym |--------+---------|
296  * | | |
297  * | | |
298  * y1 x--------x---------x Q21
299  * x1 xm x2
300  *
301  */
302  /*Checks*/
303  _assert_(x2>x1 && y2>y1);
304  _assert_(x<=x2 && x>=x1 && y<=y2 && y>=y1);
305 
306  double xm=(x2-x1)/2;
307  double ym=(y2-y1)/2;
308 
309  if (x<xm && y<ym) return Q11;
310  if (x<xm && y>ym) return Q12;
311  if (x>xm && y<ym) return Q21;
312  else return Q22;
313 }
314 /*}}}*/
InterpFromGridToMeshxThreadStruct::M
int M
Definition: InterpFromGridToMeshx.h:21
_assert_
#define _assert_(ignore)
Definition: exceptions.h:37
InterpFromGridToMeshxThreadStruct::interp
const char * interp
Definition: InterpFromGridToMeshx.h:20
pthread_handle::id
int id
Definition: issm_threads.h:12
_printf_
#define _printf_(StreamArgs)
Definition: Print.h:22
LaunchThread
void LaunchThread(void *function(void *), void *gate, int num_threads)
Definition: LaunchThread.cpp:25
pthread_handle::num
int num
Definition: issm_threads.h:13
bilinearinterp
double bilinearinterp(double x1, double x2, double y1, double y2, double Q11, double Q12, double Q21, double Q22, double x, double y)
Definition: InterpFromGridToMeshx.cpp:261
InterpFromGridToMeshxThreadStruct::N
int N
Definition: InterpFromGridToMeshx.h:22
IssmSeqVec< IssmPDouble >
InterpFromGridToMeshxThreadStruct::x_mesh
double * x_mesh
Definition: InterpFromGridToMeshx.h:24
InterpFromGridToMeshxThreadStruct::y_mesh
double * y_mesh
Definition: InterpFromGridToMeshx.h:25
InterpFromGridToMeshxThreadStruct::data_mesh
IssmSeqVec< IssmPDouble > * data_mesh
Definition: InterpFromGridToMeshx.h:26
nearestinterp
double nearestinterp(double x1, double x2, double y1, double y2, double Q11, double Q12, double Q21, double Q22, double x, double y)
Definition: InterpFromGridToMeshx.cpp:288
triangleinterp
double triangleinterp(double x1, double x2, double y1, double y2, double Q11, double Q12, double Q21, double Q22, double x, double y)
Definition: InterpFromGridToMeshx.cpp:220
InterpFromGridToMeshxThreadStruct::y
double * y
Definition: InterpFromGridToMeshx.h:16
pthread_handle
Definition: issm_threads.h:10
InterpFromGridToMeshx.h
: header file for Data interpolation routines.
PartitionRange
void PartitionRange(int *pi0, int *pi1, int num_el, int num_threads, int my_thread)
Definition: PartitionRange.cpp:13
InterpFromGridToMeshxt
void * InterpFromGridToMeshxt(void *vpthread_handle)
Definition: InterpFromGridToMeshx.cpp:90
INS_VAL
@ INS_VAL
Definition: toolkitsenums.h:14
InterpFromGridToMeshx
int InterpFromGridToMeshx(IssmSeqVec< IssmPDouble > **pdata_mesh, double *x_in, int x_rows, double *y_in, int y_rows, double *data, int M, int N, double *x_mesh, double *y_mesh, int nods, double default_value, const char *interptype)
Definition: InterpFromGridToMeshx.cpp:17
InterpFromGridToMeshxThreadStruct::default_value
double default_value
Definition: InterpFromGridToMeshx.h:19
_error_
#define _error_(StreamArgs)
Definition: exceptions.h:49
InterpFromGridToMeshxThreadStruct::x
double * x
Definition: InterpFromGridToMeshx.h:14
InterpFromGridToMeshxThreadStruct::data
double * data
Definition: InterpFromGridToMeshx.h:18
pthread_handle::gate
void * gate
Definition: issm_threads.h:11
InterpFromGridToMeshxThreadStruct::y_rows
int y_rows
Definition: InterpFromGridToMeshx.h:17
InterpFromGridToMeshxThreadStruct
Definition: InterpFromGridToMeshx.h:13
InterpFromGridToMeshxThreadStruct::x_rows
int x_rows
Definition: InterpFromGridToMeshx.h:15
InterpFromGridToMeshxThreadStruct::nods
int nods
Definition: InterpFromGridToMeshx.h:23
findindices
bool findindices(int *pn, int *pm, double *x, int x_rows, double *y, int y_rows, double xgrid, double ygrid)
Definition: InterpFromGridToMeshx.cpp:185