예제 #1
0
 public ResultsContainer(LateralDimensions lateral, int nx = -1, int nx_offset = 0)
 {
     Lateral      = lateral;
     LevelFields  = new List <AllFieldsAtLevel>();
     LocalNx      = nx < 0 ? lateral.Nx : nx;
     LocalNxStart = nx_offset;
 }
예제 #2
0
        private static double FindRhoMinInsideAnomaly(LateralDimensions dimensions, ObservationSite site)
        {
            var minX = FindMinXInsideAnomaly(dimensions, site);
            var minY = FindMinYInsideAnomaly(dimensions, site);

            return((double)Min(minX, minY));
        }
예제 #3
0
        public static unsafe AllFieldsAtSite GetSite(this AllFieldsAtLevel level, LateralDimensions lateral, int i, int j, int shiftx = 0)
        {
            int ny = lateral.Ny;

            Func <AnomalyCurrent, ComplexVector> get = (f1) => new ComplexVector(
                f1.Ptr[(i * ny + j) * 3],
                f1.Ptr[(i * ny + j) * 3 + 1],
                f1.Ptr[(i * ny + j) * 3 + 2]);

            var x    = lateral.CellSizeX * (i + shiftx) + lateral.CellSizeX / 2 + level.Level.ShiftAlongX;
            var y    = lateral.CellSizeY * j + lateral.CellSizeY / 2 + level.Level.ShiftAlongY;
            var z    = level.Level.Z;
            var name = level.Level.Name;

            return(new AllFieldsAtSite(new ObservationSite(x, y, z, name))
            {
                AnomalyE1 = get(level.AnomalyE1),
                AnomalyE2 = get(level.AnomalyE2),
                AnomalyH1 = get(level.AnomalyH1),
                AnomalyH2 = get(level.AnomalyH2),

                NormalE1 = get(level.NormalE1),
                NormalE2 = get(level.NormalE2),
                NormalH1 = get(level.NormalH1),
                NormalH2 = get(level.NormalH2),
            });
        }
예제 #4
0
        public ScalarPlansCreater(LateralDimensions lateral, HankelCoefficients hankel, int numberOfHankels)
        {
            _lateral = lateral;
            _hankel  = hankel;

            _numberOfHankels = Math.Abs(numberOfHankels);
        }
예제 #5
0
        private CartesianAnomaly CreateAnomaly(MeshParameters mesh, LateralDimensions lateral)
        {
            _logger.WriteStatus("\tCreating anomaly ...");

            var size   = new Size2D(mesh.Nx, mesh.Ny);
            var layers = new CartesianAnomalyLayer[mesh.Nz];

            var zFragmentation = mesh.CreateAnomalyFragmentation(_minZ, _maxZ);

            WriteZFragmentation(zFragmentation);

            _logger.WriteStatus("\tCreating anomaly layers ...");

            for (int i = 0; i < layers.Length; i++)
            {
                layers[i] = new CartesianAnomalyLayer(zFragmentation[i], zFragmentation[i + 1] - zFragmentation[i]);
            }

            var anomaly = new CartesianAnomaly(size, layers);

            anomaly.CreateSigma();

            _logger.WriteStatus("Anomaly structure created");

            FillModelDueToTopography(lateral, anomaly);

            return(anomaly);
        }
예제 #6
0
        private static double FindRhoMin(LateralDimensions dimensions)
        {
            var half1 = (double)(dimensions.CellSizeX / 2);
            var half2 = (double)(dimensions.CellSizeY / 2);

            return(Min(half1, half2));
        }
예제 #7
0
 public static XElement ToXElement(LateralDimensions lateralDimensions)
 {
     return(new XElement(LateralDimensionsItem,
                         new XAttribute(LateralDimensionsNxAttr, lateralDimensions.Nx),
                         new XAttribute(LateralDimensionsNyAttr, lateralDimensions.Ny),
                         new XAttribute(LateralDimensionsDxAttr, lateralDimensions.CellSizeX),
                         new XAttribute(LateralDimensionsDyAttr, lateralDimensions.CellSizeY)));
 }
예제 #8
0
 public static void CheckNumberOfProcesses(this Mpi mpi, LateralDimensions lateral)
 {
     if ((2 * lateral.Nx) % mpi.Size != 0)
     {
         throw new InvalidOperationException(
                   $"Number of MPI processes {mpi.Size} is not correct fo current Nx {lateral.Nx}");
     }
 }
예제 #9
0
        private static double FindRhoMin(LateralDimensions dimensions, ObservationSite site)
        {
            if (SiteIsInsideAnomaly(dimensions, site))
            {
                return(FindRhoMinInsideAnomaly(dimensions, site));
            }

            return(FindRhoMinOutsideAnomaly(dimensions, site));
        }
