Beispiel #1
0
static void mdlOutputs(SimStruct *S, int_T tid)
{
    /*--------Define Parameters-------*/
    const real_T NcDes              = *mxGetPr(NcDes_p(S));
    const real_T PRDes              = *mxGetPr(PRDes_p(S));
    const real_T EffDes             = *mxGetPr(EffDes_p(S));
    const real_T RlineDes           = *mxGetPr(RlineDes_p(S));
    const real_T IDes               = *mxGetPr(IDesign_p(S));
    const real_T CustBldEn          = *mxGetPr(CustBldEn_p(S));
    const real_T FBldEn             = *mxGetPr(FBldEn_p(S));
    const real_T CustBldNm          = *mxGetPr(CustBldNm_p(S));
    const real_T FracBldNm          = *mxGetPr(FracBldNm_p(S));
    
    /* vector & array data */
    const real_T *Y_C_Map_NcVec        = mxGetPr(Y_C_Map_NcVec_p(S));
    const real_T *X_C_RlineVec         = mxGetPr(X_C_RlineVec_p(S));
    const real_T *Z_C_AlphaVec         = mxGetPr(Z_C_AlphaVec_p(S));
    const real_T *T_C_Map_WcArray      = mxGetPr(T_C_Map_WcArray_p(S));
    const real_T *T_C_Map_PRArray      = mxGetPr(T_C_Map_PRArray_p(S));
    const real_T *T_C_Map_EffArray     = mxGetPr(T_C_Map_EffArray_p(S));
    
    const real_T *FracCusBldht         = mxGetPr(FracCusBldht_p(S));
    const real_T *FracCusBldPt         = mxGetPr(FracCusBldPt_p(S));
    const real_T *FracBldht            = mxGetPr(FracBldht_p(S));
    const real_T *FracBldPt            = mxGetPr(FracBldPt_p(S));
    
    const real_T *X_C_Map_WcSurgeVec   = mxGetPr(X_C_Map_WcSurgeVec_p(S));
    const real_T *T_C_Map_PRSurgeVec   = mxGetPr(T_C_Map_PRSurgeVec_p(S));
    
    /*------get dimensions of parameter arrays-------*/
    const int_T A   = mxGetNumberOfElements(Y_C_Map_NcVec_p(S));
    const int_T B   = mxGetNumberOfElements(X_C_RlineVec_p(S));
    const int_T C   = mxGetNumberOfElements(Z_C_AlphaVec_p(S));
    const int_T D   = mxGetNumberOfElements(X_C_Map_WcSurgeVec_p(S));
    
    const int_T WcMapCol  = *mxGetPr(WcMapCol_p(S));
    const int_T PRMapCol  = *mxGetPr(PRMapCol_p(S));
    const int_T EffMapCol = *mxGetPr(EffMapCol_p(S));
    const int_T WcMapRw   = *mxGetPr(WcMapRw_p(S));
    const int_T PRMapRw   = *mxGetPr(PRMapRw_p(S));
    const int_T EffMapRw  = *mxGetPr(EffMapRw_p(S));
    const int_T WcMapLay   = *mxGetPr(WcMapLay_p(S));
    const int_T PRMapLay   = *mxGetPr(PRMapLay_p(S));
    const int_T EffMapLay  = *mxGetPr(EffMapLay_p(S));
    
    /*---------Define Inputs for input port 1--------*/
    const real_T *u  = (const real_T*) ssGetInputPortSignal(S,0);
    
    double WIn      = u[0];     /* Input Flow [pps] 	*/
    double htIn     = u[1];     /* Input Enthalpy [BTU/lbm] */
    double TtIn     = u[2];     /* Temperature Input [degR] 	*/
    double PtIn     = u[3];     /* Pressure Input [psia] 	*/
    double FARcIn   = u[4];     /* Combusted Fuel to Air Ratio [frac] 	*/
    double Nmech    = u[5];     /* Mechancial Shaft Speed [rpm] 	*/
    double Rline    = u[6];     /* Rline [NA]  */
    double Alpha    = u[7];     /* Alpha [NA]  */
    double s_C_Nc   = u[8];     /* Nc map scalar [NA]  */
    double s_C_Wc   = u[9];     /* Wc map scalar [NA] */
    double s_C_PR   = u[10];     /* PR map scalar [NA]  */
    double s_C_Eff  = u[11];    /* Eff map scalar [NA]  */
    
    /*---------Define Inputs for input port 2--------*/
    const real_T *Wcust = ssGetInputPortRealSignal(S, 1);
    int uWidth1 = CustBldNm;
    
    /*---------Define Inputs for input port 3--------*/
    const real_T *FracWbld  = ssGetInputPortSignal(S,2);
    int uWidth2 = FracBldNm;
    
    real_T *y  = (real_T *)ssGetOutputPortRealSignal(S,0);   /* Output Array port 1 */
    real_T *y1  = (real_T *)ssGetOutputPortRealSignal(S,1);   /* Output Array port 2 */
    real_T *y2  = (real_T *)ssGetOutputPortRealSignal(S,2);   /* Output Array port 3 */
    
    /*--------Define Constants-------*/
    double WOut, htOut, TtOut, PtOut, FARcOut, TorqueOut, NErrorOut;
    double C_Nc, C_Wc, C_PR, C_Eff;
    double htin, Sin, Wcin, WcCalcin, WcMap, theta,delta, Pwrout, Wbleeds, Wsumbleed;
    double TtIdealout, htIdealout, Test, Sout, NcMap, Nc, PRMap, PR, EffMap, Eff;
    double Wb4bleed, Pwrb4bleed, PwrBld;
    double SPR, SPRMap, SMavail, SMMap;
    
    /* Define Arrays for bleed calcs */
    int MaxNumberBleeds = 100;
    double WcustOut[500];
    double PtcustOut[500];
    double TtcustOut[500];
    double FARcustOut[500];
    double WbldOut[500];
    double FARbldOut[500];
    double PtbldOut[500];
    double TtbldOut[500];
    double htbldOut[500];
    double htcustOut[500];
    
    double SMWcVec[500];
    double SMPRVec[500];
    
    int interpErr = 0;
    int i;
    
    /* ------- get strings -------------- */
    char * BlkNm;
    int_T buflen;
    int_T status;
    
    /* Get name of block from dialog parameter (string) */
    buflen = mxGetN(BN_p(S))*sizeof(mxChar)+1;
    BlkNm = mxMalloc(buflen);
    status = mxGetString(BN_p(S), BlkNm, buflen);
    
    
    /*-- Compute output Fuel to Air Ratio ---*/
    FARcOut = FARcIn;
    
    /*-- Compute Input enthalpy --------*/
    
    htin = t2hc(TtIn,FARcIn);
    
    /*-- Compute Input entropy  --------*/
    
    Sin = pt2sc(PtIn,TtIn,FARcIn);
    
    /*---- calculate misc. fluid condition related variables and corrected Flow --*/
    delta = PtIn / C_PSTD;
    theta = TtIn / C_TSTD;
    Wcin = WIn*sqrtT(theta)*divby(delta);
    
    /*------ Calculate corrected speed ---------*/
    Nc = Nmech*divby(sqrtT(theta));
    if (IDes < 0.5)
        C_Nc = Nc *divby(NcDes) ;
    else
        C_Nc = s_C_Nc;
    
    NcMap = Nc *divby(C_Nc);
    
    /*-- Compute Total Flow input (from Compressor map)  --------*/
    if(C > 1)
        WcMap = interp3Ac(X_C_RlineVec,Y_C_Map_NcVec,Z_C_AlphaVec,T_C_Map_WcArray,Rline,NcMap,Alpha,B,A,C,&interpErr);
    else
        WcMap = interp2Ac(X_C_RlineVec,Y_C_Map_NcVec,T_C_Map_WcArray,Rline,NcMap,B,A,&interpErr);
        
    if ((WcMapCol != B || WcMapRw != A || WcMapLay !=C) && ssGetIWork(S)[Er1]==0){
        printf("Warning in %s, Error calculating WcMap. Table size does not match axis vector lengths.\n", BlkNm);
        ssSetIWorkValue(S,Er1,1);
    }
    else if (interpErr == 1 && ssGetIWork(S)[Er1]==0){
        printf("Warning in %s, Error calculating WcMap. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,Er1,1);
    }
    
    if (IDes < 0.5)
        C_Wc = Wcin*divby(WcMap);
    else
        C_Wc = s_C_Wc;
    
    WcCalcin = WcMap * C_Wc;
    
    /*-- Compute Pressure Ratio (from Compressor map)  --------*/
    if(C > 1)
        PRMap = interp3Ac(X_C_RlineVec,Y_C_Map_NcVec,Z_C_AlphaVec,T_C_Map_PRArray,Rline,NcMap,Alpha,B,A,C,&interpErr);
    else
        PRMap = interp2Ac(X_C_RlineVec,Y_C_Map_NcVec,T_C_Map_PRArray,Rline,NcMap,B,A,&interpErr);
    
    if ((PRMapCol != B || PRMapRw != A || PRMapLay !=C) && ssGetIWork(S)[Er2]==0){
        printf("Warning in %s, Error calculating PRMap. Table size does not match axis vector lengths.\n", BlkNm);
        ssSetIWorkValue(S,Er2,1);
    }
    else if (interpErr == 1 && ssGetIWork(S)[Er2]==0){
        printf("Warning in %s, Error calculating PRMap. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,Er2,1);
    }
    
    if (IDes < 0.5)
        C_PR = (PRDes -1)*divby(PRMap-1);
    else
        C_PR = s_C_PR;
    
    PR = C_PR*(PRMap - 1) + 1 ;
    
    /*-- Compute Efficiency (from Compressor map) ---*/
    if(C > 1)
        EffMap = interp3Ac(X_C_RlineVec,Y_C_Map_NcVec,Z_C_AlphaVec,T_C_Map_EffArray,Rline,NcMap,Alpha,B,A,C,&interpErr);
    else
        EffMap = interp2Ac(X_C_RlineVec,Y_C_Map_NcVec,T_C_Map_EffArray,Rline,NcMap,B,A,&interpErr);
    
    if ((EffMapCol != B || EffMapRw != A || EffMapLay !=C) && ssGetIWork(S)[Er3]==0){
        printf("Warning in %s, Error calculating EffMap. Table size does not match axis vector lengths.\n", BlkNm);
        ssSetIWorkValue(S,Er3,1);
    }
    else if (interpErr == 1 && ssGetIWork(S)[Er3]==0){
        printf("Warning in %s, Error calculating EffMap. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,Er3,1);
    }
    
    if (IDes < 0.5)
        C_Eff = EffDes*divby(EffMap);
    else
        C_Eff = s_C_Eff;
    
    Eff = EffMap * C_Eff;
    
    /*------ Compute pressure output --------*/
    
    PtOut = PtIn*PR;
    
    
    /*------ enthalpy calculations ---------*/
    
    /* ---- Ideal enthalpy ----*/
    Sout = Sin;
    TtIdealout = sp2tc(Sout,PtOut,FARcIn);
    htIdealout = t2hc(TtIdealout,FARcIn);
    
    
    /* ---- Final enthalpy output ----*/
    
    htOut = ((htIdealout - htin)*divby(Eff)) + htin;
    
    /*------ Compute Temperature output ---------*/
    
    TtOut = h2tc(htOut,FARcIn);
    
    
    /* initalize Bleed sums components */
    Wbleeds = 0;
    PwrBld = 0;
    
    /* compute customer Bleed components */
    for (i = 0; i < uWidth1; i++)
    {
        /* if customer bleed = 0 or Cust bld is not enabled set outputs to zero */
        if (Wcust[i] == 0 || CustBldEn < 0.5){
            WcustOut[i] = 0;
            htcustOut[i] = 0;
            TtcustOut[i] = 0;
            PtcustOut[i] = 0;
            FARcustOut[i] = 0;
        }
        else {
            /*-- Compute sum of customer Bleed Flow output  --------*/
            Wbleeds = Wbleeds + Wcust[i]; /* add to total bleed value */
            WcustOut[i] = Wcust[i];
            FARcustOut[i] = FARcIn;
            htcustOut[i] = htin + FracCusBldht[i]*(htOut - htin); /* calculate customer bleed enthalpy */
            PtcustOut[i] = PtIn + FracCusBldPt[i]*(PtOut -PtIn); /* calculate customer bleed Total Pressure */
            TtcustOut[i] = h2tc(htcustOut[i],FARcustOut[i]); /* calculate customer bleed Total Temp */
            PwrBld = PwrBld + WcustOut[i]*(htcustOut[i]-htOut)*C_BTU_PER_SECtoHP;  /* calculate customer bleed power */
        }
        if (i > 4*MaxNumberBleeds && ssGetIWork(S)[Er4]==0){
            printf("Error in %s, Number of bleeds in compressor exceeds 100... Array overflow! Reading Bad Data\n", BlkNm);
            ssSetIWorkValue(S,Er4,1);
        }
    }
    
    /*----Disable Fractional bleed when requested----*/
    
    for (i = 0; i < uWidth2; i++)
    {
        if (FracWbld[i] <= 0 || FBldEn < 0.5 ){
            WbldOut[i] = 0;
            htbldOut[i] = 0;
            FARbldOut[i] = 0;
            TtbldOut[i] = 0;
            PtbldOut[i] = 0;
        }
        
        else {
            /*-- Compute sum of Fractional Bleed Flow output  --------*/
            Wbleeds = Wbleeds + FracWbld[i]*WIn; /* add to total bleed value */
            WbldOut[i] = FracWbld[i]*WIn;
            FARbldOut[i] = FARcIn;
            PtbldOut[i] = PtIn + FracBldPt[i]*(PtOut -PtIn); /* calculate  bleed Total Pressure */
            htbldOut[i] = htin + FracBldht[i]*(htOut - htin); /* calculate  bleed enthalpy */
            TtbldOut[i] = h2tc(htbldOut[i],FARbldOut[i]); /* calculate  bleed Total Temp */
            PwrBld = PwrBld + WbldOut[i]*(htbldOut[i]-htOut)*C_BTU_PER_SECtoHP;  /* calculate bleed power */
        }
        if (i > 4*MaxNumberBleeds && ssGetIWork(S)[Er4]==0){
            printf("Error in %s, Number of bleeds in compressor exceeds 100... Array overflow! Reading Bad Data\n", BlkNm);
            ssSetIWorkValue(S,Er4,1);
        }
    }
    
    /*-- Compute Flows  --------*/
    Wb4bleed = WIn;
    WOut = WIn - Wbleeds;
    
    /*------ Compute Powers ---------*/
    
    Pwrb4bleed = Wb4bleed * (htin - htOut) * C_BTU_PER_SECtoHP;
    Pwrout = Pwrb4bleed - PwrBld;
    
    /*----- Compute output Torque to shaft ----*/
    TorqueOut = C_HP_PER_RPMtoFT_LBF * Pwrout*divby(Nmech);
    
    /* ----- Compute Normalized Flow Error ----- */
    if (IDes < 0.5 && Rline == 0)
        NErrorOut = 100;
    else if (IDes < 0.5)
        NErrorOut = (Rline - RlineDes)*divby(Rline);
    else if (WIn == 0)
        NErrorOut = 100;
    else
        NErrorOut = (Wcin - WcCalcin)*divby(Wcin);
    
    /* Compute Stall Margin */
    if (C > 1){
        /* Define 1-D surge margin vectors based on alpha */
        for (i = 0; i < D/C; i++){
            SMWcVec[i] = interp1Ac(Z_C_AlphaVec, X_C_Map_WcSurgeVec + C*i, Alpha,C, &interpErr);
            if (interpErr == 1 && ssGetIWork(S)[Er5]==0){
                printf("Warning in %s, Error calculating 1D SMWcVec. Vector definitions may need to be adjusted.\n", BlkNm);
                ssSetIWorkValue(S,Er5,1);
            }
            SMPRVec[i] = interp1Ac(Z_C_AlphaVec, T_C_Map_PRSurgeVec + C*i, Alpha,C, &interpErr);
            if (interpErr == 1 && ssGetIWork(S)[Er5]==0){
                printf("Warning in %s, Error calculating 1D SMPRVec. Vector definitions may need to be adjusted.\n", BlkNm);
                ssSetIWorkValue(S,Er5,1);
            }
        }
        SPRMap = interp1Ac(SMWcVec, SMPRVec,WcMap,A,&interpErr);
        if (interpErr == 1 && ssGetIWork(S)[Er5]==0){
            printf("Warning in %s, Error calculating 2D SPR. Vector definitions may need to be adjusted.\n", BlkNm);
            ssSetIWorkValue(S,Er5,1);
        }
    }
    else
        SPRMap = interp1Ac(X_C_Map_WcSurgeVec,T_C_Map_PRSurgeVec,WcMap,D,&interpErr);
    
    if (interpErr == 1 && ssGetIWork(S)[Er5]==0){
        printf("Warning in %s, Error calculating SPR. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,Er5,1);
    }
    SPR = C_PR*(SPRMap - 1) + 1;
    SMavail = (SPR - PR)*divby(PR) * 100;
    SMMap = (SPRMap - PRMap)*divby(PRMap) * 100;
    
    /* Test variable */
    Test = SPRMap;
    
    /*------Assign output values port1------------*/
    y[0] = WOut;            /* Outlet Total Flow [pps]	*/
    y[1] = htOut;           /* Output Enthalpy [BTU/lbm]	*/
    y[2] = TtOut;           /* Outlet Temperature [degR]	*/
    y[3] = PtOut;           /* Outlet Pressure [psia] 	*/
    y[4] = FARcOut;         /* Exit Combusted Fuel Flow [frac] */
    y[5] = TorqueOut;       /* Outlet Torque [lbf*ft]	*/
    y[6] = NErrorOut;       /* Normalized compressor Error [frac]*/
    y[7] = SMavail;         /* Available Stall Margin [%] */
    y[8] = C_Nc;            /* Corrected shaft speed scalar */
    y[9] = C_Wc;            /* Corrected flow scalar */
    y[10] = C_PR;           /* Pressure Ratio scalar */
    y[11] = C_Eff;          /* Efficiency scalar */
    y[12] = Wcin;           /* Corrected input flow [pps] */
    y[13] = Nc;             /* Corrected speed [rpm]*/
    y[14] = PR;             /* Pressure ratio */
    y[15] = NcMap;          /* Map corrected speed */
    y[16] = WcMap;          /* Map corrected flow */
    y[17] = PRMap;          /* Map pressure ratio */
    y[18] = EffMap;         /* Map efficiency */
    y[19] = SPR;            /* Surge pressure ratio */
    y[20] = Wbleeds;        /* Bleed flow [pps]*/
    y[21] = Pwrb4bleed;     /* Power if there was no bleed [hp]*/
    y[22] = PwrBld;         /* Power loss due to bleed [hp] */
    y[23] = Pwrout;         /* Output power [hp]*/
    y[24] = SMMap;          /* Stall margin calculated from map values [%]*/
    y[25] = SPRMap;         /* Map stall pressure ratio*/
    y[26] = Test;           /* test signal */
    
    /*------Assign output values port2------------*/
    /* Customer or flow based bleed*/
    for (i = 0; i < uWidth1; i++)
    {
        *y1++ = WcustOut[i];
        *y1++ = htcustOut[i];
        *y1++ = TtcustOut[i];
        *y1++ = PtcustOut[i];
        *y1++ = FARcustOut[i];
    }
    
    /*------Assign output values port3------------*/
    /* fractional bleed, typically used for turbine cooling flow */
    for (i = 0; i < uWidth2; i++)
    {
        *y2++ = WbldOut[i];
        *y2++ = htbldOut[i];
        *y2++ = TtbldOut[i];
        *y2++ = PtbldOut[i];
        *y2++ = FARbldOut[i];
    }
    
}
Beispiel #2
0
/*------ the following code uses secant method to calc static pressure ----*/
double calc_Pstatic(double PtOut, double TtOut, double Wout, double Aexit, double *FAR_vec, double *Rt_vec, double *Tt_vec, double *gamma_array, double FAR, int A1, int B1)
{
    double Rt, gammat, tolerance;
    double x1, x2, x3, y1, y2, y3, z1, z2, z3, e1, e2, e3;
    int maxIters, ncount;
    int interpErr = 0;
    
    /*---   where gas constant is R = f(FAR), but NOT P & T ----*/
    Rt = interp1Ac(FAR_vec,Rt_vec,FAR,A1, &interpErr);             /* with FAR = 0 */
        if (interpErr == 1){
        printf("Warning in calc_Pstatic subroutine, Error calculating Rt. Vector definitions may need to be expanded.\n");
    }
    /*---- gamma depends on FAR and temp -----*/
    gammat = interp2Ac(FAR_vec,Tt_vec,gamma_array,FAR,TtOut,A1,B1, &interpErr);   /* with FAR = 0 */
            if (interpErr == 1){
        printf("Warning in calc_Pstatic subroutine, Error calculating gammat. Vector definitions may need to be expanded.\n");
    }
    
    /*------ iterate on Mach number until get computed flow = W ----*/
    tolerance = 0.02;     /* flow tolerance (pps) */
    maxIters = 10;
    
    /*----- use these 2 points to start the solution ----*/
    /*   where x ==> MN, y ==> W, and z ==> Ps */
    x1 = 0.2; 
    x2 = 0.5;
    
    y1 = calc_WvsMN(x1,PtOut,TtOut,Rt,gammat,Aexit); /* with FAR = 0 */
    z1 = calc_PsvsMN(x1,PtOut,gammat);
    y2 = calc_WvsMN(x2,PtOut,TtOut,Rt,gammat,Aexit); /* with FAR = 0 */
    z2 = calc_PsvsMN(x2,PtOut,gammat);
    
    e1 = Wout - y1;
    e2 = Wout - y2;
    e3 = 999;       /* force it into the while loop */
    
    ncount = 0;
    /*---- iterate x until the error is within tolerance ----*/
    while ((fabs(e3) > tolerance) && (ncount < maxIters)) {
        if (x2 - (e2*(x2-x1)*divby(e2-e1)) > 0.01)
            x3 = x2 - (e2*(x2-x1)*divby(e2-e1));
        else
            x3 = 0.01;
        
        /*----- compute y3 value (W) for new x3 (MN) ----- */
        /*       also compute z3 value (Ps) for new x3 */
        y3 = calc_WvsMN(x3,PtOut,TtOut,Rt,gammat,Aexit); /* with FAR = 0 */
        z3 = calc_PsvsMN(x3,PtOut,gammat);
        
        /*------ calculate the new error -----*/
        e3 = Wout - y3;
        /*---- want to keep solution bounded for next iteration ---*/
        if (e1*e3 <= 0) {    /* solution lies between x1 and x3, or at x3 */
            x2 = x3;
            y2 = y3;
            e2 = e3;
        }
        else {            /* solution lies between x2 and x3 */
            x1 = x3;
            y1 = y3;
            e1 = e3;
        }
        ncount++;
    }

    return z3;
}
Beispiel #3
0
static void mdlOutputs(SimStruct *S, int_T tid)
{

    /*--------parameters defined in S-function block--------*/
    const real_T AthroatIn              = *mxGetPr(AthroatIn_p(S)); /* input throat area (sq-in) */
    const real_T MNIn                   = *mxGetPr(MNIn_p(S));      /* input throat area (sq-in) */
    const int_T SolveType               = *mxGetPr(SolveType_p(S));  /* 0-solve based on Ath, 1-solve based on MNIn*/

    /*-------- vector & array data -------*/
    const real_T *X_FARVec            = mxGetPr(X_FARVec_p(S));
    const real_T *T_RtArray           = mxGetPr(T_RtArray_p(S));
    const real_T *Y_TtVec             = mxGetPr(Y_TtVec_p(S));
    const real_T *T_gammaArray    = mxGetPr(T_gammaArray_p(S));


    /*------get dimensions of parameter arrays-------*/
    const int_T A   = mxGetNumberOfElements(X_FARVec_p(S));
    const int_T B   = mxGetNumberOfElements(Y_TtVec_p(S));

    /*---------Define Inputs--------*/
    const real_T *u  = (const real_T*) ssGetInputPortSignal(S,0);

    double WIn      = u[0];     /* Input Flow [pps] 	*/
    double htIn     = u[1];     /* enthaply [BTU/lbm] 	*/
    double TtIn     = u[2];     /* Temperature Input [degR] 	*/
    double PtIn     = u[3];     /* Pressure Input [psia] 	*/
    double FARcIn   = u[4];     /* Combusted Fuel to Air Ratio [frac] 	*/

    real_T *y  = (real_T *)ssGetOutputPortRealSignal(S,0);  /* Output Array */

    /*--------Define Constants-------*/
    double PsOut, TsOut, rhosOut, MNOut, AthOut;
    double Sin, htin;
    double Rt, Rs;
    double TsMNg, PsMNg, MNg;
    double Tsg, Psg, Psg_new, Psg_old, Acalc, erA, erA_old;
    double  gammatg, gammasg, hsg, rhosg, Vg;
    double erMN_old, erMN, PsMNg_old, PsMNg_new;
    double erthr;
    int maxiter, iter;
    int interpErr = 0;

    /* ------- get strings -------------- */
    char * BlkNm;
    int_T buflen;
    int_T status;

    /* Get name of block from dialog parameter (string) */
    buflen = mxGetN(BN_p(S))*sizeof(mxChar)+1;
    BlkNm = mxMalloc(buflen);
    status = mxGetString(BN_p(S), BlkNm, buflen);

    /* Calc entropy */
    Sin = pt2sc(PtIn, TtIn, FARcIn);

    /*-- Compute Input enthalpy --------*/

    htin = t2hc(TtIn,FARcIn);

    /*  Where gas constant is R = f(FAR), but NOT P & T */
    Rt = interp1Ac(X_FARVec,T_RtArray,FARcIn,A,&interpErr);
    if (interpErr == 1 && ssGetIWork(S)[0]==0){
        printf("Warning in %s, Error calculating Rt. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,0,1);
    }
    Rs = Rt;

    /* Solve for Ts and Ps when MN is known*/
    if (SolveType == 1) {
        /*---- set MN = MNIn and calc SS Ps for iteration IC --------*/
        MNg = MNIn;
        gammatg = interp2Ac(X_FARVec,Y_TtVec,T_gammaArray,FARcIn,TtIn,A,B,&interpErr);
        if (interpErr == 1 && ssGetIWork(S)[1]==0){
            printf("Warning in %s, Error calculating gammatg. Vector definitions may need to be expanded.\n", BlkNm);
            ssSetIWorkValue(S,1,1);
        }
        TsMNg = TtIn /(1+MNg*MNg*(gammatg-1)/2);
        PsMNg = PtIn*pow((TsMNg/TtIn),(gammatg/(gammatg-1)));

        PcalcStat(PtIn, PsMNg, TtIn, htin, FARcIn, Rt, &Sin, &TsMNg, &hsg, &rhosg, &Vg);
        gammasg = interp2Ac(X_FARVec,Y_TtVec,T_gammaArray,FARcIn,TsMNg,A,B,&interpErr);
        if (interpErr == 1 && ssGetIWork(S)[2]==0){
            printf("Warning in %s, Error calculating gammasg. Vector definitions may need to be expanded.\n", BlkNm);
            ssSetIWorkValue(S,2,1);
        }
        MNg = Vg/sqrt(gammasg*Rs*TsMNg*C_GRAVITY*JOULES_CONST);

        if (Vg > 0.0001){
            Acalc = WIn/(Vg * rhosg/C_SINtoSFT);}
        else {
            Acalc = 999; /* if velocity is close to zero assume a very large Ath */}

        erMN = MNIn - MNg;
        PsMNg_new = PsMNg + 0.05;
        maxiter = 15;
        iter = 0;
        erthr = 0.0001;

        /* if Ps is not close enough to Ps at MN = MNIn, iterate to find Ps at MN = MNIn */
        while (fabs(erMN) > erthr && iter < maxiter) {
            erMN_old = erMN;
            PsMNg_old = PsMNg;
            if(fabs(PsMNg - PsMNg_new) < 0.003)
                PsMNg = PsMNg + 0.005;
            else
                PsMNg = PsMNg_new;
            PcalcStat(PtIn, PsMNg, TtIn, htin, FARcIn, Rt, &Sin, &TsMNg, &hsg, &rhosg, &Vg);
            gammasg = interp2Ac(X_FARVec,Y_TtVec,T_gammaArray,FARcIn,TsMNg,A,B,&interpErr);
            if (interpErr == 1 && ssGetIWork(S)[3]==0){
                printf("Warning in %s, Error calculating iteration gammasg. Vector definitions may need to be expanded.\n", BlkNm);
                ssSetIWorkValue(S,3,1);
            }
            MNg = Vg/sqrt(gammasg*Rs*TsMNg*C_GRAVITY*JOULES_CONST);
            /* calculated Area */
            if (Vg > 0.0001){
                Acalc = WIn/(Vg * rhosg/C_SINtoSFT);}
            else {
                Acalc = 999; /* if velocity is close to zero assume a very large Ath */}

            erMN = MNIn - MNg;
            if (fabs(erMN) > erthr) {
                /* determine next guess pressure by secant algorithm */
                PsMNg_new = PsMNg - erMN *(PsMNg - PsMNg_old)/(erMN - erMN_old);
            }
            iter = iter + 1;
        }
        if (iter == maxiter && ssGetIWork(S)[4]==0 ){
            printf("Warning in %s, Error calculating Ps at MN = MNIn. There may be error in block outputs\n", BlkNm);
            ssSetIWorkValue(S,4,1);
        }
        TsOut = TsMNg;
        PsOut = PsMNg;
        rhosOut = rhosg;
        MNOut = MNIn;
        AthOut = Acalc;
    }
    /* Solve for Ts and Ps when Ath is known*/
    else if (SolveType == 0) {

        /* guess Psout and calculate an initial Area error */
        MNg = 0.4;
        gammatg = 1.4;
        Tsg = TtIn /(1+MNg*MNg*(gammatg-1)/2);
        Psg = PtIn*pow((Tsg/TtIn),(gammatg/(gammatg-1)));
        PcalcStat(PtIn, Psg, TtIn, htin, FARcIn, Rt, &Sin, &Tsg, &hsg, &rhosg, &Vg);
        Acalc = WIn/(Vg * rhosg/C_SINtoSFT);
        MNg = Vg/sqrt(gammasg*Rs*Tsg*C_GRAVITY*JOULES_CONST);

        /* determine guess error for static pressure iteration */
        erA = (AthroatIn - Acalc)/AthroatIn;

        /* determine iteration constants */
        iter = 0;
        maxiter = 1000;
        Psg_new = Psg + 0.05;
        erthr = 0.0001;

        while ( fabs(erA) > erthr && iter < maxiter){
            erA_old = erA;
            Psg_old = Psg;
            if(fabs(Psg - Psg_new) < 0.0003) {
                Psg = Psg + 0.0005;
            }
            else {
                Psg = Psg_new;
            }
            /* calculate flow velocity and rhos */
            PcalcStat(PtIn, Psg, TtIn, htin, FARcIn, Rt, &Sin, &Tsg, &hsg, &rhosg, &Vg);

            gammasg = interp2Ac(X_FARVec,Y_TtVec,T_gammaArray,FARcIn,Tsg,A,B,&interpErr);
            if (interpErr == 1 && ssGetIWork(S)[3]==0){
                printf("Warning in %s, Error calculating iteration gammasg. Vector definitions may need to be expanded.\n", BlkNm);
                ssSetIWorkValue(S,3,1);
            }

            MNg = Vg/sqrt(gammasg*Rs*Tsg*C_GRAVITY*JOULES_CONST);

            if (Vg > 0.0001) {
                /* calculated Area */
                Acalc = WIn/(Vg * rhosg/C_SINtoSFT);
                /*determine error */
                erA = (AthroatIn - Acalc)/AthroatIn;
            }
            else {
                erA = 0;
                Psg = PtIn;
                Tsg = TtIn;
                Acalc = 999;
            }
            if (fabs(erA) > erthr) {
                /* determine next guess pressure by secant algorithm */
                Psg_new = Psg - erA *(Psg - Psg_old)/(erA - erA_old);
                /* limit algorthim change */
                if (Psg_new > 1.001*Psg) {
                    Psg_new = 1.002 * Psg;
                }
                else if (Psg_new < 0.999 * Psg) {
                    Psg_new = 0.998 * Psg;
                }
            }
            iter = iter + 1;
        }
        TsOut = Tsg;
        PsOut = Psg;
        rhosOut = rhosg;
        MNOut = MNg;
        AthOut = Acalc;
    }
    else {
        if (ssGetIWork(S)[5]==0 ){
            printf("Warning in %s, SolveType_M is not valid. There may be error in block outputs\n", BlkNm);
            ssSetIWorkValue(S,5,1);
        }
        TsOut = TtIn;
        PsOut = PtIn;
        rhosOut = 1;
        MNOut = 0;
        AthOut = 100;
    }


    /*------Assign output values------------*/
    y[0] = TsOut;      /* static Temperature [degR] */
    y[1] = PsOut;      /* static Pressure [psia] */
    y[2] = rhosOut;    /* static rho [lbm/ft3]*/
    y[3] = MNOut;      /* mach number [frac]*/
    y[4] = AthOut;     /* throat area [in^2] */

}
Beispiel #4
0
static void mdlOutputs(SimStruct *S, int_T tid)
{
    /*--------parameters defined in S-function block--------*/
    const real_T AFARc              = *mxGetPr(AFARc_p(S));
    
    /*-------- vector & array data -------*/
    const real_T *X_A_AltVec        = mxGetPr(X_A_AltVec_p(S));
    const real_T *T_A_TsVec         = mxGetPr(T_A_TsVec_p(S));
    const real_T *T_A_PsVec         = mxGetPr(T_A_PsVec_p(S));
    const real_T *X_A_FARVec        = mxGetPr(X_A_FARVec_p(S));
    const real_T *T_A_RtArray       = mxGetPr(T_A_RtArray_p(S));
    const real_T *Y_A_TVec          = mxGetPr(Y_A_TVec_p(S));
    const real_T *T_A_gammaArray    = mxGetPr(T_A_gammaArray_p(S));
    
    /*------get dimensions of parameter arrays-------*/
    const int_T A   = mxGetNumberOfElements(X_A_AltVec_p(S));
    const int_T B   = mxGetNumberOfElements(X_A_FARVec_p(S));
    const int_T C   = mxGetNumberOfElements(Y_A_TVec_p(S));
    
    /*---------Define Inputs--------*/
    const real_T *u  = (const real_T*) ssGetInputPortSignal(S,0);
    
    double AltIn     = u[0];     /* Altitude(ft) 	*/
    double dTempIn   = u[1];     /* delta Temperature [degF] 	*/
    double MNIn      = u[2];     /* Mach Number (frac) 	*/
    
    real_T *y  = (real_T *)ssGetOutputPortRealSignal(S,0);  /* Output Array */
    
    /*--------Define Constants-------*/
    double PsOut, TsOut, TtOut, PtOut, VengOut, TsStDayOut, Vsound;
    double Ttg, Ptg, Vg, Vsg, MNg, Sout, htg, gammasg, Rs, Rt;
    double hs, htOut; 
    double er, er_old, erthr, Ptg_new, Ptg_old, FAR, FAROut;
    int iter, maxiter;
    
    int interpErr = 0;
    
    /* ------- get strings -------------- */
    char * BlkNm;
    int_T buflen;
    int_T status;
    
    /* Get name of block from dialog parameter (string) */
    buflen = mxGetN(BN_p(S))*sizeof(mxChar)+1;
    BlkNm = mxMalloc(buflen);
    status = mxGetString(BN_p(S), BlkNm, buflen);
    
    FAR = AFARc;
    
    Rt = interp1Ac(X_A_FARVec,T_A_RtArray,FAR,B,&interpErr);
    if (interpErr == 1 && ssGetIWork(S)[0]==0){
        printf("Warning in %s, Error calculating Rt. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,0,1);
    }
    
    Rs = Rt;
    
    /*  Static Temperature */
    TsStDayOut = interp1Ac(X_A_AltVec,T_A_TsVec,AltIn,A,&interpErr);
    if (interpErr == 1 && ssGetIWork(S)[1]==0){
        printf("Warning in %s, Error calculating TsStDayOut. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,0,1);
    }
    TsOut = TsStDayOut + dTempIn;
    
    /* Static Pressure*/
    PsOut = interp1Ac(X_A_AltVec,T_A_PsVec,AltIn,A,&interpErr);
    if (interpErr == 1 && ssGetIWork(S)[2]==0){
        printf("Warning in %s, Error calculating PsOut. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,1,1);
    }
    
    /* Calc output entropy */
    Sout = pt2sc(PsOut, TsOut, FAR);
    /* Determine Static enthalpy */
    hs = t2hc(TsOut,FAR);
    
    /* Pt guess */
    /*------ Total Temperature ---------*/
    Ttg = TsOut * (1+MNIn*MNIn*(C_GAMMA-1)/2);
    /*------ Total Pressure ---------*/
    Ptg = PsOut/(pow((TsOut/Ttg),(C_GAMMA/(C_GAMMA-1))));
    
    /* calculate total temperature */
    Ttg = sp2tc(Sout,Ptg,FAR);
    /* calculate total enthalpy */
    htg = t2hc(Ttg,FAR);
    /* calculate velocity */
    Vg = sqrt(2 * (htg - hs)*C_GRAVITY*JOULES_CONST);
    
    gammasg = interp2Ac(X_A_FARVec,Y_A_TVec,T_A_gammaArray,FAR,TsOut,B,C,&interpErr);
    if (interpErr == 1 && ssGetIWork(S)[3]==0){
        printf("Warning in %s, Error calculating iteration gammasg. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,3,1);
    }
    Vsg = sqrt(gammasg*Rs*TsOut*C_GRAVITY*JOULES_CONST);
    MNg = Vg/Vsg;
    er = MNIn - MNg;
    Ptg_new = Ptg + 0.05;
    maxiter = 15;
    iter = 0;
    erthr = 0.001;
    
    while (fabs(er) > erthr && iter < maxiter) {
        er_old = er;
        Ptg_old = Ptg;
        if(fabs(Ptg - Ptg_new) < 0.03)
            Ptg = Ptg + 0.05;
        else
            Ptg = Ptg_new;
        
        /* calculate Total emperature */
        Ttg = sp2tc(Sout,Ptg,FAR);
        /* calculate total enthalpy */
        htg = t2hc(Ttg,FAR);
        /* calculate velocity */
        Vg = sqrt(2 * (htg - hs)*C_GRAVITY*JOULES_CONST);
        
        Vsg = sqrt(gammasg*Rs*TsOut*C_GRAVITY*JOULES_CONST);
        MNg = Vg/Vsg;
        er = MNIn - MNg;
        if (fabs(er) > erthr) {
            /* determine next guess pressure by secant algorithm */
            Ptg_new = Ptg - er *(Ptg - Ptg_old)/(er - er_old);
        }
        iter = iter + 1;
    }
    if (iter == maxiter && ssGetIWork(S)[3]==0 ){
        printf("Warning in %s, Error calculating Pt at input MN. There may be error in output pressure\n", BlkNm);
        ssSetIWorkValue(S,4,1);
    }
    
    htOut = htg;
    TtOut = Ttg;
    PtOut = Ptg;
    
    /*---- Engine Velocity ---------*/
    Vsound = Vsg;
    VengOut = Vsound * MNIn;
    
    FAROut = FAR;
    
    /*------Assign output values------------*/
    y[0] = htOut;      /* Total enthalpy */
    y[1] = TtOut;      /* Total Temperature [degR] */
    y[2] = PtOut;      /* Total Pressure [psia] */
    y[3] = FAROut;     /* Fuel to Air Ratio */
    y[4] = PsOut;      /* Static Pressure [psia] */
    y[5] = TsOut;      /* Static Temperature [degR] */
    y[6] = VengOut;    /* Engine Velocity [ft/sec] */
    
}
Beispiel #5
0
static void mdlOutputs(SimStruct *S, int_T tid)
{
    /*--------Define Parameters-------*/
    const real_T s_V_Ae_vlv                 = *mxGetPr(s_V_Ae_vlv_p(S));
    const real_T s_V_Ae_byp                 = *mxGetPr(s_V_Ae_byp_p(S));
    const real_T s_V_Ae_th                  = *mxGetPr(s_V_Ae_th_p(S));

    /*-------- vector & array data -------*/
    const real_T *X_V_FAR_vec               = mxGetPr(X_V_FAR_vec_p(S));
    const real_T *T_V_Rt_vec                = mxGetPr(T_V_Rt_vec_p(S));
    const real_T *Y_V_Tt_vec                = mxGetPr(Y_V_Tt_vec_p(S));
    const real_T *T_V_gamma_array           = mxGetPr(T_V_gamma_array_p(S));

    /*------get dimensions of parameter arrays-------*/
    const int_T A1  = mxGetNumberOfElements(X_V_FAR_vec_p(S));
    const int_T B1  = mxGetNumberOfElements(Y_V_Tt_vec_p(S));

    /*---------Define Inputs--------*/
    const real_T *u  = (const real_T*) ssGetInputPortSignal(S,0);


    double WbyIn	= u[0];     /* Bypass flow path flow rate [pps] 	*/
    double TtbyIn   = u[1];     /* Bypass Temperature [degR] 	*/
    double PtbyIn   = u[2];     /* Bypass disch. pressure [psia] 	*/
    double FARcbyIn = u[3];     /* Bypass combusted fuel to air ratio [frac] */
    double VlvPosIn	= u[4];     /* Valve Position [frac, 0-1] 	*/
    double WmfpIn	= u[5];     /* Main flow path flow rate [pps] 	*/
    double TtmfpIn	= u[6];     /* Main flow path Temprature [degR] 	*/
    double PtmfpIn	= u[7];     /* Main flow path Pressure Input [psia] 	*/
    double FARcmfpIn= u[8];     /* Main flow path combusted fuel to air ratio [frac] */

    real_T *y  = (real_T *)ssGetOutputPortRealSignal(S,0);  /* Output Array */

    /*--------Define Constants-------*/
    double Ath, Rb, gamb, Cpb, Pe, Me, Tcr_o_Te, Ae_o_Acr, Ath_o_Acr;
    double Mth0, Mth1, Tcr_o_Tth0, Tcr_o_Tth1, Ath_o_Acr0, Ath_o_Acr1, err0, err1, err;
    double Mth, Tcr_o_Tth_it, Ath_o_Acr_it, Tcr_o_T0, Tth_o_T0, Tth, Pth, rhoth, Vth, Wth, Wbyp_noz, Whpc;
    double MthOut, Test, WthOut;

    int interpErr = 0;
    int count;

    /* ------- get strings -------------- */
    char * BlkNm;
    int_T buflen;
    int_T status;

    /* Get name of block from dialog parameter (string) */
    buflen = mxGetN(BN_p(S))*sizeof(mxChar)+1;
    BlkNm = mxMalloc(buflen);
    status = mxGetString(BN_p(S), BlkNm, buflen);

    /* Input validation */
    if ((WbyIn <= 0 || WmfpIn <= 0) && ssGetIWork(S)[Er1]==0){
        printf("Flow rates must be nonzero !!");
        ssSetIWorkValue(S,Er1,1);
    }

    if (VlvPosIn > 0){
        if (VlvPosIn < 0.001)
            VlvPosIn = 0.001;
        Ath = VlvPosIn*s_V_Ae_th;      /* throat area [in^2] */

        /* define gas constants for booster discharge air */
        Rb = interp1Ac(X_V_FAR_vec,T_V_Rt_vec,FARcmfpIn,A1,&interpErr);
        if (interpErr == 1 && ssGetIWork(S)[Er2]==0){
            printf("Warning in %s, Error calculating Rb. Vector definitions may need to be expanded.\n", BlkNm);
            ssSetIWorkValue(S,Er2,1);
        }
        gamb = interp2Ac(X_V_FAR_vec,Y_V_Tt_vec,T_V_gamma_array,FARcmfpIn,TtmfpIn,A1,B1,&interpErr);
        if (interpErr == 1 && ssGetIWork(S)[Er3]==0){
            printf("Warning in %s, Error calculating gamb. Vector definitions may need to be expanded.\n", BlkNm);
            ssSetIWorkValue(S,Er3,1);
        }
        Cpb = Rb*gamb*divby(gamb-1);

        /* determine static pressure at the exit plane (entering fan); */
        /* assume bypass flow >> bleed flow */
        Pe = calc_Pstatic(PtbyIn,TtbyIn,WbyIn,s_V_Ae_byp,X_V_FAR_vec,T_V_Rt_vec,Y_V_Tt_vec,T_V_gamma_array,FARcbyIn,A1,B1);

        /* compute exit to critical area ratio */
        Me = sqrtT(2*divby(gamb-1)*(powT(Pe*divby(PtmfpIn), (1-gamb)*divby(gamb))-1));
        Tcr_o_Te = (2*divby(gamb+1))*(1 + 0.5*(gamb-1)*Me*Me);
        Ae_o_Acr = powT(Tcr_o_Te, (gamb+1)*divby(2*(gamb-1)))*divby(Me);
        
        /* obtain throat to critical area ratio */
        Ath_o_Acr = Ae_o_Acr*Ath*divby(s_V_Ae_vlv);
        
        /* determine throat Mach no. iteratively; initialize guesses, errors */
        Mth0 = 0.1;      /* subsonic guess values */
        Mth1 = 0.2;

        Tcr_o_Tth0 = (2*divby(gamb+1))*(1 + 0.5*(gamb-1)*Mth0*Mth0);
        Tcr_o_Tth1 = (2*divby(gamb+1))*(1 + 0.5*(gamb-1)*Mth1*Mth1);
        Ath_o_Acr0 = powT(Tcr_o_Tth0, (gamb+1)*divby(2*(gamb-1)))*divby(Mth0);
        Ath_o_Acr1 = powT(Tcr_o_Tth1, (gamb+1)*divby(2*(gamb-1)))*divby(Mth1);
        err0 = Ath_o_Acr - Ath_o_Acr0;
        err1 = Ath_o_Acr - Ath_o_Acr1;
        err = 100;
        count = 0;

        while (fabs(err) > 0.002 && (err0 - err1) != 0 && count < 100){

            /* compute new Mach no. guess */
            Mth = Mth0 - err0*(Mth0 - Mth1)*divby(err0 - err1);
            if (Mth > 1.0)
                Mth = 1.0;

            /* compute error to drive solution towards specified area ratio */
            Tcr_o_Tth_it = (2*divby(gamb+1))*(1 + 0.5*(gamb-1)*Mth*Mth);
            Ath_o_Acr_it = powT(Tcr_o_Tth_it, (gamb+1)*divby(2*(gamb-1)))*divby(Mth);
            err = Ath_o_Acr - Ath_o_Acr_it;

            /* propagate errors & guesses */
            Mth1 = Mth0;
            err1 = err0;
            Mth0 = Mth;
            err0 = err;

            count++;
        }

        /* compute throat static pressure, temperature and Mach no.; */
        /* modify if choked */
        Tcr_o_T0 = 2*divby(gamb+1);
        Tth_o_T0 = 1*divby(1 + 0.5*(gamb-1)*Mth*Mth);
        if (Tth_o_T0 < Tcr_o_T0)
            Tth_o_T0 = Tcr_o_T0;
        Tth = TtmfpIn*Tth_o_T0;
        Pth = PtmfpIn*powT(Tth_o_T0, gamb*divby(gamb-1));

        /* recompute the actual flow rate, assume no pressure loss */
        rhoth = Pth*144*divby(Rb*JOULES_CONST*Tth);      /* [lb/ft^3] */
        Vth = sqrtT(2*Cpb*C_GRAVITY*JOULES_CONST*(TtmfpIn - Tth));     /* [ft/s] */
        Wth = rhoth*Ath/144*Vth;        /* [lb/s] */
        Mth = Vth*divby(sqrtT(gamb*Rb*C_GRAVITY*JOULES_CONST*Tth));
    }
    else {
        Wth = 0;
        Mth = 0;
    }

    WthOut = Wth;

    Test = Vth;

    /*------Assign output values------------*/
    y[0] = WthOut;      /* Valve throat flow [pps] */
    y[1] = MthOut;      /* Mach no. at throat */
    y[2] = Test;        /* Output Test Point */

}