コード例 #1
0
 public void TransmitParticles(SimulationStructure structure, int step)
 {
     foreach (var core in structure.CoreGrid.GetCores())
     {
         foreach (NeighbourTransferSection section in core.Sections)
         {
             if (section.ToTransmit[0].Any())
             {
                 TransferParticles(section, 0, section.Grid, new Point3(-1, 0, 0), structure, step);
             }
             if (section.ToTransmit[1].Any())
             {
                 TransferParticles(section, 1, section.Grid, new Point3(1, 0, 0), structure, step);
             }
             if (section.ToTransmit[2].Any())
             {
                 TransferParticles(section, 2, section.Grid, new Point3(0, -1, 0), structure, step);
             }
             if (section.ToTransmit[3].Any())
             {
                 TransferParticles(section, 3, section.Grid, new Point3(0, 1, 0), structure, step);
             }
             if (section.ToTransmit[4].Any())
             {
                 TransferParticles(section, 4, section.Grid, new Point3(0, 0, -1), structure, step);
             }
             if (section.ToTransmit[5].Any())
             {
                 TransferParticles(section, 5, section.Grid, new Point3(0, 0, 1), structure, step);
             }
         }
     }
 }
コード例 #2
0
        public void MoveParticles(SimulationStructure structure, float step, int simStep)
        {
            var dampingF = (float)(1 / Math.Exp(step));

            foreach (var particleSection in structure.GetAllSections())
            {
                particleSection.ApplyToAllParticles(particle =>
                {
                    particle.Position += particle.Velocity * step;
                    particle.Velocity += step * (gravityPoint - particle.Position);
                    bouncer.BounceParticle(ref particle);
                    if (particle.Velocity.LengthSquared() > maxSpeedSquared)
                    {
                        particle.Velocity *= 0.9f;
                    }
                    return(particle);
                });
            }
            centerRemainTime -= step;
            if (centerRemainTime < 0)
            {
                UpdateGravityPoint(structure);
            }
            costCalculator.CalculateTotalCost(structure, simStep);
        }
 public void PutParticlesForTransmission(SimulationStructure simulationStructure)
 {
     foreach (KMeansSection section in simulationStructure.CoreGrid.GetCores().SelectMany(o => o.Sections))
     {
         for (var i = 0; i < section.CurrentParticles.Count; i++)
         {
             var particlePosition = section.CurrentParticles[i].Position;
             var sectionPosition  = section.CurrentPosition;
             var dDif             = calculatedSingleDimDif(particlePosition, sectionPosition, section);
             var bestDif          = dDif.Max();
             if (bestDif <= 0)
             {
                 continue;
             }
             for (var j = 0; j < 6; j++)
             {
                 if (bestDif != dDif[j])
                 {
                     continue;
                 }
                 section.ToTransmit[j].Add(section.CurrentParticles[i]);
                 section.CurrentParticles[i] = Particle.Null;
                 break;
             }
         }
         //o => !o.IsNull
         section.CurrentParticles = section.CurrentParticles.Where(o => !o.IsNull).ToList();
     }
 }
コード例 #4
0
 public void MoveParticles(SimulationStructure structure, float step, int simStep)
 {
     foreach (var allSection in structure.GetAllSections())
     {
         allSection.ApplyToAllParticles(
             particle =>
         {
             var randomAcceleration = step * acceleration *
                                      (
                 new Vector3((float)(randomizer.NextDouble() - 0.5d),
                             (float)(randomizer.NextDouble() - 0.5d),
                             (float)(randomizer.NextDouble() - 0.5d)) +
                 accelerationBias);
             particle.Velocity += randomAcceleration;
             if (particle.Velocity.LengthSquared() > maxSpeedSquared)
             {
                 particle.Velocity.Normalize();
                 particle.Velocity = particle.Velocity * (float)Math.Sqrt(maxSpeedSquared);
             }
             particle.Position += particle.Velocity * step;
             bouncer.BounceParticle(ref particle);
             return(particle);
         });
     }
     costCalculator.CalculateTotalCost(structure, simStep);
 }
