29 #define AREA_RATIO_THRESH (1.e-6) 30 #define MASK_THRESH (0.5) 31 #define EPSLN8 (1.e-8) 32 #define EPSLN30 (1.0e-30) 33 #define EPSLN10 (1.0e-10) 34 #define R2D (180/M_PI) 35 #define TPI (2.0*M_PI) 66 int nx,
ny, nxp,
i,
j, n_in;
67 double x_in[20], y_in[20];
74 x_in[0] =
lon[
j*nxp+
i];
75 x_in[1] =
lon[
j*nxp+
i+1];
76 x_in[2] =
lon[(
j+1)*nxp+
i+1];
77 x_in[3] =
lon[(
j+1)*nxp+
i];
78 y_in[0] =
lat[
j*nxp+
i];
79 y_in[1] =
lat[
j*nxp+
i+1];
80 y_in[2] =
lat[(
j+1)*nxp+
i+1];
81 y_in[3] =
lat[(
j+1)*nxp+
i];
82 n_in =
fix_lon(x_in, y_in, 4, M_PI);
103 double x_in[20], y_in[20];
108 for(l=0; l<
nl; l++) {
110 x_in[1] =
lon[l*nv+1];
111 x_in[2] =
lon[l*nv+2];
112 x_in[3] =
lon[l*nv+3];
114 y_in[1] =
lat[l*nv+1];
115 y_in[2] =
lat[l*nv+2];
116 y_in[3] =
lat[l*nv+3];
117 n_in =
fix_lon(x_in, y_in, nv, M_PI);
134 int nx,
ny, nxp, nyp,
i,
j;
136 double x_in[20], y_in[20], z_in[20];
146 x = (
double *)malloc(nxp*nyp*
sizeof(
double));
147 y = (
double *)malloc(nxp*nyp*
sizeof(
double));
148 z = (
double *)malloc(nxp*nyp*
sizeof(
double));
160 addEnd(grid,
x[n0],
y[n0],
z[n0], 0, 0, 0, -1);
161 addEnd(grid,
x[n1],
y[n1],
z[n1], 0, 0, 0, -1);
163 addEnd(grid,
x[n3],
y[n3],
z[n3], 0, 0, 0, -1);
185 double x_in[20], y_in[20], z_in[20];
192 x = (
double *)malloc(
nl*nv*
sizeof(
double));
193 y = (
double *)malloc(
nl*nv*
sizeof(
double));
194 z = (
double *)malloc(
nl*nv*
sizeof(
double));
198 for(l=0; l<nv; l++) {
206 addEnd(grid,
x[n0],
y[n0],
z[n0], 0, 0, 0, -1);
207 addEnd(grid,
x[n1],
y[n1],
z[n1], 0, 0, 0, -1);
209 addEnd(grid,
x[n3],
y[n3],
z[n3], 0, 0, 0, -1);
221 int nx,
ny, nxp,
i,
j, n_in;
222 double x_in[20], y_in[20];
229 x_in[0] =
lon[
j*nxp+
i];
230 x_in[1] =
lon[
j*nxp+
i+1];
231 x_in[2] =
lon[(
j+1)*nxp+
i+1];
232 x_in[3] =
lon[(
j+1)*nxp+
i];
233 y_in[0] =
lat[
j*nxp+
i];
234 y_in[1] =
lat[
j*nxp+
i+1];
235 y_in[2] =
lat[(
j+1)*nxp+
i+1];
236 y_in[3] =
lat[(
j+1)*nxp+
i];
237 n_in =
fix_lon(x_in, y_in, 4, M_PI);
247 int nx,
ny, nxp,
i,
j, n_in;
248 double x_in[20], y_in[20];
255 x_in[0] =
lon[
j*nxp+
i];
256 x_in[1] =
lon[
j*nxp+
i+1];
257 x_in[2] =
lon[(
j+1)*nxp+
i+1];
258 x_in[3] =
lon[(
j+1)*nxp+
i];
259 y_in[0] =
lat[
j*nxp+
i];
260 y_in[1] =
lat[
j*nxp+
i+1];
261 y_in[2] =
lat[(
j+1)*nxp+
i+1];
262 y_in[3] =
lat[(
j+1)*nxp+
i];
276 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
277 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
double *xgrid_area)
282 i_in, j_in, i_out, j_out, xgrid_area);
288 const double *lat_in,
const double *
lon_out,
const double *
lat_out,
289 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
290 int *j_out,
double *xgrid_area)
293 int nx1, ny1, nx2, ny2, nx1p, nx2p;
294 int i1, j1, i2, j2, nxgrid;
295 double ll_lon, ll_lat, ur_lon, ur_lat, x_in[
MV], y_in[
MV], x_out[
MV], y_out[
MV];
296 double *area_in, *area_out, min_area;
308 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
309 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
310 tmpx = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
311 tmpy = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
312 for(j1=0; j1<=ny1; j1++)
for(i1=0; i1<=nx1; i1++) {
313 tmpx[j1*nx1p+i1] = lon_in[i1];
314 tmpy[j1*nx1p+i1] = lat_in[j1];
326 for(j1=0; j1<ny1; j1++) for(i1=0; i1<nx1; i1++) if( mask_in[j1*nx1+i1] >
MASK_THRESH ) {
328 ll_lon = lon_in[i1]; ll_lat = lat_in[j1];
329 ur_lon = lon_in[i1+1]; ur_lat = lat_in[j1+1];
330 for(j2=0; j2<ny2; j2++)
for(i2=0; i2<nx2; i2++) {
335 y_in[1] =
lat_out[j2*nx2p+i2+1];
336 y_in[2] =
lat_out[(j2+1)*nx2p+i2+1];
337 y_in[3] =
lat_out[(j2+1)*nx2p+i2];
338 if ( (y_in[0]<=ll_lat) && (y_in[1]<=ll_lat)
339 && (y_in[2]<=ll_lat) && (y_in[3]<=ll_lat) )
continue;
340 if ( (y_in[0]>=ur_lat) && (y_in[1]>=ur_lat)
341 && (y_in[2]>=ur_lat) && (y_in[3]>=ur_lat) )
continue;
344 x_in[1] =
lon_out[j2*nx2p+i2+1];
345 x_in[2] =
lon_out[(j2+1)*nx2p+i2+1];
346 x_in[3] =
lon_out[(j2+1)*nx2p+i2];
347 n_in =
fix_lon(x_in, y_in, 4, (ll_lon+ur_lon)/2);
349 if ( (n_out =
clip ( x_in, y_in, n_in, ll_lon, ll_lat, ur_lon, ur_lat, x_out, y_out )) > 0 ) {
350 Xarea =
poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
351 min_area =
min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
353 xgrid_area[nxgrid] = Xarea;
380 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
381 const double *mask_in,
int *i_in,
int *j_in,
int *l_out,
double *xgrid_area)
386 i_in, j_in, l_out, xgrid_area);
392 const double *lat_in,
const double *
lon_out,
const double *
lat_out,
393 const double *mask_in,
int *i_in,
int *j_in,
int *l_out,
double *xgrid_area)
396 int nx1, ny1, nx1p, nv, npts2;
397 int i1, j1, l2, nxgrid;
398 double ll_lon, ll_lat, ur_lon, ur_lat, x_in[
MV], y_in[
MV], x_out[
MV], y_out[
MV];
399 double *area_in, *area_out, min_area;
410 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
411 area_out = (
double *)malloc(npts2*
sizeof(
double));
412 tmpx = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
413 tmpy = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
414 for(j1=0; j1<=ny1; j1++)
for(i1=0; i1<=nx1; i1++) {
415 tmpx[j1*nx1p+i1] = lon_in[i1];
416 tmpy[j1*nx1p+i1] = lat_in[j1];
428 for(j1=0; j1<ny1; j1++) for(i1=0; i1<nx1; i1++) if( mask_in[j1*nx1+i1] >
MASK_THRESH ) {
430 ll_lon = lon_in[i1]; ll_lat = lat_in[j1];
431 ur_lon = lon_in[i1+1]; ur_lat = lat_in[j1+1];
432 for(l2=0; l2<npts2; l2++) {
440 if ( (y_in[0]<=ll_lat) && (y_in[1]<=ll_lat)
441 && (y_in[2]<=ll_lat) && (y_in[3]<=ll_lat) )
continue;
442 if ( (y_in[0]>=ur_lat) && (y_in[1]>=ur_lat)
443 && (y_in[2]>=ur_lat) && (y_in[3]>=ur_lat) )
continue;
449 n_in =
fix_lon(x_in, y_in, 4, (ll_lon+ur_lon)/2);
451 if ( (n_out =
clip ( x_in, y_in, n_in, ll_lon, ll_lat, ur_lon, ur_lat, x_out, y_out )) > 0 ) {
452 Xarea =
poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
453 min_area =
min(area_in[j1*nx1+i1], area_out[l2]);
455 xgrid_area[nxgrid] = Xarea;
480 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
481 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
482 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
485 nxgrid =
create_xgrid_1dx2d_order2(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in,
lon_out,
lat_out, mask_in, i_in,
486 j_in, i_out, j_out, xgrid_area, xgrid_clon, xgrid_clat);
491 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
492 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
493 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
496 int nx1, ny1, nx2, ny2, nx1p, nx2p;
497 int i1, j1, i2, j2, nxgrid,
n;
498 double ll_lon, ll_lat, ur_lon, ur_lat, x_in[
MV], y_in[
MV], x_out[
MV], y_out[
MV];
499 double *area_in, *area_out, min_area;
511 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
512 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
513 tmpx = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
514 tmpy = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
515 for(j1=0; j1<=ny1; j1++)
for(i1=0; i1<=nx1; i1++) {
516 tmpx[j1*nx1p+i1] = lon_in[i1];
517 tmpy[j1*nx1p+i1] = lat_in[j1];
524 for(j1=0; j1<ny1; j1++) for(i1=0; i1<nx1; i1++) if( mask_in[j1*nx1+i1] >
MASK_THRESH ) {
526 ll_lon = lon_in[i1]; ll_lat = lat_in[j1];
527 ur_lon = lon_in[i1+1]; ur_lat = lat_in[j1+1];
528 for(j2=0; j2<ny2; j2++)
for(i2=0; i2<nx2; i2++) {
530 double xarea, lon_in_avg;
533 y_in[1] =
lat_out[j2*nx2p+i2+1];
534 y_in[2] =
lat_out[(j2+1)*nx2p+i2+1];
535 y_in[3] =
lat_out[(j2+1)*nx2p+i2];
536 if ( (y_in[0]<=ll_lat) && (y_in[1]<=ll_lat)
537 && (y_in[2]<=ll_lat) && (y_in[3]<=ll_lat) )
continue;
538 if ( (y_in[0]>=ur_lat) && (y_in[1]>=ur_lat)
539 && (y_in[2]>=ur_lat) && (y_in[3]>=ur_lat) )
continue;
542 x_in[1] =
lon_out[j2*nx2p+i2+1];
543 x_in[2] =
lon_out[(j2+1)*nx2p+i2+1];
544 x_in[3] =
lon_out[(j2+1)*nx2p+i2];
545 n_in =
fix_lon(x_in, y_in, 4, (ll_lon+ur_lon)/2);
548 if ( (n_out =
clip ( x_in, y_in, n_in, ll_lon, ll_lat, ur_lon, ur_lat, x_out, y_out )) > 0 ) {
549 xarea =
poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
550 min_area =
min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
552 xgrid_area[nxgrid] = xarea;
553 xgrid_clon[nxgrid] =
poly_ctrlon(x_out, y_out, n_out, lon_in_avg);
554 xgrid_clat[nxgrid] =
poly_ctrlat (x_out, y_out, n_out );
580 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
581 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
582 int *j_out,
double *xgrid_area)
587 i_in, j_in, i_out, j_out, xgrid_area);
592 const double *lat_in,
const double *
lon_out,
const double *
lat_out,
593 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
594 int *j_out,
double *xgrid_area)
597 int nx1, ny1, nx2, ny2, nx1p, nx2p;
598 int i1, j1, i2, j2, nxgrid;
599 double ll_lon, ll_lat, ur_lon, ur_lat, x_in[
MV], y_in[
MV], x_out[
MV], y_out[
MV];
600 double *area_in, *area_out, min_area;
614 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
615 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
616 tmpx = (
double *)malloc((nx2+1)*(ny2+1)*
sizeof(
double));
617 tmpy = (
double *)malloc((nx2+1)*(ny2+1)*
sizeof(
double));
618 for(j2=0; j2<=ny2; j2++)
for(i2=0; i2<=nx2; i2++) {
619 tmpx[j2*nx2p+i2] =
lon_out[i2];
620 tmpy[j2*nx2p+i2] =
lat_out[j2];
628 for(j2=0; j2<ny2; j2++)
for(i2=0; i2<nx2; i2++) {
632 for(j1=0; j1<ny1; j1++) for(i1=0; i1<nx1; i1++) if( mask_in[j1*nx1+i1] >
MASK_THRESH ) {
634 y_in[0] = lat_in[j1*nx1p+i1];
635 y_in[1] = lat_in[j1*nx1p+i1+1];
636 y_in[2] = lat_in[(j1+1)*nx1p+i1+1];
637 y_in[3] = lat_in[(j1+1)*nx1p+i1];
638 if ( (y_in[0]<=ll_lat) && (y_in[1]<=ll_lat)
639 && (y_in[2]<=ll_lat) && (y_in[3]<=ll_lat) )
continue;
640 if ( (y_in[0]>=ur_lat) && (y_in[1]>=ur_lat)
641 && (y_in[2]>=ur_lat) && (y_in[3]>=ur_lat) )
continue;
643 x_in[0] = lon_in[j1*nx1p+i1];
644 x_in[1] = lon_in[j1*nx1p+i1+1];
645 x_in[2] = lon_in[(j1+1)*nx1p+i1+1];
646 x_in[3] = lon_in[(j1+1)*nx1p+i1];
648 n_in =
fix_lon(x_in, y_in, 4, (ll_lon+ur_lon)/2);
650 if ( (n_out =
clip ( x_in, y_in, n_in, ll_lon, ll_lat, ur_lon, ur_lat, x_out, y_out )) > 0 ) {
651 Xarea =
poly_area ( x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
652 min_area =
min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
654 xgrid_area[nxgrid] = Xarea;
682 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
683 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
684 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
687 nxgrid =
create_xgrid_2dx1d_order2(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in,
lon_out,
lat_out, mask_in, i_in,
688 j_in, i_out, j_out, xgrid_area, xgrid_clon, xgrid_clat);
694 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
695 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
696 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
699 int nx1, ny1, nx2, ny2, nx1p, nx2p;
700 int i1, j1, i2, j2, nxgrid,
n;
701 double ll_lon, ll_lat, ur_lon, ur_lat, x_in[
MV], y_in[
MV], x_out[
MV], y_out[
MV];
703 double *area_in, *area_out, min_area;
718 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
719 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
720 tmpx = (
double *)malloc((nx2+1)*(ny2+1)*
sizeof(
double));
721 tmpy = (
double *)malloc((nx2+1)*(ny2+1)*
sizeof(
double));
722 for(j2=0; j2<=ny2; j2++)
for(i2=0; i2<=nx2; i2++) {
723 tmpx[j2*nx2p+i2] =
lon_out[i2];
724 tmpy[j2*nx2p+i2] =
lat_out[j2];
732 for(j2=0; j2<ny2; j2++)
for(i2=0; i2<nx2; i2++) {
736 for(j1=0; j1<ny1; j1++) for(i1=0; i1<nx1; i1++) if( mask_in[j1*nx1+i1] >
MASK_THRESH ) {
738 y_in[0] = lat_in[j1*nx1p+i1];
739 y_in[1] = lat_in[j1*nx1p+i1+1];
740 y_in[2] = lat_in[(j1+1)*nx1p+i1+1];
741 y_in[3] = lat_in[(j1+1)*nx1p+i1];
742 if ( (y_in[0]<=ll_lat) && (y_in[1]<=ll_lat)
743 && (y_in[2]<=ll_lat) && (y_in[3]<=ll_lat) )
continue;
744 if ( (y_in[0]>=ur_lat) && (y_in[1]>=ur_lat)
745 && (y_in[2]>=ur_lat) && (y_in[3]>=ur_lat) )
continue;
747 x_in[0] = lon_in[j1*nx1p+i1];
748 x_in[1] = lon_in[j1*nx1p+i1+1];
749 x_in[2] = lon_in[(j1+1)*nx1p+i1+1];
750 x_in[3] = lon_in[(j1+1)*nx1p+i1];
752 n_in =
fix_lon(x_in, y_in, 4, (ll_lon+ur_lon)/2);
755 if ( (n_out =
clip ( x_in, y_in, n_in, ll_lon, ll_lat, ur_lon, ur_lat, x_out, y_out )) > 0 ) {
756 xarea =
poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
757 min_area =
min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
759 xgrid_area[nxgrid] = xarea;
760 xgrid_clon[nxgrid] =
poly_ctrlon(x_out, y_out, n_out, lon_in_avg);
761 xgrid_clat[nxgrid] =
poly_ctrlat (x_out, y_out, n_out );
789 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
790 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
791 int *j_out,
double *xgrid_area)
796 i_in, j_in, i_out, j_out, xgrid_area);
802 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
803 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
804 int *j_out,
double *xgrid_area)
808 int nx1, nx2, ny1, ny2, nx1p, nx2p, nxgrid;
809 double *area_in, *area_out;
812 int npts_left, nblks_left,
pos,
m, npts_my, ij;
813 double *lon_out_min_list,*lon_out_max_list,*lon_out_avg,*lat_out_min_list,*lat_out_max_list;
814 double *lon_out_list, *lat_out_list;
815 int *pnxgrid=
NULL, *pstart;
817 double *pxgrid_area=
NULL;
819 int nthreads, nxgrid_block_max;
828 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
829 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
836 nthreads = omp_get_num_threads();
841 istart2 = (
int *)malloc(nblocks*
sizeof(
int));
842 iend2 = (
int *)malloc(nblocks*
sizeof(
int));
844 pstart = (
int *)malloc(nblocks*
sizeof(
int));
845 pnxgrid = (
int *)malloc(nblocks*
sizeof(
int));
847 nxgrid_block_max =
MAXXGRID/nblocks;
849 for(
m=0;
m<nblocks;
m++) {
851 pstart[
m] =
m*nxgrid_block_max;
859 pxgrid_area = xgrid_area;
862 pi_in = (
int *)malloc(
MAXXGRID*
sizeof(
int));
863 pj_in = (
int *)malloc(
MAXXGRID*
sizeof(
int));
864 pi_out = (
int *)malloc(
MAXXGRID*
sizeof(
int));
865 pj_out = (
int *)malloc(
MAXXGRID*
sizeof(
int));
866 pxgrid_area = (
double *)malloc(
MAXXGRID*
sizeof(
double));
870 nblks_left = nblocks;
872 for(
m=0;
m<nblocks;
m++) {
874 npts_my = npts_left/nblks_left;
875 iend2[
m] = istart2[
m] + npts_my - 1;
877 npts_left -= npts_my;
881 lon_out_min_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
882 lon_out_max_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
883 lat_out_min_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
884 lat_out_max_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
885 lon_out_avg = (
double *)malloc(nx2*ny2*
sizeof(
double));
886 n2_list = (
int *)malloc(nx2*ny2*
sizeof(
int));
887 lon_out_list = (
double *)malloc(
MAX_V*nx2*ny2*
sizeof(
double));
888 lat_out_list = (
double *)malloc(
MAX_V*nx2*ny2*
sizeof(
double));
890 #pragma omp parallel for default(none) shared(nx2,ny2,nx2p,lon_out,lat_out,lat_out_min_list, \ 891 lat_out_max_list,lon_out_min_list,lon_out_max_list, \ 892 lon_out_avg,n2_list,lon_out_list,lat_out_list) 894 for(ij=0; ij<nx2*ny2; ij++){
895 int i2, j2,
n, n0, n1,
n2, n3, n2_in, l;
896 double x2_in[
MV], y2_in[
MV];
900 n0 = j2*nx2p+i2; n1 = j2*nx2p+i2+1;
901 n2 = (j2+1)*nx2p+i2+1; n3 = (j2+1)*nx2p+i2;
909 n2_in =
fix_lon(x2_in, y2_in, 4, M_PI);
915 for(l=0; l<n2_in; l++) {
916 lon_out_list[
n*
MAX_V+l] = x2_in[l];
917 lat_out_list[
n*
MAX_V+l] = y2_in[l];
924 #pragma omp parallel for default(none) shared(nblocks,nx1,ny1,nx1p,mask_in,lon_in,lat_in, \ 925 istart2,iend2,nx2,lat_out_min_list,lat_out_max_list, \ 926 n2_list,lon_out_list,lat_out_list,lon_out_min_list, \ 927 lon_out_max_list,lon_out_avg,area_in,area_out, \ 928 pxgrid_area,pnxgrid,pi_in,pj_in,pi_out,pj_out,pstart,nthreads) 930 for(
m=0;
m<nblocks;
m++) {
932 for(j1=0; j1<ny1; j1++) for(i1=0; i1<nx1; i1++) if( mask_in[j1*nx1+i1] >
MASK_THRESH ) {
933 int n0, n1,
n2, n3, l,n1_in;
934 double lat_in_min,lat_in_max,lon_in_min,lon_in_max,lon_in_avg;
935 double x1_in[
MV], y1_in[
MV], x_out[
MV], y_out[
MV];
937 n0 = j1*nx1p+i1; n1 = j1*nx1p+i1+1;
938 n2 = (j1+1)*nx1p+i1+1; n3 = (j1+1)*nx1p+i1;
939 x1_in[0] = lon_in[n0]; y1_in[0] = lat_in[n0];
940 x1_in[1] = lon_in[n1]; y1_in[1] = lat_in[n1];
941 x1_in[2] = lon_in[
n2]; y1_in[2] = lat_in[
n2];
942 x1_in[3] = lon_in[n3]; y1_in[3] = lat_in[n3];
945 n1_in =
fix_lon(x1_in, y1_in, 4, M_PI);
949 for(ij=istart2[
m]; ij<=iend2[
m]; ij++) {
950 int n_in, n_out, i2, j2, n2_in;
951 double xarea, dx, lon_out_min, lon_out_max;
957 if(lat_out_min_list[ij] >= lat_in_max || lat_out_max_list[ij] <= lat_in_min )
continue;
960 for(l=0; l<n2_in; l++) {
961 x2_in[l] = lon_out_list[ij*
MAX_V+l];
962 y2_in[l] = lat_out_list[ij*
MAX_V+l];
964 lon_out_min = lon_out_min_list[ij];
965 lon_out_max = lon_out_max_list[ij];
966 dx = lon_out_avg[ij] - lon_in_avg;
970 for (l=0; l<n2_in; l++) x2_in[l] +=
TPI;
972 else if (dx > M_PI) {
975 for (l=0; l<n2_in; l++) x2_in[l] -=
TPI;
981 if(lon_out_min >= lon_in_max || lon_out_max <= lon_in_min )
continue;
982 if ( (n_out =
clip_2dx2d( x1_in, y1_in, n1_in, x2_in, y2_in, n2_in, x_out, y_out )) > 0) {
985 xarea =
poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
986 min_area =
min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
990 error_handler(
"nxgrid is greater than MAXXGRID/nthreads, increase MAXXGRID, decrease nthreads, or increase number of MPI ranks");
991 nn = pstart[
m] + pnxgrid[
m]-1;
993 pxgrid_area[nn] = xarea;
1008 nxgrid = pnxgrid[0];
1018 for(
m=0;
m<nblocks;
m++) {
1019 for(
i=0;
i<pnxgrid[
m];
i++) {
1021 i_in[nxgrid] = pi_in[nn];
1022 j_in[nxgrid] = pj_in[nn];
1023 i_out[nxgrid] = pi_out[nn];
1024 j_out[nxgrid] = pj_out[nn];
1025 xgrid_area[nxgrid] = pxgrid_area[nn];
1038 free(lon_out_min_list);
1039 free(lon_out_max_list);
1040 free(lat_out_min_list);
1041 free(lat_out_max_list);
1060 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
1061 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
1062 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1065 nxgrid =
create_xgrid_2dx2d_order2(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in,
lon_out,
lat_out, mask_in, i_in,
1066 j_in, i_out, j_out, xgrid_area, xgrid_clon, xgrid_clat);
1072 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
1073 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
1074 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1078 int nx1, nx2, ny1, ny2, nx1p, nx2p, nxgrid;
1079 double xctrlon, xctrlat;
1080 double *area_in, *area_out;
1083 int npts_left, nblks_left,
pos,
m, npts_my, ij;
1084 double *lon_out_min_list,*lon_out_max_list,*lon_out_avg,*lat_out_min_list,*lat_out_max_list;
1085 double *lon_out_list, *lat_out_list;
1086 int *pnxgrid=
NULL, *pstart;
1088 double *pxgrid_area=
NULL, *pxgrid_clon=
NULL, *pxgrid_clat=
NULL;
1090 int nthreads, nxgrid_block_max;
1099 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
1100 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
1105 #if defined(_OPENMP) 1106 #pragma omp parallel 1107 nthreads = omp_get_num_threads();
1112 istart2 = (
int *)malloc(nblocks*
sizeof(
int));
1113 iend2 = (
int *)malloc(nblocks*
sizeof(
int));
1115 pstart = (
int *)malloc(nblocks*
sizeof(
int));
1116 pnxgrid = (
int *)malloc(nblocks*
sizeof(
int));
1118 nxgrid_block_max =
MAXXGRID/nblocks;
1120 for(
m=0;
m<nblocks;
m++) {
1122 pstart[
m] =
m*nxgrid_block_max;
1130 pxgrid_area = xgrid_area;
1131 pxgrid_clon = xgrid_clon;
1132 pxgrid_clat = xgrid_clat;
1135 pi_in = (
int *)malloc(
MAXXGRID*
sizeof(
int));
1136 pj_in = (
int *)malloc(
MAXXGRID*
sizeof(
int));
1137 pi_out = (
int *)malloc(
MAXXGRID*
sizeof(
int));
1138 pj_out = (
int *)malloc(
MAXXGRID*
sizeof(
int));
1139 pxgrid_area = (
double *)malloc(
MAXXGRID*
sizeof(
double));
1140 pxgrid_clon = (
double *)malloc(
MAXXGRID*
sizeof(
double));
1141 pxgrid_clat = (
double *)malloc(
MAXXGRID*
sizeof(
double));
1144 npts_left = nx2*ny2;
1145 nblks_left = nblocks;
1147 for(
m=0;
m<nblocks;
m++) {
1149 npts_my = npts_left/nblks_left;
1150 iend2[
m] = istart2[
m] + npts_my - 1;
1152 npts_left -= npts_my;
1156 lon_out_min_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
1157 lon_out_max_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
1158 lat_out_min_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
1159 lat_out_max_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
1160 lon_out_avg = (
double *)malloc(nx2*ny2*
sizeof(
double));
1161 n2_list = (
int *)malloc(nx2*ny2*
sizeof(
int));
1162 lon_out_list = (
double *)malloc(
MAX_V*nx2*ny2*
sizeof(
double));
1163 lat_out_list = (
double *)malloc(
MAX_V*nx2*ny2*
sizeof(
double));
1164 #if defined(_OPENMP) 1165 #pragma omp parallel for default(none) shared(nx2,ny2,nx2p,lon_out,lat_out,lat_out_min_list, \ 1166 lat_out_max_list,lon_out_min_list,lon_out_max_list, \ 1167 lon_out_avg,n2_list,lon_out_list,lat_out_list) 1169 for(ij=0; ij<nx2*ny2; ij++){
1170 int i2, j2,
n, n0, n1,
n2, n3, n2_in, l;
1171 double x2_in[
MV], y2_in[
MV];
1175 n0 = j2*nx2p+i2; n1 = j2*nx2p+i2+1;
1176 n2 = (j2+1)*nx2p+i2+1; n3 = (j2+1)*nx2p+i2;
1184 n2_in =
fix_lon(x2_in, y2_in, 4, M_PI);
1190 for(l=0; l<n2_in; l++) {
1191 lon_out_list[
n*
MAX_V+l] = x2_in[l];
1192 lat_out_list[
n*
MAX_V+l] = y2_in[l];
1198 #if defined(_OPENMP) 1199 #pragma omp parallel for default(none) shared(nblocks,nx1,ny1,nx1p,mask_in,lon_in,lat_in, \ 1200 istart2,iend2,nx2,lat_out_min_list,lat_out_max_list, \ 1201 n2_list,lon_out_list,lat_out_list,lon_out_min_list, \ 1202 lon_out_max_list,lon_out_avg,area_in,area_out, \ 1203 pxgrid_area,pnxgrid,pxgrid_clon,pxgrid_clat,pi_in, \ 1204 pj_in,pi_out,pj_out,pstart,nthreads) 1206 for(
m=0;
m<nblocks;
m++) {
1208 for(j1=0; j1<ny1; j1++) for(i1=0; i1<nx1; i1++) if( mask_in[j1*nx1+i1] >
MASK_THRESH ) {
1209 int n0, n1,
n2, n3, l,n1_in;
1210 double lat_in_min,lat_in_max,lon_in_min,lon_in_max,lon_in_avg;
1211 double x1_in[
MV], y1_in[
MV], x_out[
MV], y_out[
MV];
1213 n0 = j1*nx1p+i1; n1 = j1*nx1p+i1+1;
1214 n2 = (j1+1)*nx1p+i1+1; n3 = (j1+1)*nx1p+i1;
1215 x1_in[0] = lon_in[n0]; y1_in[0] = lat_in[n0];
1216 x1_in[1] = lon_in[n1]; y1_in[1] = lat_in[n1];
1217 x1_in[2] = lon_in[
n2]; y1_in[2] = lat_in[
n2];
1218 x1_in[3] = lon_in[n3]; y1_in[3] = lat_in[n3];
1221 n1_in =
fix_lon(x1_in, y1_in, 4, M_PI);
1225 for(ij=istart2[
m]; ij<=iend2[
m]; ij++) {
1226 int n_in, n_out, i2, j2, n2_in;
1227 double xarea, dx, lon_out_min, lon_out_max;
1233 if(lat_out_min_list[ij] >= lat_in_max || lat_out_max_list[ij] <= lat_in_min )
continue;
1235 n2_in = n2_list[ij];
1236 for(l=0; l<n2_in; l++) {
1237 x2_in[l] = lon_out_list[ij*
MAX_V+l];
1238 y2_in[l] = lat_out_list[ij*
MAX_V+l];
1240 lon_out_min = lon_out_min_list[ij];
1241 lon_out_max = lon_out_max_list[ij];
1242 dx = lon_out_avg[ij] - lon_in_avg;
1246 for (l=0; l<n2_in; l++) x2_in[l] +=
TPI;
1248 else if (dx > M_PI) {
1251 for (l=0; l<n2_in; l++) x2_in[l] -=
TPI;
1257 if(lon_out_min >= lon_in_max || lon_out_max <= lon_in_min )
continue;
1258 if ( (n_out =
clip_2dx2d( x1_in, y1_in, n1_in, x2_in, y2_in, n2_in, x_out, y_out )) > 0) {
1261 xarea =
poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
1262 min_area =
min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
1266 error_handler(
"nxgrid is greater than MAXXGRID/nthreads, increase MAXXGRID, decrease nthreads, or increase number of MPI ranks");
1267 nn = pstart[
m] + pnxgrid[
m]-1;
1268 pxgrid_area[nn] = xarea;
1269 pxgrid_clon[nn] =
poly_ctrlon(x_out, y_out, n_out, lon_in_avg);
1270 pxgrid_clat[nn] =
poly_ctrlat (x_out, y_out, n_out );
1283 nxgrid = pnxgrid[0];
1295 for(
m=0;
m<nblocks;
m++) {
1296 for(
i=0;
i<pnxgrid[
m];
i++) {
1298 i_in[nxgrid] = pi_in[nn];
1299 j_in[nxgrid] = pj_in[nn];
1300 i_out[nxgrid] = pi_out[nn];
1301 j_out[nxgrid] = pj_out[nn];
1302 xgrid_area[nxgrid] = pxgrid_area[nn];
1303 xgrid_clon[nxgrid] = pxgrid_clon[nn];
1304 xgrid_clat[nxgrid] = pxgrid_clat[nn];
1319 free(lon_out_min_list);
1320 free(lon_out_max_list);
1321 free(lat_out_min_list);
1322 free(lat_out_max_list);
1337 int clip(
const double lon_in[],
const double lat_in[],
int n_in,
double ll_lon,
double ll_lat,
1338 double ur_lon,
double ur_lat,
double lon_out[],
double lat_out[])
1340 double x_tmp[
MV], y_tmp[
MV], x_last, y_last;
1341 int i_in, i_out, n_out, inside_last,
inside;
1344 x_last = lon_in[n_in-1];
1345 y_last = lat_in[n_in-1];
1346 inside_last = (x_last >= ll_lon);
1347 for (i_in=0,i_out=0;i_in<n_in;i_in++) {
1350 if ((
inside=(lon_in[i_in] >= ll_lon))!=inside_last) {
1351 x_tmp[i_out] = ll_lon;
1352 y_tmp[i_out++] = y_last + (ll_lon - x_last) * (lat_in[i_in] - y_last) / (lon_in[i_in] - x_last);
1357 x_tmp[i_out] = lon_in[i_in];
1358 y_tmp[i_out++] = lat_in[i_in];
1360 x_last = lon_in[i_in];
1361 y_last = lat_in[i_in];
1364 if (!(n_out=i_out))
return(0);
1367 x_last = x_tmp[n_out-1];
1368 y_last = y_tmp[n_out-1];
1369 inside_last = (x_last <= ur_lon);
1370 for (i_in=0,i_out=0;i_in<n_out;i_in++) {
1373 if ((
inside=(x_tmp[i_in] <= ur_lon))!=inside_last) {
1375 lat_out[i_out++] = y_last + (ur_lon - x_last) * (y_tmp[i_in] - y_last)
1376 / (x_tmp[i_in] - x_last);
1382 lat_out[i_out++] = y_tmp[i_in];
1385 x_last = x_tmp[i_in];
1386 y_last = y_tmp[i_in];
1389 if (!(n_out=i_out))
return(0);
1394 inside_last = (y_last >= ll_lat);
1395 for (i_in=0,i_out=0;i_in<n_out;i_in++) {
1399 y_tmp[i_out] = ll_lat;
1400 x_tmp[i_out++] = x_last + (ll_lat - y_last) * (
lon_out[i_in] - x_last) / (
lat_out[i_in] - y_last);
1406 y_tmp[i_out++] =
lat_out[i_in];
1412 if (!(n_out=i_out))
return(0);
1415 x_last = x_tmp[n_out-1];
1416 y_last = y_tmp[n_out-1];
1417 inside_last = (y_last <= ur_lat);
1418 for (i_in=0,i_out=0;i_in<n_out;i_in++) {
1421 if ((
inside=(y_tmp[i_in] <= ur_lat))!=inside_last) {
1423 lon_out[i_out++] = x_last + (ur_lat - y_last) * (x_tmp[i_in] - x_last) / (y_tmp[i_in] - y_last);
1429 lat_out[i_out++] = y_tmp[i_in];
1431 x_last = x_tmp[i_in];
1432 y_last = y_tmp[i_in];
1444 int clip_2dx2d(
const double lon1_in[],
const double lat1_in[],
int n1_in,
1445 const double lon2_in[],
const double lat2_in[],
int n2_in,
1448 double lon_tmp[
MV], lat_tmp[
MV];
1449 double x1_0, y1_0, x1_1, y1_1, x2_0, y2_0, x2_1, y2_1;
1450 double dx1, dy1, dx2, dy2, determ, ds1, ds2;
1451 int i_out, n_out, inside_last,
inside, i1, i2;
1456 for(i1=0; i1<n1_in; i1++) {
1457 lon_tmp[i1] = lon1_in[i1];
1458 lat_tmp[i1] = lat1_in[i1];
1460 x2_0 = lon2_in[n2_in-1];
1461 y2_0 = lat2_in[n2_in-1];
1462 for(i2=0; i2<n2_in; i2++) {
1465 x1_0 = lon_tmp[n_out-1];
1466 y1_0 = lat_tmp[n_out-1];
1467 inside_last =
inside_edge( x2_0, y2_0, x2_1, y2_1, x1_0, y1_0);
1468 for(i1=0, i_out=0; i1<n_out; i1++) {
1471 if((
inside =
inside_edge(x2_0, y2_0, x2_1, y2_1, x1_1, y1_1)) != inside_last ) {
1479 ds1 = y1_0*x1_1 - y1_1*x1_0;
1480 ds2 = y2_0*x2_1 - y2_1*x2_0;
1481 determ = dy2*dx1 - dy1*dx2;
1483 error_handler(
"the line between <x1_0,y1_0> and <x1_1,y1_1> should not parallel to " 1484 "the line between <x2_0,y2_0> and <x2_1,y2_1>");
1486 lon_out[i_out] = (dx2*ds1 - dx1*ds2)/determ;
1487 lat_out[i_out++] = (dy2*ds1 - dy1*ds2)/determ;
1499 if(!(n_out=i_out))
return 0;
1500 for(i1=0; i1<n_out; i1++) {
1515 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
1516 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
1517 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1521 mask_in, i_in, j_in, i_out, j_out, xgrid_area, xgrid_clon, xgrid_clat);
1528 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
1529 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
1530 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1533 int nx1, nx2, ny1, ny2, nx1p, nx2p, ny1p, ny2p, nxgrid, n1_in, n2_in;
1534 int n0, n1,
n2, n3, i1, j1, i2, j2;
1535 double x1_in[
MV], y1_in[
MV], z1_in[
MV];
1536 double x2_in[
MV], y2_in[
MV], z2_in[
MV];
1537 double x_out[
MV], y_out[
MV], z_out[
MV];
1541 double xctrlon, xctrlat;
1542 double *area1, *area2, min_area;
1555 x1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1556 y1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1557 z1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1558 x2 = (
double *)malloc(nx2p*ny2p*
sizeof(
double));
1559 y2 = (
double *)malloc(nx2p*ny2p*
sizeof(
double));
1560 z2 = (
double *)malloc(nx2p*ny2p*
sizeof(
double));
1562 latlon2xyz(nx1p*ny1p, lon_in, lat_in, x1, y1, z1);
1565 area1 = (
double *)malloc(nx1*ny1*
sizeof(
double));
1566 area2 = (
double *)malloc(nx2*ny2*
sizeof(
double));
1572 for(j1=0; j1<ny1; j1++) for(i1=0; i1<nx1; i1++) if( mask_in[j1*nx1+i1] >
MASK_THRESH ) {
1574 n0 = j1*nx1p+i1; n1 = (j1+1)*nx1p+i1;
1575 n2 = (j1+1)*nx1p+i1+1; n3 = j1*nx1p+i1+1;
1576 x1_in[0] = x1[n0]; y1_in[0] = y1[n0]; z1_in[0] = z1[n0];
1577 x1_in[1] = x1[n1]; y1_in[1] = y1[n1]; z1_in[1] = z1[n1];
1578 x1_in[2] = x1[
n2]; y1_in[2] = y1[
n2]; z1_in[2] = z1[
n2];
1579 x1_in[3] = x1[n3]; y1_in[3] = y1[n3]; z1_in[3] = z1[n3];
1581 for(j2=0; j2<ny2; j2++)
for(i2=0; i2<nx2; i2++) {
1585 n0 = j2*nx2p+i2; n1 = (j2+1)*nx2p+i2;
1586 n2 = (j2+1)*nx2p+i2+1; n3 = j2*nx2p+i2+1;
1587 x2_in[0] = x2[n0]; y2_in[0] = y2[n0]; z2_in[0] = z2[n0];
1588 x2_in[1] = x2[n1]; y2_in[1] = y2[n1]; z2_in[1] = z2[n1];
1589 x2_in[2] = x2[
n2]; y2_in[2] = y2[
n2]; z2_in[2] = z2[
n2];
1590 x2_in[3] = x2[n3]; y2_in[3] = y2[n3]; z2_in[3] = z2[n3];
1593 x_out, y_out, z_out)) > 0) {
1595 min_area =
min(area1[j1*nx1+i1], area2[j2*nx2+i2]);
1597 #ifdef debug_test_create_xgrid 1598 printf(
"(i2,j2)=(%d,%d), (i1,j1)=(%d,%d), xarea=%g\n", i2, j2, i1, j1, xarea);
1600 xgrid_area[nxgrid] = xarea;
1601 xgrid_clon[nxgrid] = 0;
1602 xgrid_clat[nxgrid] = 0;
1631 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
1632 const double *mask_in,
int *i_in,
int *j_in,
int *l_out,
1633 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1637 mask_in, i_in, j_in, l_out, xgrid_area, xgrid_clon, xgrid_clat);
1644 const double *lon_in,
const double *lat_in,
const double *
lon_out,
const double *
lat_out,
1645 const double *mask_in,
int *i_in,
int *j_in,
int *l_out,
1646 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1649 int nx1, ny1, npts2, nx1p, ny1p, nxgrid, n1_in, n2_in, nv;
1650 int n0, n1,
n2, n3, i1, j1, l2;
1651 double x1_in[
MV], y1_in[
MV], z1_in[
MV];
1652 double x2_in[
MV], y2_in[
MV], z2_in[
MV];
1653 double x_out[
MV], y_out[
MV], z_out[
MV];
1657 double xctrlon, xctrlat;
1658 double *area1, *area2, min_area;
1669 x1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1670 y1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1671 z1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1672 x2 = (
double *)malloc(npts2*nv*
sizeof(
double));
1673 y2 = (
double *)malloc(npts2*nv*
sizeof(
double));
1674 z2 = (
double *)malloc(npts2*nv*
sizeof(
double));
1676 latlon2xyz(nx1p*ny1p, lon_in, lat_in, x1, y1, z1);
1679 area1 = (
double *)malloc(nx1*ny1*
sizeof(
double));
1680 area2 = (
double *)malloc(npts2*
sizeof(
double));
1686 for(j1=0; j1<ny1; j1++) for(i1=0; i1<nx1; i1++) if( mask_in[j1*nx1+i1] >
MASK_THRESH ) {
1688 n0 = j1*nx1p+i1; n1 = (j1+1)*nx1p+i1;
1689 n2 = (j1+1)*nx1p+i1+1; n3 = j1*nx1p+i1+1;
1690 x1_in[0] = x1[n0]; y1_in[0] = y1[n0]; z1_in[0] = z1[n0];
1691 x1_in[1] = x1[n1]; y1_in[1] = y1[n1]; z1_in[1] = z1[n1];
1692 x1_in[2] = x1[
n2]; y1_in[2] = y1[
n2]; z1_in[2] = z1[
n2];
1693 x1_in[3] = x1[n3]; y1_in[3] = y1[n3]; z1_in[3] = z1[n3];
1695 for(l2=0; l2<npts2; l2++) {
1699 n0 = l2*nv; n1 = l2*nv+1;
1700 n2 = l2*nv+2; n3 = l2*nv+3;
1701 x2_in[0] = x2[n0]; y2_in[0] = y2[n0]; z2_in[0] = z2[n0];
1702 x2_in[1] = x2[n1]; y2_in[1] = y2[n1]; z2_in[1] = z2[n1];
1703 x2_in[2] = x2[
n2]; y2_in[2] = y2[
n2]; z2_in[2] = z2[
n2];
1704 x2_in[3] = x2[n3]; y2_in[3] = y2[n3]; z2_in[3] = z2[n3];
1707 x_out, y_out, z_out)) > 0) {
1709 min_area =
min(area1[j1*nx1+i1], area2[l2]);
1711 #ifdef debug_test_create_xgrid 1712 printf(
"(l2)=(%d,%d), (i1,j1)=(%d,%d), xarea=%g\n", l2, i1, j1, xarea);
1714 xgrid_area[nxgrid] = xarea;
1715 xgrid_clon[nxgrid] = 0;
1716 xgrid_clat[nxgrid] = 0;
1755 const double x2_in[],
const double y2_in[],
const double z2_in [],
int n2_in,
1756 double x_out[],
double y_out[],
double z_out[])
1768 int i1, i2, i1p, i2p, i2p2, npts1, npts2;
1769 int nintersect, n_out;
1770 int maxiter1, maxiter2, iter1, iter2;
1771 int found1, found2, curListNum;
1773 double pt1[
MV][3], pt2[
MV][3];
1778 double min_x1, max_x1, min_y1, max_y1, min_z1, max_z1;
1779 double min_x2, max_x2, min_y2, max_y2, min_z2, max_z2;
1813 for(i1=0; i1<n1_in; i1++)
addEnd(grid1List, x1_in[i1], y1_in[i1], z1_in[i1], 0, 0, 0, -1);
1814 for(i2=0; i2<n2_in; i2++)
addEnd(grid2List, x2_in[i2], y2_in[i2], z2_in[i2], 0, 0, 0, -1);
1815 npts1 =
length(grid1List);
1816 npts2 =
length(grid2List);
1820 #ifdef debug_test_create_xgrid 1821 printf(
"\nNOTE from clip_2dx2d_great_circle: begin to set inside value grid1List\n");
1834 #ifdef debug_test_create_xgrid 1835 printf(
"\nNOTE from clip_2dx2d_great_circle: begin to set inside value of grid2List\n");
1852 error_handler(
"create_xgrid.c(clip_2dx2d_great_circle): grid box 1 is not convex");
1854 error_handler(
"create_xgrid.c(clip_2dx2d_great_circle): grid box 2 is not convex");
1856 #ifdef debug_test_create_xgrid 1866 for(i1=0; i1<npts1; i1++) {
1871 for(i2=0; i2<npts2; i2++) {
1879 #ifdef debug_test_create_xgrid 1880 printf(
"\n\n************************ Start line_intersect_2D_3D ******************************\n");
1884 for(i1=0; i1<npts1; i1++) {
1888 for(i2=0; i2<npts2; i2++) {
1890 i2p2 = (i2+2)%npts2;
1894 #ifdef debug_test_create_xgrid 1895 printf(
"\n******************************************************************************\n");
1896 printf(
" i1 = %d, i2 = %d \n", i1, i2);
1897 printf(
"********************************************************************************\n");
1901 int is_in_subj, is_in_clip;
1908 if(
addIntersect(intersectList,
intersect[0],
intersect[1],
intersect[2], 1,
u1,
u2,
inbound, i1, i1p, i2, i2p)) {
1955 temp = intersectList;
1956 nintersect =
length(intersectList);
1957 if(nintersect > 1) {
1965 if( !has_inbound && nintersect > 1) {
1975 maxiter1 = nintersect;
1976 #ifdef debug_test_create_xgrid 1977 printf(
"\nNOTE from clip_2dx2d_great_circle: number of intersect is %d\n", nintersect);
1978 printf(
"\n size of grid2List is %d, size of grid1List is %d\n",
length(grid2List),
length(grid1List));
1979 printNode(intersectList,
"beginning intersection list");
1980 printNode(grid2List,
"beginning clip list");
1981 printNode(grid1List,
"beginning subj list");
1982 printf(
"\n************************ End line_intersect_2D_3D **********************************\n\n");
1989 for(
i=0;
i< n1_in;
i++) printf(
"lon1 = %g, lat1 = %g\n",
lon[
i]*
R2D,
lat[
i]*
R2D);
1992 for(
i=0;
i< n2_in;
i++) printf(
"lon2 = %g, lat2 = %g\n",
lon[
i]*
R2D,
lat[
i]*
R2D);
1997 addNode(polyList, *firstIntersect);
1999 #ifdef debug_test_create_xgrid 2000 printNode(polyList,
"polyList at stage 1");
2004 curList = grid1List;
2010 copyNode(curIntersect, *firstIntersect);
2014 while( iter1 < maxiter1 ) {
2015 #ifdef debug_test_create_xgrid 2016 printf(
"\n----------- At iteration = %d\n\n", iter1+1 );
2017 printNode(curIntersect,
"curIntersect at the begining of iter1");
2024 maxiter2 =
length(curList);
2028 while( iter2 < maxiter2 ) {
2029 int temp2IsIntersect;
2031 temp2IsIntersect = 0;
2041 temp3 =
temp2->Next;
2042 if( temp3 ==
NULL) temp3 = curList;
2048 temp2IsIntersect = 1;
2057 #ifdef debug_test_create_xgrid 2058 printNode(polyList,
"polyList at stage 2");
2060 if(temp2IsIntersect) {
2070 if( !found2 )
error_handler(
" not found the next intersection ");
2073 if(
sameNode( *curIntersect, *firstIntersect) ) {
2079 addNode(polyList, *curIntersect);
2080 #ifdef debug_test_create_xgrid 2081 printNode(polyList,
"polyList at stage 3");
2087 if( curListNum == 0) {
2088 curList = grid2List;
2092 curList = grid1List;
2097 if(!found1)
error_handler(
"not return back to the first intersection");
2100 if( nintersect > 0)
error_handler(
"After clipping, nintersect should be 0");
2111 if( n_out < 3) n_out = 0;
2112 #ifdef debug_test_create_xgrid 2113 printNode(polyList,
"polyList after clipping");
2122 #ifdef debug_test_create_xgrid 2123 printf(
"\nNOTE from clip_2dx2d_great_circle: check if grid1 is inside grid2\n");
2128 if(temp->intersect != 1) {
2129 #ifdef debug_test_create_xgrid 2130 printf(
"grid1->isInside = %d\n", temp->isInside);
2132 if( temp->isInside == 1) n1in2++;
2146 if(n_out>0)
return n_out;
2152 #ifdef debug_test_create_xgrid 2153 printf(
"\nNOTE from clip_2dx2d_great_circle: check if grid2 is inside grid1\n");
2159 if(temp->intersect != 1) {
2160 #ifdef debug_test_create_xgrid 2161 printf(
"grid2->isInside = %d\n", temp->isInside);
2163 if( temp->isInside == 1) n2in1++;
2204 double p1[3], v1[3], v2[3];
2205 double c1[3],
c2[3],
c3[3];
2206 double coincident,
sense, norm;
2208 int is_inter1, is_inter2;
2219 #ifdef debug_test_create_xgrid 2220 printf(
"\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *
inbound);
2230 #ifdef debug_test_create_xgrid 2231 printf(
"\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *
inbound);
2236 #ifdef debug_test_create_xgrid 2237 printf(
"\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *
inbound);
2247 #ifdef debug_test_create_xgrid 2248 printf(
"\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *
inbound);
2276 if(fabs(*u_a) <
EPSLN8) *u_a = 0;
2277 if(fabs(*u_a-1) <
EPSLN8) *u_a = 1;
2280 #ifdef debug_test_create_xgrid 2281 printf(
"\nNOTE from line_intersect_2D_3D: u_a = %19.15f\n", *u_a);
2285 if( (*u_a < 0) || (*u_a > 1) )
return 0;
2304 if(fabs(*u_q) <
EPSLN8) *u_q = 0;
2305 if(fabs(*u_q-1) <
EPSLN8) *u_q = 1;
2306 #ifdef debug_test_create_xgrid 2307 printf(
"\nNOTE from line_intersect_2D_3D: u_q = %19.15f\n", *u_q);
2311 if( (*u_q < 0) || (*u_q > 1) )
return 0;
2321 if(fabs(coincident) <
EPSLN30)
return 0;
2332 if(*u_q != 0 && *u_q != 1){
2337 v1[0] = q2[0]-q1[0];
2338 v1[1] = q2[1]-q1[1];
2339 v1[2] = q2[2]-q1[2];
2340 v2[0] = q3[0]-q2[0];
2341 v2[1] = q3[1]-q2[1];
2342 v2[2] = q3[2]-q2[2];
2351 #ifdef debug_test_create_xgrid 2352 printf(
"\nNOTE from line_intersect_2D_3D: inbound=%d\n", *
inbound);
2366 double ctrlat = 0.0;
2371 double dx = (
x[
ip]-
x[
i]);
2372 double dy, avg_y, hdy;
2378 avg_y = (lat1+
lat2)*0.5;
2379 if (dx==0.0)
continue;
2380 if(dx > M_PI) dx = dx - 2.0*M_PI;
2381 if(dx < -M_PI) dx = dx + 2.0*M_PI;
2384 ctrlat -= dx*(2*cos(avg_y) +
lat2*sin(avg_y) - cos(lat1) );
2386 ctrlat -= dx*( (sin(hdy)/hdy)*(2*cos(avg_y) +
lat2*sin(avg_y)) - cos(lat1) );
2397 double ctrlon = 0.0;
2403 double phi1, phi2, dphi, lat1,
lat2, dphi1, dphi2;
2404 double f1, f2, fac, fint;
2411 if (dphi==0.0)
continue;
2413 f1 = 0.5*(cos(lat1)*sin(lat1)+lat1);
2418 if(dphi > M_PI) dphi = dphi - 2.0*M_PI;
2419 if(dphi < -M_PI) dphi = dphi + 2.0*M_PI;
2420 dphi1 = phi1 - clon;
2421 if( dphi1 > M_PI) dphi1 -= 2.0*M_PI;
2422 if( dphi1 <-M_PI) dphi1 += 2.0*M_PI;
2424 if( dphi2 > M_PI) dphi2 -= 2.0*M_PI;
2425 if( dphi2 <-M_PI) dphi2 += 2.0*M_PI;
2427 if(abs(dphi2 -dphi1) < M_PI) {
2428 ctrlon -= dphi * (dphi1*f1+dphi2*f2)/2.0;
2435 fint = f1 + (f2-f1)*(fac-dphi1)/abs(dphi);
2436 ctrlon -= 0.5*dphi1*(dphi1-fac)*f1 - 0.5*dphi2*(dphi2+fac)*f2
2437 + 0.5*fac*(dphi1+dphi2)*fint;
2448 double box_ctrlat(
double ll_lon,
double ll_lat,
double ur_lon,
double ur_lat)
2450 double dphi = ur_lon-ll_lon;
2453 if(dphi > M_PI) dphi = dphi - 2.0*M_PI;
2454 if(dphi < -M_PI) dphi = dphi + 2.0*M_PI;
2455 ctrlat = dphi*(cos(ur_lat) + ur_lat*sin(ur_lat)-(cos(ll_lat) + ll_lat*sin(ll_lat)));
2463 double box_ctrlon(
double ll_lon,
double ll_lat,
double ur_lon,
double ur_lat,
double clon)
2465 double phi1, phi2, dphi, lat1,
lat2, dphi1, dphi2;
2466 double f1, f2, fac, fint;
2467 double ctrlon = 0.0;
2470 for(
i =0;
i<2;
i++) {
2474 lat1 =
lat2 = ll_lat;
2479 lat1 =
lat2 = ur_lat;
2482 f1 = 0.5*(cos(lat1)*sin(lat1)+lat1);
2485 if(dphi > M_PI) dphi = dphi - 2.0*M_PI;
2486 if(dphi < -M_PI) dphi = dphi + 2.0*M_PI;
2488 dphi1 = phi1 - clon;
2489 if( dphi1 > M_PI) dphi1 -= 2.0*M_PI;
2490 if( dphi1 <-M_PI) dphi1 += 2.0*M_PI;
2492 if( dphi2 > M_PI) dphi2 -= 2.0*M_PI;
2493 if( dphi2 <-M_PI) dphi2 += 2.0*M_PI;
2495 if(fabs(dphi2 -dphi1) < M_PI) {
2496 ctrlon -= dphi * (dphi1*f1+dphi2*f2)/2.0;
2503 fint = f1 + (f2-f1)*(fac-dphi1)/fabs(dphi);
2504 ctrlon -= 0.5*dphi1*(dphi1-fac)*f1 - 0.5*dphi2*(dphi2+fac)*f2
2505 + 0.5*fac*(dphi1+dphi2)*fint;
2522 for(
i=0;
i<
n-1;
i++) {
2523 for(
j=
i+1;
j<
n;
j++) {
2541 const double *x2,
const double *y2,
const double *z2,
int n2)
2547 for(
i=0;
i<n1;
i++) {
2548 for(
j=0;
j<
n2;
j++) {
2549 dist =
max(dist, pow(x1[
i]-x2[
j],2.)+pow(y1[
i]-y2[
j],2.)+pow(z1[
i]-z2[
j],2.));
2569 const double SMALL = 1.e-12;
2572 product = (
x-x0 )*(y1-y0) + (x0-x1)*(
y-y0);
2573 return (product<=SMALL) ? 1:0;
2580 #ifdef test_create_xgrid 2585 #define D2R (M_PI/180) 2586 #define R2D (180/M_PI) 2587 #define MAXPOINT 1000 2589 int main(
int argc,
char* argv[])
2592 double lon1_in[MAXPOINT], lat1_in[MAXPOINT];
2593 double lon2_in[MAXPOINT], lat2_in[MAXPOINT];
2594 double x1_in[MAXPOINT], y1_in[MAXPOINT], z1_in[MAXPOINT];
2595 double x2_in[MAXPOINT], y2_in[MAXPOINT], z2_in[MAXPOINT];
2597 double x_out[20], y_out[20], z_out[20];
2598 int n1_in, n2_in, n_out,
i,
j;
2599 int nlon1=0, nlat1=0, nlon2=0, nlat2=0;
2616 n1_in = 4; n2_in = 4;
2618 lon1_in[0] = 20; lat1_in[0] = 10;
2619 lon1_in[1] = 20; lat1_in[1] = 12;
2620 lon1_in[2] = 22; lat1_in[2] = 12;
2621 lon1_in[3] = 22; lat1_in[3] = 10;
2622 lon2_in[0] = 21; lat2_in[0] = 11;
2623 lon2_in[1] = 21; lat2_in[1] = 14;
2624 lon2_in[2] = 24; lat2_in[2] = 14;
2625 lon2_in[3] = 24; lat2_in[3] = 11;
2637 lon1_in[0] = 20; lat1_in[0] = 10;
2638 lon1_in[1] = 20; lat1_in[1] = 12;
2639 lon1_in[2] = 22; lat1_in[2] = 12;
2640 lon1_in[3] = 22; lat1_in[3] = 10;
2642 for(
i=0;
i<n2_in;
i++) {
2643 lon2_in[
i] = lon1_in[
i];
2644 lat2_in[
i] = lat1_in[
i];
2657 n1_in = 4; n2_in = 4;
2659 lon1_in[0] = 251.7; lat1_in[0] = 88.98;
2660 lon1_in[1] = 148.3; lat1_in[1] = 88.98;
2661 lon1_in[2] = 57.81; lat1_in[2] = 88.72;
2662 lon1_in[3] = 342.2; lat1_in[3] = 88.72;
2664 lon2_in[0] = 150; lat2_in[0] = 88;
2665 lon2_in[1] = 150; lat2_in[1] = 90;
2666 lon2_in[2] = 152.5; lat2_in[2] = 90;
2667 lon2_in[3] = 152.5; lat2_in[3] = 88;
2685 n1_in = 4; n2_in = 4;
2688 lon1_in[0] = -160; lat1_in[0] = 88.5354;
2689 lon1_in[1] = 152.011; lat1_in[1] = 87.8123;
2690 lon1_in[2] = 102.985; lat1_in[2] = 88.4008;
2691 lon1_in[3] = 20; lat1_in[3] = 89.8047;
2693 lon2_in[0] = 145; lat2_in[0] = 88;
2694 lon2_in[1] = 145; lat2_in[1] = 90;
2695 lon2_in[2] = 150; lat2_in[2] = 90;
2696 lon2_in[3] = 150; lat2_in[3] = 88;
2708 n1_in = 4; n2_in = 4;
2711 lon1_in[0] = -202.6; lat1_in[0] = 87.95;
2712 lon1_in[1] = -280.; lat1_in[1] = 89.56;
2713 lon1_in[2] = -100.0; lat1_in[2] = 90;
2714 lon1_in[3] = -190.; lat1_in[3] = 88;
2716 lon2_in[0] = 145; lat2_in[0] = 88;
2717 lon2_in[1] = 145; lat2_in[1] = 90;
2718 lon2_in[2] = 150; lat2_in[2] = 90;
2719 lon2_in[3] = 150; lat2_in[3] = 88;
2733 n1_in = 4; n2_in = 4;
2736 lon1_in[0] = -160; lat1_in[0] = 88.5354;
2737 lon1_in[1] = 152.011; lat1_in[1] = 87.8123;
2738 lon1_in[2] = 102.985; lat1_in[2] = 88.4008;
2739 lon1_in[3] = 20; lat1_in[3] = 89.8047;
2741 lon2_in[0] = -202.6; lat2_in[0] = 87.95;
2742 lon2_in[1] = -280.; lat2_in[1] = 89.56;
2743 lon2_in[2] = -100.0; lat2_in[2] = 90;
2744 lon2_in[3] = -190.; lat2_in[3] = 88;
2756 n1_in = 4; n2_in = 4;
2758 lon1_in[0] = 20; lat1_in[0] = 10;
2759 lon1_in[1] = 20; lat1_in[1] = 12;
2760 lon1_in[2] = 22; lat1_in[2] = 12;
2761 lon1_in[3] = 22; lat1_in[3] = 10;
2762 lon2_in[0] = 18; lat2_in[0] = 8;
2763 lon2_in[1] = 18; lat2_in[1] = 14;
2764 lon2_in[2] = 24; lat2_in[2] = 14;
2765 lon2_in[3] = 24; lat2_in[3] = 8;
2778 n1_in = 4; n2_in = 4;
2781 lon1_in[0] = 350.0; lat1_in[0] = -45;
2782 lon1_in[1] = 350.0; lat1_in[1] = -43.43;
2783 lon1_in[2] = 352.1; lat1_in[2] = -43.41;
2784 lon1_in[3] = 352.1; lat1_in[3] = -44.98;
2785 lon2_in[0] = 350.0; lat2_in[0] = -46;
2786 lon2_in[1] = 350.0; lat2_in[1] = -44;
2787 lon2_in[2] = 352.5; lat2_in[2] = -44;
2788 lon2_in[3] = 352.5; lat2_in[3] = -46;
2801 n1_in = 4; n2_in = 4;
2803 lon1_in[0] = 305.0; lat1_in[0] = -35.26;
2804 lon1_in[1] = 305.0; lat1_in[1] = -33.80;
2805 lon1_in[2] = 306.6; lat1_in[2] = -34.51;
2806 lon1_in[3] = 306.6; lat1_in[3] = -35.99;
2807 lon2_in[0] = 125; lat2_in[0] = 32;
2808 lon2_in[1] = 125; lat2_in[1] = 34;
2809 lon2_in[2] = 127.5; lat2_in[2] = 34;
2810 lon2_in[3] = 127.5; lat2_in[3] = 32;
2823 n1_in = 4; n2_in = 4;
2825 lon1_in[0] = 125.0; lat1_in[0] = 1.46935;
2826 lon1_in[1] = 126.573; lat1_in[1] = 1.5091;
2827 lon1_in[2] = 126.573; lat1_in[2] = 0;
2828 lon1_in[3] = 125.0; lat1_in[3] = 0;
2829 lon2_in[0] = 125; lat2_in[0] = 0;
2830 lon2_in[1] = 125; lat2_in[1] = 2;
2831 lon2_in[2] = 127.5; lat2_in[2] = 2;
2832 lon2_in[3] = 127.5; lat2_in[3] = 0;
2849 n1_in = (nlon1+1)*(nlat1+1);
2850 n2_in = (nlon2+1)*(nlat2+1);
2852 lon1_in[0] = 350.0; lat1_in[0] = 90.00;
2853 lon1_in[1] = 170.0; lat1_in[1] = 87.92;
2854 lon1_in[2] = 260.0; lat1_in[2] = 87.92;
2855 lon1_in[3] = 215.0; lat1_in[3] = 87.06;
2867 lon2_in[0] = 167.5; lat2_in[0] = 88;
2868 lon2_in[1] = 170; lat2_in[1] = 88;
2869 lon2_in[2] = 167.5; lat2_in[2] = 90;
2870 lon2_in[3] = 170; lat2_in[3] = 90;
2916 n1_in = (nlon1+1)*(nlat1+1);
2917 n2_in = (nlon2+1)*(nlat2+1);
2919 lon1_in[0] = 111.3; lat1_in[0] = 1.591;
2920 lon1_in[1] = 109.7; lat1_in[1] = 2.926;
2921 lon1_in[2] = 108.2; lat1_in[2] = 4.256;
2922 lon1_in[3] = 110.0; lat1_in[3] = 0.000;
2923 lon1_in[4] = 108.4; lat1_in[4] = 1.335;
2924 lon1_in[5] = 106.8; lat1_in[5] = 2.668;
2925 lon1_in[6] = 108.7; lat1_in[6] = -1.591;
2926 lon1_in[7] = 107.1; lat1_in[7] = -0.256;
2927 lon1_in[8] = 105.5; lat1_in[8] = 1.078;
2929 lon2_in[0] = 107.5; lat2_in[0] = 0;
2930 lon2_in[1] = 110; lat2_in[1] = 0;
2931 lon2_in[2] = 107.5; lat2_in[2] = 2;
2932 lon2_in[3] = 110; lat2_in[3] = 2;
2949 n1_in = (nlon1+1)*(nlat1+1);
2950 n2_in = (nlon2+1)*(nlat2+1);
2953 for(
j=0;
j<=nlat1;
j++)
for(
i=0;
i<=nlon1;
i++){
2954 lon1_in[
j*(nlon1+1)+
i] = 20.0 + (
i-1)*2.0;
2955 lat1_in[
j*(nlon1+1)+
i] = 10.0 + (
j-1)*2.0;
2957 for(
j=0;
j<=nlat2;
j++)
for(
i=0;
i<=nlon2;
i++){
2958 lon2_in[
j*(nlon2+1)+
i] = 19.0 + (
i-1)*2.0;
2959 lat2_in[
j*(nlon2+1)+
i] = 9.0 + (
j-1)*2.0;
2970 n1_in = (nlon1+1)*(nlat1+1);
2971 n2_in = (nlon2+1)*(nlat2+1);
3000 lon1_in[0] = 120.369397984526174; lat1_in[0] = 16.751543427495864;
3001 lon1_in[1] = 119.999999999999986; lat1_in[1] = 16.751871929590038;
3002 lon1_in[2] = 120.369397846883501; lat1_in[2] = 16.397797979598028;
3003 lon1_in[3] = 119.999999999999986; lat1_in[3] = 16.398120477217255;
3004 lon2_in[0] = 120.369415056522087; lat2_in[0] = 16.752176828509153;
3005 lon2_in[1] = 119.999999999999986; lat2_in[1] = 16.752505523196167;
3006 lon2_in[2] = 120.369415056522087; lat2_in[2] = 16.397797949548146;
3007 lon2_in[3] = 119.999999999999986; lat2_in[3] = 16.398120477217255;
3018 for(
i=0;
i<n1_in;
i++) {
3019 lon1_in[
i] *= D2R; lat1_in[
i] *=D2R;
3021 for(
i=0;
i<n2_in;
i++) {
3022 lon2_in[
i] *= D2R; lat2_in[
i] *=D2R;
3026 printf(
"\n*********************************************************\n");
3027 printf(
"\n Case %d \n",
n);
3028 printf(
"\n*********************************************************\n");
3033 int *i1, *j1, *i2, *j2;
3034 double *xarea, *xclon, *xclat, *mask1;
3036 mask1 = (
double *)malloc(nlon1*nlat1*
sizeof(
double));
3037 i1 = (
int *)malloc(
MAXXGRID*
sizeof(
int));
3038 j1 = (
int *)malloc(
MAXXGRID*
sizeof(
int));
3039 i2 = (
int *)malloc(
MAXXGRID*
sizeof(
int));
3040 j2 = (
int *)malloc(
MAXXGRID*
sizeof(
int));
3041 xarea = (
double *)malloc(
MAXXGRID*
sizeof(
double));
3042 xclon = (
double *)malloc(
MAXXGRID*
sizeof(
double));
3043 xclat = (
double *)malloc(
MAXXGRID*
sizeof(
double));
3045 for(
i=0;
i<nlon1*nlat1;
i++) mask1[
i] = 1.0;
3048 lon2_in, lat2_in, mask1, i1, j1, i2, j2,
3049 xarea, xclon, xclat);
3050 printf(
"\n*********************************************************\n");
3051 printf(
"\n First input grid box longitude, latitude \n \n");
3052 for(
i=0;
i<n1_in;
i++) printf(
" %g, %g \n", lon1_in[
i]*
R2D, lat1_in[
i]*
R2D);
3054 printf(
"\n Second input grid box longitude, latitude \n \n");
3055 for(
i=0;
i<n2_in;
i++) printf(
" %g, %g \n", lon2_in[
i]*
R2D, lat2_in[
i]*
R2D);
3057 printf(
"\n Number of exchange grid is %d\n", nxgrid);
3058 for(
i=0;
i<nxgrid;
i++) {
3059 printf(
"(i1,j1)=(%d,%d), (i2,j2)=(%d, %d), xgrid_area=%g, xgrid_clon=%g, xgrid_clat=%g\n",
3060 i1[
i], j1[
i], i2[
i], j2[
i], xarea[
i], xclon[
i], xclat[
i]);
3065 double *x1, *y1, *z1, *area1;
3070 for(
i=0;
i<nxgrid;
i++) {
3071 area_sum+= xarea[
i];
3074 area1 = (
double *)malloc((nlon1)*(nlat1)*
sizeof(
double));
3077 printf(
"xgrid area sum is %g, grid 1 area is %g\n", area_sum, area1[0]);
3091 latlon2xyz(n1_in, lon1_in, lat1_in, x1_in, y1_in, z1_in);
3092 latlon2xyz(n2_in, lon2_in, lat2_in, x2_in, y2_in, z2_in);
3095 x_out, y_out, z_out);
3098 printf(
"\n*********************************************************\n");
3099 printf(
"\n First input grid box longitude, latitude \n \n");
3100 for(
i=0;
i<n1_in;
i++) printf(
" %g, %g \n", lon1_in[
i]*
R2D, lat1_in[
i]*
R2D);
3102 printf(
"\n Second input grid box longitude, latitude \n \n");
3103 for(
i=0;
i<n2_in;
i++) printf(
" %g, %g \n", lon2_in[
i]*
R2D, lat2_in[
i]*
R2D);
3105 printf(
"\n output clip grid box longitude, latitude for case 1 \n \n");
int getFirstInbound(struct Node *list, struct Node *nodeOut)
double poly_ctrlat(const double x[], const double y[], int n)
int create_xgrid_1dx2d_order1(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area)
real, parameter, public radius
Radius of the Earth [m].
int create_xgrid_2dx2d_order2(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area, double *xgrid_clon, double *xgrid_clat)
l_size ! loop over number of fields ke do je do i
subroutine error_handler(routine, message)
int create_xgrid_great_circle_ug_(const int *nlon_in, const int *nlat_in, const int *npts_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *l_out, double *xgrid_area, double *xgrid_clon, double *xgrid_clat)
double gridArea(struct Node *grid)
real function intersect(x1, y1, x2, y2, x)
int create_xgrid_2dx1d_order1(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area)
double metric(const double *p)
void setInbound(struct Node *interList, struct Node *list)
real(fvprc), dimension(:), allocatable lon
int create_xgrid_2dx2d_order2_(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area, double *xgrid_clon, double *xgrid_clat)
double grid_box_radius(const double *x, const double *y, const double *z, int n)
#define RANGE_CHECK_CRITERIA
integer, parameter, public ip
int create_xgrid_great_circle_ug(const int *nlon_in, const int *nlat_in, const int *npts_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *l_out, double *xgrid_area, double *xgrid_clon, double *xgrid_clat)
int create_xgrid_2dx1d_order2_(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area, double *xgrid_clon, double *xgrid_clat)
int create_xgrid_great_circle(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area, double *xgrid_clon, double *xgrid_clat)
void get_grid_great_circle_area(const int *nlon, const int *nlat, const double *lon, const double *lat, double *area)
int intersect_tri_with_line(const double *plane, const double *l1, const double *l2, double *p, double *t)
int create_xgrid_1dx2d_order1_(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area)
double box_ctrlat(double ll_lon, double ll_lat, double ur_lon, double ur_lat)
real, dimension(1, 1) lon_out
*f90 *************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************! this routine is used to retrieve scalar boundary data for symmetric domain. subroutine MPP_GET_BOUNDARY_2D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffer, flags, &position, complete, tile_count) type(domain2D), intent(in) ::domain MPP_TYPE_, intent(in) ::field(:,:) MPP_TYPE_, intent(inout), optional ::ebuffer(:), sbuffer(:), wbuffer(:), nbuffer(:) integer, intent(in), optional ::flags, position, tile_count logical, intent(in), optional ::complete MPP_TYPE_ ::field3D(size(field, 1), size(field, 2), 1) MPP_TYPE_, allocatable, dimension(:,:) ::ebuffer2D, sbuffer2D, wbuffer2D, nbuffer2D integer ::xcount, ycount integer ::ntile logical ::need_ebuffer, need_sbuffer, need_wbuffer, need_nbuffer integer(LONG_KIND), dimension(MAX_DOMAIN_FIELDS, MAX_TILES), save ::f_addrs=-9999 integer(LONG_KIND), dimension(4, MAX_DOMAIN_FIELDS, MAX_TILES), save ::b_addrs=-9999 integer, save ::bsize(4)=0, isize=0, jsize=0, ksize=0, pos, list=0, l_size=0, upflags integer ::buffer_size(4) integer ::max_ntile, tile, update_position, ishift, jshift logical ::do_update, is_complete, set_mismatch character(len=3) ::text MPP_TYPE_ ::d_type type(overlapSpec), pointer ::bound=> NULL() ntile
void vect_cross(const double *p1, const double *p2, double *e)
real, dimension(:,:), allocatable temp1
void get_grid_area_no_adjust(const int *nlon, const int *nlat, const double *lon, const double *lat, double *area)
void addEnd(struct Node *list, double x, double y, double z, int intersect, double u, int inbound, int inside)
void xyz2latlon(int np, const double *x, const double *y, const double *z, double *lon, double *lat)
void copyNode(struct Node *node_out, struct Node node_in)
double box_ctrlon(double ll_lon, double ll_lat, double ur_lon, double ur_lat, double clon)
l_size ! loop over number of fields ke do j
void get_grid_area(const int *nlon, const int *nlat, const double *lon, const double *lat, double *area)
void get_grid_area_dimensionless(const int *nlon, const int *nlat, const double *lon, const double *lat, double *area)
integer nlon
No description.
pure elemental type(point) function latlon2xyz(lat, lon)
struct Node * getNextNode(struct Node *list)
void get_grid_great_circle_area_ug(const int *npts, const double *lon, const double *lat, double *area)
int create_xgrid_2dx1d_order1_(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area)
void get_grid_area_(const int *nlon, const int *nlat, const double *lon, const double *lat, double *area)
int insidePolygon(struct Node *node, struct Node *list)
double great_circle_area(int n, const double *x, const double *y, const double *z)
double avgval_double(int size, const double *data)
struct Node * getNode(struct Node *list, struct Node inNode)
real, dimension(1, 1) lat_out
int clip_2dx2d_great_circle(const double x1_in[], const double y1_in[], const double z1_in[], int n1_in, const double x2_in[], const double y2_in[], const double z2_in [], int n2_in, double x_out[], double y_out[], double z_out[])
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) MPP_BROADCAST length
real, dimension(:,:), allocatable area
int line_intersect_2D_3D(double *a1, double *a2, double *q1, double *q2, double *q3, double *intersect, double *u_a, double *u_q, int *inbound)
real(kind=kind_real), parameter u1
void get_grid_area_ug(const int *npts, const double *lon, const double *lat, double *area)
double poly_area_dimensionless(const double x[], const double y[], int n)
int create_xgrid_2dx1d_order2(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area, double *xgrid_clon, double *xgrid_clat)
real, dimension(:,:), allocatable temp2
integer sense
No description.
real(fvprc), dimension(:), allocatable lat
void get_grid_great_circle_area_(const int *nlon, const int *nlat, const double *lon, const double *lat, double *area)
int isIntersect(struct Node node)
type(gsw_result_mpres) n2
#define AREA_RATIO_THRESH
int sameNode(struct Node node1, struct Node node2)
void insertIntersect(struct Node *list, double x, double y, double z, double u1, double u2, int inbound, double x2, double y2, double z2)
void addNode(struct Node *list, struct Node inNode)
double poly_ctrlon(const double x[], const double y[], int n, double clon)
integer, parameter, public npts
int samePoint(double x1, double y1, double z1, double x2, double y2, double z2)
int fix_lon(double x[], double y[], int n, double tlon)
void get_grid_area_ug_(const int *npts, const double *lon, const double *lat, double *area)
int create_xgrid_1dx2d_order1_ug_(const int *nlon_in, const int *nlat_in, const int *npts_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *l_out, double *xgrid_area)
double dist_between_boxes(const double *x1, const double *y1, const double *z1, int n1, const double *x2, const double *y2, const double *z2, int n2)
double poly_area(const double x[], const double y[], int n)
void getCoordinate(struct Node node, double *x, double *y, double *z)
void get_grid_great_circle_area_ug_(const int *npts, const double *lon, const double *lat, double *area)
int clip_2dx2d(const double lon1_in[], const double lat1_in[], int n1_in, const double lon2_in[], const double lat2_in[], int n2_in, double lon_out[], double lat_out[])
double minval_double(int size, const double *data)
l_size ! loop over number of fields ke do je do ie pos
double dot(const double *p1, const double *p2)
int clip(const double lon_in[], const double lat_in[], int n_in, double ll_lon, double ll_lat, double ur_lon, double ur_lat, double lon_out[], double lat_out[])
int create_xgrid_2dx2d_order1_(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area)
int inside_edge(double x0, double y0, double x1, double y1, double x, double y)
double maxval_double(int size, const double *data)
int create_xgrid_1dx2d_order2_(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area, double *xgrid_clon, double *xgrid_clat)
int addIntersect(struct Node *list, double x, double y, double z, int intersect, double u1, double u2, int inbound, int is1, int ie1, int is2, int ie2)
int create_xgrid_1dx2d_order1_ug(const int *nlon_in, const int *nlat_in, const int *npts_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *l_out, double *xgrid_area)
integer nlat
No description.
int create_xgrid_1dx2d_order2(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area, double *xgrid_clon, double *xgrid_clat)
int create_xgrid_2dx2d_order1(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area)
double poly_area_no_adjust(const double x[], const double y[], int n)
real(kind=kind_real), parameter u2
void getCoordinates(struct Node *node, double *p)
void printNode(struct Node *list, char *str)
int create_xgrid_great_circle_(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, double *xgrid_area, double *xgrid_clon, double *xgrid_clat)