コード例 #1
0
        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();
            }
        }
コード例 #2
0
        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)");
            }
        }
コード例 #3
0
        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];
                }
            }
        }
コード例 #4
0
        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;
            }
        }
コード例 #5
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;
            }
        }
コード例 #6
0
        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;
                }
            }
        }
コード例 #7
0
        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];
                }
            }
        }