public MeshInitializer(KrakenModule krakenModule) { NSSPPts = Enumerable.Repeat(0, krakenModule.MaxMedium + 1).ToList(); z = Enumerable.Repeat(0d, maxSSP + 1).ToList(); if (krakenModule.BCTop[0] == 'S') { cpSpline = new List <List <Complex> >(4 + 1); for (var i = 0; i < 5; i++) { cpSpline.Add(Enumerable.Repeat(new Complex(), maxSSP + 1).ToList()); } csSpline = new List <List <Complex> >(4 + 1); for (var i = 0; i < 5; i++) { csSpline.Add(Enumerable.Repeat(new Complex(), maxSSP + 1).ToList()); } rhoSpline = new List <List <Complex> >(4 + 1); for (var i = 0; i < 5; i++) { rhoSpline.Add(Enumerable.Repeat(new Complex(), maxSSP + 1).ToList()); } } else { alpha = Enumerable.Repeat(new Complex(), maxSSP + 1).ToList(); beta = Enumerable.Repeat(new Complex(), maxSSP + 1).ToList(); rho = Enumerable.Repeat(0d, maxSSP + 1).ToList(); } }
public void EvaluateSSP(KrakenModule krakenModule, List <double> depth, List <Complex> cP, List <Complex> cS, List <double> RhoTop, int medium, ref int n1, int offset, double Frequency, string SSPType, string attenUnit, string task, List <List <double> > ssp) { switch (SSPType) { case "N": N2Linear(krakenModule, depth, cP, cS, RhoTop, medium, ref n1, offset, Frequency, attenUnit, task, ssp); break; case "C": CLinear(krakenModule, depth, cP, cS, RhoTop, medium, ref n1, offset, Frequency, attenUnit, task, ssp); break; case "S": CubicSpline(krakenModule, depth, cP, cS, RhoTop, medium, ref n1, offset, Frequency, attenUnit, task, ssp); break; default: throw new KrakenException("Unknown profile option (SSPType)"); } }
public void ComputeBoundaryConditionImpedance(KrakenModule krakenModule, double x, string BCType, string botTop, Complex cPHS, Complex cSHS, double rhoHS, ref double f, ref double g, ref int iPow) { iPow = 0; var yV = Enumerable.Repeat(0d, 5 + 1).ToList(); if (BCType[0] == 'V' || BCType[0] == 'S' || BCType[0] == 'H' || BCType[0] == 'T' || BCType[0] == 'I') { f = 1.0; g = 0.0; yV[1] = f; yV[2] = g; yV[3] = 0.0; yV[4] = 0.0; yV[5] = 0.0; } if (BCType[0] == 'R') { f = 0.0; g = 1.0; yV[1] = f; yV[2] = g; yV[3] = 0.0; yV[4] = 0.0; yV[5] = 0.0; } if (BCType[0] == 'A') { Complex gammaS2, gammaP2, gammaS, gammaP; double mu; if (cSHS.Real > 0) { gammaS2 = x - krakenModule.Omega2 / Math.Pow(cSHS.Real, 2); gammaP2 = x - krakenModule.Omega2 / Math.Pow(cPHS.Real, 2); gammaS = Complex.Sqrt(gammaS2); gammaP = Complex.Sqrt(gammaP2); mu = rhoHS * Math.Pow(cSHS.Real, 2); yV[1] = ((gammaS * gammaP - x) / mu).Real; yV[2] = ((Complex.Pow((gammaS2 + x), 2) - 4.0 * gammaS * gammaP * x) * mu).Real; yV[3] = (2.0 * gammaS * gammaP - gammaS2 - x).Real; yV[4] = (gammaP * (x - gammaS2)).Real; yV[5] = (gammaS * (gammaS2 - x)).Real; f = krakenModule.Omega2 * yV[4]; g = yV[2]; if (g > 0) { krakenModule.ModeCount++; } } else { gammaP = Complex.Sqrt(x - krakenModule.Omega2 / Complex.Pow(cPHS, 2)); f = gammaP.Real; g = rhoHS; } } if (botTop == "TOP") { g = -g; } if (botTop == "TOP") { if (krakenModule.FirstAcoustic > 1) { for (var medium = 1; medium <= krakenModule.FirstAcoustic - 1; medium++) { ElasticDown(krakenModule, x, yV, ref iPow, medium); } f = krakenModule.Omega2 * yV[4]; g = yV[2]; } } else { if (krakenModule.LastAcoustic < krakenModule.NMedia) { for (var medium = krakenModule.NMedia; medium >= krakenModule.LastAcoustic + 1; medium--) { ElasticUp(krakenModule, x, yV, ref iPow, medium); } f = krakenModule.Omega2 * yV[4]; g = yV[2]; } } }
private void ElasticDown(KrakenModule krakenModule, double x, List <double> yV, ref int iPow, int medium) { var xV = Enumerable.Repeat(0d, 5 + 1).ToList(); var zV = Enumerable.Repeat(0d, 5 + 1).ToList(); double roof = Math.Pow(10, 50); double floor = Math.Pow(10, -50); int iPowR = 50; int iPowF = -50; double twoX, twoH, fourHX, xB3; int j; twoX = 2.0 * x; twoH = 2.0 * krakenModule.H[medium]; fourHX = 4.0 * krakenModule.H[medium] * x; j = krakenModule.Loc[medium] + 1; xB3 = x * krakenModule.B3[j] - krakenModule.Rho[j]; zV[1] = yV[1] + 0.5 * (krakenModule.B1[j] * yV[4] - krakenModule.B2[j] * yV[5]); zV[2] = yV[2] + 0.5 * (-krakenModule.Rho[j] * yV[4] - xB3 * yV[5]); zV[3] = yV[3] + 0.5 * (twoH * yV[4] + krakenModule.B4[j] * yV[5]); zV[4] = yV[4] + 0.5 * (xB3 * yV[1] + krakenModule.B2[j] * yV[2] - twoX * krakenModule.B4[j] * yV[3]); zV[5] = yV[5] + 0.5 * (krakenModule.Rho[j] * yV[1] - krakenModule.B1[j] * yV[2] - fourHX * yV[3]); for (var II = 1; II <= krakenModule.N[medium]; II++) { j += 1; for (var i = 0; i < yV.Count; i++) { xV[i] = yV[i]; } for (var i = 0; i < zV.Count; i++) { yV[i] = zV[i]; } xB3 = x * krakenModule.B3[j] - krakenModule.Rho[j]; zV[1] = xV[1] + (krakenModule.B1[j] * yV[4] - krakenModule.B2[j] * yV[5]); zV[2] = xV[2] + (-krakenModule.Rho[j] * yV[4] - xB3 * yV[5]); zV[3] = xV[3] + (twoH * yV[4] + krakenModule.B4[j] * yV[5]); zV[4] = xV[4] + (xB3 * yV[1] + krakenModule.B2[j] * yV[2] - twoX * krakenModule.B4[j] * yV[3]); zV[5] = xV[5] + (krakenModule.Rho[j] * yV[1] - krakenModule.B1[j] * yV[2] - fourHX * yV[3]); if (II != krakenModule.N[medium]) { if (Math.Abs(zV[2]) < floor) { for (var i = 0; i < zV.Count; i++) { yV[i] *= roof; zV[i] *= roof; } iPow -= iPowR; } if (Math.Abs(zV[2]) > roof) { for (var i = 0; i < zV.Count; i++) { yV[i] *= floor; zV[i] *= floor; } iPow -= iPowF; } } } for (var i = 1; i < yV.Count; i++) { yV[i] = (xV[i] + 2 * yV[i] + zV[i]) / 4.0; } }
public void ProccedMesh(KrakenModule krakenModule, List <List <double> > ssp, List <double> tahsp, List <double> tsp, List <double> bahsp) { string SSPType = krakenModule.BCTop[0].ToString(); string BCType = krakenModule.BCTop[1].ToString(); string attenUnit = krakenModule.BCTop[2].ToString(); if (krakenModule.BCTop.Length > 3) { attenUnit += krakenModule.BCTop[3].ToString(); } alphaR = 1500.0; betaR = 0.0; rhoR = 0.0; alphaI = 0.0; betaI = 0.0; var NElts = 0; var rho = new List <double>() { 0, 0 }; if (BCType == "A") { alphaR = tahsp[2]; betaR = tahsp[3]; rhoR = tahsp[4]; alphaI = tahsp[5]; betaI = tahsp[6]; if (alphaR == 0 || rhoR == 0) { throw new KrakenException("Sound speed or density vanishes in halfspace"); } krakenModule.CPTop = ConvertToSingleComplexWaveSpeed(alphaR, alphaI, krakenModule.Frequency, attenUnit); krakenModule.CSTop = ConvertToSingleComplexWaveSpeed(betaR, betaI, krakenModule.Frequency, attenUnit); krakenModule.RhoTop = rhoR; } if (BCType == "S" || BCType == "H" || BCType == "T" || BCType == "I") { krakenModule.BumpDensity = tsp[1]; krakenModule.Eta = tsp[2]; krakenModule.Xi = tsp[3]; } var cP = new List <Complex>(maxSSP + 1); var cS = new List <Complex>(maxSSP + 1); for (var medium = 1; medium <= krakenModule.NMedia; medium++) { if ((25 * krakenModule.Frequency / 1500) * Math.Pow(krakenModule.Sigma[medium], 2) > 1) { krakenModule.Warnings.Add("The Rayleigh roughness parameter might exceed the region of validity for the scatter approximation"); } var task = "INIT"; EvaluateSSP(krakenModule, krakenModule.Depth, cP, cS, rho, medium, ref NElts, 0, krakenModule.Frequency, SSPType, attenUnit, task, ssp); var c = alphaR; if (betaR > 0) { c = betaR; } var deltaZ = c / krakenModule.Frequency / 20; var nNeeded = (int)(krakenModule.Depth[medium + 1] - krakenModule.Depth[medium]) / deltaZ; nNeeded = Math.Max(nNeeded, 10); if (krakenModule.NG[medium] == 0) { krakenModule.NG[medium] = (int)nNeeded; } else if (krakenModule.NG[medium] < nNeeded / 2) { throw new KrakenException("Mesh is too coarse"); } } BCType = krakenModule.BCBottom[0].ToString(); if (BCType == "A") { alphaR = bahsp[2]; betaR = bahsp[3]; rhoR = bahsp[4]; alphaI = bahsp[5]; betaI = bahsp[6]; if (alphaR == 0 || rhoR == 0) { throw new KrakenException("Sound speed or density vanishes in halfspace"); } krakenModule.CPBottom = ConvertToSingleComplexWaveSpeed(alphaR, alphaI, krakenModule.Frequency, attenUnit); krakenModule.CSBottom = ConvertToSingleComplexWaveSpeed(betaR, betaI, krakenModule.Frequency, attenUnit); krakenModule.RhoBottom = rhoR; } }
private void CubicSpline(KrakenModule krakenModule, List <double> depth, List <Complex> cP, List <Complex> cS, List <double> RhoTop, int medium, ref int n1, int offset, double Frequency, string attenUnit, string task, List <List <double> > ssp) { int ILoc; if (task.Contains("INIT")) { NSSPPts[medium] = n1; if (medium == 1) { krakenModule.Loc[medium] = 0; } else { krakenModule.Loc[medium] = krakenModule.Loc[medium - 1] + NSSPPts[medium - 1]; } ILoc = krakenModule.Loc[medium]; n1 = 1; for (var i = 1; i <= maxSSP; i++) { try { int ind = ILoc + i; z[ind] = ssp[ind][1]; alphaR = ssp[ind][2]; betaR = ssp[ind][3]; rhoR = ssp[ind][4]; alphaI = ssp[ind][5]; betaI = ssp[ind][6]; cpSpline[1][ILoc + i] = ConvertToSingleComplexWaveSpeed(alphaR, alphaI, Frequency, attenUnit); csSpline[1][ILoc + i] = ConvertToSingleComplexWaveSpeed(betaR, betaI, Frequency, attenUnit); rhoSpline[1][ILoc + i] = rhoR; } catch (ArgumentOutOfRangeException) { throw new KrakenException("The SSP reading error. Check the medium info and the SSP values"); } if (Math.Abs(z[ILoc + i] - depth[medium + 1]) < 0.0000001 * depth[medium + 1]) { NSSPPts[medium] = n1; if (medium == 1) { depth[1] = z[1]; } if (NSSPPts[medium] == 1) { throw new KrakenException("The SSP must have at least 2 points in each layer"); } var IBCBEG = 0; var IBCEND = 0; var splineC = new SplineCalculator(); splineC.CalculateCubicSpline(z, cpSpline, ILoc, NSSPPts[medium], IBCBEG, IBCEND); splineC.CalculateCubicSpline(z, csSpline, ILoc, NSSPPts[medium], IBCBEG, IBCEND); splineC.CalculateCubicSpline(z, rhoSpline, ILoc, NSSPPts[medium], IBCBEG, IBCEND); return; } n1++; } throw new KrakenException("Number of SSP points exceeds limit"); } else { ILoc = NSSPPts[medium - 1]; var N = n1 - 1; var h = (z[ILoc + NSSPPts[medium]] - z[ILoc + 1]) / N; var Lay = 1; for (var i = offset; i <= n1 + offset - 1; i++) { double zT = z[ILoc + 1] + (i - offset) * h; if (i == n1 + offset) { zT = z[ILoc + NSSPPts[medium]]; } while (zT > z[ILoc + Lay + 1]) { Lay += 1; } var splineCalculator = new SplineCalculator(); var hSpline = zT - z[ILoc + Lay]; cP[i] = splineCalculator.CalculateExponentialSpline(cpSpline, ILoc + Lay, hSpline); cS[i] = splineCalculator.CalculateExponentialSpline(csSpline, ILoc + Lay, hSpline); RhoTop[i] = splineCalculator.CalculateExponentialSpline(rhoSpline, ILoc + Lay, hSpline).Real; } } }
private void CLinear(KrakenModule krakenModule, List <double> depth, List <Complex> cP, List <Complex> cS, List <double> RhoTop, int medium, ref int n1, int offset, double Frequency, string attenUnit, string task, List <List <double> > ssp) { int ILoc; if (task.Contains("INIT")) { NSSPPts[medium] = n1; if (medium == 1) { krakenModule.Loc[medium] = 0; } else { krakenModule.Loc[medium] = krakenModule.Loc[medium - 1] + NSSPPts[medium - 1]; } ILoc = krakenModule.Loc[medium]; n1 = 1; for (var i = 1; i <= maxSSP; i++) { try { int ind = ILoc + i; z[ind] = ssp[ind][1]; alphaR = ssp[ind][2]; betaR = ssp[ind][3]; rhoR = ssp[ind][4]; alphaI = ssp[ind][5]; betaI = ssp[ind][6]; } catch (ArgumentOutOfRangeException) { throw new KrakenException("SSP reading error. Check medium info and SSP values"); } alpha[ILoc + i] = ConvertToSingleComplexWaveSpeed(alphaR, alphaI, Frequency, attenUnit); beta[ILoc + i] = ConvertToSingleComplexWaveSpeed(betaR, betaI, Frequency, attenUnit); rho[ILoc + i] = rhoR; if (Math.Abs(z[ILoc + i] - depth[medium + 1]) < 0.0000001 * depth[medium + 1]) { NSSPPts[medium] = n1; if (medium == 1) { depth[1] = z[1]; } if (NSSPPts[medium] == 1) { throw new KrakenException("The SSP must have at least 2 points in each layer"); } return; } n1++; } throw new KrakenException("Number of SSP points exceeds limit"); } else { ILoc = NSSPPts[medium - 1]; var N = n1 - 1; var h = (z[ILoc + NSSPPts[medium]] - z[ILoc + 1]) / N; var Lay = 1; for (var i = offset; i <= n1 + offset - 1; i++) { double zT = z[ILoc + 1] + (i - offset) * h; if (i == n1 + offset) { zT = z[ILoc + NSSPPts[medium]]; } while (zT > z[ILoc + Lay + 1]) { Lay += 1; } var r = (zT - z[ILoc + Lay]) / (z[ILoc + Lay + 1] - z[ILoc + Lay]); cP[i] = (1.0 - r) * alpha[ILoc + Lay] + r * alpha[ILoc + Lay + 1]; cS[i] = (1.0 - r) * beta[ILoc + Lay] + r * beta[ILoc + Lay + 1]; RhoTop[i] = (1.0 - r) * rho[ILoc + Lay] + r * rho[ILoc + Lay + 1]; } } }