Merge branch '4-Thin_Client' into 104-integration
Former-commit-id:62c587b841
[formerly62c587b841
[formerly aaf3d445f517bba03e9f6b768850f2a8c77d26ed]] Former-commit-id:c825bd03a2
Former-commit-id:0fab56e0f1
This commit is contained in:
commit
f265cb965d
6 changed files with 302 additions and 168 deletions
|
@ -32,6 +32,6 @@
|
|||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
unpack="true"/>
|
||||
|
||||
</feature>
|
||||
|
|
Binary file not shown.
|
@ -5,7 +5,8 @@ Bundle-SymbolicName: meteolib.jni
|
|||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Activator: meteolib.jni.Activator
|
||||
Require-Bundle: org.eclipse.ui,
|
||||
org.eclipse.core.runtime
|
||||
org.eclipse.core.runtime,
|
||||
org.apache.commons.lang;bundle-version="2.3.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .,
|
||||
gluegen-rt.jar
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.eclipse.core.runtime.FileLocator;
|
|||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.apache.commons.lang.SystemUtils;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
|
@ -90,10 +91,46 @@ public class Activator extends AbstractUIPlugin {
|
|||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not need to reformat the path for Windows here because
|
||||
* Java does not care.
|
||||
*/
|
||||
System.load(nativeLibraryPath);
|
||||
|
||||
// Re-format for Windows.
|
||||
if (SystemUtils.IS_OS_WINDOWS)
|
||||
{
|
||||
/*
|
||||
* We reformat here because this is the path that will be
|
||||
* returned to python scripts that use the meteoLib library.
|
||||
*/
|
||||
return formatWindowsPath(nativeLibraryPath);
|
||||
}
|
||||
|
||||
return nativeLibraryPath;
|
||||
}
|
||||
|
||||
private static String formatWindowsPath(String nativeLibraryPath) {
|
||||
/*
|
||||
* Remove the leading "/" if there is one.
|
||||
*/
|
||||
if (nativeLibraryPath.startsWith("/"))
|
||||
{
|
||||
int length = nativeLibraryPath.length();
|
||||
nativeLibraryPath = nativeLibraryPath.substring(1, length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace all file path separators with the Windows version of
|
||||
* a file path separator.
|
||||
*/
|
||||
if (nativeLibraryPath.contains("/"))
|
||||
{
|
||||
nativeLibraryPath = nativeLibraryPath.replace("/", "\\");
|
||||
}
|
||||
|
||||
return nativeLibraryPath;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
@ -116,5 +153,4 @@ public class Activator extends AbstractUIPlugin {
|
|||
public static Activator getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -54,12 +54,12 @@ void createSlices(float * vc3d, float * param3d, int sense,
|
|||
int nx, int ny, int nz,
|
||||
float * vcC, int nc, float * paramC);
|
||||
|
||||
void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
||||
int capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
||||
float * p0, float * th0, float * sh0,
|
||||
int mnx, int nx, int ny, int nz,
|
||||
float * cape_dat, float * cin_dat);
|
||||
|
||||
void dcapeFunc(float usetv, const float ** p_dat, const float ** t_dat, const float **
|
||||
int dcapeFunc(float usetv, const float ** p_dat, const float ** t_dat, const float **
|
||||
td_dat, float * p0, float * th0, float * sh0,
|
||||
int mnx, int nx, int ny, int nz,
|
||||
float max_evap, float max_rh, float * dcape_dat);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// things that can be arithemitically averaged for a mixed layer.
|
||||
// If usetv=1, buoyancy is done with virtual temp, if usetv=0 with temp.
|
||||
// If usetv=0, must supply temps in tve_dat.
|
||||
void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
||||
int capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
||||
float * p0, float * th0, float * sh0,
|
||||
int mnx, int nx, int ny, int nz,
|
||||
float * cape_dat, float * cin_dat)
|
||||
|
@ -51,29 +51,49 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
tt = th0;
|
||||
qq = sh0;
|
||||
tec = tec_st = (float*)malloc(n2*sizeof(float));
|
||||
if (tec == NULL || tec_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
tvc = tvc_st = (float*)malloc(n2*sizeof(float));
|
||||
if (tvc == NULL || tvc_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
pc = pc_st = (float*)malloc(n2*sizeof(float));
|
||||
if (pc == NULL || pc_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
pp1 = pp1_st = (float*)malloc(n2*sizeof(float));
|
||||
if (pp1 == NULL || pp1_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
eptr = pp0+nn;
|
||||
if (dd==0)
|
||||
{
|
||||
i = 0x7FFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = nx;
|
||||
}
|
||||
for (; pp0<eptr; pp0++,pp1++,tt++,qq++,pc++,tec++,tvc++)
|
||||
{
|
||||
{
|
||||
*pp1 = *pp0;
|
||||
if (--i<0)
|
||||
{
|
||||
{
|
||||
pp0 += dd;
|
||||
tt += dd;
|
||||
qq += dd;
|
||||
i = nxm;
|
||||
}
|
||||
}
|
||||
if (*pp0>1e36 || *tt>1e36 || *qq>1e36 || *qq<0.0005)
|
||||
{
|
||||
{
|
||||
*tec = *tvc = *pc = 1e37;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
t0 = (*tt)*pow((*pp0)/1000,kapa);
|
||||
b = c0-log( (*pp0)/(622./(*qq) + 0.378) );
|
||||
td = (b-sqrt(b*b-c_1))/c_2;
|
||||
|
@ -81,11 +101,19 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
*pc = (*pp0)*pow(tdc/t0,kapa_1);
|
||||
*tec = adiabatic_te(&tdc,pc);
|
||||
*tvc = td*(1+usetv*0.000608*(*qq));
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize md and pmd, which will be pressure of and max Te delta.
|
||||
md_st = (float*)malloc(n2*sizeof(float));
|
||||
if (md_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
pmd_st = (float*)malloc(n2*sizeof(float));
|
||||
if (pmd_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
memset(md_st, 0, n2*sizeof(float));
|
||||
memset(pmd_st, 0, n2*sizeof(float));
|
||||
|
||||
|
@ -94,8 +122,12 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
// which has been tweaked to not be cooler than dry adiabatic from the
|
||||
// parcel start. Record the level of max parcel difference.
|
||||
tvp = tvp_st = (float*)malloc(n3*sizeof(float));
|
||||
if (tvp == NULL || tvp_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
for (k=0; k<nz; k++)
|
||||
{
|
||||
{
|
||||
pp1 = pp1_st;
|
||||
pp = p_dat[k];
|
||||
tve = tve_dat[k];
|
||||
|
@ -106,41 +138,51 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
pmd = pmd_st;
|
||||
eptr = pp+nn;
|
||||
if (dd==0)
|
||||
{
|
||||
i = 0x7FFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = nx;
|
||||
}
|
||||
for (; pp<eptr; pp1++,pp++,pc++,tec++,tvc++,tvp++,tve++,md++,pmd++)
|
||||
{
|
||||
{
|
||||
if (--i<0)
|
||||
{
|
||||
{
|
||||
pp += dd;
|
||||
tve += dd;
|
||||
i = nxm;
|
||||
}
|
||||
}
|
||||
if (*pc>1e36 || *pp>1e36 || *tve>1e36)
|
||||
{
|
||||
{
|
||||
*tvp = 1e37;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
t0 = (*tvc)*pow((*pp)/(*pc),kapa);
|
||||
if (*pp>=*pc)
|
||||
{
|
||||
*tvp = t0;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
td = (*tec)*pow((*pp)/(*pc),kapa);
|
||||
*tvp = td = temp_of_te(&td, pp);
|
||||
if (usetv>0)
|
||||
*tvp *= (*pp)/( *pp-exp(25.687958917-c1*td-c2/td) );
|
||||
}
|
||||
}
|
||||
if (*tve<t0)
|
||||
{
|
||||
*tvp -= t0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tvp -= *tve;
|
||||
}
|
||||
if (*pp>*pc || *tvp<*md) continue;
|
||||
*md = *tvp;
|
||||
*pmd = *pp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This loop performs the actual cape and cin calculation. Here we will
|
||||
// reuse storage for virt temp, equiv temp, and max delta for prev parcel
|
||||
|
@ -148,7 +190,7 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
// contributions we have not yet added into the cape and cin yet.
|
||||
tvp = tvp_st;
|
||||
for (k=0; k<nz; k++)
|
||||
{
|
||||
{
|
||||
pp0 = p0;
|
||||
pc = pc_st;
|
||||
pmd = pmd_st;
|
||||
|
@ -161,25 +203,29 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
cin = cin_dat;
|
||||
eptr = pp+nn;
|
||||
if (dd==0)
|
||||
{
|
||||
i = 0x7FFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = nx;
|
||||
}
|
||||
for (; pp<eptr; pp0++,pc++,pmd++,pp1++,pp++,tvp1++,tvp++,
|
||||
cap++,cin++,pos++,neg++)
|
||||
{
|
||||
cap++,cin++,pos++,neg++)
|
||||
{
|
||||
if (--i<0)
|
||||
{
|
||||
{
|
||||
pp0 += dd;
|
||||
pp += dd;
|
||||
cap += dd;
|
||||
cin += dd;
|
||||
i = nxm;
|
||||
}
|
||||
}
|
||||
if (k==0)
|
||||
{
|
||||
{
|
||||
*cin = *cap = 1e37;
|
||||
*pos = *neg = 0;
|
||||
}
|
||||
}
|
||||
else if (*pp0>1e36)
|
||||
continue;
|
||||
else if (*pp1>1e36 || *tvp1>1e36)
|
||||
|
@ -189,8 +235,7 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
else if (*pp>=*pp0)
|
||||
;
|
||||
else
|
||||
{
|
||||
|
||||
{
|
||||
// Now we finally have the data we need for calculating
|
||||
// the cape/cin contribution for this layer.
|
||||
if (*cap>1e36) *cap = *cin = 0;
|
||||
|
@ -199,20 +244,20 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
// First deal with possibility of bottom lvl being below the
|
||||
// initial parcel.
|
||||
if (*pp1>*pp0)
|
||||
{
|
||||
{
|
||||
dlnp = log((*pp0)/(*pp));
|
||||
dn = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
dlnp = log((*pp1)/(*pp));
|
||||
dn = dlnp*287*(*tvp1);
|
||||
}
|
||||
}
|
||||
|
||||
// Now deal with the fact that not allowing superadiabatic
|
||||
// layers means no cape below condensation pressure.
|
||||
if (*pp1>=*pc)
|
||||
{
|
||||
{
|
||||
if (dn>0) dn = 0;
|
||||
if (*tvp<=0)
|
||||
up = dlnp*287*(*tvp);
|
||||
|
@ -220,9 +265,11 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
up = 0;
|
||||
else
|
||||
up = log((*pc)/(*pp))*287*(*tvp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
up = dlnp*287*(*tvp);
|
||||
}
|
||||
|
||||
// Deal with where the break point is.
|
||||
b = up*dn>=0 ? 0.5 : up/(up-dn);
|
||||
|
@ -240,93 +287,93 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
|
||||
// Continuing upward acceleration.
|
||||
else if (up>=0 && (dn>0 || dn==0 && (*pp<*pmd || *neg==0) ) )
|
||||
{
|
||||
{
|
||||
*pos += up+dn;
|
||||
if (*pp>*pmd && (*cap)+(*pos)<=(*cin)+(*neg))
|
||||
; // no net cape and below max delta
|
||||
else if (*pp>*pmd || *cap==0)
|
||||
{ // below max delta or cape uninitialized
|
||||
{ // below max delta or cape uninitialized
|
||||
*cap += *pos;
|
||||
*cin += *neg;
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
else if (*pos>=*neg)
|
||||
{ // cape initialized and net positive contribution
|
||||
{ // cape initialized and net positive contribution
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transition to upward acceleration.
|
||||
else if (up>0 && dn<=0)
|
||||
{
|
||||
{
|
||||
*neg += -dn;
|
||||
if (*pp1<=*pmd)
|
||||
{ // above max delta, only use net pos contribution
|
||||
{ // above max delta, only use net pos contribution
|
||||
*pos += up;
|
||||
if (*pos>=*neg)
|
||||
{
|
||||
{
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*pp<=*pmd)
|
||||
{ // straddle max delta, force cape initialization
|
||||
{ // straddle max delta, force cape initialization
|
||||
if (*cap==0)
|
||||
{
|
||||
{
|
||||
*cin += *neg;
|
||||
*cap += *pos;
|
||||
}
|
||||
}
|
||||
else if (*neg>*pos)
|
||||
*cin += *neg-*pos;
|
||||
else
|
||||
*cap += *pos-*neg;
|
||||
*cap += up;
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
else if ((*cap)+(*pos)+up<=(*cin)+(*neg))
|
||||
{// no net cape to this point
|
||||
{// no net cape to this point
|
||||
if ((*cap)+(*pos)>0)
|
||||
{ // reinitialize if there was cape before
|
||||
{ // reinitialize if there was cape before
|
||||
*cin -= (*cap)+(*pos);
|
||||
*pos = *cap = 0;
|
||||
}
|
||||
}
|
||||
*cin += *neg;
|
||||
*pos += up;
|
||||
*neg = 0;
|
||||
}
|
||||
}
|
||||
else if (*cap==0)
|
||||
{ // initialize cape
|
||||
{ // initialize cape
|
||||
*cap += *pos+up;
|
||||
*cin += *neg;
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // what remains, only use net pos contribution
|
||||
{ // what remains, only use net pos contribution
|
||||
*pos += up;
|
||||
if (*pos>=*neg)
|
||||
{
|
||||
{
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transition to decceleration.
|
||||
else
|
||||
{
|
||||
{
|
||||
*pos += dn;
|
||||
if (*pp1<=*pmd)
|
||||
{ // above max delta, only use net pos contribution
|
||||
{ // above max delta, only use net pos contribution
|
||||
if (*pos>=*neg)
|
||||
{
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
*neg += -up;
|
||||
}
|
||||
}
|
||||
else if ((*cap)+(*pos)<=(*cin)+(*neg)-up)
|
||||
{// no net cape to this point
|
||||
{// no net cape to this point
|
||||
if (*cap>0)
|
||||
{// reinitialize if there was cape before
|
||||
*cin -= (*cap)+(*pos);
|
||||
|
@ -334,30 +381,30 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
}
|
||||
*cin += *neg-up;
|
||||
*pos = *neg = 0;
|
||||
}
|
||||
}
|
||||
else if (*cap==0) // initialize cape
|
||||
{
|
||||
{
|
||||
*cap += *pos;
|
||||
*cin += *neg-up;
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // what remains, only use net pos contribution
|
||||
{ // what remains, only use net pos contribution
|
||||
if (*pos>=*neg)
|
||||
{
|
||||
{
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
*neg += -up;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make current layer top next layer bottom.
|
||||
*tvp1 = *tvp;
|
||||
*pp1 = *pp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unallocate our dynamic storage.
|
||||
free(tec_st);
|
||||
|
@ -367,14 +414,16 @@ void capeFunc(float usetv, const float ** p_dat, const float ** tve_dat,
|
|||
free(pmd_st);
|
||||
free(tvp_st);
|
||||
free(pp1_st);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// In this version we stop the computation at some arbitrary upper level, ptop.
|
||||
void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
||||
int capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
||||
float * p0, float * th0, float * sh0,
|
||||
int mnx, int nx, int ny, int nz,
|
||||
float * cape_dat, float * cin_dat, float * ptop)
|
||||
{
|
||||
{
|
||||
// These pointers point to our dynamic storarge.
|
||||
float *tvp_st, *tec_st, *tvc_st, *pc_st, *pp1_st, *pmd_st, *md_st;
|
||||
tvp_st = tec_st = tvc_st = pc_st = pp1_st = pmd_st = md_st = 0;
|
||||
|
@ -409,30 +458,50 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
qq = sh0;
|
||||
pfin = ptop;
|
||||
tec = tec_st = (float*)malloc(n2*sizeof(float));
|
||||
if (tec == NULL || tec_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
tvc = tvc_st = (float*)malloc(n2*sizeof(float));
|
||||
if (tvc == NULL || tvc_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
pc = pc_st = (float*)malloc(n2*sizeof(float));
|
||||
if (pc == NULL || pc_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
pp1 = pp1_st = (float*)malloc(n2*sizeof(float));
|
||||
if (pp1 == NULL || pp1_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
eptr = pp0+nn;
|
||||
if (dd==0)
|
||||
{
|
||||
i = 0x7FFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = nx;
|
||||
}
|
||||
for (; pp0<eptr; pp0++,pp1++,tt++,qq++,pc++,tec++,tvc++,pfin++)
|
||||
{
|
||||
{
|
||||
*pp1 = *pp0;
|
||||
if (--i<0)
|
||||
{
|
||||
{
|
||||
pfin += dd;
|
||||
pp0 += dd;
|
||||
tt += dd;
|
||||
qq += dd;
|
||||
i = nxm;
|
||||
}
|
||||
}
|
||||
if (*pp0>1e36 || *tt>1e36 || *qq>1e36 || *qq<0.0005 || *pp0<*pfin)
|
||||
{
|
||||
{
|
||||
*tec = *tvc = *pc = 1e37;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
t0 = (*tt)*pow((*pp0)/1000,kapa);
|
||||
b = c0-log( (*pp0)/(622./(*qq) + 0.378) );
|
||||
td = (b-sqrt(b*b-c_1))/c_2;
|
||||
|
@ -440,11 +509,19 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
*pc = (*pp0)*pow(tdc/t0,kapa_1);
|
||||
*tec = adiabatic_te(&tdc,pc);
|
||||
*tvc = td*(1+usetv*0.000608*(*qq));
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize md and pmd, which will be pressure of and max Te delta.
|
||||
md_st = (float*)malloc(n2*sizeof(float));
|
||||
if (md_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
pmd_st = (float*)malloc(n2*sizeof(float));
|
||||
if (pmd_st == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
memset(md_st, 0, n2*sizeof(float));
|
||||
memset(pmd_st, 0, n2*sizeof(float));
|
||||
|
||||
|
@ -455,7 +532,7 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
tvp = tvp_st = (float*)malloc(n3*sizeof(float));
|
||||
nzm = 0;
|
||||
for (k=0; k<nz; k++)
|
||||
{
|
||||
{
|
||||
pp1 = pp1_st;
|
||||
pfin = ptop;
|
||||
pp = p_dat[k];
|
||||
|
@ -467,45 +544,55 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
pmd = pmd_st;
|
||||
eptr = pp+nn;
|
||||
if (dd==0)
|
||||
{
|
||||
i = 0x7FFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = nx;
|
||||
}
|
||||
for (; pp<eptr; pp1++,pp++,pc++,pfin++,tec++,tvc++,
|
||||
tvp++,tve++,md++,pmd++)
|
||||
{
|
||||
{
|
||||
if (--i<0)
|
||||
{
|
||||
{
|
||||
pfin += dd;
|
||||
pp += dd;
|
||||
tve += dd;
|
||||
i = nxm;
|
||||
}
|
||||
}
|
||||
if (*pc>1e36 || *pp>1e36 || *tve>1e36 || *pp1<=*pfin)
|
||||
{
|
||||
{
|
||||
*tvp = 1e37;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*pp1 = *pp;
|
||||
nzm = k;
|
||||
t0 = (*tvc)*pow((*pp)/(*pc),kapa);
|
||||
if (*pp>=*pc)
|
||||
{
|
||||
*tvp = t0;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
td = (*tec)*pow((*pp)/(*pc),kapa);
|
||||
*tvp = td = temp_of_te(&td, pp);
|
||||
if (usetv>0)
|
||||
*tvp *= (*pp)/( *pp-exp(25.687958917-c1*td-c2/td) );
|
||||
}
|
||||
}
|
||||
if (*tve<t0)
|
||||
{
|
||||
*tvp -= t0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tvp -= *tve;
|
||||
}
|
||||
if (*pp>*pc || *pp<*pfin || *tvp<*md) continue;
|
||||
*md = *tvp;
|
||||
*pmd = *pp;
|
||||
}
|
||||
}
|
||||
}
|
||||
nz = nzm+1;
|
||||
|
||||
// This loop performs the actual cape and cin calculation. Here we will
|
||||
|
@ -515,7 +602,7 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
dlnp = 0;
|
||||
tvp = tvp_st;
|
||||
for (k=0; k<nz; k++)
|
||||
{
|
||||
{
|
||||
pp0 = p0;
|
||||
pc = pc_st;
|
||||
pmd = pmd_st;
|
||||
|
@ -529,26 +616,30 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
cin = cin_dat;
|
||||
eptr = pp+nn;
|
||||
if (dd==0)
|
||||
{
|
||||
i = 0x7FFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = nx;
|
||||
}
|
||||
for (; pp<eptr; pp0++,pc++,pmd++,pp1++,pp++,pfin++,tvp1++,tvp++,
|
||||
cap++,cin++,pos++,neg++)
|
||||
{
|
||||
{
|
||||
if (--i<0)
|
||||
{
|
||||
{
|
||||
pp0 += dd;
|
||||
pp += dd;
|
||||
pfin += dd;
|
||||
cap += dd;
|
||||
cin += dd;
|
||||
i = nxm;
|
||||
}
|
||||
}
|
||||
if (k==0)
|
||||
{
|
||||
{
|
||||
*cin = *cap = 1e37;
|
||||
*pos = *neg = 0;
|
||||
}
|
||||
}
|
||||
else if (*pp0>1e36)
|
||||
continue;
|
||||
else if (*pp1>1e36 || *tvp1>1e36)
|
||||
|
@ -558,8 +649,7 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
else if (*pp>=*pp0)
|
||||
;
|
||||
else
|
||||
{
|
||||
|
||||
{
|
||||
// Now we finally have the data we need for calculating
|
||||
// the cape/cin contribution for this layer.
|
||||
if (*cap>1e36) *cap = *cin = 0;
|
||||
|
@ -568,29 +658,29 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
// First deal with possibility of bottom lvl being below the
|
||||
// initial parcel and/or hitting the top of the computation.
|
||||
if (*pp<*pfin)
|
||||
{
|
||||
{
|
||||
b = log((*pp1)/(*pp));
|
||||
dlnp = log((*pp1)/(*pfin));
|
||||
*tvp = *tvp1+(dlnp/b)*(*tvp-*tvp1);
|
||||
}
|
||||
}
|
||||
if (*pp1>*pp0)
|
||||
{
|
||||
{
|
||||
if (*pp<*pfin)
|
||||
dlnp = log((*pp0)/(*pfin));
|
||||
else
|
||||
dlnp = log((*pp0)/(*pp));
|
||||
dn = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if (*pp>=*pfin) dlnp = log((*pp1)/(*pp));
|
||||
dn = dlnp*287*(*tvp1);
|
||||
}
|
||||
}
|
||||
|
||||
// Now deal with the fact that not allowing superadiabatic
|
||||
// layers means no cape below condensation pressure.
|
||||
if (*pp1>=*pc)
|
||||
{
|
||||
{
|
||||
if (dn>0) dn = 0;
|
||||
if (*tvp<=0)
|
||||
up = dlnp*287*(*tvp);
|
||||
|
@ -600,9 +690,11 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
up = log((*pc)/(*pfin))*287*(*tvp);
|
||||
else
|
||||
up = log((*pc)/(*pp))*287*(*tvp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
up = dlnp*287*(*tvp);
|
||||
}
|
||||
|
||||
// Deal with where the break point is.
|
||||
b = up*dn>=0 ? 0.5 : up/(up-dn);
|
||||
|
@ -620,124 +712,128 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
|
||||
// Continuing upward acceleration.
|
||||
else if (up>=0 && (dn>0 || dn==0 && (*pp<*pmd || *neg==0) ) )
|
||||
{
|
||||
{
|
||||
*pos += up+dn;
|
||||
if (*pp>*pmd && (*cap)+(*pos)<=(*cin)+(*neg))
|
||||
; // no net cape and below max delta
|
||||
else if (*pp>*pmd || *cap==0)
|
||||
{ // below max delta or cape uninitialized
|
||||
{ // below max delta or cape uninitialized
|
||||
*cap += *pos;
|
||||
*cin += *neg;
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
else if (*pos>=*neg)
|
||||
{ // cape initialized and net positive contribution
|
||||
{ // cape initialized and net positive contribution
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transition to upward acceleration.
|
||||
else if (up>0 && dn<=0)
|
||||
{
|
||||
{
|
||||
*neg += -dn;
|
||||
if (*pp1<=*pmd)
|
||||
{ // above max delta, only use net pos contribution
|
||||
{ // above max delta, only use net pos contribution
|
||||
*pos += up;
|
||||
if (*pos>=*neg)
|
||||
{
|
||||
{
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*pp<=*pmd)
|
||||
{ // straddle max delta, force cape initialization
|
||||
{ // straddle max delta, force cape initialization
|
||||
if (*cap==0)
|
||||
{
|
||||
{
|
||||
*cin += *neg;
|
||||
*cap += *pos;
|
||||
}
|
||||
}
|
||||
else if (*neg>*pos)
|
||||
{
|
||||
*cin += *neg-*pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
*cap += *pos-*neg;
|
||||
}
|
||||
*cap += up;
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
else if ((*cap)+(*pos)+up<=(*cin)+(*neg))
|
||||
{// no net cape to this point
|
||||
{// no net cape to this point
|
||||
if ((*cap)+(*pos)>0)
|
||||
{ // reinitialize if there was cape before
|
||||
{ // reinitialize if there was cape before
|
||||
*cin -= (*cap)+(*pos);
|
||||
*pos = *cap = 0;
|
||||
}
|
||||
}
|
||||
*cin += *neg;
|
||||
*pos += up;
|
||||
*neg = 0;
|
||||
}
|
||||
}
|
||||
else if (*cap==0)
|
||||
{ // initialize cape
|
||||
{ // initialize cape
|
||||
*cap += *pos+up;
|
||||
*cin += *neg;
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // what remains, only use net pos contribution
|
||||
{ // what remains, only use net pos contribution
|
||||
*pos += up;
|
||||
if (*pos>=*neg)
|
||||
{
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transition to decceleration.
|
||||
else
|
||||
{
|
||||
*pos += dn;
|
||||
if (*pp1<=*pmd)
|
||||
{ // above max delta, only use net pos contribution
|
||||
if (*pos>=*neg)
|
||||
{
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
*neg += -up;
|
||||
}
|
||||
else if ((*cap)+(*pos)<=(*cin)+(*neg)-up)
|
||||
{// no net cape to this point
|
||||
if (*cap>0)
|
||||
{// reinitialize if there was cape before
|
||||
*cin -= (*cap)+(*pos);
|
||||
*pos = *cap = 0;
|
||||
}
|
||||
*cin += *neg-up;
|
||||
*pos = *neg = 0;
|
||||
}
|
||||
else if (*cap==0) // initialize cape
|
||||
{
|
||||
*cap += *pos;
|
||||
*cin += *neg-up;
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
else
|
||||
{ // what remains, only use net pos contribution
|
||||
if (*pos>=*neg)
|
||||
{
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
*neg += -up;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transition to decceleration.
|
||||
else
|
||||
{
|
||||
*pos += dn;
|
||||
if (*pp1<=*pmd)
|
||||
{ // above max delta, only use net pos contribution
|
||||
if (*pos>=*neg)
|
||||
{
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
*neg += -up;
|
||||
}
|
||||
else if ((*cap)+(*pos)<=(*cin)+(*neg)-up)
|
||||
{// no net cape to this point
|
||||
if (*cap>0)
|
||||
{// reinitialize if there was cape before
|
||||
*cin -= (*cap)+(*pos);
|
||||
*pos = *cap = 0;
|
||||
}
|
||||
*cin += *neg-up;
|
||||
*pos = *neg = 0;
|
||||
}
|
||||
else if (*cap==0) // initialize cape
|
||||
{
|
||||
*cap += *pos;
|
||||
*cin += *neg-up;
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
else
|
||||
{ // what remains, only use net pos contribution
|
||||
if (*pos>=*neg)
|
||||
{
|
||||
*cap += (*pos-*neg);
|
||||
*neg = *pos = 0;
|
||||
}
|
||||
*neg += -up;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make current layer top next layer bottom.
|
||||
*tvp1 = *tvp;
|
||||
*pp1 = *pp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unallocate our dynamic storage.
|
||||
free(tec_st);
|
||||
|
@ -748,5 +844,6 @@ void capeFuncTop(float usetv, float ** p_dat, float ** tve_dat,
|
|||
free(pmd_st);
|
||||
free(tvp_st);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue