//, ref double[] D, ref double[] T)///Add 'D' term, for distance traveled laterally before exit. One number for each direction. public static Complex[][] Transfer_Matrix_Explicit_Alpha(bool freq_log, bool Rigid_Backed, int sample_Freq, double c_sound, List<ABS_Layer> LayerList, ref double[] frequency, ref Complex[] anglesdeg) { if (freq_log) { //3rd octave band frequencies... List<double> freq = new List<double>(); double f = 15.625; int ct = 1; while (f < sample_Freq / 2) { ct++; f = 15.625 * Math.Pow(2, ct / 3); freq.Add(f); } frequency = freq.ToArray(); } else { //Linear frequency scale frequency = new double[4096]; double step = (sample_Freq / 2) / 4096; for (int i = 0; i < frequency.Length; i++) frequency[i] = (i + .5) * step; } anglesdeg = new Complex[(int)(180 / 5)]; double[] Angle = new double[anglesdeg.Length]; Complex[][] sintheta_inc = new Complex[36][]; Complex[][][] Angle_Inc = new Complex[LayerList.Count][][]; Complex[] K_Air = AbsorptionModels.Operations.Air_Wavenumber(c_sound, frequency); Complex[] Zc_Air = AbsorptionModels.Operations.Air_CharImpedance(1.2, c_sound, frequency); for (double a = 2.5, i = 0; a <= 180; a += 5, i++) { sintheta_inc[(int)i] = new Complex[frequency.Length]; anglesdeg[(int)i] = 90 - a; if (a <= 90) Angle[(int)i] = (90 - a) * Utilities.Numerics.Pi_180; sintheta_inc[(int)i][0] = Complex.Sin(a <= 90 ? Angle[(int)i] : Angle[36 - (int)i]); for (int j = 1; j < sintheta_inc[(int)i].Length; j++) sintheta_inc[(int)i][j] = sintheta_inc[(int)i][0]; } SparseMatrix[][][] T = new SparseMatrix[LayerList.Count][][]; for (int a = 0; a < anglesdeg.Length; a++) { //sintheta_trans[i][j] = K0[j] * sintheta_inc[i][j] / K[j]; //Kxi[i][j] = Complex.Sqrt(K[j] * K[j] * (1 - sintheta_trans[i][j] * sintheta_trans[i][j])); } for (int i = LayerList.Count - 1; i >= 0; i--) { ABS_Layer Layer_i = (LayerList[i] as ABS_Layer); T[i] = new SparseMatrix[anglesdeg.Length][]; for(int a = 0; a < anglesdeg.Length; a++) { T[i][a] = new SparseMatrix[4096]; double sintheta = Math.Sin(Angle[a]); switch (Layer_i.T) { case ABS_Layer.LayerType.AirSpace: for(int f = 0; f < 4096; f++) { Complex Ksintheta = K_Air[f] * sintheta; T[i][a][f] = Explicit_TMM.FluidMatrix(Layer_i.depth * 1000, Complex.Sqrt(K_Air[f] * K_Air[f] - Ksintheta * Ksintheta), frequency[f], 1.2); } break; case ABS_Layer.LayerType.PorousDB: Complex[] Kdb = Equivalent_Fluids.DelaneyBazley_WNumber(1.2, c_sound, Layer_i.Flow_Resist, frequency); for(int f = 0; f < 4096; f++) { Complex Ksintheta = K_Air[f] * sintheta; T[i][a][f] = Explicit_TMM.FluidMatrix(Layer_i.depth, Complex.Sqrt(Kdb[f] * Kdb[f] - Ksintheta * Ksintheta), frequency[f], 1.2); } break; case ABS_Layer.LayerType.PorousCA: Complex[] Kca = Equivalent_Fluids.DBAllardChampoux_WNumber(1.2, c_sound, Layer_i.Flow_Resist, frequency); for(int f = 0; f < 4096; f++) { Complex Ksintheta = K_Air[f] * sintheta; T[i][a][f] = Explicit_TMM.FluidMatrix(Layer_i.depth, Complex.Sqrt(Kca[f] * Kca[f] - Ksintheta * Ksintheta), frequency[f], 1.2); } break; case ABS_Layer.LayerType.PorousM: Complex[] Km = Equivalent_Fluids.DB_Miki_WNumber(1.2, c_sound, Layer_i.Flow_Resist, frequency); for(int f = 0; f < 4096; f++) { //Complex Ksintheta = K_Air[f] * sintheta; T[i][a][f] = Explicit_TMM.FluidMatrix(Layer_i.depth, Complex.Sqrt(Km[f] * Km[f] * (1 - sintheta * sintheta)), frequency[f], 1.2); } break; //case ABS_Layer.LayerType.Perforated_Modal: //case ABS_Layer.LayerType.Slotted_Modal: //case ABS_Layer.LayerType.CircularPerforations: //case ABS_Layer.LayerType.SquarePerforations: //case ABS_Layer.LayerType.Slots: //case ABS_Layer.LayerType.MicroPerforated: //case ABS_Layer.LayerType.Microslit: default: throw new Exception("Unknown Layer Type"); } } } SparseMatrix[] I = new SparseMatrix[LayerList.Count]; SparseMatrix[] J = new SparseMatrix[LayerList.Count]; //SparseMatrix Yterm; //if ((int)LayerList[0].T <= 10) //{ // //Fluid Layer // Yterm = Explicit_TMM.RigidTerminationF(); //} //else if ((int)LayerList[0].T == 15 || (int)LayerList[0].T == 16) //{ // //Biot Porous absorbers // Yterm = Explicit_TMM.RigidTerminationP(); //} //else //{ // //Solid Layer // Yterm = Explicit_TMM.RigidTerminationS(); //} //Get Interface Matrices for (int i = 0; i < LayerList.Count; i++) { if (i == LayerList.Count - 1) { if ((int)LayerList[i].T <= 10) { //Fluid Layer I[i] = MathNet.Numerics.LinearAlgebra.Complex.SparseMatrix.CreateIdentity(2); J[i] = MathNet.Numerics.LinearAlgebra.Complex.SparseMatrix.CreateIdentity(2); } else if ((int)LayerList[i].T == 15 || (int)LayerList[i].T == 16) { //Biot Porous absorbers I[i] = Explicit_TMM.Interfacepf_Porous(LayerList[i].porosity); J[i] = Explicit_TMM.Interfacepf_Fluid(LayerList[i].porosity); } else { //Solid Layer I[i] = Explicit_TMM.InterfaceSF_Solid(); J[i] = Explicit_TMM.InterfaceSF_Fluid(); } continue; } if ((int)LayerList[i].T <= 10) { //Fluid Layer if ((int)LayerList[i + 1].T <= 10) { //Fluid Layer I[i] = MathNet.Numerics.LinearAlgebra.Complex.SparseMatrix.CreateIdentity(2); J[i] = MathNet.Numerics.LinearAlgebra.Complex.SparseMatrix.CreateIdentity(2); } else if ((int)LayerList[i + 1].T == 15 || (int)LayerList[i + 1].T == 16) { //Biot Porous absorbers I[i] = Explicit_TMM.Interfacepf_Fluid(LayerList[i + 1].porosity) as SparseMatrix; J[i] = Explicit_TMM.Interfacepf_Porous(LayerList[i + 1].porosity); } else { //Solid Layer I[i] = SparseMatrix.CreateIdentity(4); J[i] = SparseMatrix.CreateIdentity(4); } } else if ((int)LayerList[i].T == 15 || (int)LayerList[i + 1].T == 16) { //Biot Porous absorbers if ((int)LayerList[i + 1].T <= 10) { //Fluid Layer I[i] = Explicit_TMM.Interfacepf_Porous(LayerList[i].porosity); J[i] = Explicit_TMM.Interfacepf_Fluid(LayerList[i].porosity); } else if ((int)LayerList[i + 1].T == 15 || (int)LayerList[i + 1].T == 16) { //Biot Porous absorbers I[i] = Explicit_TMM.InterfacePP(LayerList[i].porosity, LayerList[i + 1].porosity);//TODO: Check that we have the right porosities in the right places... J[i] = SparseMatrix.CreateIdentity(6); } else { //Solid Layer I[i] = Explicit_TMM.Interfacesp_Porous(); J[i] = Explicit_TMM.Interfacesp_Solid(); } } else { //Solid Layer if ((int)LayerList[i + 1].T <= 10) { //Fluid Layer I[i] = Explicit_TMM.InterfaceSF_Solid(); J[i] = Explicit_TMM.InterfaceSF_Fluid(); } else if ((int)LayerList[i + 1].T == 15 || (int)LayerList[i + 1].T == 16) { //Biot Porous absorbers I[i] = Explicit_TMM.Interfacesp_Solid(); J[i] = Explicit_TMM.Interfacesp_Porous(); } else { //Solid Layer I[i] = Explicit_TMM.InterfaceSF_Fluid() as SparseMatrix; J[i] = Explicit_TMM.InterfaceSF_Solid(); } } } //List<SparseMatrix[][]> T = Layer(LayerList.Count - 1, LayerList, K_Air, sintheta_inc, K_Air, c_sound, frequency); Complex[][] Z = new Complex[sintheta_inc.Length][]; for (int a = 0; a < sintheta_inc.Length; a++) { Z[a] = new Complex[sintheta_inc[a].Length]; for(int f = 0; f < sintheta_inc[a].Length; f++) { SparseMatrix V; if (T.First()[a][f].RowCount == 2) { V = new SparseMatrix(2, 1); V[0, 0] = 1; } else if (T.First()[a][f].RowCount == 4) { V = new SparseMatrix(4, 1); V[0, 0] = 1; V[1, 0] = 1; } else { V = new SparseMatrix(6, 1); V[0, 0] = 1; V[1, 0] = 1; V[2, 0] = 1; } for (int i = 0; i < T.Length; i++) { V = -((J[i] * T[i][a][f]) * I[i].Inverse() as SparseMatrix) * V; //V = T[i][a][f] * V; } V = -(J.Last() * I.Last().Inverse() as SparseMatrix) * V; Z[a][f] = V[0, 0] * 100000 / V[1, 0]; } } return Z; }