コード例 #5
0
 public void PutParticlesForTransmission(SimulationStructure simulationStructure)
 {
     foreach (KMeansSection section in simulationStructure.CoreGrid.GetCores().SelectMany(o => o.Sections))
     {
         for (var i = 0; i < section.CurrentParticles.Count; i++)
         {
             var ownDistance   = Vector3.DistanceSquared(section.CurrentParticles[i].Position, section.CurrentPosition) * (1f + GrowParameter * section.CurrentParticles.Count);
             var minDistance   = ownDistance;
             var bestDirection = -1;
             for (var j = 0; j < 6; j++)
             {
                 var localDistance = Vector3.DistanceSquared(section.CurrentParticles[i].Position, section.NeighbourPositions[j]) * (1f + GrowParameter * section.neighbourSizes[j]);
                 if (!(localDistance < minDistance))
                 {
                     continue;
                 }
                 bestDirection = j;
                 minDistance   = localDistance;
             }
             if (bestDirection == -1)
             {
                 continue;
             }
             section.ToTransmit[bestDirection].Add(section.CurrentParticles[i]);
             section.CurrentParticles[i] = Particle.Null;
         }
         section.CurrentParticles = section.CurrentParticles.Where(o => !o.IsNull).ToList();
     }
 }
コード例 #6
0
        private void drawCoreCenters(SimulationStructure structure, Image <Rgb, byte> image)
        {
            foreach (var section in structure.CoreGrid.GetCores().SelectMany(c => c.Sections))
            {
                if (!(section is NeighbourTransferSection))
                {
                    break;
                }
                var curpos = ((NeighbourTransferSection)section).CurrentPosition;
                var coord  = getPictureCoordinatesFor(curpos.X, curpos.Z, structure);

                for (var i = -1; i < 2; i++)
                {
                    for (var j = -1; j < 2; j++)
                    {
                        try
                        {
                            image[coord.Item2 + i, coord.Item1 + j] = new Rgb(Color.Red);
                        }catch
                        {
                        }
                    }
                }
            }
        }
コード例 #7
0
 public void PutParticlesForTransmission(SimulationStructure simulationStructure)
 {
     foreach (KMeansSection section in simulationStructure.CoreGrid.GetCores().SelectMany(o => o.Sections))
     {
         PrepareSectionTransmission(section);
     }
 }
コード例 #8
0
 public void Sort(SimulationStructure simulationStructure, int step)
 {
     neighbourPositionGetter.GetOldPositionsNeighbours(simulationStructure);
     neighbourSizeGetter.GetOldSizesNeighbours(simulationStructure);
     positionUpdater.UpdateSectionPositions(simulationStructure);
     foreach (KMeansSection section in simulationStructure.CoreGrid.GetCores().SelectMany(o => o.Sections))
     {
         for (var i = 0; i < section.CurrentParticles.Count; i++)
         {
             var ownDistance   = Vector3.DistanceSquared(section.CurrentParticles[i].Position, section.CurrentPosition);
             var minDistance   = ownDistance;
             var bestDirection = -1;
             for (var j = 0; j < 6; j++)
             {
                 var localDistance = Vector3.DistanceSquared(section.CurrentParticles[i].Position, section.NeighbourPositions[j]);
                 if (!(localDistance < minDistance))
                 {
                     continue;
                 }
                 bestDirection = j;
                 minDistance   = localDistance;
             }
             if (bestDirection == -1)
             {
                 continue;
             }
             section.ToTransmit[bestDirection].Add(section.CurrentParticles[i]);
             section.CurrentParticles[i] = Particle.Null;
         }
         section.CurrentParticles = section.CurrentParticles.Where(o => !o.IsNull).ToList();
     }
     nTransmitter.TransmitParticles(simulationStructure, step);
 }
