Example #1
0
void dg_qmsl ( int *ixmscl, int *iymscl, float *gddx, float *gddy,
	       int *iret )
/************************************************************************
 * dg_qmsl								*
 *									*
 * This subroutine retrieves the grid number for map scale factors and	*
 * grid spacing in x, y.						*
 *									*
 * dg_qmsl ( ixmscl, iymscl, gddx, gddy, iret )				*
 *									*
 * Input parameters:							*
 *									*
 * Output parameters:							*
 *	*ixmscl		int		ixmscl in mapscl.h		*
 *	*iymscl		int		iymscl in mapscl.h		*
 *	*gddx		float		gddx in mapscl.h		*
 *	*gddy		float		gddy in mapscl.h		*
 *	*iret		int		Return code			*
 *					   0 = normal return		*
 **									*
 * Log:									*
 * R. Tian/SAIC		 3/06						*
 ************************************************************************/
{
    int nval;
/*----------------------------------------------------------------------*/
    *iret = 0;

    nval = 1;
    dg_iget ( "IXMSCL", &nval, ixmscl, iret );
    dg_iget ( "IYMSCL", &nval, iymscl, iret );
    dg_fget ( "GDDX", &nval, gddx, iret );
    dg_fget ( "GDDY", &nval, gddy, iret );

    return;
}
Example #2
0
void dv_shr ( int *iret )
/************************************************************************
 * dv_shr				     				*
 *									*
 * This subroutine computes the shearing deformation of a vector:	*
 *									*
 *     SHR ( V ) = DDX ( v ) + DDY ( u ) + v * {(mx/my)*[d(my)/dx]}	*
 *					 + u * {(my/mx)*[d(mx)/dy]}	*
 *									*
 * where mx and my are scale factors along x and y, respectively.	*
 * The quantities in braces are assumed to exist in common arrays	*
 * YMSDX and XMSDY, respectively.  SHR generates a scalar grid.		*
 *									*
 * dv_shr ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETV			*
 **									*
 * Log:									*
 * M. desJardins/GSFC	10/85						*
 * I. Graffman/RDS	 7/88	Call to DG_UPDH				*
 * G. Huffman/GSC	 9/88	New stack functions			*
 * G. Huffman/GSC	 9/88	Error messages				*
 * K. Brill/GSC          4/89   Map scale factor code			*
 * K. Brill/GSC          8/89   Subsetting				*
 * K. Brill/GSC         10/89   Subsetting				*
 * T. Lee/GSC		 4/96   Single dimension for dgg		*
 * T. Lee/GSC		 5/96   Moved IGDPT outside DO loop		*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		 5/02	Eliminate LLMXGD declarations in DGCMN	*
 *				using int grds for scl fctr derivatives *
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * S. Gilbert/NCEP	11/05	Translation from Fortran                *
 ************************************************************************/
{
        const int       zero=0;
        int             i, ier, nval, kxd, kyd, ksub1, ksub2;
	int		numu, numv, nddx, nddy, ixmsdy, iymsdx, numout;
	float		*gru, *grv, *grddx, *grddy, *grxmdy, *grymdx, *grout;
        float           dx, dy, vv, dd;

/*----------------------------------------------------------------------*/
	*iret = 0;
	dg_ssub ( iret );

        /*
         *	Get the vector.
         */
	dg_getv  ( &numu, &numv, iret );
	if  ( *iret != 0 ) return;

        /*
         *   Put the v component on the stack, compute DDX, and get the result.
         */
	dg_puts  ( &numv, iret );
	if  ( *iret != 0 ) return;
	df_ddx  ( iret );
	if  ( *iret != 0 ) return;
	dg_gets  ( &nddx, iret );
	if  ( *iret != 0 ) return;

        /*
         *   Put the u component on the stack, compute DDY, and get the result.
         */
	dg_puts  ( &numu, iret );
	if  ( *iret != 0 ) return;
	df_ddy  ( iret );
	if  ( *iret != 0 ) return;
	dg_gets  ( &nddy, iret );
	if  ( *iret != 0 ) return;

        /*
         *	Compute map scale factor derivative coefficients.
         */
	dg_dmsf ( iret );
	if ( *iret != 0 ) return;

        nval = 1;
        dg_iget ( "IXMSDY", &nval, &ixmsdy, iret );
        dg_iget ( "IYMSDX", &nval, &iymsdx, iret );
        dg_getg ( &ixmsdy, &grxmdy, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &iymsdx, &grymdx, &kxd, &kyd, &ksub1, &ksub2, iret );

        /*
         *	Get a new grid and compute the shearing deformation.
         */
	dg_nxts  ( &numout, iret );
	if  ( *iret != 0 )  return;

        dg_getg ( &numu, &gru, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numv, &grv, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nddx, &grddx, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nddy, &grddy, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numout, &grout, &kxd, &kyd, &ksub1, &ksub2, iret );

	for ( i = ksub1 - 1; i < ksub2; i++ ) {
		dx =  grddx[i];
		dy =  grddy[i];
		dd =  gru[i];
		vv =  grv[i];
		if  ( ERMISS (dx) || ERMISS (dy) ||
     		      ERMISS (dd) || ERMISS (vv) )
		    grout[i] = RMISSD;
		else
		    grout[i] = dx + dy + dd * grxmdy[i] + vv * grymdx[i] ;
		
        }

        /*
         *	Make a name of the form 'SHR'//u and update header;
         *	update the stack.
         */
	dg_updh  ( "SHR", &numout, &numu, &zero, iret );
	dg_puts  ( &numout, iret );
	dg_esub  ( &numout, &zero, &zero, &zero, &ier );
	if ( ier != 0 ) *iret = ier;

	return;
}
Example #3
0
void df_nmax ( int *iret )
/************************************************************************
 * df_nmax								*
 *									*
 * This subroutine computes NMAX (S,ROI), the neigborhood maximum	*
 * value of a scalar field (S) within some radius of influence    	*
 * (ROI; meters). Masking could be used [e.g., SGT(S1,S2)] to subset *
 * and filter the grid beforehand to allow for faster processing.      	*
 *									*
 * df_nmax ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * C. Melick/SPC	06/12						*
 ************************************************************************/
{
    int num1, num2, num3, num, kxd, kyd, ksub1, ksub2, zero, indx, ier;
    int ixmscl, iymscl, jgymin, jgymax, jgxmin, jgxmax, idglat, idglon;
    int row, col, ibeg, iend, jbeg, jend, ibox, jbox, boxindx, nval;
    float  gddx, gddy, gdspdx, gdspdy, radius;
    float *gnum1, *gnumn, *gkxms, *gkyms, *gnumroi, *glat, *glon, *dist;
    /*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Compute map scale factors.
     */
    dg_mscl ( iret );
    if ( *iret != 0 ) return;

    /*
     * Query DGCMN.CMN idglat/idglon.
    */

    nval = 1;
    dg_iget ( "IDGLAT", &nval, &idglat, iret );
    if ( *iret != 0 ) return;
    dg_iget ( "IDGLON", &nval, &idglon, iret );
    if ( *iret != 0 ) return;

    /*
     * Get the grids from the stack.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num2, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid number.
     */
    dg_nxts ( &num3, iret );
    if ( *iret != 0 ) return;
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    dg_qmsl ( &ixmscl, &iymscl, &gddx, &gddy, &ier );
    dg_qbnd ( &jgxmin, &jgxmax, &jgymin, &jgymax, &ier );
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &num,  &gnumn,  &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &ixmscl, &gkxms, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &iymscl, &gkyms, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &num2, &gnumroi, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &idglat, &glat, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &idglon, &glon, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &num3, &dist, &kxd, &kyd, &ksub1, &ksub2, &ier );

    radius = gnumroi[0];

    /*  QC check on lower and upper bounds of radius of influence.  */

    if ( radius < 0 ) {
        radius = 0.0;
        printf ("\n WARNING : RADIUS value less than zero.  "
                "Resetting to zero.\n");
    }

    if ( radius > 0.5*gddx*(float)(kxd)) {
        radius = 0.5*gddx*(float)(kxd);
        printf ("\n WARNING : RADIUS value too high.  "
                "Resetting to half the distance in X (%f meters).\n",radius);
    }

    /*
     * Loop over all grid points to initialize output grid.
     */
    for ( row = jgymin; row <= jgymax; row++ ) {
        for ( col = jgxmin; col <= jgxmax; col++ ) {
            indx=(row-1)*kxd+(col-1);
            if ( ERMISS ( gnum1[indx] ) ) {
                gnumn[indx] = RMISSD;
            } else {
                gnumn[indx] = gnum1[indx];
            }
        }
    }

    /*
     * Loop over all grid points to determine neighborhood maximum for each grid point.
     */

    for ( row = jgymin; row <= jgymax; row++ ) {
        for ( col = jgxmin; col <= jgxmax; col++ ) {
            indx=(row-1)*kxd+(col-1);
            if ( ! ERMISS ( gnum1[indx] ) ) {
                gdspdx= gddx / gkxms[indx];
                gdspdy= gddy / gkyms[indx];

                /*  Constructing box for each grid point */
                ibeg = col- G_NINT(radius / gdspdx);
                iend = col+ G_NINT(radius / gdspdx);
                jbeg = row- G_NINT(radius / gdspdy);
                jend = row+ G_NINT(radius / gdspdy);
                if (ibeg < jgxmin) {
                    ibeg = jgxmin;
                }
                if (iend > jgxmax) {
                    iend = jgxmax;
                }
                if (jbeg < jgymin) {
                    jbeg = jgymin;
                }
                if (jend > jgymax) {
                    jend = jgymax;
                }
                for ( ibox = ibeg; ibox <= iend; ibox++ ) {
                    for ( jbox = jbeg; jbox <= jend; jbox++ ) {
                        boxindx=(jbox-1)*kxd+(ibox-1);
                        if ((glat[indx] == glat[boxindx]) && (glon[indx] == glon[boxindx])) {
                            dist[boxindx]=0.0;
                        } else {
                            /* Great Circle Distance calculation */
                            dist[boxindx] = acos(sin(glat[boxindx])*sin(glat[indx]) + cos(glat[boxindx])*cos(glat[indx])*cos((glon[boxindx])-(glon[indx])));
                            dist[boxindx] = RADIUS * dist[boxindx];
                        }
                        /* Check maximum value if neighboring point is defined and within radius of influence. */
                        if ( (dist[boxindx] <= radius) && (! ERMISS ( gnum1[boxindx] ) ) ) {
                            if ( gnum1[boxindx] > gnumn[indx] ) {
                                gnumn[indx] = gnum1[boxindx];
                            }
                        }
                    }
                }
                for ( ibox = ibeg; ibox <= iend; ibox++ ) {
                    for ( jbox = jbeg; jbox <= jend; jbox++ ) {
                        boxindx=(jbox-1)*kxd+(ibox-1);
                        /* Spreading the response around to surrounding undefined values */
                        if ( ERMISS ( gnum1[boxindx] ) ) {
                            if (dist[boxindx] <= radius) {
                                if ( ERMISS ( gnumn[boxindx] ) ) {
                                    gnumn[boxindx] = gnumn[indx];
                                } else if ( gnum1[indx] > gnumn[boxindx] ) {
                                    gnumn[boxindx] = gnum1[indx];
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /*
     * Make a name of the form 'NMAX'//S and update header;
     * update stack.
     */
    dg_updh ( "NMAX", &num, &num1, &num2, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Example #4
0
void dv_mdiv ( int *iret )
/************************************************************************
 * dv_mdiv								*
 *									*
 * This subroutine computes layer-average mass divergence:		*
 *									*
 *     MDIV ( V ) = DIV ( [ MASS * LAV (u), MASS * LAV (v) ] )		*
 *									*
 * V must be a grid parameter for LAV to work correctly.  		*
 * MDIV generates a scalar grid.					*
 *									*
 * dv_mdiv  ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETV			*
 **									*
 * Log:									*
 * M. Goodman/RDS	11/85						*
 * G. Huffman/GSC	 9/88	New stack functions			*
 * G. Huffman/GSC	 9/88	Error messages				*
 * M. desJardins/NMC	 7/93	Changed update scheme			*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * S. Gilbert/NCEP	11/05	Translation from Fortran                *
 ************************************************************************/
{
	int		nu, nv, nmass, nmdiv;

	char	        gnam[13], gvect[13], gdum[13], pdum[13];
        char            time1[21], time2[21];
	int		level1, level2, ivcord, zero=0, ier, idlun, nval;
/*------------------------------------------------------------------------*/
	*iret = 0;
	dg_ssub ( iret );

        /*
         *	Read the vector name on top of the stack and replace it with
         *	PRES (so that MASS will pick up in-line parameters).
         */
	dg_topv  ( gvect, &nu, &nv, time1, time2, &level1, 
                           &level2, &ivcord, pdum, iret );
	if  ( *iret != 0 ) return;
	dg_rpls  ( "PRES", &zero, iret );
	if  ( *iret != 0 ) return;

        /*
         *	Compute the mass / unit volume, and read the number of the grid.
         */
	df_mass  ( iret );
	if  ( *iret != 0 ) return;
	dg_tops  ( gdum, &nmass, time1, time2, &level1, &level2, 
                          &ivcord, pdum, iret );
	if  ( *iret != 0 ) return;

        /*
         *	Replace the top of the stack with the vector name, compute the
         *	average wind vector within the layer, and leave the result.
         */
	dg_rplv  ( gvect, &zero, &zero, iret );
	if  ( *iret != 0 ) return;
	dv_vlav  ( iret );
	if  ( *iret != 0 ) return;

        /*
         *	Put the mass on top of the stack, compute the mass divergence,
         *	and read the grid number of the result.
         */
	dg_puts  ( &nmass, iret );
	if  ( *iret != 0 ) return;
	dv_sdiv  ( iret );
	if  ( *iret != 0 ) return;
	dg_tops  ( gdum, &nmdiv, time1, time2, &level1, &level2, 
                          &ivcord, pdum, iret );
	if  ( *iret != 0 ) return;

        /*
         *	Make a name of the form 'MDIV'//u and update header; the
         *	stack is current.
         */
        nval = 1;
        dg_iget ( "IDLUN", &nval, &idlun, iret );

	dg_mnam  ( "MDIV", gvect, "", gnam, &ier );
	dg_upsg  ( time1, time2, &level1, &level2, &ivcord, 
                               &idlun, gnam, &nmdiv, iret );
	dg_esub  ( &nmdiv, &zero, &zero, &zero, &ier );
	if ( ier != 0 ) *iret = ier;

	return;
}
Example #5
0
void dv_nrmv ( int *iret )
/************************************************************************
 * dv_nrmv								*
 *									*
 * This subroutine computes the vector component of a vector field (V)	*
 * normal to the orientation vector whose direction is specified in	*
 * COMMON / DGOVEC /.							*
 *									*
 *     NORMV = ( ( -k cross V ) dot ( normalized orientation vector ) )	*
 *		     times ( normalized orientation vector )		*
 *									*
 * NORMV generates a vector field.					*
 *									*
 * dv_nrmv  ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETV or DG_MSCL	*
 *					-28 = no orientation vector	*
 **									*
 * Log:									*
 * K. Brill/GSC		 7/89    					*
 * K. Brill/GSC		 8/89 	Subsetting				*
 * K. Brill/GSC	        10/89	Subsetting				*
 * K. Brill/NMC		 4/92	Nonconformal case reused ORNTV->error	*
 * T. Lee/GSC		 4/96   Single dimension for dgg		*
 * T. Lee/GSC		 5/96   Moved IGDPT outside DO loop		*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		 5/02	Eliminate LLMXGD declarations in DGCMN	*
 *				by using internal grids for scl fctrs	*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * S. Gilbert/NCEP	11/05	Translation from Fortran                *
 ************************************************************************/
{
	int		i, ier, nval, kxd, kyd, ksub1, ksub2, zero=0;
        int             numu, numv, numu1, numv1, ixmscl, iymscl;
        float           *gru, *grv, *gru1, *grv1, *grxms, *gryms;
	float 		orntv[2], ornang, du1, dv1, orn1, orn2;
        float           du2, dv2, rnm;

/*------------------------------------------------------------------------*/
	*iret = 0;
	dg_ssub ( iret );

	dg_nxtv ( &numu, &numv, iret );
	if  ( *iret != 0 ) return;

        dg_getg ( &numu, &gru, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numv, &grv, &kxd, &kyd, &ksub1, &ksub2, iret );

        nval = 1;
        dg_fget ( "ORNANG", &nval, &ornang, iret );

	if ( ERMISS ( ornang ) ) {
	  for ( i = ksub1 - 1; i < ksub2; i++ ) {
	      gru[i] = RMISSD;
	      grv[i] = RMISSD;
	  }
	  *iret = -28;
	  return;
	}

        /*
         *	Compute the unit tangent vector components.
         */
	orntv [ 0 ] = - sin ( ornang );
	orntv [ 1 ] = - cos ( ornang );

        /*
         *	Compute the map scale factors just in case the grid is not
         *	conformal.
         */
	dg_mscl ( iret );
	if ( *iret != 0 ) return;

        /*
         *	Get the vector.
         */
	dg_getv  ( &numu1, &numv1, iret );
	if  ( *iret != 0 ) return;

        /*
         *	Compute the normal component.
         */
        dg_getg ( &numu1, &gru1, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numv1, &grv1, &kxd, &kyd, &ksub1, &ksub2, iret );

        nval = 1;
        dg_iget ( "IXMSCL", &nval, &ixmscl, iret );
        dg_iget ( "IYMSCL", &nval, &iymscl, iret );
        dg_getg ( &ixmscl, &grxms, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &iymscl, &gryms, &kxd, &kyd, &ksub1, &ksub2, iret );

	for ( i = ksub1 - 1; i < ksub2; i++ ) {
	    du1 = gru1[i];
	    dv1 = grv1[i];
	    if  ( ERMISS (du1) || ERMISS (dv1) ) {
		gru[i] = RMISSD;
	        grv[i] = RMISSD;
            }
	    else if ( G_DIFF(grxms[i], gryms[i]) ) {
		gru[i] =  ( du1 * orntv [ 1 ] -
     				    dv1 * orntv [ 0 ] ) * orntv [ 1 ] ;
		grv[i] =  ( -du1 * orntv [ 1 ] +
     				    dv1 * orntv [ 0 ] ) * orntv [ 0 ] ;
            }
            else {

                /*
                 *	Treat the case when the grid map projection is
                 *  	nonconformal.
                 * 
                 *	Scale the grid relative orientation vector and normalize
                 *	it.
                 */
                du2 = orntv [ 0 ] / grxms[i];
	        dv2 = orntv [ 1 ] / gryms[i];
		rnm =  sqrt ( du2 * du2 + dv2 * dv2 );
	        orn1 = du2 / rnm;
	        orn2 = dv2 / rnm;
		gru[i] =  ( du1 * orn2 - dv1 * orn1 ) * orn2 ;
		grv[i] =  ( -du1 * orn2 + dv1 * orn1 ) * orn1;
	    }
	}

        /*
         *	Make a name of the form 'NORMV'//u,v and update header;
         *	update stack.
         */
	dg_updv  ( "NORMV", &numu, &numv, &numu1, &numv1, iret );
	dg_putv  ( &numu, &numv, iret );
	dg_esub  ( &numu, &numv, &zero, &zero, &ier );
	if ( ier != 0 ) *iret = ier;

	return;
}
Example #6
0
void dv_rich  ( int *iret )
/************************************************************************
 * dv_rich								*
 *									*
 * This subroutine computes the Richardson stability number in a layer:	*
 *									*
 *     RICH ( V ) = GRAVTY * DZ * LDF (THTA) / 				*
 *                  [ LAV (THTA) * MAG ( VLDF (V) ) ** 2 ]		*
 *									*
 *                  Where: DZ = change in height across the layer	*
 *                            = -( RDGAS / GRAVTY ) * LAV (THTA) *	*
 *                              ( LAV (PRES) / 1000 ) ** KAPPA *	*
 *                              LDF (PRES) / LAV (PRES)			*
 *                              in THTA coordinates			*
 *									*
 * RICH generates a scalar grid.					*
 *									*
 * dv_rich ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETV			*
 **									*
 * Log:									*
 * M. Goodman/RDS	12/85						*
 * M. desJardins/GSFC	10/86	Added parameter statement for RKAPPA	*
 * G. Huffman/GSC	 9/88	New stack functions			*
 * G. Huffman/GSC	 9/88	Error messages				*
 * K. Brill/GSC  	 8/89	Subsetting				*
 * K. Brill/GSC		10/89	Subsetting				*
 * K. Brill/GSC		12/89	Compute dz from p,T when HGHT is missing*
 * M. desJardins/NMC	 7/93	Changed update scheme			*
 * T. Lee/GSC		 4/96   Single dimension for dgg		*
 * T. Lee/GSC		 5/96   Moved IGDPT outside DO loop		*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * S. Gilbert/NCEP	11/05	Translation from Fortran                *
 ************************************************************************/
{
        int             i, ier, kxd, kyd, ksub1, ksub2, nval, zero=0, tmp;
	int		nu, nv, nvldfu, nvldfv, nmag, idlun;

        int             ndz, ndp, npbar, ntbar, npav;
        float           *grdz, *grdp, *grpbar, *grtbar, *grpav;

        int             ndth, nath, nwsq, nrich;
        float           *grdth, *grath, *grwsq, *grrich;

        float           dp, tbar, pbar, avthta, cnst, dz, deltht, ath, dth;
        float           dwsq, pav, avtht;

	char	        gp[13], wname[13], gdum[13], pdum[13];
        char            time1[21], time2[21], errst[1024];
	int		level1, level2, ivcord;

/*------------------------------------------------------------------------*/
	*iret = 0;
	dg_ssub ( iret );

        /*
         *	Read the wind vector name, level, and vertical coordinate.
         *	Compute the wind shear in the layer and read the grid number
         *	of the result.
         */
	dg_topv  ( wname, &nu, &nv, time1, time2, &level1, &level2, 
                          &ivcord, pdum, iret );
	if  ( *iret != 0 )  return;
	dv_vldf  ( iret );
	if  ( *iret != 0 )  return;
	dg_topv  ( gdum, &nvldfu, &nvldfv, time1, time2, &level1,
                          &level2, &ivcord, pdum, iret );
	if  ( *iret != 0 )  return;

        /*
         *	Compute the magnitude of the wind shear and square it (by
         *	reading the grid number of the result, putting another copy
         *	on the stack, and multiplying).  Read the grid number of the
         *	result.
         */
	dv_mag  ( iret );
	if  ( *iret != 0 )  return;

	dg_tops  ( gdum, &nmag, time1, time2, &level1, &level2, 
                          &ivcord, pdum, iret );
	if  ( *iret != 0 )  return;
	dg_puts  ( &nmag, iret );
	if  ( *iret != 0 )  return;
	df_mul  ( iret );
	if  ( *iret != 0 )  return;
	dg_tops  ( gdum, &nwsq, time1, time2, &level1, &level2,
                          &ivcord, pdum, iret );
	if  ( *iret != 0 )  return;

        /*
         *	Compute a grid of delta height depending upon the coordinate
         *	system.
         */
	if  ( ivcord == 1 ) {

            /*
             *	    Pressure coordinate system.
             *	    Replace the top of the stack with HGHT (preserving in-line
             *	    parameters), compute LDF, and read the grid number of the
             *	    result.
             */
	    dg_rpls  ( "HGHT", &zero, iret );
	    if  ( *iret != 0 )  return;
	    df_ldf  ( iret );

	    if  ( *iret != 0 )  {

              /*
               *       Compute dz from p and T.
               */
	      dg_rpls ( "PRES", &zero, iret );
	      if ( *iret != 0 ) return;
	      df_lav ( iret );
	      if ( *iret != 0 ) return;
	      dg_tops  ( gdum, &npbar, time1, time2, &level1, &level2,
                                &ivcord, pdum, iret );
	      if ( *iret != 0 ) return;
	      dg_rpls ( "TMPK", &zero, iret );
	      if ( *iret != 0 ) return;
	      df_lav ( iret );
	      if ( *iret != 0 ) return;
	      dg_tops  ( gdum, &ntbar, time1, time2, &level1, &level2,
                                &ivcord, pdum, iret );
              if ( *iret != 0 ) return;
	      dg_rpls ( "PRES", &zero, iret );
              if ( *iret != 0 ) return;
	      df_ldf ( iret );
              if ( *iret != 0 ) return;
	      dg_tops  ( gdum, &ndp, time1, time2, &level1, &level2,
                                &ivcord, pdum, iret );
              if ( *iret != 0 ) return;
	      dg_nxts ( &ndz, iret );
              if ( *iret != 0 ) return;

              dg_getg ( &ndp, &grdp, &kxd, &kyd, &ksub1, &ksub2, iret );
              dg_getg ( &ndz, &grdz, &kxd, &kyd, &ksub1, &ksub2, iret );
              dg_getg ( &ntbar, &grtbar, &kxd, &kyd, &ksub1, &ksub2, iret );
              dg_getg ( &npbar, &grpbar, &kxd, &kyd, &ksub1, &ksub2, iret );

	      for ( i = ksub1 - 1; i < ksub2; i++ ) {
	          dp   = grdp[i];
	          tbar = grtbar[i];
	          pbar = grpbar[i];
	          if ( ERMISS ( dp ) || ERMISS ( tbar ) || ERMISS ( pbar ) ) 
	            grdz[i] = RMISSD;
	          else
	            grdz[i] = -RKAP * tbar * dp / pbar;
	          
              }
          }
	  else {
	      dg_tops ( gdum, &ndz, time1, time2, &level1, &level2, 
                               &ivcord, pdum, iret );
	      if  ( *iret != 0 )  return;
	  }

        }
	else if  ( ivcord == 2 )  {

            /*
             *	    Isentropic coordinate system.
             *	    Compute the height differences as documented in the header.
             *	    The PRES operations preserve access to in-line parameters.
             */
	    avthta = (level1 + level2) / 2.;
	    cnst   = -avthta * RKAP;

	    dg_rpls  ( "PRES", &zero, iret );
	    if  ( *iret != 0 )  return;
	    df_lav  ( iret );
	    if  ( *iret != 0 )  return;
	    dg_tops  ( gdum, &npav, time1, time2, &level1, &level2, 
                              &ivcord, pdum, iret );
	    if  ( *iret != 0 )  return;

	    dg_rpls  ( "PRES", &zero, iret );
	    if  ( *iret != 0 )  return;
	    df_ldf  ( iret );
	    if  ( *iret != 0 )  return;
	    dg_tops  ( gdum, &ndp, time1, time2, &level1, &level2,
                              &ivcord, pdum, iret );
	    if  ( *iret != 0 )  return;

            /*
             *	    Get a new grid number for the height field.
             */
	    dg_nxts ( &ndz, iret );
	    if  ( *iret != 0 )  return;

            dg_getg ( &ndp, &grdp, &kxd, &kyd, &ksub1, &ksub2, iret );
            dg_getg ( &ndz, &grdz, &kxd, &kyd, &ksub1, &ksub2, iret );
            dg_getg ( &npav, &grpav, &kxd, &kyd, &ksub1, &ksub2, iret );

	    for ( i = ksub1 - 1; i < ksub2; i++ ) {
		if ( ( G_DIFFT(grpav[i], 0.0F, GDIFFD) ) || 
     		     ERMISS ( grpav[i] ) || ERMISS ( grdp[i] ) )
		    grdz[i] = RMISSD;
		else {
		    dp  = grdp[i];
		    pav = grpav[i];
		    grdz[i] = cnst * pow ( ( pav / 1000. ), RKAPPA ) 
                                   * ( dp / pav );
		}
	    }

        }
	else if ( ivcord == 3 ) {

            /*
             *	    Height coordinate system.
             *	    Generate a (constant) grid of height difference.  No stack
             *	    operations occur.
             */
	    dg_nxts  ( &ndz, iret );
	    if  ( *iret != 0 )  return;

	    dz = level1 - level2;
	    dg_real  ( &dz, &ndz, iret );

        }
	else { 

            /*
             *	    "No" or unrecognized coordinate system.  This is an error.
             */
	    *iret = -24;
            tmp = -1;
	    dg_merr  ( "", "", "", &tmp, &tmp, &ivcord, errst, &ier );
            dg_cset ( "ERRST", errst, iret );
	    return;

        }

        /*
         *	Compute the average THTA and THTA difference in the layer
         *	depending upon the coordinate system.  Stack operations are
         *	designed to preserve access to in-line parameters.
         */
	if (( ivcord == 1 ) || ( ivcord == 3)) {

            /*
             *	    Pressure or height coordinate system.
             *	    Compute the delta THTA in the layer.
             */
	    dg_rpls  ( "THTA", &zero, iret );
	    if  ( *iret != 0 )  return;
	    df_ldf  ( iret );
	    if  ( *iret != 0 )  return;
	    dg_tops  ( gdum, &ndth, time1, time2, &level1, &level2, 
                              &ivcord, pdum, iret );
	    if  ( *iret != 0 )  return;

            /*
             *	    Compute the average THTA in the layer.
             */
	    dg_rpls  ( "THTA", &zero, iret );
	    if  ( *iret != 0 )  return;
	    df_lav  ( iret );
	    if  ( *iret != 0 )  return;
	    dg_tops  ( gdum, &nath, time1, time2, &level1, &level2,
                              &ivcord, pdum, iret );
	    if  ( *iret != 0 )  return;

        }
	else if ( ivcord == 2 ) {

            /*
             *	  Isentropic coordinate system.
             *	  Constant values are put into new grids (no stack operations).
             *	  Compute the average THTA in the layer.
             */
	    dg_nxts ( &nath, iret );
	    if ( *iret != 0 )  return;

	    avtht  = (level1 + level2) / 2.;
	    dg_real ( &avtht, &nath, iret );

            /*
             *	    Compute the THTA difference in the layer.
             */
	    dg_nxts ( &ndth, iret );
	    if ( *iret != 0 )  return;

	    deltht =  level1 - level2;
	    dg_real ( &deltht, &ndth, iret );

        }

        /*
         *	No test for other values of IVCORD was needed because they
         *	were kicked out in the IF for DZ.  Get a new grid for the
         *	Richardson number and compute it.
         */
	dg_nxts ( &nrich, iret );
	if ( *iret != 0 )  return;

        dg_getg ( &ndz, &grdz, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &ndth, &grdth, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nath, &grath, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nwsq, &grwsq, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nrich, &grrich, &kxd, &kyd, &ksub1, &ksub2, iret );

	for ( i = ksub1 - 1; i < ksub2; i++ ) {
	    ath  = grath[i];
	    dth  = grdth[i];
	    dz   = grdz[i];
	    dwsq = grwsq[i];

	    if ( ERMISS (ath ) || G_DIFFT(ath,  0.0F, GDIFFD) || 
     	 	 ERMISS (dwsq) || G_DIFFT(dwsq, 0.0F, GDIFFD) ||
     	 	 ERMISS (dth ) || ERMISS (dz ) ) 
		grrich[i] = RMISSD;
	    else
		grrich[i] = ( GRAVTY * dz / ath) * ( dth / dwsq );
	    
	}

        /*
         *	Make a name of the form 'RICH'//V and update header;
         *	update the stack.
         */
	dg_mnam ( "RICH", wname, "", gp, iret );
        nval = 1;
        dg_iget ( "IDLUN", &nval, &idlun, iret);
	dg_upsg ( time1, time2, &level1, &level2, &ivcord, &idlun, gp, 
                         &nrich, iret );
	dg_rpls ( "", &nrich, iret );
	dg_esub  ( &nrich, &zero, &zero, &zero, &ier );
	if ( ier != 0 ) *iret = ier;

	return;
}
Example #7
0
void dv_div ( int *iret )
/************************************************************************
 * dv_div								*
 *									*
 * This subroutine computes the divergence of a vector:			*
 *									*
 *     DIV ( V ) = DDX ( u ) + DDY ( v ) - u * {(mx/my)*[d(my)/dx]}   	*
 *					 - v * {(my/mx)*[d(mx)/dy]}	*
 *									*
 * where my and mx are scale factors.  The quantities in braces are	*
 * assumed to exist in common arrays YMSDX and XMSDY, respectively. 	*
 * Divergence is a scalar field.					*
 *									*
 * dv_div ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETV			*
 **									*
 * Log:									*
 * M. desJardins/GSFC	10/85						*
 * I. Graffman/RDS	 7/88	Call to DG_UPDH				*
 * G. Huffman/GSC	 9/88	New stack functions			*
 * G. Huffman/GSC	 9/88	Error messages				*
 * K. F. Brill/GSC	 4/89   Added scale factor code			*
 * K. Brill/GSC		 8/89   Subsetting				*
 * K. Brill/GSC		10/89   Subsetting				*
 * T. Lee/GSC		 4/96   Single dimension for dgg		*
 * T. Lee/GSC		 5/96	Moved IGDPT outside DO loop		*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		 5/02	Eliminate LLMXGD declarations in DGCMN	*
 *				using int grds for scl fctr derivatives *
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * S. Gilbert/NCEP	11/05	Translate from Fortran                  *
 ************************************************************************/
{
        int             i, zero=0, nval, kxd, kyd, ksub1, ksub2, ier;
	int		numu, numv, numout, nddx, nddy, ixmsdy, iymsdx;
        float           *gru, *grv, *grout, *grddx, *grddy, *grxmsdy, *grymsdx;

/*------------------------------------------------------------------------*/
	*iret = 0;
	dg_ssub ( iret );

        /*
         *	Get the (wind) vector.
         */
	dg_getv  ( &numu, &numv, iret );
	if  ( *iret != 0 ) return;

        /*
         *	Get a new grid number.
         */
	dg_nxts  ( &numout, iret );
	if  ( *iret != 0 )  return;

        /*
         *	Compute x derivative of u component.
         */
	dg_puts ( &numu, iret );
	if ( *iret != 0 ) return;
	df_ddx ( iret );
	if ( *iret != 0 ) return;
	dg_gets ( &nddx, iret );
	if ( *iret != 0 ) return;

        /*
         *	Compute y derivative of v component.
         */
	dg_puts ( &numv, iret );
	if ( *iret != 0 ) return;
	df_ddy ( iret );
	if ( *iret != 0 ) return;
	dg_gets ( &nddy, iret );
	if ( *iret != 0 ) return;

        /*
         *	Combine terms to compute divergence.
         */
        dg_getg( &numu, &gru, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg( &numv, &grv, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg( &numout, &grout, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg( &nddx, &grddx, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg( &nddy, &grddy, &kxd, &kyd, &ksub1, &ksub2, iret );

        /*
         *	Compute map scale factor derivative coefficients.
         */
	dg_dmsf ( iret );
	if ( *iret != 0 ) return;

        nval = 1;
        dg_iget ("IXMSDY", &nval, &ixmsdy, iret );
        dg_iget ("IYMSDX", &nval, &iymsdx, iret );
        dg_getg( &ixmsdy, &grxmsdy, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg( &iymsdx, &grymsdx, &kxd, &kyd, &ksub1, &ksub2, iret );


	 for ( i = ksub1 - 1; i < ksub2; i++ ) {
	    if ( ERMISS ( grddx[i] ) || ERMISS ( grddy[i] ) ||
     	       	 ERMISS ( gru[i] )  || ERMISS ( grv[i] ) ) 
	       grout[i] = RMISSD;
	    else
	       grout[i] = grddx[i] + grddy[i] -
     			  gru[i] * grymsdx[i] - 
     		  	  grv[i] * grxmsdy[i];
	    
	}

        /*
         *	Make a name of the form 'DIV'//u and update header; update stack
         */
	dg_updh  ( "DIV", &numout, &numu, &zero, iret );
	dg_puts  ( &numout, iret );
	dg_esub  ( &numout, &zero, &zero, &zero, &ier );
	if ( ier != 0 ) *iret = ier;

	return;
}
Example #8
0
void dv_dvdx ( int *iret )
/************************************************************************
 * dv_dvdx								*
 *									*
 * This subroutine computes the x-derivative of a vector:		*
 *									*
 *     DVDX ( V ) = [ DDX (u) - v * ( (my/mx) * d(mx)/dy ),		*
 *			 DDX (v) + u * ( (my/mx) * d(mx)/dy ) ]		*
 *									*
 * where mx and my are scale factors along x and y, respectively.  	*
 *									*
 * dv_dvdx ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETV			*
 **									*
 * Log:									*
 * K. Brill/NMC	         1/93						*
 * S. Jacobs/NMC	 4/94	Clean up				*
 * T. Lee/GSC		 4/96   Single dimension for dgg		*
 * T. Lee/GSC		 5/96   Moved IGDPT outside DO loop		*
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		 5/02	Eliminate LLMXGD declarations in DGCMN	*
 *				using int grds for scl fctr derivatives *
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * S. Gilbert/NCEP	11/05	Translation from Fortran                *
 ************************************************************************/
{
	int		i, kxd, kyd, ksub1, ksub2, ier, nval, zero=0;
	int		nu, nv, numu, numv;
	float		*grnu, *grnv, *grnumu, *grnumv;
        int             nuddx, nvddx, ixmsdy;
        float           *gruddx, *grvddx, *grxmsdy;

/*------------------------------------------------------------------------*/
	*iret = 0;
	dg_ssub ( iret );

        /*
         *	Get the (wind) vector.
         */
	dg_getv  ( &numu, &numv, iret );
	if  ( *iret != 0 ) return;

        /*
         *	Get a new vector grid number.
         */
	dg_nxtv  ( &nu, &nv, iret );
	if  ( *iret != 0 )  return;

        /*
         *	Compute x derivatives of u and v components.
         */
	dg_puts ( &numu, iret );
	if ( *iret != 0 ) return;
	df_ddx ( iret );
	if ( *iret != 0 ) return;
	dg_gets ( &nuddx, iret );
	if ( *iret != 0 ) return;
	dg_puts ( &numv, iret );
	if ( *iret != 0 ) return;
	df_ddx ( iret );
	if ( *iret != 0 ) return;
	dg_gets ( &nvddx, iret );
	if ( *iret != 0 ) return;

        /*
         *	Compute map scale factor derivative coefficients.
         */
	dg_dmsf ( iret );
	if ( *iret != 0 ) return;

        nval = 1;
        dg_iget ( "IXMSDY", &nval, &ixmsdy, iret);
        dg_getg ( &ixmsdy, &grxmsdy, &kxd, &kyd, &ksub1, &ksub2, iret );

        /*
         *	Compute the output vector components.
         */
        dg_getg ( &nu, &grnu, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nv, &grnv, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numu, &grnumu, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &numv, &grnumv, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nuddx, &gruddx, &kxd, &kyd, &ksub1, &ksub2, iret );
        dg_getg ( &nvddx, &grvddx, &kxd, &kyd, &ksub1, &ksub2, iret );

	for ( i = ksub1 - 1; i < ksub2; i++ ) {
	    if ( ERMISS ( grvddx[i] )  || ERMISS ( gruddx[i] )  ||
     		 ERMISS ( grnumu[i] )  || ERMISS ( grnumv[i] ) ) {
	       grnu[i] = RMISSD;
	       grnv[i] = RMISSD;
            }
	    else {
	       grnu[i] = gruddx[i] - grnumv[i] * grxmsdy[i];
	       grnv[i] = grvddx[i] + grnumu[i] * grxmsdy[i];
	    }
	}

        /*
         *	Make a name of the form 'DVDX'//u and update header;
         *	update stack.
         */
	dg_updv  ( "DVDX", &nu, &nv, &numu, &zero, iret );
	dg_putv  ( &nu, &nv, iret );
	dg_esub  ( &nu, &nv, &zero, &zero, &ier );
	if ( ier != 0 ) *iret = ier;

	return;
}