/// <summary>
        /// extract the Fields from the solution, Resample them equally spaced and ready to use in an fft
        /// </summary>
        private void Resample(int iterIndex, double[] currentSol, MultigridOperator Mgop, string component)
        {
            if (Mgop.GridData.SpatialDimension == 2 && Mgop.LevelIndex == 0)
            {
                MultidimensionalArray SamplePoints;

                GridData GD = (GridData)Mgop.Mapping.AggGrid.AncestorGrid;

                BoundingBox BB = GD.GlobalBoundingBox;

                double xDist       = BB.Max[0] - BB.Min[0];
                double yDist       = BB.Max[1] - BB.Min[1];
                double aspectRatio = xDist / yDist;

                MGViz     viz    = new MGViz(Mgop);
                DGField[] Fields = viz.ProlongateToDg(currentSol, "Error");

                for (int p = 0; p < Fields.Length; p++)
                {
                    var field = Fields[p];

                    int    DOF = field.DOFLocal;
                    double N   = Math.Sqrt(DOF);
                    int    Nx  = (int)Math.Round(Math.Sqrt(aspectRatio) * N);
                    int    Ny  = (int)Math.Round(1 / Math.Sqrt(aspectRatio) * N);

                    SamplePoints = MultidimensionalArray.Create(Ny, Nx);

                    for (int i = 0; i < Nx; i++)
                    {
                        MultidimensionalArray points = MultidimensionalArray.Create(Ny, 2);

                        for (int k = 0; k < Ny; k++)
                        {
                            points[k, 0] = BB.Min[0] + (i + 1) * xDist / (Nx + 1);
                            points[k, 1] = BB.Min[1] + (k + 1) * yDist / (Ny + 1);
                        }

                        List <DGField> fields = new List <DGField>();
                        fields.Add(field);

                        FieldEvaluation FE = new FieldEvaluation(GD);

                        MultidimensionalArray Result = MultidimensionalArray.Create(Ny, 1);

                        FE.Evaluate(1.0, fields, points, 1.0, Result);

                        SamplePoints.ExtractSubArrayShallow(-1, i).Acc(1.0, Result.ExtractSubArrayShallow(-1, 0));
                    }

                    SamplePoints.SaveToTextFile("ResampleFFT_lvl" + Mgop.LevelIndex + "_" + iterIndex + "_" + component + "_" + field.Identification + ".txt");
                }
            }
        }
예제 #2
0
        /// <summary>
        /// computes the L2-error of the interface points onto the LevelSet-DGfield
        /// </summary>
        /// <param name="LevelSet"></param>
        /// <param name="interP"></param>
        public double InterfaceProjectionError(SinglePhaseField LevelSet, MultidimensionalArray interP)
        {
            GridData        grdat = (GridData)LevelSet.GridDat;
            FieldEvaluation fEval = new FieldEvaluation(grdat);

            MultidimensionalArray PhiAtSamplePoints = MultidimensionalArray.Create(interP.Lengths[0], 1);

            DGField[] DGLevSet = new DGField[] { LevelSet };
            int       outP     = fEval.Evaluate(1, DGLevSet, interP, 0, PhiAtSamplePoints);

            if (outP != 0)
            {
                throw new Exception("points outside the grid for fieldevaluation");
            }

            return(PhiAtSamplePoints.L2Norm());
        }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="velocity"></param>
        /// <returns></returns>
        public override double[] ComputeChangerate(double dt, ConventionalDGField[] velocity, double[] current_FLSprop)
        {
            GridData        grdat = (GridData)velocity[0].GridDat;
            FieldEvaluation fEval = new FieldEvaluation(grdat);

            MultidimensionalArray VelocityAtSamplePoints = MultidimensionalArray.Create(current_interfaceP.Lengths);

            int outP = fEval.Evaluate(1, velocity, current_interfaceP, 0, VelocityAtSamplePoints);

            if (outP != 0)
            {
                throw new Exception("points outside the grid for fieldevaluation");
            }

            // change rate for the material points is the velocity at the points
            if (FourierEvolve == Fourier_Evolution.MaterialPoints)
            {
                double[] velAtP = new double[2 * numFp];
                for (int sp = 0; sp < numFp; sp++)
                {
                    velAtP[sp * 2]     = VelocityAtSamplePoints[sp, 0];
                    velAtP[sp * 2 + 1] = VelocityAtSamplePoints[sp, 1];
                }
                return(velAtP);
            }

            // compute an infinitesimal change of sample points at the Fourier points/ change of Fourier modes
            MultidimensionalArray interfaceP_evo = current_interfaceP.CloneAs();
            double dt_infin = dt * 1e-3;

            interfaceP_evo.Acc(dt_infin, VelocityAtSamplePoints);

            RearrangeOntoPeriodicDomain(interfaceP_evo);
            double[] samplP_change = current_samplP.CloneAs();
            InterpolateOntoFourierPoints(interfaceP_evo, samplP_change);

            if (FourierEvolve == Fourier_Evolution.FourierPoints)
            {
                samplP_change.AccV(-1.0, current_samplP);
                samplP_change.ScaleV(1.0 / dt_infin);
                return(samplP_change);
            }
            else
            if (FourierEvolve == Fourier_Evolution.FourierModes)
            {
                Complex[] samplP_complex = new Complex[numFp];
                for (int sp = 0; sp < numFp; sp++)
                {
                    samplP_complex[sp] = (Complex)samplP_change[sp];
                }
                //Complex[] DFT_change = DFT.NaiveForward(samplP_complex, FourierOptions.Matlab);
                Complex[] DFT_change = samplP_complex; samplP_complex = null;
                Fourier.Forward(DFT_change, FourierOptions.Matlab);
                double[] DFT_change_double = new double[2 * numFp];
                for (int sp = 0; sp < numFp; sp++)
                {
                    DFT_change_double[sp * 2]     = (DFT_change[sp].Real - DFT_coeff[sp].Real) / dt_infin;
                    DFT_change_double[sp * 2 + 1] = (DFT_change[sp].Imaginary - DFT_coeff[sp].Imaginary) / dt_infin;
                }
                return(DFT_change_double);
            }
            else
            {
                throw new ArgumentException();
            }
        }
예제 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="velocity"></param>
        /// <returns></returns>
        public override double[] ComputeChangerate(double dt, ConventionalDGField[] velocity, double[] current_FLSprop)
        {
            setMaterialInterfacePoints(current_FLSprop);

            GridData        grdat = (GridData)(velocity[0].GridDat);
            FieldEvaluation fEval = new FieldEvaluation(grdat);

            // Movement of the material interface points
            MultidimensionalArray VelocityAtSamplePointsXY = MultidimensionalArray.Create(current_interfaceP.Lengths);

            int outP = fEval.Evaluate(1, velocity, current_interfaceP, 0, VelocityAtSamplePointsXY);

            if (outP != 0)
            {
                throw new Exception("points outside the grid for fieldevaluation");
            }

            int numIp = current_interfaceP.Lengths[0];


            // change rate for the material points is the velocity at the points
            if (FourierEvolve == Fourier_Evolution.MaterialPoints)
            {
                double[] velAtP = new double[2 * numIp];
                for (int sp = 0; sp < numIp; sp++)
                {
                    velAtP[sp * 2]       = VelocityAtSamplePointsXY[sp, 0];
                    velAtP[(sp * 2) + 1] = VelocityAtSamplePointsXY[sp, 1];
                }
                return(velAtP);
            }

            // compute an infinitesimal change of sample points at the Fourier points/ change of Fourier modes
            MultidimensionalArray interfaceP_evo = current_interfaceP.CloneAs();
            double dt_infin = dt * 1e-3;

            interfaceP_evo.Acc(dt_infin, VelocityAtSamplePointsXY);

            // Movement of the center point
            MultidimensionalArray center_evo       = center.CloneAs();
            MultidimensionalArray VelocityAtCenter = center.CloneAs();

            switch (CenterMove)
            {
            case CenterMovement.None: {
                VelocityAtCenter.Clear();
                break;
            }

            case CenterMovement.Reconstructed: {
                center_evo = GetGeometricCenter(interfaceP_evo);
                //Console.WriteLine("center_evo = ({0}, {1}) / center = ({2}, {3})", center_evo[0, 0], center_evo[0, 1], center[0, 0], center[0, 1]);
                MultidimensionalArray center_change = center_evo.CloneAs();
                center_change.Acc(-1.0, center);
                center_change.Scale(1.0 / dt_infin);
                VelocityAtCenter[0, 0] = center_change[0, 0];
                VelocityAtCenter[0, 1] = center_change[0, 1];
                break;
            }

            case CenterMovement.VelocityAtCenter: {
                outP = fEval.Evaluate(1, velocity, center, 0, VelocityAtCenter);
                if (outP != 0)
                {
                    throw new Exception("center point outside the grid for fieldevaluation");
                }
                center_evo.Acc(dt_infin, VelocityAtCenter);
                break;
            }
            }
            //Console.WriteLine("Velocity at Center point = ({0}, {1})", VelocityAtCenter[0, 0], VelocityAtCenter[0, 1]);

            // transform to polar coordiantes
            MultidimensionalArray interP_evo_polar = interfaceP_polar.CloneAs();

            for (int sp = 0; sp < numIp; sp++)
            {
                double x_c = interfaceP_evo[sp, 0] - center_evo[0, 0];
                double y_c = interfaceP_evo[sp, 1] - center_evo[0, 1];

                double theta = Math.Atan2(y_c, x_c);
                if (theta < 0)
                {
                    theta = Math.PI * 2 + theta;
                }
                ;
                interP_evo_polar[sp, 0] = theta;
                interP_evo_polar[sp, 1] = Math.Sqrt(x_c.Pow2() + y_c.Pow2());
            }

            RearrangeOntoPeriodicDomain(interP_evo_polar);
            double[] samplP_change = current_samplP.CloneAs();
            InterpolateOntoFourierPoints(interP_evo_polar, samplP_change);

            if (FourierEvolve == Fourier_Evolution.FourierPoints)
            {
                samplP_change.AccV(-1.0, current_samplP);
                samplP_change.ScaleV(1.0 / dt_infin);
                double[] FPchange = new double[numFp + 2];
                FPchange[0] = VelocityAtCenter[0, 0];
                FPchange[1] = VelocityAtCenter[0, 1];
                for (int p = 0; p < numFp; p++)
                {
                    FPchange[p + 2] = samplP_change[p];
                }
                return(FPchange);
            }
            else
            if (FourierEvolve == Fourier_Evolution.FourierModes)
            {
                Complex[] samplP_complex = new Complex[numFp];
                for (int sp = 0; sp < numFp; sp++)
                {
                    samplP_complex[sp] = (Complex)samplP_change[sp];
                }
                //Complex[] DFTchange = DFT.NaiveForward(samplP_complex, FourierOptions.Matlab);
                Complex[] DFTchange = samplP_complex; samplP_complex = null;
                Fourier.Forward(DFTchange, FourierOptions.Matlab);
                double[] DFTchange_double = new double[2 * numFp + 2];
                DFTchange_double[0] = VelocityAtCenter[0, 0];
                DFTchange_double[1] = VelocityAtCenter[0, 1];
                for (int sp = 0; sp < numFp; sp++)
                {
                    DFTchange_double[2 + (sp * 2)]     = (DFTchange[sp].Real - DFT_coeff[sp].Real) / dt_infin;
                    DFTchange_double[2 + (sp * 2) + 1] = (DFTchange[sp].Imaginary - DFT_coeff[sp].Imaginary) / dt_infin;
                }
                return(DFTchange_double);
            }
            else
            {
                throw new ArgumentException();
            }
        }