コード例 #9
0
 public void GetOldSizesNeighbours(SimulationStructure simulationStructure)
 {
     foreach (var section in simulationStructure.CoreGrid.GetCores().SelectMany(core => core.Sections.Cast <KMeansSection>()))
     {
         Point3           ownPos;
         IParticleSection otherParticleSection;
         section.Grid.SectionCoreMapping.TryGetValue(section, out ownPos);
         var ownSize = section.CurrentParticles.Count;
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(-1, 0, 0), out otherParticleSection))
         {
             section.neighbourSizes[0] = (((KMeansSection)otherParticleSection).CurrentParticles.Count + section.neighbourSizes[0] * inertia) / (inertia + 1);
         }
         else
         {
             section.neighbourSizes[0] = ownSize;
         }
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(1, 0, 0), out otherParticleSection))
         {
             section.neighbourSizes[1] = (((KMeansSection)otherParticleSection).CurrentParticles.Count + section.neighbourSizes[1] * inertia) / (inertia + 1);
         }
         else
         {
             section.neighbourSizes[1] = ownSize;
         }
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(0, -1, 0), out otherParticleSection))
         {
             section.neighbourSizes[2] = (section.neighbourSizes[2] * inertia + ((KMeansSection)otherParticleSection).CurrentParticles.Count) / (inertia + 1);
         }
         else
         {
             section.neighbourSizes[2] = ownSize;
         }
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(0, 1, 0), out otherParticleSection))
         {
             section.neighbourSizes[3] = (section.neighbourSizes[3] * inertia + ((KMeansSection)otherParticleSection).CurrentParticles.Count) / (inertia + 1);
         }
         else
         {
             section.neighbourSizes[3] = ownSize;
         }
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(0, 0, -1), out otherParticleSection))
         {
             section.neighbourSizes[4] = (section.neighbourSizes[4] * inertia + ((KMeansSection)otherParticleSection).CurrentParticles.Count) / (inertia + 1);
         }
         else
         {
             section.neighbourSizes[4] = ownSize;
         }
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(0, 0, 1), out otherParticleSection))
         {
             section.neighbourSizes[5] = (section.neighbourSizes[5] * inertia + ((KMeansSection)otherParticleSection).CurrentParticles.Count) / (inertia + 1);
         }
         else
         {
             section.neighbourSizes[5] = ownSize;
         }
         //TODO add cost.
     }
 }
コード例 #10
0
        private void UpdateGravityPoint(SimulationStructure structure)
        {
            var sections        = structure.CoreGrid.GetCores().SelectMany(c => c.Sections).ToList();
            var particleSection = sections[random.Next(sections.Count)];

            gravityPoint      = particleSection.UpperBound / 2 + particleSection.LowerBound / 2;
            centerRemainTime += swapTime;
        }
コード例 #11
0
 public void GetOldPositionsNeighbours(SimulationStructure simulationStructure)
 {
     foreach (var section in simulationStructure.CoreGrid.GetCores().SelectMany(core => core.Sections.Cast <NeighbourTransferSection>()))
     {
         Point3           ownPos;
         IParticleSection otherParticleSection;
         section.Grid.SectionCoreMapping.TryGetValue(section, out ownPos);
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(-1, 0, 0), out otherParticleSection))
         {
             section.NeighbourPositions[0] = ((NeighbourTransferSection)otherParticleSection).CurrentPosition;
         }
         else
         {
             section.NeighbourPositions[0] = new Vector3(-100, -100, -100);
         }
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(1, 0, 0), out otherParticleSection))
         {
             section.NeighbourPositions[1] = ((NeighbourTransferSection)otherParticleSection).CurrentPosition;
         }
         else
         {
             section.NeighbourPositions[1] = new Vector3(100, 100, 100);
         }
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(0, -1, 0), out otherParticleSection))
         {
             section.NeighbourPositions[2] = ((NeighbourTransferSection)otherParticleSection).CurrentPosition;
         }
         else
         {
             section.NeighbourPositions[2] = new Vector3(-100, -100, -100);
         }
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(0, 1, 0), out otherParticleSection))
         {
             section.NeighbourPositions[3] = ((NeighbourTransferSection)otherParticleSection).CurrentPosition;
         }
         else
         {
             section.NeighbourPositions[3] = new Vector3(100, 100, 100);
         }
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(0, 0, -1), out otherParticleSection))
         {
             section.NeighbourPositions[4] = ((NeighbourTransferSection)otherParticleSection).CurrentPosition;
         }
         else
         {
             section.NeighbourPositions[4] = new Vector3(-100, -100, -100);
         }
         if (section.Grid.SectionCoreMapping.TryGetKey(ownPos + new Point3(0, 0, 1), out otherParticleSection))
         {
             section.NeighbourPositions[5] = ((NeighbourTransferSection)otherParticleSection).CurrentPosition;
         }
         else
         {
             section.NeighbourPositions[5] = new Vector3(100, 100, 100);
         }
         //TODO add cost.
     }
 }