예제 #10
0
        public CartesianModel(LateralDimensions lateral, CartesianSection1D section1D, CartesianAnomaly anomaly)
        {
            if (section1D.NumberOfLayers == 0)
            {
                throw new ArgumentOutOfRangeException(nameof(section1D));
            }

            LateralDimensions = lateral;
            Section1D         = section1D;
            Anomaly           = anomaly;
        }
예제 #11
0
        public CartesianModel CreateModel(MeshParameters mesh, decimal xCellSize, decimal yCellSize)
        {
            var lateral   = new LateralDimensions(mesh.Nx, mesh.Ny, xCellSize, yCellSize);
            var section1D = CreateSection1D();
            var anomaly   = CreateAnomaly(mesh, lateral);

            var model = new CartesianModel(lateral, section1D, anomaly);


            return(model);
        }
예제 #12
0
        private static double FindRhoMinOutsideAnomaly(LateralDimensions dimensions, ObservationSite site)
        {
            var rhos = new[]
            {
                Abs(site.X),
                Abs(site.Y),
                Abs(site.X - dimensions.Nx * dimensions.CellSizeX),
                Abs(site.Y - dimensions.Ny * dimensions.CellSizeY),
            };

            return((double)rhos.Min());
        }
예제 #13
0
        public static double FindRhoMax(LateralDimensions dim, decimal shiftX, decimal shiftY)
        {
            double[] rhos =
            {
                FindRhoMaxByFourPoints(dim, shiftX, shiftY,                            0,                            0),
                FindRhoMaxByFourPoints(dim, shiftX, shiftY,                            0, dim.CellSizeY * (dim.Ny - 1)),
                FindRhoMaxByFourPoints(dim, shiftX, shiftY, dim.CellSizeX * (dim.Nx - 1), dim.CellSizeY * (dim.Ny - 1)),
                FindRhoMaxByFourPoints(dim, shiftX, shiftY, dim.CellSizeX * (dim.Nx - 1), 0)
            };

            return(rhos.Max());
        }
예제 #14
0
        private static double FindRhoMax(LateralDimensions dim, decimal srcX, decimal srcY, decimal shiftX, decimal shiftY)
        {
            double[] rhos =
            {
                FindRhoMaxByFourPoints(dim, shiftX, shiftY, srcX,                                srcY),
                FindRhoMaxByFourPoints(dim, shiftX, shiftY, srcX,                                srcY + dim.CellSizeY * (dim.Ny - 1)),
                FindRhoMaxByFourPoints(dim, shiftX, shiftY, srcX + dim.CellSizeX * (dim.Nx - 1), srcY + dim.CellSizeY * (dim.Ny - 1)),
                FindRhoMaxByFourPoints(dim, shiftX, shiftY, srcX + dim.CellSizeX * (dim.Nx - 1), srcY)
            };

            return(rhos.Max());
        }
예제 #15
0
        private static double FindRhoMax(LateralDimensions dimensions)
        {
            var half1 = (double)(dimensions.CellSizeX / 2);
            var half2 = (double)(dimensions.CellSizeY / 2);

            var anomalySizeX = (double)(dimensions.Nx * dimensions.CellSizeX);
            var anomalySizeY = (double)(dimensions.Ny * dimensions.CellSizeY);

            var maxX = anomalySizeX - half1;
            var maxY = anomalySizeY - half2;

            return(Sqrt(maxX * maxX + maxY * maxY));
        }
예제 #16
0
        public static int CalcLocalNxStart(this Mpi mpi, LateralDimensions lateral)
        {
            var fullNx = lateral.Nx * 2;

            if (fullNx % mpi.Size != 0)
            {
                throw new ArgumentException($"fullNx % mpi.Size != 0, mpi.Size = [{mpi.Size}], fullNx = [{fullNx}]");
            }

            var localNxSize = fullNx / mpi.Size;

            return(localNxSize * mpi.Rank);
        }
예제 #17
0
        private void FillModelDueToTopography(LateralDimensions lateral, CartesianAnomaly anomaly)
        {
            var shift = _shift;

            var xSize = (double)lateral.CellSizeX;
            var ySize = (double)lateral.CellSizeY;

            var zLength = anomaly.Layers.Count();


            System.Threading.Tasks.Parallel.For(0, lateral.Nx, i =>

                                                //for (int i = 0; i < lateral.Nx; i++)
            {
                _logger.WriteStatus($"nx: {i + 1} of {lateral.Nx}");

                for (int j = 0; j < lateral.Ny; j++)
                {
                    var x = i * xSize;
                    var y = j * ySize;

                    var depths = _topography.GetDepths(x - shift.X, y - shift.Y, xSize, ySize);

                    for (int k = 0; k < zLength; k++)
                    {
                        var z0 = anomaly.Layers[k].Depth;
                        var z1 = z0 + anomaly.Layers[k].Thickness;

                        double impact = CaculateDepthImpact(depths, z0, z1);

                        if (impact == 1)
                        {
                            for (int k2 = k; k2 < zLength; k2++)
                            {
                                anomaly.Sigma[i, j, k2] = CrustConductivity;
                            }
                            break;
                        }

                        anomaly.Sigma[i, j, k] = impact == 0
                            ? OceanConductivity
                            : CalculateCunductivity(impact, OceanConductivity, CrustConductivity);
                    }
                }
            });
        }