예제 #5
0
        /// <summary>
        /// Reconstructs a <see cref="BoSSS.Foundation.XDG.LevelSet"/> from a given set of points on a given DG field
        /// </summary>
        /// <param name="field">The DG field to work with</param>
        /// <param name="points"> <see cref="MultidimensionalArray"/>
        ///  Lengths --> [0]: numOfPoints, [1]: 2
        ///  [1] --> [0]: x, [1]: y
        /// </param>
        public static SinglePhaseField ReconstructLevelSetField(SinglePhaseField field, MultidimensionalArray points)
        {
            // Init
            IGridData gridData = field.GridDat;

            // Evaluate gradient
            SinglePhaseField gradientX = new SinglePhaseField(field.Basis, "gradientX");
            SinglePhaseField gradientY = new SinglePhaseField(field.Basis, "gradientY");

            gradientX.DerivativeByFlux(1.0, field, d: 0);
            gradientY.DerivativeByFlux(1.0, field, d: 1);
            //gradientX = PatchRecovery(gradientX);
            //gradientY = PatchRecovery(gradientY);
            FieldEvaluation       ev       = new FieldEvaluation((GridData)gridData);
            MultidimensionalArray GradVals = MultidimensionalArray.Create(points.GetLength(0), 2);

            ev.Evaluate(1.0, new DGField[] { gradientX, gradientY }, points, 0.0, GradVals);

            // Level set reconstruction
            Console.WriteLine("Reconstruction of field levelSet started...");
            int count = 0;
            Func <double[], double> func = delegate(double[] X) {
                double minDistSigned            = double.MaxValue;
                int    iMin                     = int.MaxValue;
                double closestPointOnInterfaceX = double.MaxValue;
                double closestPointOnInterfaceY = double.MaxValue;

                double x = X[0];
                double y = X[1];

                for (int i = 0; i < points.Lengths[0]; i++)
                {
                    double currentPointX = points[i, 0];
                    double currentPointY = points[i, 1];

                    double deltaX = x - currentPointX;
                    double deltaY = y - currentPointY;

                    double dist = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);

                    if (dist <= minDistSigned)
                    {
                        iMin                     = i;
                        minDistSigned            = dist;
                        closestPointOnInterfaceX = currentPointX;
                        closestPointOnInterfaceY = currentPointY;
                    }
                }

                //// Compute global cell index of quadrature node
                //gridData.LocatePoint(X, out long GlobalId, out long GlobalIndex, out bool IsInside, out bool OnThisProcess);

                //// Compute local node set
                //NodeSet nodeSet = GetLocalNodeSet(gridData, X, (int)GlobalIndex);

                //// Evaluate gradient
                //// Get local cell index of quadrature node
                //int j0Grd = gridData.CellPartitioning.i0;
                //int j0 = (int)(GlobalIndex - j0Grd);

                //int Len = 1;
                //MultidimensionalArray resultGradX = MultidimensionalArray.Create(1, 1);
                //MultidimensionalArray resultGradY = MultidimensionalArray.Create(1, 1);
                //gradientX.Evaluate(j0, Len, nodeSet, resultGradX);
                //gradientY.Evaluate(j0, Len, nodeSet, resultGradY);

                int sign = Math.Sign((x - closestPointOnInterfaceX) * GradVals[iMin, 0] + (y - closestPointOnInterfaceY) * GradVals[iMin, 1]);
                minDistSigned *= sign;

                //Console.WriteLine(String.Format("Quadrature point #{0}: ({1}, {2}), interface point: ({3}, {4})", count, X[0], X[1], closestPointOnInterfaceX, closestPointOnInterfaceY));
                count++;

                return(minDistSigned);
            };

            // DG level set field
            SinglePhaseField DGLevelSet = new SinglePhaseField(field.Basis, "levelSet_recon");

            DGLevelSet.ProjectField(func.Vectorize());

            Console.WriteLine("finished");
            return(DGLevelSet);
        }