コード例 #12
0
 public void UpdateSectionPositions(SimulationStructure simulationStructure)
 {
     foreach (
         var section in
         simulationStructure.CoreGrid.GetCores().SelectMany(core => core.Sections.Cast <NeighbourTransferSection>()))
     {
         SetAveragePosition(section);
     }
 }
コード例 #13
0
 public void VisualizeStep(SimulationStructure structure, int step)
 {
     if ((step + 1) % snapTime != 0)
     {
         return;
     }
     combinedVisualizer.VisualizeStep(structure, step);
     pictureMerger.CreatePicture(step);
 }
コード例 #14
0
        public Tuple <int, int> GetPictureCoordinatesFor(float x, float z, SimulationStructure structure)
        {
            latestBound = LatestBoundary(structure);
            var xFac = x / latestBound.X;
            var zFac = z / latestBound.Z;

            xFac *= (width - 2);
            zFac *= (height - 2);
            return(new Tuple <int, int>(((int)xFac), ((int)zFac)));
        }
コード例 #15
0
 public void Sort(SimulationStructure simulationStructure, int step)
 {
     sectionPositionUpdater.UpdateSectionPositions(simulationStructure);
     // puts right amount of particles for transmission calculates the total transmission space needed.
     bridgeTransmissionPreparer.PutParticlesForTransmission(simulationStructure);
     transmitter.TransmitParticles(simulationStructure, step);
     neighbourPositionGetter.GetOldPositionsNeighbours(simulationStructure);
     //Calculate new increase and send and give to neighbours.
     bridgeInterestGetter.GetOldNeighbourInterests(simulationStructure);
 }
コード例 #16
0
        private Rgb GetColorOf(IParticleSection particleSection, SimulationStructure structure)
        {
            var coord = getPictureCoordinatesFor(particleSection.UpperBound.X, particleSection.UpperBound.Z, structure);
            var r     = (0.5 + 0.4 * Math.Cos((double)coord.Item1 * 20 + coord.Item2 * 22)) * 256;
            var g     = (0.5 + 0.4 * Math.Cos((double)coord.Item1 * 18 + coord.Item2 * 20)) * 256;
            var b     = (0.5 + 0.4 * Math.Cos((double)coord.Item1 * 16 + coord.Item2 * 18)) * 256;


            return(new Rgb(Color.FromArgb((int)r, (int)g, (int)b)));
        }
コード例 #17
0
 public void Sort(SimulationStructure simulationStructure, int step)
 {
     foreach (var core in simulationStructure.CoreGrid.GetCores())
     {
         foreach (StrictBoundaryParticleSection section in core.Sections)
         {
             SortInnerParticles(section, step, simulationStructure);
             SortOuterParticles(section, step);
         }
     }
     transmitter.TransmitParticles(simulationStructure, step);
 }
コード例 #18
0
        void ISectionTransmissionPreparer.PutParticlesForTransmission(SimulationStructure simulationStructure)
        {
            foreach (KMeansSection section in simulationStructure.CoreGrid.GetCores().SelectMany(o => o.Sections))
            {
                var currentPosition = section.CurrentPosition;
                var mySize          = (section.CurrentParticles.Count + section.LastSize) / 2;
                for (var i = 0; i < section.CurrentParticles.Count; i++)
                {
                    var   currentParticle = section.CurrentParticles[i];
                    var   particlePosition = currentParticle.Position;
                    int   xNeighbour, yNeighbour, zNeighbour;
                    float xTransScore, yTransScore, zTransScore;
                    var   xGood = CalculationParticleMovementSingleDimension(particlePosition.X, currentPosition.X,
                                                                             section, 0, mySize, currentParticle, i, section.NeighbourPositions[0].X,
                                                                             section.NeighbourPositions[0 + 1].X, growParameter, out xTransScore,
                                                                             out xNeighbour);


                    var yGood =
                        CalculationParticleMovementSingleDimension(particlePosition.Y, currentPosition.Y, section, 2,
                                                                   mySize, currentParticle, i, section.NeighbourPositions[2].Y, section.NeighbourPositions[2 + 1].Y,
                                                                   growParameter, out yTransScore, out yNeighbour);

                    var zGood = CalculationParticleMovementSingleDimension(particlePosition.Z, currentPosition.Z, section, 4,
                                                                           mySize, currentParticle, i, section.NeighbourPositions[4].Z, section.NeighbourPositions[4 + 1].Z, growParameter, out zTransScore, out zNeighbour);

                    var best = Math.Max(Math.Max(xTransScore, yTransScore), zTransScore);
                    //TODO PLEASE REFACTOR TO ARRAY of dim 3 before...
                    if ((!xGood) && (!yGood) && (!zGood))
                    {
                        continue;
                    }
                    section.CurrentParticles[i] = Particle.Null;
                    if (best == xTransScore && xGood)
                    {
                        section.ToTransmit[xNeighbour].Add(currentParticle);
                        continue;
                    }
                    if (best == yTransScore && yGood)
                    {
                        section.ToTransmit[yNeighbour].Add(currentParticle);
                        continue;
                    }
                    if (best == zTransScore && zGood)
                    {
                        section.ToTransmit[zNeighbour].Add(currentParticle);
                        continue;
                    }
                }
                section.CurrentParticles = section.CurrentParticles.Where(o => !o.IsNull).ToList();
            }
        }
