/*NP*/ void trace_parcel (float pres, float temp, float dwpt) /*************************************************************/ /* TRACE_PARCEL */ /* John Hart NSSFC KCMO */ /* */ /* Plots parcel(pres, temp, dwpt) trajectory on SkewT */ /* graphic. */ /* */ /* pres - Pressure of initial parcel(mb) */ /* temp - Temperature of initial parcel (c) */ /* dwpt - Dew Point of initial parcel (c) */ /*************************************************************/ { float i, p2, t2, t3; short x, y; if (!qc (pres) || !qc (temp) || !qc (dwpt)) return; setcolor (31, draw_reg, gc); setlinestyle (4, 1); x = temp_to_pix (virtemp (pres, temp, dwpt), pres); y = pres_to_pix (pres); moveto (x, y); drylift (pres, temp, dwpt, &p2, &t2); x = temp_to_pix (virtemp (p2, t2, t2), p2); y = pres_to_pix (p2); lineto (x, y); for (i = p2 - 50; i >= 100; i = i - 50) { t3 = wetlift (p2, t2, i); x = temp_to_pix (virtemp (i, t3, t3), i); y = pres_to_pix (i); lineto (x, y); } t3 = wetlift (p2, t2, 100); x = temp_to_pix (virtemp (100, t3, t3), 100); y = pres_to_pix (100); lineto (x, y); }
/*NP*/ float visual1(float lower, float upper, float pres, float temp, float dwpt, int ulx, int uly, int vwid) /*************************************************************/ /* 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) */ /*************************************************************/ { short i, lptr, uptr, pIndex, zIndex, tIndex, tdIndex; float te1, pe1, te2, pe2, h1, h2, lyre, tdef1, tdef2, totp, totn; float te3, pe3, h3, tp1, tp2, tp3, tdef3, lyrf, lyrlast, pelast; float tote, dh, restim, uvv, ix1, ix2, tottim; float u, v, du, dv, tsu, tsv, tdist, tangle, disp, angl; short colrx; lyre = -1; totp = 25; totn = 0; pIndex = getParmIndex("PRES"); zIndex = getParmIndex("HGHT"); tIndex = getParmIndex("TEMP"); tdIndex = getParmIndex("DWPT"); if (!sndg || pIndex == -1 || zIndex == -1 || tIndex == -1 || tdIndex == -1) return RMISSD; /* ----- See if default layer is specified ----- */ if (lower == -1) { lower = sndg[sfc()][pIndex]; } if (upper == -1) { upper = sndg[numlvl-1][pIndex]; } /* ----- Make sure this is a valid layer ----- */ if( lower > pres ) { lower = pres; } if( !qc( i_vtmp( upper , I_PRES))) { return RMISSD; } if( !qc( i_vtmp( lower , I_PRES))) { return RMISSD; } /* ----- Begin with Mixing Layer (LPL-LCL) ----- */ te1 = i_vtmp(pres , I_PRES); pe1 = lower; h1 = i_hght(pe1 , I_PRES); tp1 = virtemp(pres, temp, dwpt); drylift(pres, temp, dwpt, &pe2, &tp2); h2 = i_hght(pe2 , I_PRES); te2 = i_vtmp(pe2 , I_PRES); if( lower > pe2 ) { lower = pe2; } /* ----- Find lowest observation in layer ----- */ i = 0; while( sndg[i][pIndex] > lower) { i++; } while ( !qc(sndg[i][tdIndex]) ) { i++; } lptr = i; if( sndg[i][pIndex] == lower ) { lptr++; } /* ----- Find highest observation in layer ----- */ i=numlvl-1; while(sndg[i][pIndex] < upper) { i--; } uptr = i; if( sndg[i][pIndex] == upper ) { uptr--; } /* ----- Start with interpolated bottom layer ----- */ pe1 = lower; h1 = i_hght( pe1 , I_PRES); te1 = i_vtmp( pe1 , I_PRES); tp1 = wetlift(pe2, tp2, pe1); totp = 25; totn = 0; tsu = 0; tsv = 0; restim = 0; tottim = 0; for (i = lptr; i < numlvl; i++) { if (qc(sndg[i][tIndex])) { /* ----- Calculate every level that reports a temp ----- */ pe2 = sndg[i][pIndex]; h2 = sndg[i][zIndex]; te2 = i_vtmp( pe2 , I_PRES); tp2 = wetlift(pe1, tp1, pe2); tdef1 = (virtemp(pe1, tp1, tp1) - te1) / (te1 + 273.15); tdef2 = (virtemp(pe2, tp2, tp2) - te2) / (te2 + 273.15); lyrlast = lyre; lyre = 9.8F * (tdef1 + tdef2) / 2.0F * (h2 - h1); if( lyre > 0 ) { totp += lyre; } else { if(pe2 > 500) { totn += lyre; } } tote += lyre; uvv = (float)sqrt( totp * 2 ); dh = h2 - h1; restim = dh / uvv; tottim += restim; sr_wind( pe1, pe2, st_dir, 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((tsu*tsu) + (tsv*tsv)); tangle = angle(tsu, tsv); pelast = pe1; 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 ) { totp -= lyrf; } else { if(pe2 > 500) { totn -= lyrf; } } pe2 = upper; h2 = i_hght( pe2 , I_PRES); te2 = i_vtmp( pe2 , I_PRES); tp2 = wetlift(pe3, tp3, pe2); tdef3 = (virtemp(pe3, tp3, tp3) - te3) / (te3 + 273.15); tdef2 = (virtemp(pe2, tp2, tp2) - te2) / (te2 + 273.15); lyrf = 9.8F * (tdef3 + tdef2) / 2.0F * (h2 - h3); if( lyrf > 0 ) { totp += lyrf; } else { if(pe2 > 500) { totn -= lyrf; } } if( totp == 0 ) { totn = 0; } uvv = (float)sqrt( totp * 2 ); dh = h2 - h1; restim = dh / uvv; tottim += restim; sr_wind( pe1, pe2, st_dir, 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((tsu*tsu) + (tsv*tsv)); tangle = angle(tsu, tsv); colrx = 7; vis_xy( -tsu, -tsv, colrx, ulx, uly, vwid); angl = 90 - angle( tdist, agl(h2)); write_vis_data( tottim, angl, ulx, uly, vwid ); return 1; } colrx = 13; if (h2>msl(3000)) colrx=3; if (h2>msl(6000)) colrx=27; if (h2>msl(9000)) colrx=20; if (h2>msl(12000)) colrx=6; vis_xy(-tsu, -tsv, colrx, ulx, uly, vwid); if (sndg[i][pIndex] == 500) { disp = tdist; angl = 90 - angle( tdist, agl(sndg[i][zIndex])); } } } return 1.0; /* ? mkay. there was no value before. bad thing */ }