/**************************************************************************** * * WhitenCrusher1::CalculateModel( ) * ****************************************************************************/ bool WhitenCrusher1::CalculateModel( PFlowStream1 FeedStream ) { // Test that streams are valid for use if( FeedStream==0 || Discharge==0 ) { goto calculateFail; } else { //-- Setting Up ----------------------------------------------------- int i = 0; int j = 0; double Error = 0; double TOLERANCE = 1e-8; int ITERMAX = 100; int Iteration = 0; MatrixView& FEED = FeedStream->AccessSolidsMatrix(); MatrixView& PROD = Discharge->AccessSolidsMatrix(); VectorView& SIZE = config_->GetSizes(); TPH = FEED.sum(); F80 = FeedStream->CombinedP80(); k1 = a0*CSS + a1*TPH + a2*F80 + a3*LLen + a4; k2 = b0*CSS + b1*TPH + b2*F80 + b3*LHr + b4*ET + b5; k3 = c0; Ecs = d0 * exp( -d1*CSS ); Capacity = e0*CSS + e1; NetPower = 0; //-- Construct nominal size vector ---------------------------------- // coarsest fraction nomSize_[0] = sqrt(2.0f) * SIZE[0]; // undersize fraction nomSize_[nSize_-1] = 0.5 * SIZE[nSize_-2]; // intermediate fractions for( i=1; i<(nSize_-1); i++ ) nomSize_[i] = sqrt( SIZE[i] * SIZE[i-1] ); //-- Construct classification function C ---------------------------- for( i=0; i<nSize_; i++ ) { if( nomSize_[i] < k1 ) C_[i] = 0; else if( nomSize_[i] < k2 ) C_[i] = 1.0 - pow( (k2 - nomSize_[i])/(k2 - k1 ) , k3 ); else C_[i] = 1.0; } //-- Transport water to product streams ----------------------------- Discharge->SetLiquidMass( FeedStream->GetLiquidMass() ); //-- Process each feed component to discharge stream ---------------- for( i=0; i<nType_; i++ ) { // Refer to columns of size distributions TableVector iFEED = FEED.column(i); TableVector iPROD = PROD.column(i); // Refer to material being processed PMineralInfo1 RockInfo = config_->GetMineral(i); // Calculate the T10 that will apply T10[i] = RockInfo->CalcT10( Ecs ); //** Iteration Loop **// Content_.clear( ); Iteration = 0; Error = 2 * TOLERANCE; Content_ = iFEED; while( Error > TOLERANCE && Iteration < ITERMAX ) { // Select content to feed breakage mechanism BreakFeed_ = Content_; BreakFeed_ *= C_; // Break each size fraction of selected content // into breakage products BreakProd_.clear( ); for( j=0; j<nSize_; j++ ) { NetPower += BreakFeed_[j] * Ecs; RockInfo->BreakRockT10 ( nomSize_[j], // size of rock in fraction j BreakFeed_[j], // quantity of rock to break T10[i], // T10 of breakage product SIZE, // sizes in product distribution BreakProd_ // vector to acquire fragments ); } // Copy breakage products + feed into content // making note of maximum mis-convergence Error = 0; for( j=0; j<nSize_; j++ ) { double newC = iFEED[j] + BreakProd_[j]; double newE = abs( newC - Content_[j] ); if( newE > Error ) Error = newE; Content_[j] = newC; } } // Build materials in Discharge stream iPROD = Content_; iPROD -= BreakFeed_; } } // Refresh data in streams Discharge->Refresh(); P80 = Discharge->CombinedP80(); // Construct output vector GrossPower = NoLoadPower + NetPower; Utilization = ( fabs(Capacity)>1e-8 ? TPH / Capacity * 100 : 0 ); ModelOutput[ 0] = TPH; ModelOutput[ 1] = Capacity; ModelOutput[ 2] = Utilization; ModelOutput[ 3] = F80; ModelOutput[ 4] = P80; ModelOutput[ 5] = k1; ModelOutput[ 6] = k2; ModelOutput[ 7] = k3; ModelOutput[ 8] = Ecs; ModelOutput[ 9] = NetPower; ModelOutput[10] = GrossPower; // Success return true; calculateFail: // Failed to calculate model return false; };
//##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; }