コード例 #19
0
        private void CalculateParticleCost(SimulationStructure structure, int step)
        {
            const double movementCost         = 1.1454431510266E-007;
            const double chargeDepositionCost = 0.000000182;
            const double noReduction          = movementCost + chargeDepositionCost;
            //Console.Out.WriteLine(noReduction);
            var sumCost = noReduction * particleReductionFactor;

            foreach (var core in structure.CoreGrid.GetCores())
            {
                storage.AddCost(particleCost, core, step, core.Sections.Sum(o => o.Particles.Count() * sumCost));
            }
        }
コード例 #20
0
        public void AddCost(IParticleSection section, IParticleSection otherSection, int nBParticles,
                            SimulationStructure structure, int step)
        {
            var core1 = section.Core;
            var core2 = otherSection.Core;

            if (core1 == core2)
            {
                return;
            }
            storage.AddCost(sendingCost, core1, step, nBParticles * particleReductionFactor * SendCost);
            storage.AddCost(receivingCost, core2, step, nBParticles * particleReductionFactor * ReceiveCost);
        }
コード例 #21
0
 public void MoveParticles(SimulationStructure structure, float step, int simStep)
 {
     for (int i = 0; i < Particles.GetLength(0); i++)
     {
         for (int j = 0; j < Particles.GetLength(1); j++)
         {
             for (int k = 0; k < Particles.GetLength(2); k++)
             {
                 throw new NotImplementedException();
             }
         }
     }
 }
コード例 #22
0
 public void DrawVisualization(SimulationStructure structure, Image <Rgb, byte> image)
 {
     for (var i = 0; i < image.Size.Height; i++)
     {
         var w = ((int)(((double)i) / ((double)image.Size.Height) * image.Size.Width));
         if (w == image.Size.Width)
         {
             w--;
         }
         var wComp = image.Size.Width - 1 - w;
         image[i, w]     = new Rgb(Color.Red);
         image[i, wComp] = new Rgb(Color.Red);
     }
 }
コード例 #23
0
 public void CalculateField(SimulationStructure structure, int step)
 {
     foreach (var core in structure.CoreGrid.GetCores())
     {
         foreach (var section in core.Sections)
         {
             foreach (var particle in section.Particles)
             {
                 comCostCalculator.AddParticleCost(core, section.GetContainingParticle(particle.Position).Core, particle, step);
             }
         }
         constSolveCostCalculator.AddCostForCore(core, step);
     }
     comCostCalculator.FlushCommunicationCosts(step);
 }
コード例 #24
0
        public void VisualizeStep(SimulationStructure structure, int step)
        {
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            var image = new Image <Rgb, byte>(width, height);

            foreach (var subVisualizer in Visualizers)
            {
                subVisualizer.DrawVisualization(structure, image);
            }
            var bitmap = image.ToBitmap();

            bitmap.Save(outputPath + step + ".jpg");
            VisualizeMatrixStep(structure, step);
        }
