awips2/ncep/gov.noaa.nws.ncep.ui.nsharp/nsharp_c/caveNsharp.c
root 9f19e3f712 Initial revision of AWIPS2 11.9.0-7p5
Former-commit-id: 64fa9254b946eae7e61bbc3f513b7c3696c4f54f
2012-01-06 08:55:05 -06:00

378 lines
11 KiB
C

#include "gui.h"
#include "sharp95.h"
struct sndg_struct myStaticSndgStruct;
//this is copy from sndg_parms..but adding typedef for our implementation
typedef struct Sndg_parms
{
float omega;
float pres;
float hght;
float temp;
float dwpt;
float drct;
float sped;
} SndgParms;
typedef struct stormSlinkyStr
{
int size;
float tottim;
float angl;
float tsuv[200][2];
} StormSlinkyStr;
SndgParms * populateSndgData(SndgParms snDataArray[], int arraySize, float winDir, float winSpd) {
int i;
/*if (sndgp)
free(sndgp);
sndgs[0] = (struct sndg_struct *)malloc(sizeof(struct sndg_struct));
sndgp = sndgs[0];*/
sndgs[0] = &myStaticSndgStruct;
sndgp = sndgs[0];
sndgp->numlev = arraySize;
for (i =0; i< sndgp->numlev; i++){
sndgp->sndg[i].drct = snDataArray[i].drct;
sndgp->sndg[i].sped = snDataArray[i].sped;
sndgp->sndg[i].pres = snDataArray[i].pres;
sndgp->sndg[i].hght = snDataArray[i].hght;
sndgp->sndg[i].dwpt = snDataArray[i].dwpt;
sndgp->sndg[i].temp = snDataArray[i].temp;
sndgp->sndg[i].omega = snDataArray[i].omega;
}
//Chin, I dont need this....copy_sndg();
sndgp->st_dir = winDir;
sndgp->st_spd = winSpd;
return sndgp;
}
void showSndgData(){
int i;
printf("Snd layer num = %d\n", sndgp->numlev);
for (i =0; i< sndgp->numlev; i++){
printf(" %d: Pre %.4f Hgt %.4f Temp %.4f Dew %.4f Wspd %.4f Wdir %.2f\n",
i,sndgp->sndg[i].pres,
sndgp->sndg[i].hght,
sndgp->sndg[i].temp,sndgp->sndg[i].dwpt,
sndgp->sndg[i].sped, sndgp->sndg[i].drct);
}
}
void populateSndgTestData(void) {
int i;
sndgs[0] = (struct sndg_struct *)malloc(sizeof(struct sndg_struct));
sndgp = sndgs[0];
sndgp->numlev = 10;
for (i =0; i< sndgp->numlev; i++){
sndgp->sndg[i].drct = i + 10;
sndgp->sndg[i].sped = i + 100;
sndgp->sndg[i].pres = i * 100 + 100;
sndgp->sndg[i].hght = (10-i) * 1000 + 100;
sndgp->sndg[i].dwpt = -50 + (i * 6);
sndgp->sndg[i].temp = -80 + (i * 6);
sndgp->sndg[i].omega = -999;
}
copy_sndg();
}
void get_lpvaluesData(struct _lplvalues *pParcel){
pParcel->temp = sndgp->lplvals.temp;
pParcel->dwpt = sndgp->lplvals.dwpt;
pParcel->pres = sndgp->lplvals.pres;
pParcel->flag = sndgp->lplvals.flag;
strcpy(pParcel->desc, sndgp->lplvals.desc);
//printf("desc %s\n", pParcel->desc);
}
/*
* This function is used to get surface pressure and temp directly from sndgp. As some other api need
* them as input parameters and legacy code API does not provide such.
*/
void get_surface(float* pressure, float * temp, float * dewpt){
*pressure = sndgp->sndg[sfc()].pres;
*temp = sndgp->sndg[sfc()].temp;
*dewpt = sndgp->sndg[sfc()].dwpt;
}
void get_surfaceWind(float* windSp, float * windDir){
*windSp = sndgp->sndg[sfc()].sped;
*windDir = sndgp->sndg[sfc()].drct;
}
/*
* This function is used to get top layer pressure and temp directly from sndgp. As some other api need
* them as input parameters and legacy code API does not provide such.
*/
void get_top(float* pressure, float * temp, float * dewpt){
*pressure = sndgp->sndg[sndgp->numlev-1].pres;
*temp = sndgp->sndg[sndgp->numlev-1].temp;
*dewpt = sndgp->sndg[sndgp->numlev-1].dwpt;
}
/*
* This function is used to get storm speed and direction directly from sndgp. As some other api need
* them as input parameters and legacy code API does not provide such.
*/
void get_storm(float* speed, float * direction){
*direction = sndgp->st_dir;
*speed = sndgp->st_spd;
}
void set_storm(float speed, float direction){
sndgp->st_dir = direction;
sndgp->st_spd = speed;
}
/*
* This function is to get an array of points for storm slinky plotting
* original function plot them directly, but CAVE has to plot on its own
* way.
*/
void cave_visual1 ( float lower, float upper, float pres, float temp, float dwpt , struct stormSlinkyStr * stmSlinky)
/*************************************************************/
/* VISUAL1 */
/* John Hart NSSFC KCMO */
/* */
/* Lifts specified parcel, given an initial 5 m/s push. */
/* parcel trajectory is then calculated, using strict */
/* parcel theory. Updraft size is assumed 1km dia. */
/* */
/* All calculations use the virtual temperature correction. */
/* */
/* lower = Bottom level of layer (mb) [ -1=SFC] */
/* upper = Top level of layer (mb) [ -1=TOP] */
/* pres = LPL pressure (mb) */
/* temp = LPL temperature (c) */
/* dwpt = LPL dew point (c) *
** *
* Log: *
*
*************************************************************/
{
short i, lptr, uptr;
float te1, pe1, te2, pe2, h1, h2, lyre, tdef1, tdef2, totp, totn;
float te3, pe3, h3, tp1, tp2, tp3, tdef3, lyrf;
float tote, dh, restim, uvv, ix1, ix2, tottim;
float u, v, du, dv, tsu, tsv, tdist, angl;
int size=0;
/* float tangle; */
lyre = -1.0F;
totp = 25.0F;
totn = 0.0F;
tote = 0.0F;
/* ----- See if default layer is specified ----- */
if( lower == -1.0F) { lower = sndgp->sndg[sfc()].pres; }
if( upper == -1.0F) { upper = sndgp->sndg[sndgp->numlev-1].pres; }
/* ----- Make sure this is a valid layer ----- */
if( lower > pres ) { lower = pres; }
if( !qc( i_vtmp( upper ))) { return; }
if( !qc( i_vtmp( lower ))) { return; }
/* ----- Begin with Mixing Layer (LPL-LCL) ----- */
te1 = i_vtmp( pres );
pe1 = lower;
h1 = i_hght( pe1 );
tp1 = virtemp( pres, temp, dwpt);
drylift(pres, temp, dwpt, &pe2, &tp2);
h2 = i_hght( pe2 );
te2 = i_vtmp( pe2 );
if( lower > pe2 ) { lower = pe2; }
/* ----- Find lowest observation in layer ----- */
i = 0;
while( sndgp->sndg[i].pres > lower) { i++; }
while ( !qc(sndgp->sndg[i].dwpt) ) { i++; }
lptr = i;
if( sndgp->sndg[i].pres == lower ) { lptr++; }
/* ----- Find highest observation in layer ----- */
i=(short)(sndgp->numlev-1);
while(sndgp->sndg[i].pres < upper) { i--; }
uptr = i;
if( sndgp->sndg[i].pres == upper ) { uptr--; }
/* ----- Start with interpolated bottom layer ----- */
pe1 = lower;
h1 = i_hght( pe1 );
te1 = i_vtmp( pe1 );
tp1 = wetlift(pe2, tp2, pe1);
totp = 25.0F;
totn = 0.0F;
tsu = 0.0F;
tsv = 0.0F;
restim = 0.0F;
tottim = 0.0F;
//printf("number of layer %d\n", sndgp->numlev);
for( i = lptr; i < sndgp->numlev; i++)
{
if( qc(sndgp->sndg[i].temp) )
{
//printf( " temp %f\n", sndgp->sndg[i].temp);
/* ----- Calculate every level that reports a temp ----- */
pe2 = sndgp->sndg[i].pres;
h2 = sndgp->sndg[i].hght;
te2 = i_vtmp( pe2 );
tp2 = wetlift(pe1, tp1, pe2);
tdef1 = (virtemp(pe1, tp1, tp1) - te1) / (te1 + 273.15F);
tdef2 = (virtemp(pe2, tp2, tp2) - te2) / (te2 + 273.15F);
lyre = 9.8F * (tdef1 + tdef2) / 2.0F * (h2 - h1);
if( lyre > 0.0F ) { totp += lyre; }
else { if(pe2 > 500.0F) { totn += lyre; } }
tote += lyre;
uvv = (float)sqrt( (double)(totp * 2.0F) );
dh = h2 - h1;
restim = dh / uvv;
tottim += restim;
sr_wind( pe1, pe2, sndgp->st_dir, sndgp->st_spd, &u, &v, &ix1, &ix2);
du = kt_to_mps(u) * restim;
dv = kt_to_mps(v) * restim;
tsu -= du;
tsv += dv;
tdist = (float)sqrt((double)(tsu*tsu) + (double)(tsv*tsv));
/* tangle = angle(tsu, tsv); NOT used */
pe1 = pe2;
h1 = h2;
te1 = te2;
tp1 = tp2;
/* ----- Is this the top of given layer ----- */
if(i >= uptr)
{
pe3 = pe1;
h3 = h1;
te3 = te1;
tp3 = tp1;
lyrf = lyre;
if( lyrf > 0.0F )
{ totp -= lyrf; }
else
{ if(pe2 > 500.0F) { totn -= lyrf; } }
pe2 = upper;
h2 = i_hght( pe2 );
te2 = i_vtmp( pe2 );
tp2 = wetlift(pe3, tp3, pe2);
tdef3 = (virtemp(pe3, tp3, tp3) - te3) / (te3 + 273.15F);
tdef2 = (virtemp(pe2, tp2, tp2) - te2) / (te2 + 273.15F);
lyrf = 9.8F * (tdef3 + tdef2) / 2.0F * (h2 - h3);
if( lyrf > 0.0F )
{ totp += lyrf; }
else
{ if(pe2 > 500.0F) { totn -= lyrf; } }
if( totp == 0.0F ) { totn = 0.0F; }
uvv = (float)sqrt( (double)(totp * 2.0F) );
dh = h2 - h1;
restim = dh / uvv;
tottim += restim;
sr_wind( pe1, pe2, sndgp->st_dir, sndgp->st_spd, &u, &v, &ix1, &ix2);
du = kt_to_mps(u) * restim;
dv = kt_to_mps(v) * restim;
tsu -= du;
tsv += dv;
tdist = (float)sqrt((double)(tsu*tsu) + (double)(tsv*tsv));
/* tangle = angle(tsu, tsv); NOT used */
//vis_xy( tsu, tsv);
stmSlinky->tsuv[size][0]= tsu;
stmSlinky->tsuv[size][1]= tsv;
//printf( " returning with size %d\n", size+1);
angl = 90.0F - angle( tdist, agl(h2));
//write_vis_data( tottim, angl );
stmSlinky->tottim = tottim;
stmSlinky->angl = angl;
stmSlinky->size = size+1;
return;
}
//vis_xy( tsu, tsv);
stmSlinky->tsuv[size][0]= tsu;
stmSlinky->tsuv[size][1]= tsv;
stmSlinky->size = size+1;
size++;
//printf( "tsu=%f tsv=%f \n", tsu, tsv);
if(size>= 200)
return;
if( sndgp->sndg[i].pres == 500.0F )
{
angl = 90.0F - angle( tdist, agl(sndgp->sndg[i].hght));
}
}
}
}
float cave_bulk_rich ( float lplpres, float bplus,float *brnshear )
/*************************************************************/
/* ported from skparams.c but change its input parameters */
/* BRN */
/* John Hart NSSFC KCMO */
/* */
/* Calculates the Bulk Richardson Number for given parcel. */
/* Value is returned both as (param) and as a RETURN. */
/*************************************************************/
{
float ptop, pbot, x1, y1, x2, y2, z1, z2, dx, dy;
if(sndgp->lplvals.flag < 4)
{
ptop = i_pres(msl(6000));
pbot = sndgp->sndg[sfc()].pres;
}
else
{
pbot = i_pres(i_hght(lplpres) - 500);
if (!qc(pbot)) pbot = sndgp->sndg[sfc()].pres;
ptop = i_pres(i_hght(pbot) + 6000);
}
/* ----- First, calculate lowest 500m mean wind ----- */
mean_wind( pbot, i_pres(i_hght(pbot)+500), &x1, &y1, &z1, &z2);
/* ----- Next, calculate 6000m mean wind ----- */
mean_wind( pbot, ptop, &x2, &y2, &z1, &z2);
/* ----- Check to make sure CAPE and SHEAR are avbl ----- */
if (!qc(bplus)) {return -999;}
if (!qc(x1)) {return -999;}
if (!qc(x2)) {return -999;}
/* ----- Calculate shear between winds ----- */
dx = x2 - x1;
dy = y2 - y1;
*brnshear = (float)(sqrt((dx * dx) + (dy * dy))) * .51479;
*brnshear = *brnshear * *brnshear / 2;
/* ----- Calculate and return BRN ----- Chin: I dont know why return this value*/
/* BRN valus is returned in *brnshear*/
return bplus / *brnshear;
}
void printSfcInfo() {
float sfctemp, sfcdwpt, sfcpres, lower, upper;
struct _parcel pcl;
sfctemp = sndgp->lplvals.temp;
sfcdwpt = sndgp->lplvals.dwpt;
sfcpres = sndgp->lplvals.pres;
parcel( -1, -1, sfcpres, sfctemp, sfcdwpt, &pcl);
lower = pcl.lfcpres;
upper = pcl.elpres;
printf("before call meanwind sfctemp=%f sfcdwpt=%f sfcpres=%f lower=%f upper=%f\n", sfctemp, sfcdwpt, sfcpres, lower, upper);
}