int SameDimensions( Databox *databoxp, Databox *databoxq) { if ((DataboxNx(databoxp) != DataboxNx(databoxq)) || (DataboxNy(databoxp) != DataboxNy(databoxq)) || (DataboxNz(databoxp) != DataboxNz(databoxq))) { return 0; } return 1; }
void ComputeBottom(Databox *mask, Databox *bottom) { int i, j, k; int nx, ny, nz; nx = DataboxNx(mask); ny = DataboxNy(mask); nz = DataboxNz(mask); for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { for (k = 0; k < nz; ++k) { if( *(DataboxCoeff(mask, i, j, k)) > 0.0 ) { break; } } if(k >= 0) { *(DataboxCoeff(bottom, i, j, 0)) = k; } else { *(DataboxCoeff(bottom, i, j, 0)) = -1; } } } }
void ComputeTop(Databox *mask, Databox *top) { int i, j, k; int nx, ny, nz; nx = DataboxNx(mask); ny = DataboxNy(mask); nz = DataboxNz(mask); for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { for (k = nz-1; k >= 0; --k) { if( *(DataboxCoeff(mask, i, j, k)) > 0.0 ) { break; } } if(k >= 0) { *(DataboxCoeff(top, i, j, 0)) = k; } else { *(DataboxCoeff(top, i, j, 0)) = -1; } } } }
void ExtractTop(Databox *top, Databox *data, Databox *top_values_of_data) { int i, j; int nx, ny, nz; nx = DataboxNx(data); ny = DataboxNy(data); nz = DataboxNz(data); for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { int k = *(DataboxCoeff(top, i, j, 0)); if ( k < 0 ) { /* outside domain what value? */ *(DataboxCoeff(top_values_of_data, i, j, 0)) = 0.0; } else if( k < nz) { *(DataboxCoeff(top_values_of_data, i, j, 0)) = *(DataboxCoeff(data, i, j, k)); } else { printf("Error: Index in top (k=%d) is outside of data (nz=%d)\n", k, nz); } } } }
void LoadParflowB( char *filename, SubgridArray *all_subgrids, Background *background, Databox *databox) { char output_name[MAXPATHLEN]; FILE *file; FILE *dist_file; Subgrid *subgrid; int process, num_procs; int p; double *ptr; int NX = DataboxNx(databox); int NY = DataboxNy(databox); int NZ = DataboxNz(databox); int ix, iy, iz; int nx, ny, nz; int k, j, s_i; long file_pos=0; /*-------------------------------------------------------------------- * Determine num_procs, and clear output files *--------------------------------------------------------------------*/ num_procs = -1; ForSubgridI(s_i, all_subgrids) { subgrid = SubgridArraySubgrid(all_subgrids, s_i); process = SubgridProcess(subgrid); #ifdef AMPS_SPLIT_FILE sprintf(output_name, "%s.%05d", filename, process); remove(output_name); #endif if (process > num_procs) num_procs = process; }
int InRange( int i, int j, int k, Databox *databox) { if ((i < 0 || i >= DataboxNx(databox)) || (j < 0 || j >= DataboxNy(databox)) || (k < 0 || k >= DataboxNz(databox))) { return 0; } return 1; }
Databox *CompFlux( Databox *k, Databox *h) { Databox *flux; int nx, ny, nz; double x, y, z; double dx, dy, dz; double *fluxp, *kp, *hp; double qxp, qxm, qyp, qym, qzp, qzm; int cell, cell_xm1, cell_xp1, cell_ym1, cell_yp1, cell_zm1, cell_zp1; int ii, jj, kk; nx = DataboxNx(k); ny = DataboxNy(k); nz = DataboxNz(k); x = DataboxX(k); y = DataboxY(k); z = DataboxZ(k); dx = DataboxDx(k); dy = DataboxDy(k); dz = DataboxDz(k); #if 0 /* ADD LATER */ if ((dx != DataboxDx(h)) || (dy != DataboxDy(h)) || (dz != DataboxDz(h))) { Error("Spacings are not compatible\n"); return NULL; } #endif if ((flux = NewDatabox(nx, ny, nz, x, y, z, dx, dy, dz)) == NULL) return((Databox*)NULL); kp = DataboxCoeffs(k); hp = DataboxCoeffs(h); fluxp = DataboxCoeffs(flux); cell = 0; cell_xm1 = cell - 1; cell_xp1 = cell + 1; cell_ym1 = cell - nx; cell_yp1 = cell + nx; cell_zm1 = cell - nx * ny; cell_zp1 = cell + nx * ny; kp += nx * ny; hp += nx * ny; fluxp += nx * ny; for (kk = 1; kk < (nz - 1); kk++) { kp += nx; hp += nx; fluxp += nx; for (jj = 1; jj < (ny - 1); jj++) { kp++; hp++; fluxp++; for (ii = 1; ii < (nx - 1); ii++) { qxp = -Mean(kp[cell_xp1], kp[cell]) * (hp[cell_xp1] - hp[cell]) / dx; qxm = -Mean(kp[cell], kp[cell_xm1]) * (hp[cell] - hp[cell_xm1]) / dx; qyp = -Mean(kp[cell_yp1], kp[cell]) * (hp[cell_yp1] - hp[cell]) / dy; qym = -Mean(kp[cell], kp[cell_ym1]) * (hp[cell] - hp[cell_ym1]) / dy; qzp = -Mean(kp[cell_zp1], kp[cell]) * (hp[cell_zp1] - hp[cell]) / dz; qzm = -Mean(kp[cell], kp[cell_zm1]) * (hp[cell] - hp[cell_zm1]) / dz; fluxp[cell] = (qxp - qxm) * dy * dz + (qyp - qym) * dx * dz + (qzp - qzm) * dx * dy; kp++; hp++; fluxp++; } kp++; hp++; fluxp++; } kp += nx; hp += nx; fluxp += nx; } return flux; }
void SigDiff( Databox *v1, Databox *v2, int m, double absolute_zero, FILE *fp) { double *v1_p, *v2_p; double sig_dig_rhs; double adiff, amax, sdiff; double max_adiff = 0.0, max_sdiff; int i, j, k; int mi = 0, mj = 0, mk = 0; int nx, ny, nz; int sig_digs; int m_sig_digs, m_sig_digs_everywhere; /*----------------------------------------------------------------------- * check that dimensions are the same *-----------------------------------------------------------------------*/ nx = DataboxNx(v1); ny = DataboxNy(v1); nz = DataboxNz(v1); /*----------------------------------------------------------------------- * diff the values and print the results *-----------------------------------------------------------------------*/ if (m >= 0) sig_dig_rhs = 0.5 / pow(10.0, ((double) m)); else sig_dig_rhs = 0.0; v1_p = DataboxCoeffs(v1); v2_p = DataboxCoeffs(v2); m_sig_digs_everywhere = TRUE; max_sdiff = 0.0; for (k = 0; k < nz; k++) { for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { adiff = fabs((*v1_p) - (*v2_p)); amax = max(fabs(*v1_p), fabs(*v2_p)); m_sig_digs = TRUE; if (amax > absolute_zero) { sdiff = adiff / amax; if ( sdiff > sig_dig_rhs ) m_sig_digs = FALSE; } if (!m_sig_digs) { if (m >= 0) { fprintf(fp, "(%d,%d,%d) : %e, %e, %e\n", i, j, k, adiff, *v1_p, *v2_p); } if (sdiff > max_sdiff) { max_sdiff = sdiff; max_adiff = adiff; mi = i; mj = j; mk = k; } m_sig_digs_everywhere = FALSE; } v1_p++; v2_p++; } } } if (!m_sig_digs_everywhere) { /* compute min number of sig digs */ sig_digs = 0; sdiff = max_sdiff; while (sdiff <= 0.5e-01) { sdiff *= 10.0; sig_digs++; } fprintf(fp, "Minimum significant digits at (% 3d, %3d, %3d) = %2d\n", mi, mj, mk, sig_digs); fprintf(fp, "Maximum absolute difference = %e\n", max_adiff); } }
void MSigDiff( Tcl_Interp *interp, Databox *v1, Databox *v2, int m, double absolute_zero, Tcl_Obj *result) { double *v1_p, *v2_p; double sig_dig_rhs; double adiff, amax, sdiff; double max_adiff = 0.0, max_sdiff; int i, j, k; int mi = 0, mj = 0, mk = 0; int nx, ny, nz; int sig_digs; int m_sig_digs, m_sig_digs_everywhere; /*----------------------------------------------------------------------- * check that dimensions are the same *-----------------------------------------------------------------------*/ nx = DataboxNx(v1); ny = DataboxNy(v1); nz = DataboxNz(v1); /*----------------------------------------------------------------------- * diff the values and print the results *-----------------------------------------------------------------------*/ if (m >= 0) sig_dig_rhs = 0.5 / pow(10.0, ((double) m)); else sig_dig_rhs = 0.0; v1_p = DataboxCoeffs(v1); v2_p = DataboxCoeffs(v2); m_sig_digs_everywhere = TRUE; max_sdiff = 0.0; for (k = 0; k < nz; k++) { for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { adiff = fabs((*v1_p) - (*v2_p)); amax = max(fabs(*v1_p), fabs(*v2_p)); if ( max_adiff < adiff ) max_adiff = adiff; m_sig_digs = TRUE; if (amax > absolute_zero) { sdiff = adiff / amax; if ( sdiff > sig_dig_rhs ) m_sig_digs = FALSE; } if (!m_sig_digs) { if (sdiff > max_sdiff) { max_sdiff = sdiff; mi = i; mj = j; mk = k; } m_sig_digs_everywhere = FALSE; } v1_p++; v2_p++; } } } if (!m_sig_digs_everywhere) { Tcl_Obj *double_obj; Tcl_Obj *int_obj; Tcl_Obj *list_obj; /* compute min number of sig digs */ sig_digs = 0; sdiff = max_sdiff; while (sdiff <= 0.5e-01) { sdiff *= 10.0; sig_digs++; } /* Create a Tcl list of the form: {{mi mj mk sig_digs} max_adiff} */ /* and append it to the result string. */ list_obj = Tcl_NewListObj(0, NULL); int_obj = Tcl_NewIntObj(mi); Tcl_ListObjAppendElement(interp, list_obj, int_obj); int_obj = Tcl_NewIntObj(mj); Tcl_ListObjAppendElement(interp, list_obj, int_obj); int_obj = Tcl_NewIntObj(mk); Tcl_ListObjAppendElement(interp, list_obj, int_obj); int_obj = Tcl_NewIntObj(sig_digs); Tcl_ListObjAppendElement(interp, list_obj, int_obj); Tcl_ListObjAppendElement(interp, result, list_obj); double_obj = Tcl_NewDoubleObj(max_adiff); Tcl_ListObjAppendElement(interp, result, double_obj); } }
void ComputeDomain( SubgridArray *all_subgrids, Databox *top, Databox *bottom, int P, int Q, int R) { int num_procs = P * Q * R; int p; // For each subgrid find the min/max k values // in the active region (using top/bottom). // Reset the subgrid to reflect this vertical extent. for(p = 0; p < num_procs; p++) { int s_i; ForSubgridI(s_i, all_subgrids) { Subgrid* subgrid = SubgridArraySubgrid(all_subgrids, s_i); int process = SubgridProcess(subgrid); if(process == p) { int i; int j; int ix = SubgridIX(subgrid); int iy = SubgridIY(subgrid); int iz = SubgridIZ(subgrid); int nx = SubgridNX(subgrid); int ny = SubgridNY(subgrid); int nz = SubgridNZ(subgrid); int patch_top = iz; int patch_bottom = iz + nz; for (j = iy; j < iy+ ny; ++j) { for (i = ix; i < ix + nx; ++i) { int k_top = *(DataboxCoeff(top, i, j, 0)); if ( k_top >= 0 ) { patch_top = max(patch_top, k_top); } int k_bottom = *(DataboxCoeff(bottom, i, j, 0)); if ( k_bottom >= 0 ) { patch_bottom = min(patch_bottom, k_bottom); } } } // adjust grid to include 2 pad cells patch_top = min(patch_top+2, iz + nz - 1); patch_bottom = max(patch_bottom-2, iz); // adjust for ghost cells, need to have patches // that extend in height to the neighbor patches. // // There is a more efficient way to compute all this but // since these are 2d arrays it should be reasonably quick. // Not a single loop since we don't need to pad these values. ix = max(0, ix -1); nx = min(DataboxNx(top) - ix, nx + 2 - ix); iy = max(0, iy -1); ny = min(DataboxNy(top) - iy, ny + 2 - iy); for (j = iy; j < iy+ ny; ++j) { for (i = ix; i < ix + nx; ++i) { int k_top = *(DataboxCoeff(top, i, j, 0)); if ( k_top >= 0 ) { patch_top = max(patch_top, k_top); } int k_bottom = *(DataboxCoeff(bottom, i, j, 0)); if ( k_bottom >= 0 ) { patch_bottom = min(patch_bottom, k_bottom); } } } SubgridIZ(subgrid) = patch_bottom; SubgridNZ(subgrid) = (patch_top - SubgridIZ(subgrid)) + 1; } } }
Databox *ReadSDS(char *filename, int ds_num, double default_value) { Databox *v; int32 dim[MAX_VAR_DIMS]; int32 edges[3]; int32 start[3]; int i; int z; int32 type; char name[MAX_NC_NAME]; int32 sd_id; int32 sds_id; int32 rank, nt, nattrs; int nx, ny, nz; int m; double *double_ptr; sd_id = SDstart(filename, DFACC_RDONLY); sds_id = SDselect(sd_id, ds_num); SDgetinfo(sds_id, name, &rank, dim, &type, &nattrs); start[0] = start[1] = start[2] = 0; /* create the new databox structure */ if((v = NewDatabox(dim[2], dim[1], dim[0], 0, 0, 0, 0, 0, 0, default_value)) == NULL) return((Databox *)NULL); double_ptr = DataboxCoeffs(v); edges[0] = 1; edges[1] = DataboxNy(v); edges[2] = DataboxNx(v); switch (type) { case DFNT_FLOAT32 : { float32 *convert_ptr, *data; if( (data = convert_ptr = (float32 *)malloc(dim[1]*dim[2] * sizeof(float32))) == NULL) { exit(1); } for(z=0; z < dim[0]; z++) { start[0] = z; SDreaddata(sds_id, start, NULL, edges, data); convert_ptr = data; for(i=dim[1]*dim[2]; i--;) *double_ptr++ = *convert_ptr++; } free(data); break; }; case DFNT_FLOAT64 : { float64 *convert_ptr, *data; if( (data = convert_ptr = (float64 *)malloc(dim[1]*dim[2] * sizeof(float64))) == NULL) { exit(1); } for(z=0; z < dim[0]; z++) { start[0] = z; SDreaddata(sds_id, start, NULL, edges, data); convert_ptr = data; for(i=dim[1]*dim[2]; i--;) *double_ptr++ = *convert_ptr++; } free(data); break; }; case DFNT_INT8 : { int8 *convert_ptr, *data; if( (data = convert_ptr = (int8 *)malloc(dim[1]*dim[2] * sizeof(int8))) == NULL) { exit(1); } for(z=0; z < dim[0]; z++) { start[0] = z; SDreaddata(sds_id, start, NULL, edges, data); convert_ptr = data; for(i=dim[1]*dim[2]; i--;) *double_ptr++ = *convert_ptr++; } free(data); break; }; case DFNT_UINT8 : { uint8 *convert_ptr, *data; if( (data = convert_ptr = (uint8 *)malloc(dim[1]*dim[2] * sizeof(uint8))) == NULL) { exit(1); } for(z=0; z < dim[0]; z++) { start[0] = z; SDreaddata(sds_id, start, NULL, edges, data); convert_ptr = data; for(i=dim[1]*dim[2]; i--;) *double_ptr++ = *convert_ptr++; } free(data); break; }; case DFNT_INT16 : { int16 *convert_ptr, *data; if( (data = convert_ptr = (int16 *)malloc(dim[1]*dim[2] * sizeof(int16))) == NULL) { exit(1); } for(z=0; z < dim[0]; z++) { start[0] = z; SDreaddata(sds_id, start, NULL, edges, data); convert_ptr = data; for(i=dim[1]*dim[2]; i--;) *double_ptr++ = *convert_ptr++; } free(data); break; }; case DFNT_UINT16 : { uint16 *convert_ptr, *data; if( (data = convert_ptr = (uint16 *)malloc(dim[1]*dim[2] * sizeof(uint16))) == NULL) { exit(1); } for(z=0; z < dim[0]; z++) { start[0] = z; SDreaddata(sds_id, start, NULL, edges, data); convert_ptr = data; for(i=dim[1]*dim[2]; i--;) *double_ptr++ = *convert_ptr++; } free(data); break; }; case DFNT_INT32 : { int32 *convert_ptr, *data; if( (data = convert_ptr = (int32 *)malloc(dim[1]*dim[2] * sizeof(int32))) == NULL) { exit(1); } for(z=0; z < dim[0]; z++) { start[0] = z; SDreaddata(sds_id, start, NULL, edges, data); convert_ptr = data; for(i=dim[1]*dim[2]; i--;) *double_ptr++ = *convert_ptr++; } free(data); break; }; case DFNT_UINT32 : { uint32 *convert_ptr, *data; if( (data = convert_ptr = (uint32 *)malloc(dim[1]*dim[2] * sizeof(uint32))) == NULL) { exit(1); } for(z=0; z < dim[0]; z++) { start[0] = z; SDreaddata(sds_id, start, NULL, edges, data); convert_ptr = data; for(i=dim[1]*dim[2]; i--;) *double_ptr++ = *convert_ptr++; } free(data); break; }; } SDendaccess(sds_id); SDend(sd_id); return v; }