// Calculate Paramater B for LoadBasedScreen1 //##ModelId=40A1898A0191 double LoadBasedScreen1::CalculateB( double FractOS ) { double B = 0; const int nRowsB = 7; static double BArray [ nRowsB ] [ 2 ] = { // Fract B // Oversize Oversize // in Feed Factor { 0.00 , 1.60 }, { 0.50 , 1.00 }, { 0.80 , 0.64 }, { 0.85 , 0.56 }, { 0.90 , 0.44 }, { 0.95 , 0.24 }, { 1.00 , 0.00 }, }; double* p = (pBArray ? pBArray : *BArray); Matrix BMatrix( nRowsB, 2, p ); CubicSpline BSpline; BSpline.SetSpline ( BMatrix.column(0), BMatrix.column(1) ); B = BSpline.CalculateY ( FractOS ); // Vector TempSplineVec( nRows ); // SPN3( nRows, BMatrix.column(0), BMatrix.column(1), TempSplineVec ); // B = SPNV3( nRows, BMatrix.column(0), BMatrix.column(1), TempSplineVec, FractOS ); return B; }
// Calculate Paramater C for LoadBasedScreen1 //##ModelId=40A1898A019B double LoadBasedScreen1::CalculateC( double FractHS ) { double C = 0; const int nRowsC = 18; static double CArray [ nRowsC ] [ 2 ] = { // Fract of C // Feed < S/2 // Factor { 0.00 , 0.70 }, { 0.25 , 1.00 }, { 0.30 , 1.06 }, { 0.35 , 1.13 }, { 0.40 , 1.21 }, { 0.45 , 1.30 }, { 0.50 , 1.40 }, { 0.55 , 1.52 }, { 0.60 , 1.67 }, { 0.65 , 1.85 }, { 0.70 , 2.05 }, { 0.75 , 2.26 }, { 0.80 , 2.50 }, { 0.85 , 2.75 }, { 0.90 , 3.20 }, { 0.95 , 4.00 }, { 0.98 , 6.00 }, { 1.00 , 10.00 }, }; double* p = (pCArray ? pCArray : *CArray); Matrix CMatrix( nRowsC, 2, p ); CubicSpline CSpline; CSpline.SetSpline ( CMatrix.column(0), CMatrix.column(1) ); C = CSpline.CalculateY ( FractHS ); // Vector TempSplineVec( nRows ); // SPN3( nRows, CMatrix.column(0), CMatrix.column(1), TempSplineVec ); // C = SPNV3( nRows, CMatrix.column(0), CMatrix.column(1), TempSplineVec, FractHS ); return C; }
// Calculate Paramater A for LoadBasedScreen1 //##ModelId=40A1898A017D double LoadBasedScreen1::CalculateA( double S ) { double A = 0; const int nRowsA = 19; static double AArray [ nRowsA ] [ 2 ] = { // S A // Screen Basic // Opening Capacity { 0 , 0.0 }, { 1 , 1.1 }, { 2 , 2.0 }, { 3 , 3.0 }, { 4 , 3.9 }, { 5 , 4.8 }, { 6.35 , 5.9 }, { 8 , 7.0 }, { 10 , 8.2 }, { 12 , 9.4 }, { 15 , 10.7 }, { 18 , 12.0 }, { 22 , 13.4 }, { 26 , 14.6 }, { 30 , 15.8 }, { 40 , 18.2 }, { 75 , 25.0 }, { 160 , 41.5 }, { 500 , 107.5 }, }; double* p = (pAArray ? pAArray : *AArray); Matrix AMatrix( nRowsA, 2, p ); CubicSpline ASpline; ASpline.SetSpline( AMatrix.column(0), AMatrix.column(1) ); A = ASpline.CalculateY ( S ); return A; }
//##ModelId=40A1898902EF bool LoadBasedScreen1::CalculateModel( PFlowStream1 FeedStream ) { // Local Variables int i = 0; int j = 0; double ScaleFactor = 0.00; double Denom = 0.00; Vector CombCPPSizing ( nSize ); CubicSpline FeedSpline; MatrixView FeedSolids = FeedStream->AccessSolidsMatrix( ); MatrixView OversizeSolids = Oversize->AccessSolidsMatrix( ); MatrixView UndersizeSolids = Undersize->AccessSolidsMatrix( ); // Ensure correct shape feed matrix if( FeedSolids.rowCount() != nSize ) goto calcFailed; if( FeedSolids.columnCount() != nType ) goto calcFailed; // Calculate total feed flow rate (solids) QF = FeedSolids.sum( ); // Convert feed matrix into single component size distribution for( i = 0; i < nSize; i++ ) CombRetSizing[ i ] = (FeedSolids.row(i)).sum(); if (fabs(QF)<1e-8) ScaleFactor = 0.00; else ScaleFactor = 1/QF; // Scale single component distribution to cumulative sizing // scaled to fraction basis: ie. 1 passes top-size CombCPPSizing[ nSize - 1 ] = 0; for( i = nSize - 2; i >=0; i-- ) CombCPPSizing[ i ] = CombCPPSizing[i + 1] + ( CombRetSizing[i + 1] * ScaleFactor ); // Construct cubic spline passing through cumulative curve FeedSpline.SetSpline( Sizes, CombCPPSizing ); // Use cubic spline to get fraction passing half apperture size Feed_HS = FeedSpline.CalculateY( S/2 ); // Use spline to get fraction passing apperture size U = Feed_US = FeedSpline.CalculateY( S ); Feed_OS = 1 - Feed_US; // Calculate area factors for this screen A = CalculateA( S ); B = CalculateB( Feed_OS ); C = CalculateC( Feed_HS ); D = CalculateD( DL ); E = CalculateE( WS, S ); H = CalculateH( OT ); J = CalculateJ( ST, S, OA ); K = CalculateK( FT ); L = CalculateL(); X = CalculateX( CF ); // Calculate denominator of load equation - ensure not zero Denom = A * B * C * D * E * F * H * J * K * L * AF * X; if (fabs(Denom)<1e-8) Denom = 1e-8; // Calculate load V = ( 90 * QF * U ) / ( Denom ); // Calculate efficiency that matches this load T = CalculateT( V ); // Calculate factor G G = ( V * T ) / 90; // calculate flow to undersize at this efficiency QU = QF * U * T; // Solve for D50 that matches the undersize flow D50 = zbrent( S * 0.1, S * 0.99, TOLERANCE ); // Calculate splitting of feed water to products Undersize->SetLiquidMass( FeedStream->GetLiquidMass() * WR ); Oversize->SetLiquidMass( FeedStream->GetLiquidMass() * (1-WR) ); // Calculate splitting of solids components to products for( i=0; i<nType; i++ ) { for( j=0; j<nSize; j++ ) { double feed = FeedSolids[j][i]; OversizeSolids[j][i] = feed * PartitionCurve[j]; UndersizeSolids[j][i] = feed * ( 1 - PartitionCurve[j] ); } } // Setup model output vector ModelOutput[0] = QF; ModelOutput[1] = Feed_OS; ModelOutput[2] = Feed_US; ModelOutput[3] = Feed_HS; ModelOutput[4] = QU; ModelOutput[5] = QF - QU; ModelOutput[6] = S; ModelOutput[7] = T; ModelOutput[8] = AF; ModelOutput[9] = D50; ModelOutput[10] = A; ModelOutput[11] = B; ModelOutput[12] = C; ModelOutput[13] = D; ModelOutput[14] = E; ModelOutput[15] = F; ModelOutput[16] = G; ModelOutput[17] = H; ModelOutput[18] = J; ModelOutput[19] = K; ModelOutput[20] = L; ModelOutput[21] = X; ModelOutput[22] = V; // Indicate success return true; calcFailed: // Indicate failure return false; }