コード例 #25
0
        public void Sort(SimulationStructure simulationStructure, int step)
        {
            if (!initialCalculated)
            {
                for (int i = 0; i < 10; i++)
                {
                    sectionPositionUpdater.UpdateSectionPositions(simulationStructure);
                }
                System.Console.Out.WriteLine("Updated K Means");
                initialCalculated = true;
            }
            neighbourPositionGetter.GetOldPositionsNeighbours(simulationStructure);
            neighbourSizeGetter.GetOldSizesNeighbours(simulationStructure);
            sectionPositionUpdater.UpdateSectionPositions(simulationStructure);
            transmissionPreparer.PutParticlesForTransmission(simulationStructure);

            particleTransmitter.TransmitParticles(simulationStructure, step);
        }
コード例 #26
0
        public void Sort(SimulationStructure simulationStructure, int step)
        {
            bool shown = false;

            foreach (IParticleSection particleSection in simulationStructure.GetAllSections())
            {
                SingleSectionSort((ParticleSection)particleSection);
                if (!shown)
                {
                    foreach (var s in ((ParticleSection)particleSection).elementsPerSide)
                    {
                        Console.Out.WriteLine(s);
                    }
                    shown = true;
                }
            }
            sideSorterTransmitter.TransmitParticles(simulationStructure, step);
        }
コード例 #27
0
        public void MoveParticles(SimulationStructure structure, float step, int simStep)
        {
            var f = ((float)Math.Sin((float)simStep / 400));


            foreach (var allSection in structure.GetAllSections())
            {
                allSection.ApplyToAllParticles(particle =>
                {
                    particle.Velocity = new Vector3((particle.Velocity.X + f / 5) * 0.5f, 0,
                                                    0);
                    particle.Position += particle.Velocity * step;
                    bouncer.BounceParticle(ref particle);
                    return(particle);
                });
            }

            costCalculator.CalculateTotalCost(structure, simStep);
        }
コード例 #28
0
        private void drawParticles(SimulationStructure structure, Image <Rgb, byte> image)
        {
            var sections = structure.CoreGrid.GetCores().SelectMany(o => o.Sections);

            foreach (var sec in sections)
            {
                var color = GetColorOf(sec, structure);
                foreach (var particle in sec.Particles)
                {
                    var coord = getPictureCoordinatesFor(particle.Position.X, particle.Position.Z, structure);
                    try
                    {
                        image[coord.Item2, coord.Item1] = color;
                    }
                    catch (Exception)
                    {
                    }
                }
            }
        }
コード例 #29
0
 private void SwapZBorderSection(MatrixSortParticleSection lower, MatrixSortParticleSection upper, int step,
                                 SimulationStructure structure)
 {
     for (int i = 0; i < lower.ParticlesMatrix.GetLength(0); i++)
     {
         for (int j = 0; j < lower.ParticlesMatrix.GetLength(1); j++)
         {
             Particle particle1 = upper.ParticlesMatrix[i, j, 0];
             Particle particle2 = lower.ParticlesMatrix[i, j, lower.ParticlesMatrix.GetLength(2) - 1];
             if (particle2.Position.Z <= particle1.Position.Z)
             {
                 continue;
             }
             lower.ParticlesMatrix[i, j, lower.ParticlesMatrix.GetLength(2) - 1] = particle1;
             upper.ParticlesMatrix[i, j, 0] = particle2;
         }
     }
     costCalculator.AddTransmissionCost(lower, upper,
                                        lower.ParticlesMatrix.GetLength(2) * lower.ParticlesMatrix.GetLength(1), structure, step);
 }
コード例 #30
0
 private void SwapXBorderSection(MatrixSortParticleSection lower, MatrixSortParticleSection upper, int step,
                                 SimulationStructure structure)
 {
     for (int i = 1; i < lower.ParticlesMatrix.GetLength(1); i++)
     {
         for (int j = 1; j < lower.ParticlesMatrix.GetLength(2); j++)
         {
             Particle particle1 = lower.ParticlesMatrix[lower.ParticlesMatrix.GetLength(0) - 1, i, j];
             Particle particle2 = upper.ParticlesMatrix[0, i, j];
             if (particle1.Position.X <= particle2.Position.X)
             {
                 continue;
             }
             lower.ParticlesMatrix[lower.ParticlesMatrix.GetLength(0) - 1, i, j] = particle2;
             upper.ParticlesMatrix[0, i, j] = particle1;
         }
     }
     costCalculator.AddTransmissionCost(lower, upper,
                                        lower.ParticlesMatrix.GetLength(2) * lower.ParticlesMatrix.GetLength(1), structure, step);
 }