private void TestBucketSortArrayMatrixRow() { try { ILArray <string> A = new ILArray <string>(3, 4); A[0, 0] = "abc"; A[0, 1] = "rtu"; A[0, 2] = "sfkw"; A[0, 3] = "lsdkfi"; A[1, 0] = "iowejkc"; A[1, 1] = "cjks"; A[1, 2] = "wokys"; A[1, 3] = "suem,"; A[2, 0] = "fgj"; A[2, 1] = "JKSF"; A[2, 2] = "SEs"; A[2, 3] = "SEFsr"; ILArray <double> ind; ILArray <string> res = ILMath.sort(A, out ind, 0, false); if (!res.Equals(A[ind])) { throw new Exception("invalid indices/values detected"); } ILArray <Int16> indI = ILMath.toint16(ILMath.counter(0.0, 1.0, A.Dimensions.ToIntArray())); res = ILMath.sort(A, ref indI, 0, true, new ILASCIIKeyMapper()); if (!res.Equals(A[indI])) { throw new Exception("invalid indices/values detected"); } Success(" elapsed: " + m_stopwatch.ElapsedMilliseconds + " ms"); } catch (Exception e) { Error(0, e.Message); } }
private void TestQuickSortDesc() { try { ILArray <double> A = ILMath.counter(5, 4, 3); System.Diagnostics.Debug.Assert(!A.IsReference); ILArray <double> result = ILMath.sort(A, 1, true); ILArray <double> expect = A[":;3,2,1,0;:"]; if (!result.Equals(expect)) { throw new Exception("invalid values"); } // test scalar A = 3.0; result = ILMath.sort(A, 0, true); if (result != 3.0) { throw new Exception("invalid values: scalar"); } // test empty A = ILArray <double> .empty(); if (!ILMath.sort(A, 0, true).IsEmpty) { throw new Exception("invalid values: empty"); } Success(); } catch (Exception e) { Error(0, e.Message); } }
/// <summary> /// create composite shape /// </summary> /// <param name="panel">scene hosting the scene</param> /// <param name="numVertices">number of overall vertices for the shape</param> /// <param name="verticesPerShape">Number of vertices per shape</param> public ILCompositeShape(ILPanel panel, int numVertices, int verticesPerShape) : base(panel, numVertices, verticesPerShape) { Opacity = 255; m_shapeIndices = ILMath.toint32( ILMath.counter(0.0, 1.0, VerticesPerShape, numVertices / VerticesPerShape)); }
/// <summary> /// create composite shape /// </summary> /// <param name="panel">hosting panel</param> /// <param name="verticesPerShape">number of vertices per shape</param> /// <param name="X">x coordinates vector </param> /// <param name="Y">y coordinates vector </param> /// <param name="Z">z coordinates vector </param> /// <remarks>The constructor creates a new composite shape out of all vertices specified in X,Y and Z. /// Every vertex is only used once. Every shape uses /// <see cref="ILNumerics.Drawing.Shapes.ILShape<T>.VerticesPerShape"/> vertices one after another.</remarks> public ILCompositeShape(ILPanel panel, int verticesPerShape, ILBaseArray X, ILBaseArray Y, ILBaseArray Z) : base(panel, X.Length, verticesPerShape) { Update(X, Y, Z); m_shapeIndices = ILMath.toint32( ILMath.counter(0.0, 1.0, VerticesPerShape, m_vertCount / VerticesPerShape)); Opacity = 255; m_shading = ShadingStyles.Flat; }
public Bars AddBars(ILArray <double> barLength) { if (!barLength.IsVector && !barLength.IsScalar) { throw new ILArgumentException("Argument must be a vector or scalar"); } int n = barLength.Dimensions[0]; return(AddBars(ILMath.zeros(n), barLength, ILMath.counter(n) - 1.0, 0.8, BarType.Vertical)); }
protected static ILArray <double> _c(double start, double incrementation, double limit) { return(ILMath.counter(start, incrementation, 1, (limit - start) / incrementation + 1)); }
protected static ILArray <double> _c(decimal start, decimal incrementation, decimal limit) { return(ILMath.counter((double)start, (double)incrementation, 1, (int)_csize(start, incrementation, limit))); }
protected static ILArray <int> _c_(int start, int incrementation, int limit) { return(ILMath.counter <int>(start, incrementation, 1, (limit - start) / incrementation + 1)); }
/// <summary> /// construct new filled graph /// </summary> /// <param name="panel">panel hosting the graph</param> /// <param name="X">X coords, if null, range 0..[cols of Z] will be created</param> /// <param name="Y">Y coords, if null, range 0..[rows of Z] will be created</param> /// <param name="Z">Z coords (heights)</param> /// <param name="C">Colors for Z</param> /// <param name="clippingContainer">gloabal limits of panel</param> public ILFilledGraph(ILPanel panel, ILBaseArray X, ILBaseArray Y, ILBaseArray Z, ILBaseArray C, ILClippingData clippingContainer) : base(panel, clippingContainer) { #region argument checking m_localClipping.EventingSuspend(); if (Z == null || !Z.IsMatrix) { throw new ILArgumentException("ILFilledGraph: Z must be matrix!"); } if (!Z.IsNumeric) { throw new ILArgumentException("ILFilledGraph: Z must be numeric!"); } m_sourceArray = ILMath.tosingle(Z); m_rows = m_sourceArray.Dimensions[0]; m_cols = m_sourceArray.Dimensions[1]; ILArray <float> tmp; if (!object.Equals(X, null) && !X.IsEmpty) { if (!X.IsMatrix || !X.IsNumeric) { throw new ILArgumentException("ILFilledGraph: X must be numeric matrix!"); } if (X.Dimensions.IsSameSize(Z.Dimensions)) { tmp = ILMath.tosingle(X); tmp.ExportValues(ref m_xCoords); m_localClipping.XMax = tmp.MaxValue; m_localClipping.XMin = tmp.MinValue; } else { throw new ILArgumentException("ILFilledGraph: X must be of same size than Z!"); } } else { ILMath.tosingle(ILMath.repmat(ILMath.counter(0.0, 1.0, 1, m_cols), m_rows, 1)).ExportValues(ref m_xCoords); m_localClipping.XMin = 0; m_localClipping.XMax = m_cols - 1; } if (!object.Equals(Y, null) && !Y.IsEmpty) { if (!Y.IsMatrix || !Y.IsNumeric) { throw new ILArgumentException("ILFilledGraph: Y must be numeric matrix!"); } if (Y.Dimensions.IsSameSize(Z.Dimensions)) { tmp = ILMath.tosingle(Y); tmp.ExportValues(ref m_yCoords); m_localClipping.YMax = tmp.MaxValue; m_localClipping.YMin = tmp.MinValue; } else { throw new ILArgumentException("ILFilledGraph: Y must be same size than Z!"); } } else { ILMath.tosingle(ILMath.repmat(ILMath.counter(0.0, 1.0, m_rows, 1), 1, m_cols)).ExportValues(ref m_yCoords); m_localClipping.YMax = m_rows - 1; m_localClipping.YMin = 0; } if (object.Equals(C, null) || C.IsEmpty) { m_colors = null; } else { m_colors = ILMath.tosingle(C); } m_localClipping.ZMax = m_sourceArray.MaxValue; m_localClipping.ZMin = m_sourceArray.MinValue; #endregion m_Vertcount = m_rows * m_cols; m_vertexReady = false; m_indexReady = false; // default view properties m_opacity = 1.0f; m_wireLines = new ILLineProperties(); m_wireLines.Changed += new EventHandler(m_wireLines_Changed); m_filled = true; m_localClipping.EventingResume(); }
private void TestQuickSortAsc() { try { ILArray <double> A = ILMath.counter(5, 4, 3); System.Diagnostics.Debug.Assert(!A.IsReference); ILArray <double> result = ILMath.sort(A, 1, false); ILArray <double> expect = A[":;:;:"]; if (!result.Equals(expect)) { throw new Exception("invalid values"); } // test real sortable values A = ILMath.counter(60.0, -1.0, 5, 4, 3); result = ILMath.sort(A, 1, false); expect = A[":;3,2,1,0;:"]; if (!result.Equals(expect)) { throw new Exception("invalid values"); } // test ascending values to sort ascending A = ILMath.counter(1.0, 1.0, 11, 2); result = ILMath.sort(A, 0, false); if (!result.Equals(A)) { throw new Exception("invalid values"); } // test descending values to sort ascending A = ILMath.counter(22.0, -1, 11, 2); result = ILMath.sort(A, 0, false); expect = ILMath.counter(1.0, 1.0, 11, 2)[":;1,0"]; if (!result.Equals(expect)) { throw new Exception("invalid values"); } // test scalar A = 3.0; result = ILMath.sort(A, 0, false); if (result != 3.0) { throw new Exception("invalid values: scalar"); } // test empty A = ILArray <double> .empty(); if (!ILMath.sort(A, 0, false).IsEmpty) { throw new Exception("invalid values: empty"); } // test nan A = ILMath.counter(1.0, 1.0, 20, 2); A[2] = double.NaN; A[4] = double.PositiveInfinity; A[8] = double.NegativeInfinity; A[18] = double.NegativeInfinity; A[14] = double.NaN; result = ILMath.sort(A, 0, false); expect = ILMath.counter(1.0, 1.0, 20, 2); expect[":;0"] = new double[] { double.NegativeInfinity, double.NegativeInfinity, 1, 2, 4, 6, 7, 8, 10, 11, 12, 13, 14, 16, 17, 18, 20, double.PositiveInfinity, double.NaN, double.NaN }; if (!result.Equals(expect)) { throw new Exception("invalid values"); } Success(); } catch (Exception e) { Error(0, e.Message); } }
private void TestQuickSortDescIDX(int dim, int len) { try { // asc along dimension (already ordered values) int[] dims = new int[4] { 5, 4, 3, 2 }; dims[dim] = len; ILArray <double> A = ILMath.counter(dims); ILArray <double> ind; ILArray <double> result = ILMath.sort(A, out ind, dim, true); ILArray <double> expect = null; ILArray <double> expectInd; expectInd = ILMath.counter(A.Dimensions[dim] - 1, -1.0, 1, A.Dimensions[dim]); ILBaseArray[] revDims = new ILBaseArray[dims.Length]; revDims[dim] = expectInd; expect = A[revDims]; if (!result.Equals(expect)) { throw new Exception("invalid values"); } int [] dimsEx = new int[dims.Length]; expectInd = ILMath.repmat(expectInd, A.Dimensions.SequentialIndexDistance(dim), 1); sortIDXTestHelper001(dim, dims, ref expectInd, dimsEx); expectInd = ILMath.repmat(expectInd, dimsEx); if (!ind.Equals(expectInd)) { throw new Exception("invalid indices"); } // reverse values ... A = ILMath.counter(A.Dimensions.NumberOfElements, -1.0, dims); result = ILMath.sort(A, out ind, dim, true); if (!result.Equals(A.C)) { throw new Exception("invalid values"); } expectInd = ILMath.counter(0.0, 1.0, 1, A.Dimensions[dim]); expectInd = ILMath.repmat(expectInd, A.Dimensions.SequentialIndexDistance(dim), 1); sortIDXTestHelper001(dim, dims, ref expectInd, dimsEx); expectInd = ILMath.repmat(expectInd, dimsEx); if (!ind.Equals(expectInd)) { throw new Exception("invalid indices"); } // test scalar A = 3.0; result = ILMath.sort(A, out ind, 0, true); if (result != 3.0) { throw new Exception("invalid values: scalar"); } if (ind != 0.0) { throw new Exception("invalid indices"); } // test empty A = ILArray <double> .empty(); if (!ILMath.sort(A, out ind, 0, true).IsEmpty) { throw new Exception("invalid values: empty"); } if (!ind.IsEmpty) { throw new Exception("invalid indices"); } Success(); } catch (Exception e) { Error(0, e.Message); } }
//% The main file for running the wind farm controll and wake simulation. // It is not completely done yet. Further updates will come // Currently there are only 4 turbines, for test purposes. But is should be // easily updated to a larger number of turbines. // Similarly there is a lot of room for speed optimizations, even though it // now runs slowly with only 4 turbines // 19/07-13 MS public static double[][] Simulation(WakeFarmControlConfig config) { var parm = new WindTurbineParameters(); ILMatFile env; ILMatFile wt; ILArray <int> idx; ILArray <double> ee; double Ki; double Kp; int PC_MaxPit; int PC_MinPit; double VS_CtInSp; double VS_RtGnSp; double VS_Rgn2K; double omega0; double beta0; double power0; ILArray <double> x; ILArray <double> u0; ILArray <double> u; ILArray <double> Mg_old; ILArray <double> P_ref; ILArray <double> Pa; ILArray <double> Power; ILArray <double> Ct; ILArray <double> P_ref_new; ILArray <double> v_nac; double alpha; double Mg_max_rate; ILArray <double> e; ILArray <double> Mg; ILArray <double> beta; ILArray <double> Cp; ILArray <double> Omega; ILArray <double> out_; if (config.NTurbines == 0) { return(null); } // Wind farm properties //turbine properties env = wt = new ILMatFile(config.NREL5MW_MatFile); //Load parameters from the NREL 5MW turbine parm.N = config.NTurbines; // number of turbines in farm parm.rho = (double)env.GetArray <double>("env_rho"); //air density parm.radius = ((double)(wt.GetArray <double>("wt_rotor_radius"))) * ILMath.ones(1, config.NTurbines); // rotor radius (NREL5MW) parm.rated = 5e6 * ILMath.ones(1, config.NTurbines); //rated power (NREL5MW) parm.ratedSpeed = (double)wt.GetArray <double>("wt_rotor_ratedspeed"); //rated rotor speed idx = ILMath.empty <int>(); ILMath.max(wt.GetArray <double>("wt_cp_table")[ILMath.full], idx); //Find index for max Cp; parm.Cp = ILMath.ones(1, config.NTurbines) * wt.GetArray <double>("wt_cp_table").GetValue(idx.ToArray()); //Set power coefficent to maximum value in the cp table parm.Ct = ILMath.ones(1, config.NTurbines) * wt.GetArray <double>("wt_ct_table").GetValue(idx.ToArray()); //Set power coefficent to maximum value in the ct table // NOTE: controller parameters should be imported from the wt....struct in //Pitch control ee = 0; //blade pitch integrator Ki = 0.008068634 * 360 / 2 / ILMath.pi; // integral gain (NREL5MW) Kp = 0.01882681 * 360 / 2 / ILMath.pi; // proportional gain (NREL5MW) PC_MaxPit = 90; PC_MinPit = 0; //region control NREL VS_CtInSp = 70.16224; VS_RtGnSp = 121.6805; VS_Rgn2K = 2.332287; // load initial wind data var wind = new ILMatFile(config.Wind_MatFile); //% Set initial conditions omega0 = 1.267; //Rotation speed beta0 = 0; //Pitch var timeLine = (int)config.TimeLine(); power0 = parm.rated.GetValue(0); //Power production x = (omega0 * ILMath.ones(parm.N, 1)).Concat((wind.GetArray <double>("wind").GetValue(0, 1) * ILMath.ones(parm.N, 1)), 1); u0 = (beta0 * ILMath.ones(parm.N, 1)).Concat((power0 * ILMath.ones(parm.N, 1)), 1); u = u0.C; Mg_old = u[ILMath.full, 1]; P_ref = ILMath.zeros(parm.N, (int)config.TimeLine()); //Initialize matrix to save the power production history for each turbine Pa = P_ref.C; //Initialize available power matrix Power = P_ref.C; Ct = parm.Ct.C; //Initialize Ct - is this correct? Ct[timeLine - 1, ILMath.full] = Ct[0, ILMath.full]; P_ref_new = power0 * ILMath.ones(config.NTurbines, 1); v_nac = ILMath.zeros(Ct.Size[1], timeLine); Mg = ILMath.zeros(u.Size[0], timeLine); beta = ILMath.zeros(u.Size[0], timeLine); Omega = ILMath.zeros(Ct.Size[1], timeLine); Cp = ILMath.zeros(timeLine, parm.Cp.Size[1]); var turbineModel = new TurbineDrivetrainModel(); //% Simulate wind farm operation //var timeLine = (int) config.TimeLine(); for (var i = 2; i <= timeLine; i++) //At each sample time(DT) from Tstart to Tend { //Calculate the wake using the current Ct values { ILArray <double> out_v_nac; WakeCalculation.Calculate((Ct[i - 1 - 1, ILMath.full]), i, wind, out out_v_nac); v_nac[ILMath.full, i - 1] = out_v_nac; } x[ILMath.full, 1] = v_nac[ILMath.full, i - 1]; //Farm control //Calculate the power distribution references for each turbine if (config.EnablePowerDistribution) { ILArray <double> out_Pa; PowerDistributionControl.DistributePower(v_nac[ILMath.full, i - 1], config.Pdemand, Power[ILMath.full, i - 1 - 1], parm, out P_ref_new, out out_Pa); Pa[ILMath.full, i - 1] = out_Pa; } //Hold the demand for some seconds if (ILMath.mod(i, ILMath.round(config.PRefSampleTime / config.DT)) == 2) //??? { P_ref[ILMath.full, i - 1] = P_ref_new; } else { if (config.PowerRefInterpolation) { alpha = 0.01; P_ref[ILMath.full, i - 1] = (1 - alpha) * P_ref[ILMath.full, i - 1 - 1] + (alpha) * P_ref_new; } else { P_ref[ILMath.full, i - 1] = P_ref_new; } } //Calculate control for each individual turbine - should be moved to the //turbine (drivetrain) model. //Torque controller for (var j = 1; j <= parm.N; j++) { if ((x.GetValue(j - 1, 0) * 97 >= VS_RtGnSp) || (u.GetValue(j - 1, 0) >= 1)) // We are in region 3 - power is constant { u.SetValue(P_ref.GetValue(j - 1, i - 1) / x.GetValue(j - 1, 0), j - 1, 1); } else if (x.GetValue(j - 1, 0) * 97 <= VS_CtInSp) //! We are in region 1 - torque is zero { u.SetValue(0.0, j - 1, 1); } else //! We are in region 2 - optimal torque is proportional to the square of the generator speed { u.SetValue(97 * VS_Rgn2K * x.GetValue(j - 1, 0) * x.GetValue(j - 1, 0) * Math.Pow(97, 2), j - 1, 1); } } //Rate limit torque change // u(:,2) - Mg_old; Mg_max_rate = 1e6 * config.DT; u[ILMath.full, 1] = ILMath.sign(u[ILMath.full, 1] - Mg_old) * ILMath.min(ILMath.abs(u[ILMath.full, 1] - Mg_old), Mg_max_rate) + Mg_old; //Pitch controller e = 97 * (omega0 * ILMath.ones(parm.N, 1) - x[ILMath.full, 0]); ee = ee - config.DT * e; ee = ILMath.min(ILMath.max(ee, PC_MinPit / Ki), PC_MaxPit / Ki); u[ILMath.full, 0] = -Kp * config.DT * e + Ki * ee; for (var j = 1; j <= parm.N; j++) { u.SetValue(Math.Min(Math.Max(u.GetValue(j - 1, 0), PC_MinPit), PC_MaxPit), j - 1, 0); } if (!config.EnableTurbineDynamics) { u = u0; } Mg[ILMath.full, i - 1] = u[ILMath.full, 1]; Mg_old = Mg[ILMath.full, i - 1]; beta[ILMath.full, i - 1] = u[ILMath.full, 0]; //Set pitch //Turbine dynamics - can be simplified if (config.EnableTurbineDynamics) { for (var j = 1; j <= parm.N; j++) { double out_x; double out_Ct; double out_Cp; turbineModel.Model(x[j - 1, ILMath.full], u[j - 1, ILMath.full], wt, env, config.DT, out out_x, out out_Ct, out out_Cp); x.SetValue(out_x, j - 1, 0); Ct.SetValue(out_Ct, i - 1, j - 1); Cp.SetValue(out_Cp, i - 1, j - 1); } } else { Ct[i - 1, ILMath.full] = parm.Ct; Cp[i - 1, ILMath.full] = parm.Cp; x[ILMath.full, 0] = parm.ratedSpeed;//Rotational speed } Omega[ILMath.full, i - 1] = x[ILMath.full, 0]; Power[ILMath.full, i - 1] = Omega[ILMath.full, i - 1] * Mg[ILMath.full, i - 1]; } //% Save output data out_ = (config.DT * (ILMath.counter(0, 1, config.TimeLine()))); out_ = out_.Concat(v_nac.T, 1); out_ = out_.Concat(Omega.T, 1); out_ = out_.Concat(beta.T, 1); out_ = out_.Concat(P_ref.T, 1); out_ = out_.Concat(Ct, 1); out_ = out_.Concat(Cp, 1); out_ = out_.Concat(Pa.T, 1); out_ = out_.Concat(Mg.T, 1); out_ = out_.Concat(Power.T, 1); //Ttotal power demand var l = config.NTurbines * 3 + 1; var r = l + config.NTurbines - 1; out_ = out_.Concat(ILMath.sum(out_[ILMath.full, ILMath.r(l, r)], 1) / 1e6, 1); // P_ref sum l = config.NTurbines * 6 + 1; r = l + config.NTurbines - 1; out_ = out_.Concat(ILMath.sum(out_[ILMath.full, ILMath.r(l, r)], 1) / 1e6, 1); // Pa sum. 'Power Demand' out_ = out_.Concat(ILMath.sum(Power).T / 1e6, 1); // 'Actual Production' //Ttotal power demand out_ = out_.Concat(ILMath.sum(P_ref.T, 1), 1); // 'Demand' out_ = out_.Concat(ILMath.sum(Pa.T, 1), 1); // 'Available' out_ = out_.Concat(ILMath.sum(Mg * Omega).T, 1); // 'Actual' //Total power produced out_ = out_.Concat((Mg * Omega).T, 1); var out_doubleArray = new double[out_.Size[0]][]; for (int i = 0; i <= out_doubleArray.GetLength(0) - 1; i++) { out_doubleArray[i] = new double[out_.Size[1]]; for (int j = 0; j <= out_doubleArray[i].GetLength(0) - 1; j++) { out_doubleArray[i][j] = out_.GetValue(i, j); } } return(out_doubleArray); }