22 #include "mosaic_util.h"
23 #include "gradient_c2l.h"
48 void grad_c2l_(
const int *
nlon,
const int *
nlat,
const double *pin,
const double *dx,
const double *dy,
const double *
area,
49 const double *edge_w,
const double *edge_e,
const double *edge_s,
const double *edge_n,
50 const double *en_n,
const double *en_e,
const double *vlon,
const double *vlat,
51 double *grad_x,
double *grad_y,
const int *on_west_edge,
const int *on_east_edge,
52 const int *on_south_edge,
const int *on_north_edge)
54 grad_c2l(
nlon,
nlat, pin, dx, dy,
area, edge_w, edge_e, edge_s, edge_n, en_n, en_e, vlon, vlat, grad_x, grad_y,
55 on_west_edge, on_east_edge, on_south_edge, on_north_edge);
58 void grad_c2l(
const int *
nlon,
const int *
nlat,
const double *pin,
const double *dx,
const double *dy,
const double *
area,
59 const double *edge_w,
const double *edge_e,
const double *edge_s,
const double *edge_n,
60 const double *en_n,
const double *en_e,
const double *vlon,
const double *vlat,
61 double *grad_x,
double *grad_y,
const int *on_west_edge,
const int *on_east_edge,
62 const int *on_south_edge,
const int *on_north_edge)
65 double *pb, *pdx, *pdy, *grad3;
66 int nx, ny, nxp, nyp, i, j, m0, m1, n;
72 pb = (
double *)malloc(nxp*nyp*
sizeof(
double));
73 pdx = (
double *)malloc(3*nx*(ny+1)*
sizeof(double));
74 pdy = (
double *)malloc(3*(nx+1)*ny*
sizeof(double));
75 grad3 = (
double *)malloc(3*nx*ny*
sizeof(
double));
76 a2b_ord2(nx, ny, pin, edge_w, edge_e, edge_s, edge_n, pb, *on_west_edge, *on_east_edge,*on_south_edge, *on_north_edge);
78 for(j=0; j<nyp; j++)
for(i=0; i<nx; i++) {
82 pdx[3*m0+n] = 0.5*(pb[m1]+pb[m1+1])*dx[m0]*en_n[3*m0+n];
86 for(j=0; j<ny; j++)
for(i=0; i<nxp; i++) {
89 pdy[3*m0+n] = 0.5*(pb[m0]+pb[m0+nxp])*dy[m0]*en_e[3*m0+n];
94 for(j=0; j<ny; j++)
for(i=0; i<nx; i++) {
97 grad3[m0+n] = pdx[3*((j+1)*nx+i)+n]-pdx[m0+n]-pdy[3*(j*nxp+i)+n]+pdy[3*(j*nxp+i+1)+n];
102 for(j=0; j<ny; j++)
for(i=0; i<nx; i++) {
106 grad_x[m0] = (vlon[m1]*grad3[m1] + vlon[m1+1]*grad3[m1+1] + vlon[m1+2]*grad3[m1+2])/
area[m0];
107 grad_x[m0] *= RADIUS;
109 grad_y[m0] = (vlat[m1]*grad3[m1] + vlat[m1+1]*grad3[m1+1] + vlat[m1+2]*grad3[m1+2] )/
area[m0];
110 grad_y[m0] *= RADIUS;
124 void a2b_ord2(
int nx,
int ny,
const double *qin,
const double *edge_w,
const double *edge_e,
125 const double *edge_s,
const double *edge_n,
double *qout,
126 int on_west_edge,
int on_east_edge,
int on_south_edge,
int on_north_edge)
129 int istart, iend, jstart, jend;
131 const double r3 = 1./3.;
135 q1 = (
double *)malloc((nx+2)*
sizeof(double));
136 q2 = (
double *)malloc((ny+2)*
sizeof(double));
157 for(j=jstart; j<jend; j++)
for(i=istart; i<iend; i++) {
158 qout[j*nxp+i] = 0.25*(qin[j*(nx+2)+i] + qin[j*(nx+2)+i+1] +
159 qin[(j+1)*(nx+2)+i] + qin[(j+1)*(nx+2)+i+1] );
163 if(on_west_edge && on_south_edge)qout[ 0] = r3*(qin[1* (nx+2)+1 ]+qin[1* (nx+2) ]+qin[ 1]);
164 if(on_east_edge && on_south_edge)qout[ nx] = r3*(qin[1* (nx+2)+nx]+qin[ nx ]+qin[1* (nx+2)+nxp]);
165 if(on_east_edge && on_north_edge)qout[ny*nxp+nx] = r3*(qin[ny*(nx+2)+nx]+qin[ny*(nx+2)+nxp]+qin[nyp*(nx+2)+nx ]);
166 if(on_west_edge && on_north_edge)qout[ny*nxp ] = r3*(qin[ny*(nx+2)+1 ]+qin[ny*(nx+2) ]+qin[nyp*(nx+2)+1 ]);
170 for(j=jstart; j<=jend; j++){
171 q2[j] = 0.5*(qin[j*(nx+2)] + qin[j*(nx+2)+1]);
173 for(j=jstart; j<jend; j++){
174 qout[j*nxp] = edge_w[j]*q2[j] + (1-edge_w[j])*q2[j+1];
180 for(j=jstart; j<=jend; j++){
181 q2[j] = 0.5*(qin[j*(nx+2)+nx] + qin[j*(nx+2)+nxp]);
183 for(j=jstart; j<jend; j++){
184 qout[j*nxp+nx] = edge_e[j]*q2[j] + (1-edge_e[j])*q2[j+1];
190 for(i=istart; i<=iend; i++){
191 q1[i] = 0.5*(qin[i] + qin[(nx+2)+i]);
193 for(i=istart; i<iend; i++){
194 qout[i] = edge_s[i]*q1[i] + (1 - edge_s[i])*q1[i+1];
200 for(i=istart; i<=iend; i++){
201 q1[i] = 0.5*(qin[ny*(nx+2)+i] + qin[nyp*(nx+2)+i]);
203 for(i=istart; i<iend; i++){
204 qout[ny*nxp+i] = edge_n[i]*q1[i] + (1 - edge_n[i])*q1[i+1];
214 void get_edge(
int nx,
int ny,
const double *lont,
const double *latt,
215 const double *lonc,
const double *latc,
double *edge_w,
double *edge_e,
double *edge_s,
double *edge_n,
216 int on_west_edge,
int on_east_edge,
int on_south_edge,
int on_north_edge)
219 int istart, iend, jstart, jend;
227 for(i=0; i<nxp; i++) {
231 for(j=0; j<nyp; j++) {
236 px = (
double *)malloc(2*(nx+2)*
sizeof(double));
237 py = (
double *)malloc(2*(ny+2)*
sizeof(double));
259 for(j=jstart; j<=jend; j++) {
261 p1[0] = lont[j*(nx+2)+i ]; p1[1] = latt[j*(nx+2)+i ];
262 p2[0] = lont[j*(nx+2)+i+1]; p2[1] = latt[j*(nx+2)+i+1];
263 mid_pt_sphere(p1, p2, &(py[2*j]));
266 for(j=jstart; j<jend; j++) {
267 p1[0] = lonc[j*nxp+i];
268 p1[1] = latc[j*nxp+i];
269 d1 = great_circle_distance(py+2*j, p1);
270 d2 = great_circle_distance(py+2*(j+1), p1);
271 edge_w[j] = d2/(d1+d2);
277 for(j=jstart; j<=jend; j++) {
279 p1[0] = lont[j*(nx+2)+i ]; p1[1] = latt[j*(nx+2)+i ];
280 p2[0] = lont[j*(nx+2)+i+1]; p2[1] = latt[j*(nx+2)+i+1];
281 mid_pt_sphere(p1, p2, &(py[2*j]));
284 for(j=jstart; j<jend; j++) {
285 p1[0] = lonc[j*nxp+i];
286 p1[1] = latc[j*nxp+i];
287 d1 = great_circle_distance(&(py[2*j]), p1);
288 d2 = great_circle_distance(&(py[2*(j+1)]), p1);
289 edge_e[j] = d2/(d1+d2);
296 for(i=istart; i<=iend; i++) {
297 p1[0] = lont[j *(nx+2)+i]; p1[1] = latt[j *(nx+2)+i];
298 p2[0] = lont[(j+1)*(nx+2)+i]; p2[1] = latt[(j+1)*(nx+2)+i];
299 mid_pt_sphere(p1, p2, &(px[2*i]));
301 for(i=istart; i<iend; i++) {
302 p1[0] = lonc[j*nxp+i];
303 p1[1] = latc[j*nxp+i];
304 d1 = great_circle_distance(&(px[2*i]), p1);
305 d2 = great_circle_distance(&(px[2*(i+1)]), p1);
306 edge_s[i] = d2/(d1+d2);
312 for(i=istart; i<=iend; i++) {
313 p1[0] = lont[j *(nx+2)+i]; p1[1] = latt[j *(nx+2)+i];
314 p2[0] = lont[(j+1)*(nx+2)+i]; p2[1] = latt[(j+1)*(nx+2)+i];
315 mid_pt_sphere(p1, p2, &(px[2*i]));
317 for(i=istart; i<iend; i++) {
318 p1[0] = lonc[j*nxp+i];
319 p1[1] = latc[j*nxp+i];
320 d1 = great_circle_distance(&(px[2*i]), p1);
321 d2 = great_circle_distance(&(px[2*(i+1)]), p1);
322 edge_n[i] = d2/(d1+d2);
331 void mid_pt_sphere(
const double *p1,
const double *p2,
double *pm)
333 double e1[3], e2[3], e3[3];
337 mid_pt3_cart(e1, e2, e3);
338 xyz2latlon(1, e3, e3+1, e3+2, pm, pm+1);
342 void mid_pt3_cart(
const double *p1,
const double *p2,
double *e)
346 e[0] = p1[0] + p2[0];
347 e[1] = p1[1] + p2[1];
348 e[2] = p1[2] + p2[2];
349 dd = sqrt( e[0]*e[0] + e[1]*e[1] + e[2]*e[2] );
374 void calc_c2l_grid_info_(
int *nx_pt,
int *ny_pt,
const double *xt,
const double *yt,
const double *xc,
const double *yc,
375 double *dx,
double *dy,
double *
area,
double *edge_w,
double *edge_e,
double *edge_s,
376 double *edge_n,
double *en_n,
double *en_e,
double *vlon,
double *vlat,
377 int *on_west_edge,
int *on_east_edge,
int *on_south_edge,
int *on_north_edge)
379 calc_c2l_grid_info(nx_pt, ny_pt, xt, yt, xc, yc, dx, dy,
area, edge_w, edge_e, edge_s, edge_n,
380 en_n, en_e, vlon, vlat, on_west_edge, on_east_edge, on_south_edge, on_north_edge);
384 void calc_c2l_grid_info(
int *nx_pt,
int *ny_pt,
const double *xt,
const double *yt,
const double *xc,
const double *yc,
385 double *dx,
double *dy,
double *
area,
double *edge_w,
double *edge_e,
double *edge_s,
386 double *edge_n,
double *en_n,
double *en_e,
double *vlon,
double *vlat,
387 int *on_west_edge,
int *on_east_edge,
int *on_south_edge,
int *on_north_edge)
389 double *x, *y, *z, *xt_tmp, *yt_tmp;
390 int nx, ny, nxp, nyp, i, j;
391 double p1[3], p2[3], p3[3], p4[3];
399 for(j=0; j<nyp; j++)
for(i=0; i<nx; i++) {
402 p2[0] = xc[j*nxp+i+1];
403 p2[1] = yc[j*nxp+i+1];
404 dx[j*nx+i] = great_circle_distance(p1, p2);
407 for(j=0; j<ny; j++)
for(i=0; i<nxp; i++) {
410 p2[0] = xc[(j+1)*nxp+i];
411 p2[1] = yc[(j+1)*nxp+i];
412 dy[j*nxp+i] = great_circle_distance(p1, p2);
415 for(j=0; j<ny; j++)
for(i=0; i<nx; i++) {
418 p2[0] = xc[(j+1)*nxp+i];
419 p2[1] = yc[(j+1)*nxp+i];
420 p3[0] = xc[j*nxp+i+1];
421 p3[1] = yc[j*nxp+i+1];
422 p4[0] = xc[(j+1)*nxp+i+1];
423 p4[1] = yc[(j+1)*nxp+i+1];
424 area[j*nx+i] = spherical_excess_area(p1, p2, p3, p4, RADIUS);
427 x = (
double *)malloc(nxp*nyp*
sizeof(
double));
428 y = (
double *)malloc(nxp*nyp*
sizeof(
double));
429 z = (
double *)malloc(nxp*nyp*
sizeof(
double));
432 for(j=0; j<nyp; j++)
for(i=0; i<nx; i++) {
436 p2[0] = x[j*nxp+i+1];
437 p2[1] = y[j*nxp+i+1];
438 p2[2] = z[j*nxp+i+1];
439 vect_cross(p1, p2, en_n+3*(j*nx+i) );
440 normalize_vect(en_n+3*(j*nx+i));
443 for(j=0; j<ny; j++)
for(i=0; i<nxp; i++) {
447 p1[0] = x[(j+1)*nxp+i];
448 p1[1] = y[(j+1)*nxp+i];
449 p1[2] = z[(j+1)*nxp+i];
450 vect_cross(p1, p2, en_e+3*(j*nxp+i) );
451 normalize_vect(en_e+3*(j*nxp+i));
454 xt_tmp = (
double *)malloc(nx*ny*
sizeof(
double));
455 yt_tmp = (
double *)malloc(nx*ny*
sizeof(
double));
456 for(j=0; j<ny; j++)
for(i=0; i<nx; i++) {
457 xt_tmp[j*nx+i] = xt[(j+1)*(nx+2)+i+1];
458 yt_tmp[j*nx+i] = yt[(j+1)*(nx+2)+i+1];
460 unit_vect_latlon(nx*ny, xt_tmp, yt_tmp, vlon, vlat);
461 get_edge(nx, ny, xt, yt, xc, yc, edge_w, edge_e, edge_s, edge_n, *on_west_edge, *on_east_edge,
462 *on_south_edge, *on_north_edge);
pure elemental type(point) function latlon2xyz(lat, lon)
Return the (x,y,z) position of a given (lat,lon) point.
real(r8_kind), dimension(:,:), allocatable area
area of each grid box
integer nlat
No description.
integer nlon
No description.