예제 #18
0
        private static double FindRhoMaxByFourPoints(LateralDimensions dim, decimal shiftX, decimal shiftY, decimal x0, decimal y0)
        {
            var x1 = shiftX - dim.CellSizeX / 2;
            var y1 = shiftY - dim.CellSizeY / 2;
            var x2 = x1 + dim.CellSizeX * dim.Nx;
            var y2 = y1 + dim.CellSizeY * dim.Ny;

            double[] rhos =
            {
                Sqrt((double)((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0))),
                Sqrt((double)((x2 - x0) * (x2 - x0) + (y1 - y0) * (y1 - y0))),
                Sqrt((double)((x2 - x0) * (x2 - x0) + (y2 - y0) * (y2 - y0))),
                Sqrt((double)((x1 - x0) * (x1 - x0) + (y2 - y0) * (y2 - y0)))
            };

            return(rhos.Max());
        }
예제 #19
0
        private CartesianModel Convert(MeshParameters mesh, decimal[] anomalyZSegmentation)
        {
            var xCellSize = (EndX - StartX) / mesh.Nx;
            var yCellSize = (EndY - StartY) / mesh.Ny;

            if (!CheckSimpleGriddingPossibility(xCellSize, yCellSize))
            {
                throw new InvalidOperationException("!CheckSimpleGriddingPossibility(xCellSize, yCellSize)");
            }

            var lateral = new LateralDimensions(mesh.Nx, mesh.Ny, xCellSize, yCellSize);

            var section1D = GetSection1D();
            var anomaly   = ConvertAnomaly(lateral, section1D, anomalyZSegmentation);

            return(new CartesianModel(lateral, section1D, anomaly));
        }
예제 #20
0
        private void FillLateralGriddingFor(double[,,] sigma, int k, LateralDimensions lateral, double layer1DValue)
        {
            decimal x0 = StartX;
            decimal y0 = StartY;

            for (int i = LocalNxStart; i < LocalNxStart + LocalNxLength; i++)
            {
                for (int j = 0; j < lateral.Ny; j++)
                {
                    var xStart = x0 + i * lateral.CellSizeX;
                    var yStart = y0 + j * lateral.CellSizeY;

                    sigma[i - LocalNxStart, j, k]
                        = GetValueFor(xStart, lateral.CellSizeX,
                                      yStart, lateral.CellSizeY,
                                      layer1DValue);
                }
            }
        }
예제 #21
0
        private static CartesianAnomaly LoadAnomalies(string path, LateralDimensions lateral, XElement xmodel)
        {
            var xanomaly = xmodel.Element(AnomalySection);

            var size          = new Size2D(lateral.Nx, lateral.Ny);
            var anomalyLayers = new List <CartesianAnomalyLayer>();

            if (xanomaly == null)
            {
                return(new CartesianAnomaly(size, anomalyLayers));
            }

            foreach (var xlayer in xanomaly.Elements(AnomalyLayer))
            {
                var loadedLayer = ReadAnomalyLayer(xlayer, size, path);
                anomalyLayers.Add(loadedLayer);
            }

            return(new CartesianAnomaly(size, anomalyLayers));
        }
예제 #22
0
        private static double FindRhoMax(LateralDimensions dimensions, ObservationSite site)
        {
            if (site == null)
            {
                throw new ArgumentNullException(nameof(site));
            }

            var anomalySizeX = dimensions.Nx * dimensions.CellSizeX;
            var anomalySizeY = dimensions.Ny * dimensions.CellSizeY;

            var anomalyXStart = 0;
            var anomalyYStart = 0;

            var anomalyXEnd = anomalyXStart + anomalySizeX;
            var anomalyYEnd = anomalyYStart + anomalySizeY;

            var maxX = (double)Max(Abs(anomalyXStart - site.X), Abs(anomalyXEnd - site.X));
            var maxY = (double)Max(Abs(anomalyYStart - site.Y), Abs(anomalyYEnd - site.Y));

            return(Sqrt(maxX * maxX + maxY * maxY));
        }
예제 #23
0
        public static ResultsContainer Load(XDocument xdoc, LateralDimensions lateral = default(LateralDimensions))
        {
            var xresult = xdoc.Element("ResultsMT");

            if (xresult == null)
            {
                throw new ArgumentOutOfRangeException("xdoc");
            }

            if (lateral == default(LateralDimensions))
            {
                lateral = ModelReader.LateralDimensionsFromXElement(xresult);
            }

            if (lateral == default(LateralDimensions))
            {
                throw new InvalidOperationException("no lateral dimensions");
            }

            var xfreq = xresult.Element("Frequencies");
            var xobs  = xresult.Element("Observations");
            var xvals = xresult.Element("Values");

            if (xfreq == null)
            {
                throw new InvalidDataException("Frequencies");
            }
            if (xobs == null)
            {
                throw new InvalidDataException("Observations");
            }
            if (xvals == null)
            {
                throw new InvalidDataException("Values");
            }

            var result = new ResultsContainer(lateral);

            return(result);
        }
예제 #24
0
        private CartesianAnomaly ConvertAnomaly(LateralDimensions lateral, CartesianSection1D section1D, decimal[] anomalyZSegmentation)
        {
            var allLayers = new CartesianAnomalyLayer[anomalyZSegmentation.Length - 1];

            for (int k = 0; k < allLayers.Length; k++)
            {
                decimal zStart = anomalyZSegmentation[k];
                decimal zEnd   = anomalyZSegmentation[k + 1];

                var thickness = zEnd - zStart;

                allLayers[k] = new CartesianAnomalyLayer(zStart, thickness);
            }

            var anomaly = new CartesianAnomaly(new Size2D(LocalNxLength, lateral.Ny), allLayers);

            if (_createSigma)
            {
                anomaly.CreateSigma();
                FillSigma(section1D, anomaly, lateral);
            }

            return(anomaly);
        }
예제 #25
0
 protected abstract void FillSigma(CartesianSection1D section1D, CartesianAnomaly anomaly, LateralDimensions lateral);
예제 #26
0
        //     public void SaveToFile(string fileName) => SaveToXDocument().Save(fileName);

        public static ResultsContainer Load(string fileName, LateralDimensions lateral = default(LateralDimensions))
        => Load(XDocument.Load(fileName), lateral);
예제 #27
0
 private static void SaveLateralDimensions(XElement xmodel, LateralDimensions lateral)
 {
     xmodel.Add(ToXElement(lateral));
 }
예제 #28
0
        protected override void FillSigma(CartesianSection1D section1D, CartesianAnomaly anomaly, LateralDimensions lateral)
        {
            for (int k = 0; k < anomaly.Layers.Count; k++)
            {
                var     layer  = anomaly.Layers[k];
                decimal zStart = layer.Depth;
                decimal zEnd   = layer.Depth + layer.Thickness;

                var index = ModelUtils.FindCorrespondingBackgroundLayerIndex(section1D, layer);
                var value = section1D[index].Sigma;

                PrepareLayer(zStart, zEnd);
                FillLateralGriddingFor(anomaly.Sigma, k, lateral, value);
            }
        }
예제 #29
0
 public static int CalcLocalNxLength(this Mpi mpi, LateralDimensions lateral)
 => CalcLocalNxLength(mpi, lateral.Nx * 2);
예제 #30
0
        protected override void FillSigma(CartesianSection1D section1D, CartesianAnomaly anomaly, LateralDimensions lateral)
        {
            var x0 = (double)StartX;
            var y0 = (double)StartY;

            var xSize = (double)lateral.CellSizeX;
            var ySize = (double)lateral.CellSizeY;

            var zLength = anomaly.Layers.Count();

            for (int i = LocalNxStart; i < LocalNxStart + LocalNxLength; i++)
            {
                Logger.WriteStatus($"nx: {i + 1} of {lateral.Nx}");

                for (int j = 0; j < lateral.Ny; j++)
                {
                    var x = x0 + i * xSize;
                    var y = y0 + j * ySize;

                    var depths = _topography.GetDepths(x, y, xSize, ySize);

                    for (int k = 0; k < zLength; k++)
                    {
                        var z0 = anomaly.Layers[k].Depth;
                        var z1 = z0 + anomaly.Layers[k].Thickness;

                        double impact = CaculateDepthImpact(depths, z0, z1);

                        if (impact == 1)
                        {
                            for (int k2 = k; k2 < zLength; k2++)
                            {
                                anomaly.Sigma[i, j, k2] = CrustConductivity;
                            }
                            break;
                        }

                        var topCond = z1 > section1D.ZeroAirLevelAlongZ ? OceanConductivity : AirConductivity;

                        anomaly.Sigma[i, j, k] = impact == 0
                            ? topCond
                            : CalculateCunductivity(impact, topCond, CrustConductivity);
                    }
                }
            }
        }