Ejemplo n.º 1
0
        /// <summary>
        /// Sets fields an their exact derivatives.
        /// </summary>
        protected override void SetInitial()
        {
            if (this.GridData.SpatialDimension == 3)
            {
                f1.ProjectField((x, y, z) => (3 * x + z));
                f1Gradient_Analytical[0].ProjectField((x, y, z) => 3.0);
                f1Gradient_Analytical[1].ProjectField((x, y, z) => 0.0);
                f1Gradient_Analytical[2].ProjectField((x, y, z) => 1.0);

                f2.ProjectField((x, y, z) => z + 2 * y);
                f2Gradient_Analytical[0].ProjectField((x, y, z) => 0.0);
                f2Gradient_Analytical[1].ProjectField((x, y, z) => 2.0);
                f2Gradient_Analytical[2].ProjectField((x, y, z) => 1.0);

                Laplace_f1_Analytical.ProjectField((x, y, z) => 0.0);
                Laplace_f2_Analytical.ProjectField((x, y, z) => 0.0);
            }
            else if (this.GridData.SpatialDimension == 2)
            {
                if (AltRefSol == false)
                {
                    f1.ProjectField((x, y) => (3 * x));
                    f1Gradient_Analytical[0].ProjectField((x, y) => 3);
                    f1Gradient_Analytical[1].ProjectField((x, y) => 0);

                    f2.ProjectField((x, y) => x + 2 * y);
                    f2Gradient_Analytical[0].ProjectField((x, y) => 1.0);
                    f2Gradient_Analytical[1].ProjectField((x, y) => 2.0);

                    Laplace_f1_Analytical.ProjectField((x, y) => 0.0);
                    Laplace_f2_Analytical.ProjectField((x, y) => 0.0);
                }
                else
                {
                    f1.ProjectField((x, y) => Math.Sin(Math.Atan(y / x) * 4.0));
                    f1Gradient_Analytical[0].ProjectField((x, y) => (-4 * Math.Cos(4 * Math.Atan(y / x)) * y / (x * x) / (1 + (y * y) / (x * x))));
                    f1Gradient_Analytical[1].ProjectField((x, y) => (4 * Math.Cos(4 * Math.Atan(y / x)) / x / (1 + (y * y) / (x * x))));
                }
            }
            else if (this.GridData.SpatialDimension == 1)
            {
                f1.ProjectField((x) => (3 * x));
                f1Gradient_Analytical[0].ProjectField((_1D)((x) => 3));

                f2.ProjectField((x) => x * x);
                f2Gradient_Analytical[0].ProjectField((_1D)((x) => 2 * x));

                Laplace_f1_Analytical.ProjectField((_1D)((x) => 0.0));
                Laplace_f2_Analytical.ProjectField((_1D)((x) => 2.0));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Calculate A Level-Set field from the Explicit description
        /// </summary>
        /// <param name="LevelSet">Target Field</param>
        /// <param name="LsTrk"></param>
        public void ProjectToDGLevelSet(SinglePhaseField LevelSet, LevelSetTracker LsTrk = null)
        {
            CellMask VolMask;

            if (LsTrk == null)
            {
                VolMask = CellMask.GetFullMask(LevelSet.Basis.GridDat);
            }
            else
            {
                // set values in positive and negative FAR region to +1 and -1
                CellMask Near   = LsTrk.Regions.GetNearMask4LevSet(0, 1);
                CellMask PosFar = LsTrk.Regions.GetLevelSetWing(0, +1).VolumeMask.Except(Near);
                CellMask NegFar = LsTrk.Regions.GetLevelSetWing(0, -1).VolumeMask.Except(Near);

                LevelSet.Clear(PosFar);
                LevelSet.AccConstant(1, PosFar);
                LevelSet.Clear(NegFar);
                LevelSet.AccConstant(-1, NegFar);

                // project Fourier levelSet to DGfield on near field
                VolMask = Near;
            }

            LevelSet.Clear(VolMask);
            // scalar function is already vectorized for parallel execution
            // nodes in global coordinates
            LevelSet.ProjectField(1.0,
                                  PhiEvaluation(mode),
                                  new Foundation.Quadrature.CellQuadratureScheme(true, VolMask));

            // check the projection error
            projErr_phiDG = LevelSet.L2Error(
                PhiEvaluation(mode),
                new Foundation.Quadrature.CellQuadratureScheme(true, VolMask));
            //if (projErr_phiDG >= 1e-5)
            //    Console.WriteLine("WARNING: LevelSet projection error onto PhiDG = {0}", projErr_phiDG);


            // project on higher degree field and take the difference
            //SinglePhaseField higherLevSet = new SinglePhaseField(new Basis(LevelSet.GridDat, LevelSet.Basis.Degree * 2), "higherLevSet");
            //higherLevSet.ProjectField(1.0, PhiEvaluator(), new Foundation.Quadrature.CellQuadratureScheme(true, VolMask));
            //double higherProjErr = higherLevSet.L2Error(
            //    PhiEvaluator(),
            //    new Foundation.Quadrature.CellQuadratureScheme(true, VolMask));
            //Console.WriteLine("LevelSet projection error onto higherPhiDG = {0}", higherProjErr.ToString());


            // check the projection from current sample points on the DGfield
            //MultidimensionalArray interP = MultidimensionalArray.Create(current_interfaceP.Lengths);
            //if (this is PolarFourierLevSet) {
            //    interP = ((PolarFourierLevSet)this).interfaceP_cartesian;
            //} else {
            //    interP = current_interfaceP;
            //}

            //projErr_interface = InterfaceProjectionError(LevelSet, current_interfaceP);
            //if (projErr_interface >= 1e-3)
            //    Console.WriteLine("WARNING: Interface projection Error onto PhiDG = {0}", projErr_interface);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Sets level-set and solution at time (<paramref name="time"/> + <paramref name="dt"/>).
        /// </summary>
        double DelUpdateLevelset(DGField[] CurrentState, double time, double dt, double UnderRelax, bool _incremental)
        {
            // new time
            double t = time + dt;

            // project new level-set
            double s = 1.0;

            LevSet.ProjectField((x, y) => - (x - s * t).Pow2() - y.Pow2() + (2.4).Pow2());
            LsTrk.UpdateTracker(incremental: _incremental);
            LsTrk.PushStacks();

            // exact solution for new timestep
            uXEx.GetSpeciesShadowField("A").ProjectField((x, y) => x + alpha_A * t);
            uXEx.GetSpeciesShadowField("B").ProjectField((x, y) => x + alpha_B * t);

            // uX.Clear();
            //uX.Acc(1.0, uXEx);

            // single-phase-properties
            u.Clear();
            u.ProjectField(NonVectorizedScalarFunction.Vectorize(uEx, t));

            Grad_u.Clear();
            Grad_u.Gradient(1.0, u);

            MagGrad_u.Clear();
            MagGrad_u.ProjectFunction(1.0,
                                      (double[] X, double[] U, int jCell) => Math.Sqrt(U[0].Pow2() + U[1].Pow2()),
                                      new Foundation.Quadrature.CellQuadratureScheme(),
                                      Grad_u.ToArray());

            // return level-set residual
            return(0.0);
        }
Ejemplo n.º 4
0
        private SinglePhaseField ComputeDistanceField()
        {
            SinglePhaseField phiDist = new SinglePhaseField(phi.Basis);
            GridData         GridDat = (GridData)(phi.GridDat);

            // calculate distance field phiDist = 0.5 * log(Max(1+phi, eps)/Max(1-phi, eps)) * sqrt(2) * Cahn
            // ===================
            phiDist.ProjectField(
                (ScalarFunctionEx) delegate(int j0, int Len, NodeSet NS, MultidimensionalArray result)
            {     // ScalarFunction2
                Debug.Assert(result.Dimension == 2);
                Debug.Assert(Len == result.GetLength(0));
                int K = result.GetLength(1);     // number of nodes

                // evaluate Phi
                // -----------------------------
                phi.Evaluate(j0, Len, NS, result);

                // compute the pointwise values of the new level set
                // -----------------------------

                result.ApplyAll(x => 0.5 * Math.Log(Math.Max(1 + x, 1e-10) / Math.Max(1 - x, 1e-10)) * Math.Sqrt(2) * this.Control.cahn);
            }
                );

            return(phiDist);
        }
Ejemplo n.º 5
0
        private double SetUpConfiguration()
        {
            testCase.UpdateLevelSet(levelSet);
            levelSetTracker.UpdateTracker(__NearRegionWith: 0, incremental: false, __LevSetAllowedMovement: 2);

            XDGField.Clear();
            XDGField.GetSpeciesShadowField("A").ProjectField(
                1.0, testCase.JumpingFieldSpeciesAInitialValue, default(CellQuadratureScheme));
            XDGField.GetSpeciesShadowField("B").ProjectField(
                1.0, testCase.JumpingFieldSpeciesBInitialValue, default(CellQuadratureScheme));

            SinglePhaseField.Clear();
            SinglePhaseField.ProjectField(testCase.ContinuousFieldInitialValue);

            double referenceValue = testCase.Solution;

            if (testCase is IVolumeTestCase)
            {
                QuadRule standardRule = Grid.RefElements[0].GetQuadratureRule(2 * XDGField.Basis.Degree + 1);
                ScalarFieldQuadrature uncutQuadrature = new ScalarFieldQuadrature(
                    GridData,
                    XDGField,
                    new CellQuadratureScheme(
                        new FixedRuleFactory <QuadRule>(standardRule),
                        levelSetTracker.Regions.GetCutCellSubGrid().Complement().VolumeMask),
                    standardRule.OrderOfPrecision);
                uncutQuadrature.Execute();

                referenceValue -= uncutQuadrature.Result;
            }

            return(referenceValue);
        }
Ejemplo n.º 6
0
        protected override void SetInitial()
        {
            this.LsUpdate(0.0);

            u.ProjectField((x, y) => x);
            du_dx_Exact.ProjectField((x, y) => 1.0);
        }
Ejemplo n.º 7
0
        void TestAgglomeration_Extraploation(MultiphaseCellAgglomerator Agg)
        {
            _2D SomePolynomial;

            if (this.u.Basis.Degree == 0)
            {
                SomePolynomial = (x, y) => 3.2;
            }
            else if (this.u.Basis.Degree == 1)
            {
                SomePolynomial = (x, y) => 3.2 + x - 2.4 * y;
            }
            else
            {
                SomePolynomial = (x, y) => x * x + y * y;
            }

            // ========================================================
            // extrapolate polynomial function for species B of a XDG-field
            // ========================================================


            var Bmask = LsTrk.Regions.GetSpeciesMask("B");

            XDGField xt = new XDGField(new XDGBasis(this.LsTrk, this.u.Basis.Degree), "XDG-test");

            xt.GetSpeciesShadowField("B").ProjectField(1.0,
                                                       SomePolynomial.Vectorize(),
                                                       new CellQuadratureScheme(true, Bmask));


            double[] bkupVec = xt.CoordinateVector.ToArray();

            Agg.ClearAgglomerated(xt.Mapping);
            Agg.Extrapolate(xt.Mapping);

            double Err = GenericBlas.L2DistPow2(bkupVec, xt.CoordinateVector).MPISum().Sqrt();

            Console.WriteLine("Agglom: extrapolation error: " + Err);
            Assert.LessOrEqual(Err, 1.0e-10);

            // ========================================================
            // extrapolate polynomial function for a single-phase-field
            // ========================================================

            SinglePhaseField xt2 = new SinglePhaseField(this.u.Basis, "DG-test");

            xt2.ProjectField(SomePolynomial);

            double[] bkupVec2 = xt2.CoordinateVector.ToArray();

            Agg.ClearAgglomerated(xt2.Mapping);
            Agg.Extrapolate(xt2.Mapping);

            double Err2 = GenericBlas.L2DistPow2(bkupVec, xt.CoordinateVector).MPISum().Sqrt();

            Console.WriteLine("Agglom: extrapolation error: " + Err2);
            Assert.LessOrEqual(Err2, 1.0e-10);
        }
Ejemplo n.º 8
0
 void PlotAnalyticSolution(Func <double[], double> AnalyticSolution, Basis PlotBasis, string Identification)
 {
     if (AnalyticSolution != null)
     {
         SinglePhaseField tmp = new SinglePhaseField(PlotBasis, Identification);
         tmp.ProjectField(AnalyticSolution);
         m_IOFields.Add(tmp);
     }
 }
Ejemplo n.º 9
0
        /// <summary>
        /// sets some initial value for field <see cref="u"/>;
        /// </summary>
        protected override void SetInitial()
        {
            switch (GridData.SpatialDimension)
            {
            case 2:



                u.ProjectField((_2D)(delegate(double x, double y) {
                    //double r = Math.Sqrt(x*x + y*y);
                    //return Math.Exp(-r * r);
                    return(x);
                }));


                Velocity[0].ProjectField((_2D)((x, y) => 1.0));
                Velocity[1].ProjectField((_2D)((x, y) => 0.0));

                break;

            case 3:
                u.ProjectField((x, y, z) => ((Math.Abs(x) <= 3.0 && Math.Abs(y) <= 3.0 && Math.Abs(z) <= 3.0) ? 1 : 0));
                Velocity[0].ProjectField((_3D)((x, y, z) => 1));
                Velocity[1].ProjectField((_3D)((x, y, z) => 0));
                Velocity[2].ProjectField((_3D)((x, y, z) => 0));


                break;

            default:
                throw new NotImplementedException();
            }



            double rank = GridData.MpiRank;
            int    J    = GridData.iLogicalCells.NoOfLocalUpdatedCells;

            for (int j = 0; j < J; j++)
            {
                mpi_rank.SetMeanValue(j, rank);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Setting initial value.
        /// </summary>
        protected override void SetInitial()
        {
            TestData.ProjectField(TestDataFunc);
            DelUpdateLevelset(new DGField[] { uX }, 0.0, 0.0, 1.0, false);

            uX.ProjectField((x, y) => 1.0);

            // check error
            double L2err = TestData.L2Error(TestDataFunc);

            Console.WriteLine("Projection error from old to new grid: " + L2err);
            Assert.LessOrEqual(L2err, 1.0e-8, "Projection error of test field to high.");
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Setting initial value.
        /// </summary>
        protected override void SetInitial()
        {
            TestData.ProjectField(TestDataFunc);
            DelUpdateLevelset(new DGField[] { uX }, 0.0, 0.0, 1.0, false);

            uX.ProjectField((x, y) => 1.0);

            /*
             * RefinedGrid = this.GridData;
             * Refined_u = this.u;
             * Refined_TestData = new SinglePhaseField(this.u.Basis, "TestData");
             * Refined_Grad_u = this.Grad_u;
             * Refined_MagGrad_u = this.MagGrad_u;
             */
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Projects every basis polynomial for the quadrature rule of the
        /// given order onto a single cell grid supplied by the sub-class and
        /// approximates the LInfinity error of the projection.
        /// </summary>
        /// <remarks>
        /// The DG projection uses a quadrature rule of 2*n+1 for a basis of
        /// order n. Thus, make sure <paramref name="order"/> that a quadrature
        /// rule of order 2*order+1 exists before calling this method</remarks>
        /// <param name="order">The <b>requested</b> order</param>
        /// <param name="polynomials">The orthonormal polynomials</param>
        /// <param name="rule">The tested quadrature rule</param>
        private void TestProjectionError(int order, PolynomialList polynomials, QuadRule rule)
        {
            Basis basis = new Basis(context, order);

            for (int i = 0; i < polynomials.Count; i++)
            {
                if (2 * polynomials[i].AbsoluteDegree + 1 > order)
                {
                    // Not integrable _exactly_ with this rule
                    continue;
                }

                DGField        field    = new SinglePhaseField(basis);
                ScalarFunction function = delegate(MultidimensionalArray input, MultidimensionalArray output) {
                    polynomials[i].Evaluate(output, new NodeSet(rule.RefElement, input));
                };
                field.ProjectField(function);

                double LInfError = 0;
                for (int j = 0; j < rule.NoOfNodes; j++)
                {
                    MultidimensionalArray result = MultidimensionalArray.Create(1, 1);
                    NodeSet point = new NodeSet(context.iGeomCells.GetRefElement(0), 1, rule.SpatialDim);
                    for (int k = 0; k < rule.SpatialDim; k++)
                    {
                        point[0, k] = rule.Nodes[j, k];
                    }
                    point.LockForever();

                    //Evaluate pointwise because we don't want the accumulated
                    //result
                    field.Evaluate(0, 1, point, result, 0.0);

                    MultidimensionalArray exactResult = MultidimensionalArray.Create(1);
                    polynomials[i].Evaluate(exactResult, point);

                    LInfError = Math.Max(Math.Abs(result[0, 0] - exactResult[0]), LInfError);
                }
                //Console.WriteLine("ProjectionError: {0}", LInfError);

                Assert.IsTrue(
                    LInfError <= 1e-13,
                    String.Format(
                        "Projection error too high for polynomial {0}. Error: {1:e}",
                        i,
                        LInfError));
            }
        }
Ejemplo n.º 13
0
        // Reinitialize Phasefield with changed interface thickness
        private void ReInit(double cahn_old, double cahn)
        {
            Console.WriteLine($"Reprojecting Phasefield:\n" +
                              $"  old thickness:  {cahn_old}\n" +
                              $"  new thickness:  {cahn}");
            // we assume the current phasefield is close to the equilibrium tangenshyperbolicus form
            SinglePhaseField phiNew  = new SinglePhaseField(phi.Basis);
            GridData         GridDat = (GridData)(phi.GridDat);

            // compute and project
            // step one calculate distance field phiDist = 0.5 * log(Max(1+phi, eps)/Max(1-phi, eps)) * sqrt(2) * Cahn_old
            // step two project the new phasefield phiNew = tanh(phiDist/(sqrt(2) * Cahn_new))
            // here done in one step, with default quadscheme
            // ===================
            phiNew.ProjectField(
                (ScalarFunctionEx) delegate(int j0, int Len, NodeSet NS, MultidimensionalArray result)
            {     // ScalarFunction2
                Debug.Assert(result.Dimension == 2);
                Debug.Assert(Len == result.GetLength(0));
                int K = result.GetLength(1);     // number of nodes

                // evaluate Phi
                // -----------------------------
                phi.Evaluate(j0, Len, NS, result);

                // compute the pointwise values of the new level set
                // -----------------------------

                result.ApplyAll(x => Math.Tanh(0.5 * Math.Log(Math.Max(1 + x, 1e-10) / Math.Max(1 - x, 1e-10)) * (cahn_old / cahn)));
            }
                );

            phi.Clear();
            phi.Acc(1.0, phiNew);

            CorrectionLevSet.Clear();
            CorrectionLevSet.Acc(1.0, phi);
            this.CorrectionLsTrk.UpdateTracker(0.0);

            // update DG LevelSet
            DGLevSet.Clear();
            DGLevSet.Acc(1.0, phi);

            reinit++;
            PlotCurrentState(0.0, reinit);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Returns thermodynamic pressure as function of inital mass and temperature.
        /// </summary>
        /// <param name="InitialMass"></param>
        /// <param name="Temperature"></param>
        /// <returns></returns>
        public override double GetMassDeterminedThermodynamicPressure(double InitialMass, SinglePhaseField Temperature)
        {
            SinglePhaseField omega = new SinglePhaseField(Temperature.Basis);

            omega.ProjectField(1.0,
                               delegate(int j0, int Len, NodeSet NS, MultidimensionalArray result) {
                int K = result.GetLength(1);     // No nof Nodes
                MultidimensionalArray temp = MultidimensionalArray.Create(Len, K);
                Temperature.Evaluate(j0, Len, NS, temp);
                for (int j = 0; j < Len; j++)
                {
                    for (int k = 0; k < K; k++)
                    {
                        result[j, k] = 1 / temp[j, k];
                    }
                }
            }, new Foundation.Quadrature.CellQuadratureScheme(true, null));
            return(InitialMass / omega.IntegralOver(null));
        }
Ejemplo n.º 15
0
        /// <summary>
        /// calculate the curvature corresponding to the Level-Set
        /// </summary>
        /// <param name="Curvature"></param>
        /// <param name="LevSetGradient"></param>
        /// <param name="VolMask"></param>
        public void ProjectToDGCurvature(SinglePhaseField Curvature, out VectorField <SinglePhaseField> LevSetGradient, CellMask VolMask = null)
        {
            if (VolMask == null)
            {
                VolMask = CellMask.GetFullMask(Curvature.Basis.GridDat);
            }

            Curvature.Clear();
            Curvature.ProjectField(1.0,
                                   CurvEvaluation(mode),
                                   new Foundation.Quadrature.CellQuadratureScheme(true, VolMask));

            // check the projection error
            projErr_curv = Curvature.L2Error(
                CurvEvaluation(mode),
                new Foundation.Quadrature.CellQuadratureScheme(true, VolMask));
            //if (projErr_curv >= 1e-5)
            //    Console.WriteLine("WARNING: Curvature projection error onto PhiDG = {0}", projErr_curv);


            LevSetGradient = null;
        }
Ejemplo n.º 16
0
#pragma warning restore 649

        /// <summary>
        /// creates heat equation related fields
        /// </summary>
        public void CreateHeatFields()
        {
            int D = this.GridData.SpatialDimension;

            this.Temperature = new XDGField(new XDGBasis(this.LsTrk, this.Control.FieldOptions[VariableNames.Temperature].Degree), VariableNames.Temperature);
            base.RegisterField(this.Temperature);
            this.ResidualHeat = new XDGField(this.Temperature.Basis, "ResidualHeat");
            base.RegisterField(this.ResidualHeat);

            this.HeatFlux = new VectorField <XDGField>(D.ForLoop(d => new XDGField(new XDGBasis(this.LsTrk, this.Control.FieldOptions[VariableNames.HeatFluxVectorComponent(d)].Degree), VariableNames.HeatFluxVectorComponent(d))));
            base.RegisterField(this.HeatFlux);
            if (this.Control.conductMode != ConductivityInSpeciesBulk.ConductivityMode.SIP)
            {
                this.ResidualAuxHeatFlux = new VectorField <XDGField>(D.ForLoop(d => new XDGField(new XDGBasis(this.LsTrk, this.Control.FieldOptions[VariableNames.HeatFluxVectorComponent(d)].Degree), VariableNames.ResidualAuxHeatFluxVectorComponent(d))));
                base.RegisterField(this.ResidualAuxHeatFlux);
            }

            this.DisjoiningPressure = new SinglePhaseField(new Basis(this.GridData, this.Control.FieldOptions[VariableNames.Pressure].Degree), "DisjoiningPressure");
            if (this.Control.DisjoiningPressureFunc != null)
            {
                DisjoiningPressure.ProjectField(this.Control.DisjoiningPressureFunc);
            }
            base.RegisterField(this.DisjoiningPressure);
        }
Ejemplo n.º 17
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);
        }
Ejemplo n.º 18
0
        void TestAgglomeration_Projection(int quadOrder, MultiphaseCellAgglomerator Agg)
        {
            var Bmask      = LsTrk.Regions.GetSpeciesMask("B");
            var BbitMask   = Bmask.GetBitMask();
            var XDGmetrics = LsTrk.GetXDGSpaceMetrics(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, quadOrder, 1);

            int degree = Math.Max(0, this.u.Basis.Degree - 1);

            _2D SomePolynomial;

            if (degree == 0)
            {
                SomePolynomial = (x, y) => 3.2;
            }
            else if (degree == 1)
            {
                SomePolynomial = (x, y) => 3.2 + x - 2.4 * y;
            }
            else
            {
                SomePolynomial = (x, y) => x * x + y * y;
            }

            // ------------------------------------------------
            // project the polynomial onto a single-phase field
            // ------------------------------------------------
            SinglePhaseField NonAgglom = new SinglePhaseField(new Basis(this.GridData, degree), "NonAgglom");

            NonAgglom.ProjectField(1.0,
                                   SomePolynomial.Vectorize(),
                                   new CellQuadratureScheme(true, Bmask));

            // ------------------------------------------------
            // project the polynomial onto the aggomerated XDG-field
            // ------------------------------------------------

            var qsh = XDGmetrics.XQuadSchemeHelper;

            // Compute the inner product of 'SomePolynomial' with the cut-cell-basis, ...
            SinglePhaseField xt = new SinglePhaseField(NonAgglom.Basis, "test");

            xt.ProjectField(1.0,
                            SomePolynomial.Vectorize(),
                            qsh.GetVolumeQuadScheme(this.LsTrk.GetSpeciesId("B")).Compile(this.GridData, Agg.CutCellQuadratureOrder));

            CoordinateMapping map = xt.Mapping;

            // ... change to the cut-cell-basis, ...
            double[] xVec = xt.CoordinateVector.ToArray();
            Agg.ManipulateMatrixAndRHS(default(MsrMatrix), xVec, map, null);

            {
                double[] xVec2 = xVec.CloneAs();
                Agg.ClearAgglomerated(xVec2, map); // clearing should have no effect now.

                double Err3 = GenericBlas.L2DistPow2(xVec, xVec2).MPISum().Sqrt();
                Assert.LessOrEqual(Err3, 0.0);
            }

            // ... multiply with the inverse mass-matrix, ...
            var            Mfact   = XDGmetrics.MassMatrixFactory;
            BlockMsrMatrix MassMtx = Mfact.GetMassMatrix(map, false);

            Agg.ManipulateMatrixAndRHS(MassMtx, default(double[]), map, map);
            var InvMassMtx = MassMtx.InvertBlocks(OnlyDiagonal: true, Subblocks: true, ignoreEmptyBlocks: true, SymmetricalInversion: true);

            double[] xAggVec = new double[xVec.Length];

            InvMassMtx.SpMV(1.0, xVec, 0.0, xAggVec);

            // ... and extrapolate.
            // Since we projected a polynomial, the projection is exact and after extrapolation, must be equal
            // to the polynomial.
            xt.CoordinateVector.SetV(xAggVec);
            Agg.Extrapolate(xt.Mapping);

            // ------------------------------------------------
            // check the error
            // ------------------------------------------------


            //double Err2 = xt.L2Error(SomePolynomial.Vectorize(), new CellQuadratureScheme(domain: Bmask));
            double Err2 = NonAgglom.L2Error(xt);

            Console.WriteLine("Agglom: projection and extrapolation error: " + Err2);
            Assert.LessOrEqual(Err2, 1.0e-10);
        }
Ejemplo n.º 19
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            origin.ProjectField((x, y) => (Math.Sin(x) + Math.Cos(x) + x - (Math.Cos(y) + 1)));   // 2D
            //origin.ProjectField((x, y, z) => (Math.Sin(x) + Math.Cos(x) + x - (y + 1) + Math.Sin(z))); // 3D
            //origin.ProjectField((x, y, z) => Math.Sqrt(x.Pow2() + y.Pow2() + z.Pow2()) - 1);
            //origin.ProjectField((x, y) => x * x + y * y * y - x * y);
            //origin.ProjectField((x,y) => x + y);
            //origin.ProjectField((x, y) => Math.Sin(2 * Math.PI * (x / 3.0)));


            CellMask msk2D = CellMask.GetCellMask((BoSSS.Foundation.Grid.Classic.GridData)(this.GridData), X => (X[0] > 0.0 && X[0] < 4.0 && X[1] > 0.0 && X[1] < 1.0));
            //|| (X[0] > 1.0 && X[0] < 3.0 && X[1] > 1.0 && X[1] < 2.0)
            //|| (X[0] > 2.0 && X[0] < 4.0 && X[1] > 2.0 && X[1] < 3.0)
            //|| (X[0] > 3.0 && X[0] < 4.0 && X[1] > 3.0 && X[1] < 4.0));
            //CellMask msk3D = CellMask.GetCellMask(this.GridData, X => (X[0] > 0.0 && X[0] < 3.0 && X[1] > 0.0 && X[1] < 3.0 && X[2] > 0.0 && X[2] < 1.5)
            //|| (X[0] > 0.0 && X[0] < 1.5 && X[1] > 0.0 && X[1] < 3.0 && X[2] > 0.0 && X[2] < 3.0)
            //|| (X[0] > 0.0 && X[0] < 3.0 && X[1] > 0.0 && X[1] < 1.5 && X[2] > 0.0 && X[2] < 3.0));
            CellMask test = null;

            cdgField.ProjectDGField(1.0, origin, test);
            cdgField.AccToDGField(1.0, result);

            //specField.ProjectDGField(1.0, origin, test);
            //specField.AccToDGField(1.0, specFieldDG);

            //MultidimensionalArray n4 = MultidimensionalArray.Create(3, 2);
            //n4[0, 0] = 0.3;
            //n4[0, 1] = -1;
            //n4[1, 0] = 0.6;
            //n4[1, 1] = -1;
            //n4[2, 0] = 0.9;
            //n4[2, 1] = -1;

            //MultidimensionalArray n11 = MultidimensionalArray.Create(3, 2);
            //n11[0, 0] = -0.4;
            //n11[0, 1] = 1;
            //n11[1, 0] = 0.2;
            //n11[1, 1] = 1;
            //n11[2, 0] = 0.8;
            //n11[2, 1] = 1;

            //NodeSet ns4 = new NodeSet(Grid.GetRefElement(0), n4);
            //NodeSet ns11 = new NodeSet(Grid.GetRefElement(0), n11);

            //MultidimensionalArray res4 = MultidimensionalArray.Create(1, 3);
            //MultidimensionalArray res11 = MultidimensionalArray.Create(1, 3);

            //result.Evaluate(4,1,ns4, res4);
            //result.Evaluate(11, 1, ns11, res11);



            PlotCurrentState(0.0, 0, 4);

            //var err = origin.CloneAs();
            //err.Acc(-1.0, result);

            double L2err  = 0.0; //err.L2Norm();
            double L2jump = JumpNorm(result, test);

            Console.WriteLine("");
            //double L2jump_specFEM = JumpNorm(specFieldDG, test);
            //Console.WriteLine("L2 error =  " + L2err);
            Console.WriteLine("L2 Norm of [[u]] = " + L2jump);
            //Console.WriteLine("L2 Norm of [[u]] = " + L2jump_specFEM);
            if (L2err < 1.0e-10 && L2jump < 1.0e-12)
            {
                Console.WriteLine("Test PASSED");
                passed = true;
            }
            else
            {
                Console.WriteLine("Test FAILED");
                passed = false;
            }

            base.TerminationKey = true;
            return(0.0);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Computation of mean curvature according to Bonnet's formula.
        /// </summary>
        /// <param name="scale"></param>
        /// <param name="Output">
        /// output.
        /// </param>
        /// <param name="quadScheme"></param>
        /// <param name="UseCenDiffUpTo">
        /// Either 0, 1, or 2:
        /// If 0, all derivatives are computed locally (broken derivative);
        /// if 1, the first order derivatives are computed by central
        /// differences, while the second order ones are computed locally,
        /// based on the first order ones;
        /// if 2, all derivatives are computed by central differences.
        /// </param>
        /// <param name="_1stDerivDegree">
        /// Relative DG polynomial degree for the 1st order derivatives, i.e.
        /// degree is <paramref name="_1stDerivDegree"/>+<em>p</em>, where
        /// <em>p</em> is the degree of this field.
        /// Only active if <paramref name="UseCenDiffUpTo"/> is greater than 0.
        /// </param>
        /// <param name="_2ndDerivDegree">
        /// Relative DG polynomial degree for the 2nd order derivatives, i.e.
        /// degree is <paramref name="_2ndDerivDegree"/>+<em>p</em>, where
        /// <em>p</em> is the degree of this field. Only active if
        /// <paramref name="UseCenDiffUpTo"/> is greater than 1.
        /// </param>
        /// <remarks>
        /// using central differences causes memory allocation: <em>D</em>
        /// fields for <paramref name="UseCenDiffUpTo"/>=1, and
        /// <em>D</em>*(<em>D</em>+1) for <paramref name="UseCenDiffUpTo"/>=2,
        /// where <em>D</em> notates the spatial dimension.
        /// </remarks>
        public void ProjectTotalcurvature2(
            double scale,
            SinglePhaseField Output,
            int UseCenDiffUpTo,
            int _1stDerivDegree             = 0,
            int _2ndDerivDegree             = 0,
            CellQuadratureScheme quadScheme = null)
        {
            using (new FuncTrace()) {
                if (UseCenDiffUpTo < 0 || UseCenDiffUpTo > 2)
                {
                    throw new ArgumentOutOfRangeException();
                }

                //int M = Output.Basis.Length;
                //int N = this.Basis.Length;
                int D = this.GridDat.SpatialDimension;
                //var NSC = m_context.NSC;

                SubGrid sgrd = null;
                SpatialOperator.SubGridBoundaryModes bndMode = SpatialOperator.SubGridBoundaryModes.InnerEdge;
                if (UseCenDiffUpTo >= 1 && quadScheme != null && quadScheme.Domain != null)
                {
                    sgrd    = new SubGrid(quadScheme.Domain);
                    bndMode = SpatialOperator.SubGridBoundaryModes.OpenBoundary;
                }

                // compute 1st order derivatives by central differences, if desired
                // ================================================================
                Basis B2 = new Basis(this.GridDat, this.Basis.Degree + _1stDerivDegree);

                SinglePhaseField[] GradientVector = null;
                if (UseCenDiffUpTo >= 1)
                {
                    GradientVector = new SinglePhaseField[D];
                    for (int d = 0; d < D; d++)
                    {
                        GradientVector[d] = new SinglePhaseField(B2);
                        GradientVector[d].DerivativeByFlux(1.0, this, d, sgrd, bndMode);
                    }
                }

                // compute 2nd order derivatives by central differences, if desired
                // ===============================================================
                Basis B3 = new Basis(this.GridDat, this.Basis.Degree + _2ndDerivDegree);

                SinglePhaseField[,] HessianTensor = null;
                if (UseCenDiffUpTo >= 2)
                {
                    HessianTensor = new SinglePhaseField[D, D];
                    for (int d1 = 0; d1 < D; d1++)
                    {
                        for (int d2 = 0; d2 < D; d2++)
                        {
                            HessianTensor[d1, d2] = new SinglePhaseField(B3);
                            HessianTensor[d1, d2].DerivativeByFlux(1.0, GradientVector[d1], d2, sgrd, bndMode);
                        }
                    }
                }

                // compute and project
                // ===================

                // buffers:
                MultidimensionalArray Phi     = new MultidimensionalArray(2);
                MultidimensionalArray GradPhi = new MultidimensionalArray(3);
                MultidimensionalArray HessPhi = new MultidimensionalArray(4);

                MultidimensionalArray ooNormGrad = new MultidimensionalArray(2);
                MultidimensionalArray Laplace    = new MultidimensionalArray(2);
                MultidimensionalArray Q          = new MultidimensionalArray(3);

                // evaluate/project:
                //double Erracc = 0;
                Output.ProjectField(scale,
                                    (ScalarFunctionEx) delegate(int j0, int Len, NodeSet NodeSet, MultidimensionalArray result) { // ScalarFunction2
                    Debug.Assert(result.Dimension == 2);
                    Debug.Assert(Len == result.GetLength(0));
                    int K = result.GetLength(1); // number of nodes


                    // alloc buffers
                    // -------------

                    if (Phi.GetLength(0) != Len || Phi.GetLength(1) != K)
                    {
                        Phi.Allocate(Len, K);
                        GradPhi.Allocate(Len, K, D);
                        HessPhi.Allocate(Len, K, D, D);
                        ooNormGrad.Allocate(Len, K);
                        Laplace.Allocate(Len, K);
                        Q.Allocate(Len, K, D);
                    }
                    else
                    {
                        Phi.Clear();
                        GradPhi.Clear();
                        HessPhi.Clear();
                        ooNormGrad.Clear();
                        Laplace.Clear();
                        Q.Clear();
                    }

                    // evaluate Gradient and Hessian
                    // -----------------------------

                    if (UseCenDiffUpTo >= 1)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            GradientVector[d].Evaluate(j0, Len, NodeSet, GradPhi.ExtractSubArrayShallow(-1, -1, d));
                        }
                    }
                    else
                    {
                        this.EvaluateGradient(j0, Len, NodeSet, GradPhi);
                    }

                    if (UseCenDiffUpTo == 2)
                    {
                        for (int d1 = 0; d1 < D; d1++)
                        {
                            for (int d2 = 0; d2 < D; d2++)
                            {
                                HessianTensor[d1, d2].Evaluate(j0, Len, NodeSet, HessPhi.ExtractSubArrayShallow(-1, -1, d1, d2));
                            }
                        }
                    }
                    else if (UseCenDiffUpTo == 1)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            var GradientVector_d = GradientVector[d];
                            GradientVector_d.EvaluateGradient(j0, Len, NodeSet, HessPhi.ExtractSubArrayShallow(-1, -1, d, -1), 0, 0.0);
                        }
                    }
                    else if (UseCenDiffUpTo == 0)
                    {
                        this.EvaluateHessian(j0, Len, NodeSet, HessPhi);
                    }
                    else
                    {
                        Debug.Assert(false);
                    }

                    // compute the monstrous formula
                    // -----------------------------

                    // norm of Gradient:
                    for (int d = 0; d < D; d++)
                    {
                        var GradPhi_d = GradPhi.ExtractSubArrayShallow(-1, -1, d);
                        ooNormGrad.Multiply(1.0, GradPhi_d, GradPhi_d, 1.0, "ik", "ik", "ik");
                    }
                    ooNormGrad.ApplyAll(x => 1.0 / Math.Sqrt(x));

                    // laplacian of phi:
                    for (int d = 0; d < D; d++)
                    {
                        var HessPhi_d_d = HessPhi.ExtractSubArrayShallow(-1, -1, d, d);
                        Laplace.Acc(1.0, HessPhi_d_d);
                    }

                    // result = Laplacian(phi)/|Grad phi|
                    result.Multiply(1.0, Laplace, ooNormGrad, 0.0, "ik", "ik", "ik");


                    // result = Grad(1/|Grad(phi)|)
                    for (int d1 = 0; d1 < D; d1++)
                    {
                        var Qd = Q.ExtractSubArrayShallow(-1, -1, d1);

                        for (int d2 = 0; d2 < D; d2++)
                        {
                            var Grad_d2    = GradPhi.ExtractSubArrayShallow(-1, -1, d2);
                            var Hess_d2_d1 = HessPhi.ExtractSubArrayShallow(-1, -1, d2, d1);

                            Qd.Multiply(-1.0, Grad_d2, Hess_d2_d1, 1.0, "ik", "ik", "ik");
                        }
                    }

                    ooNormGrad.ApplyAll(x => x * x * x);

                    result.Multiply(1.0, GradPhi, Q, ooNormGrad, 1.0, "ik", "ikd", "ikd", "ik");

                    //for (int i = 0; i < Len; i++) {
                    //    for (int k = 0; k < K; k++) {
                    //        double acc = 0;
                    //        for (int d = 0; d < D; d++) {
                    //            acc += GradPhi[i,k,d]*Q[i,k,d]*ooNormGrad[i,k];
                    //        }

                    //        Erracc += (acc - result[i,k]).Abs();
                    //    }
                    //}
                },
                                    quadScheme.SaveCompile(this.GridDat, (Output.Basis.Degree + this.m_Basis.Degree * (this.m_Basis.Degree - 1) * D) * 2)
                                    );
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Single run of the solver
        /// </summary>
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            using (new FuncTrace()) {
                if (Control.ExactSolution_provided)
                {
                    Tex.Clear();
                    Tex.ProjectField(this.Control.InitialValues_Evaluators["Tex"]);

                    RHS.Clear();
                    RHS.ProjectField(this.Control.InitialValues_Evaluators["RHS"]);
                }

                if (Control.AdaptiveMeshRefinement == false)
                {
                    base.NoOfTimesteps = -1;
                    if (TimestepNo > 1)
                    {
                        throw new ApplicationException("steady-state-equation.");
                    }
                    base.TerminationKey = true;
                }

                // Update matrices
                // ---------------

                UpdateMatrices();


                // call solver
                // -----------
                double mintime, maxtime;
                bool   converged;
                int    NoOfIterations;

                ClassicSolve(out mintime, out maxtime, out converged, out NoOfIterations);


                Console.WriteLine("finished; " + NoOfIterations + " iterations.");
                Console.WriteLine("converged? " + converged);
                Console.WriteLine("Timespan: " + mintime + " to " + maxtime + " seconds");


                base.QueryHandler.ValueQuery("minSolRunT", mintime, true);
                base.QueryHandler.ValueQuery("maxSolRunT", maxtime, true);
                base.QueryHandler.ValueQuery("Conv", converged ? 1.0 : 0.0, true);
                base.QueryHandler.ValueQuery("NoIter", NoOfIterations, true);
                base.QueryHandler.ValueQuery("NoOfCells", this.GridData.CellPartitioning.TotalLength, true);
                base.QueryHandler.ValueQuery("DOFs", T.Mapping.TotalLength, true);
                base.QueryHandler.ValueQuery("BlockSize", T.Basis.Length, true);



                if (base.Control.ExactSolution_provided)
                {
                    Error.Clear();
                    Error.AccLaidBack(1.0, Tex);
                    Error.AccLaidBack(-1.0, T);

                    double L2_ERR = Error.L2Norm();
                    Console.WriteLine("\t\tL2 error on " + this.Grid.NumberOfCells + ": " + L2_ERR);
                    base.QueryHandler.ValueQuery("SolL2err", L2_ERR, true);
                }

                // evaluate residual
                // =================
                {
                    this.ResiualKP1.Clear();
                    if (this.Control.InitialValues_Evaluators.ContainsKey("RHS"))
                    {
                        this.ResiualKP1.ProjectField(this.Control.InitialValues_Evaluators["RHS"]);
                    }

                    var ev = this.LapaceIp.GetEvaluator(T.Mapping, ResiualKP1.Mapping);
                    ev.Evaluate(-1.0, 1.0, ResiualKP1.CoordinateVector);
                }

                // return
                // ======

                return(0.0);
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="output">output</param>
        /// <param name="cm">mask on which the filtering should be performed</param>
        /// <param name="input">input</param>
        /// <param name="mode"></param>
        public static void FilterStencilProjection(SinglePhaseField output, CellMask cm, SinglePhaseField input, PatchRecoveryMode mode)
        {
            var GridDat = input.GridDat;

            if (!object.ReferenceEquals(output.GridDat, GridDat))
            {
                throw new ArgumentException();
            }
            if (!object.ReferenceEquals(input.GridDat, GridDat))
            {
                throw new ArgumentException();
            }

            if (cm == null)
            {
                cm = CellMask.GetFullMask(GridDat);
            }

            switch (mode)
            {
            case PatchRecoveryMode.L2_unrestrictedDom:
            case PatchRecoveryMode.L2_restrictedDom: {
                var  Mask = cm.GetBitMaskWithExternal();
                bool RestrictToCellMask = mode == PatchRecoveryMode.L2_restrictedDom;
                foreach (int jCell in cm.ItemEnum)
                {
                    int[] NeighCells, dummy;
                    GridDat.GetCellNeighbours(jCell, GetCellNeighbours_Mode.ViaVertices, out NeighCells, out dummy);

                    if (RestrictToCellMask == true)
                    {
                        NeighCells = NeighCells.Where(j => Mask[j]).ToArray();
                    }

                    FilterStencilProjection(output, jCell, NeighCells, input);
                }

                return;
            }

            case PatchRecoveryMode.ChebychevInteroplation: {
                int P = input.Basis.Degree * 3;

                double[] ChebyNodes = ChebyshevNodes(P);
                NodeSet  Nds        = new NodeSet(GridDat.iGeomCells.RefElements[0], P, 1);
                Nds.SetColumn(0, ChebyNodes);
                Nds.LockForever();
                Polynomial[] Polynomials = GetNodalPolynomials(ChebyNodes);

                MultidimensionalArray PolyVals = MultidimensionalArray.Create(P, P);


                for (int p = 0; p < P; p++)
                {
                    Polynomials[p].Evaluate(PolyVals.ExtractSubArrayShallow(p, -1), Nds);

                    for (int i = 0; i < P; i++)
                    {
                        Debug.Assert(Math.Abs(((i == p) ? 1.0 : 0.0) - PolyVals[p, i]) <= 1.0e-8);
                    }
                }


                foreach (int jCell in cm.ItemEnum)
                {
                    AffineTrafo T;
                    var         NodalValues = NodalPatchRecovery(jCell, ChebyNodes, input, out T);

                    /*
                     * MultidimensionalArray Nodes2D = MultidimensionalArray.Create(P, P, 2);
                     * for (int i = 0; i < P; i++) {
                     *  for (int j = 0; j < P; j++) {
                     *      Nodes2D[i, j, 0] = ChebyNodes[i];
                     *      Nodes2D[i, j, 1] = ChebyNodes[j];
                     *  }
                     * }
                     * var _Nodes2D = Nodes2D.ResizeShallow(P*P, 2);
                     * var xNodes = _Nodes2D.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { P*P - 1, 0 });
                     * var yNodes = _Nodes2D.ExtractSubArrayShallow(new int[] { 0, 1 }, new int[] { P*P - 1, 1 });
                     * int K = P*P;
                     *
                     * MultidimensionalArray xPolyVals = MultidimensionalArray.Create(P, K);
                     * MultidimensionalArray yPolyVals = MultidimensionalArray.Create(P, K);
                     *
                     * for (int p = 0; p < P; p++) {
                     *  Polynomials[p].Evaluate(yPolyVals.ExtractSubArrayShallow(p, -1), yNodes);
                     *  Polynomials[p].Evaluate(xPolyVals.ExtractSubArrayShallow(p, -1), xNodes);
                     *
                     * }
                     *
                     *
                     * double ERR = 0;
                     * for (int k = 0; k < K; k++) {
                     *
                     *  double x = xNodes[k, 0];
                     *  double y = yNodes[k, 0];
                     *
                     *  double acc = 0;
                     *  double BasisHits = 0.0;
                     *  for (int i = 0; i < P; i++) {
                     *      for (int j = 0; j < P; j++) {
                     *
                     *          bool isNode = (Math.Abs(x - ChebyNodes[i]) < 1.0e-8) && (Math.Abs(y - ChebyNodes[j]) < 1.0e-8);
                     *          double BasisSoll = isNode ? 1.0 : 0.0;
                     *          if (isNode)
                     *              Console.WriteLine();
                     *
                     *          double Basis_ij = xPolyVals[i, k]*yPolyVals[j, k];
                     *
                     *          Debug.Assert((Basis_ij - BasisSoll).Abs() < 1.0e-8);
                     *
                     *          BasisHits += Math.Abs(Basis_ij);
                     *
                     *          acc += Basis_ij*NodalValues[i, j];
                     *      }
                     *  }
                     *  Debug.Assert(Math.Abs(BasisHits - 1.0) < 1.0e-8);
                     *
                     *
                     *
                     *
                     *  double soll = yNodes[k,0];
                     *  Debug.Assert((soll - acc).Pow2() < 1.0e-7);
                     *  ERR = (soll - acc).Pow2();
                     * }
                     * Console.WriteLine(ERR);
                     */

                    output.ProjectField(1.0,
                                        delegate(int j0, int Len, NodeSet Nodes, MultidimensionalArray result) {
                            var K = Nodes.NoOfNodes;

                            MultidimensionalArray NT = T.Transform(Nodes);

                            var xNodes = new NodeSet(null, NT.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { K - 1, 0 }));
                            var yNodes = new NodeSet(null, NT.ExtractSubArrayShallow(new int[] { 0, 1 }, new int[] { K - 1, 1 }));

                            MultidimensionalArray xPolyVals = MultidimensionalArray.Create(P, K);
                            MultidimensionalArray yPolyVals = MultidimensionalArray.Create(P, K);

                            for (int p = 0; p < P; p++)
                            {
                                Polynomials[p].Evaluate(yPolyVals.ExtractSubArrayShallow(p, -1), yNodes);
                                Polynomials[p].Evaluate(xPolyVals.ExtractSubArrayShallow(p, -1), xNodes);
                            }


                            for (int k = 0; k < K; k++)
                            {
                                double acc = 0;
                                for (int i = 0; i < P; i++)
                                {
                                    for (int j = 0; j < P; j++)
                                    {
                                        acc += xPolyVals[i, k] * yPolyVals[j, k] * NodalValues[i, j];
                                    }
                                }
                                result[0, k] = acc;
                            }
                        },
                                        new CellQuadratureScheme(true, new CellMask(input.GridDat, Chunk.GetSingleElementChunk(jCell))));
                }


                return;
            }
            }
        }
Ejemplo n.º 23
0
        private void MassCorrection()
        {
            double[] Qnts_old = ComputeBenchmarkQuantities();

            CorrectionLevSet.Clear();
            CorrectionLevSet.Acc(1.0, phi);
            this.CorrectionLsTrk.UpdateTracker(0.0);

            double[] Qnts = ComputeBenchmarkQuantities();

            double massDiff = Qnts_old[0] - Qnts[0];

            // we assume the current phasefield is close to the equilibrium tangenshyperbolicus form
            SinglePhaseField phiNew  = new SinglePhaseField(phi.Basis);
            GridData         GridDat = (GridData)(phi.GridDat);
            double           mass_uc = Qnts[0];

            int i = 0;

            while (massDiff.Abs() > 1e-6)
            {
                // calculated for a cone, one could include the shape e.g. by using the circularity
                // correction guess
                double correction = Math.Sign(massDiff) * 1e-10;//-Qnts[1] / (4 * Qnts[0] * Math.PI) * massDiff * 1e-5;

                // take the correction guess and calculate a forward difference to approximate the derivative
                phiNew.ProjectField(
                    (ScalarFunctionEx) delegate(int j0, int Len, NodeSet NS, MultidimensionalArray result)
                {     // ScalarFunction2
                    Debug.Assert(result.Dimension == 2);
                    Debug.Assert(Len == result.GetLength(0));
                    int K = result.GetLength(1);     // number of nodes

                    // evaluate Phi
                    // -----------------------------
                    phi.Evaluate(j0, Len, NS, result);

                    // compute the pointwise values of the new level set
                    // -----------------------------

                    result.ApplyAll(x => 0.5 * Math.Log(Math.Max(1 + x, 1e-10) / Math.Max(1 - x, 1e-10)) * Math.Sqrt(2) * this.Control.cahn);
                    result.ApplyAll(x => Math.Tanh((x + correction) / (Math.Sqrt(2) * this.Control.cahn)));
                }
                    );

                // update LsTracker
                CorrectionLevSet.Clear();
                CorrectionLevSet.Acc(1.0, phiNew);
                this.CorrectionLsTrk.UpdateTracker(0.0);

                Qnts = ComputeBenchmarkQuantities();

                correction = -(massDiff) / ((Qnts_old[0] - Qnts[0] - massDiff) / (correction));

                double initial  = massDiff;
                bool   finished = false;
                int    k        = 0;
                //while (massDiff.Abs() - initial.Abs() >= 0.0 && step > 1e-12)
                while (!finished)
                {
                    double step = Math.Pow(0.5, k);
                    // compute and project
                    // step one calculate distance field phiDist = 0.5 * log(Max(1+c, eps)/Max(1-c, eps)) * sqrt(2) * Cahn
                    // step two project the new phasefield phiNew = tanh((cDist + correction)/(sqrt(2) * Cahn))
                    // ===================
                    phiNew.ProjectField(
                        (ScalarFunctionEx) delegate(int j0, int Len, NodeSet NS, MultidimensionalArray result)
                    {     // ScalarFunction2
                        Debug.Assert(result.Dimension == 2);
                        Debug.Assert(Len == result.GetLength(0));
                        int K = result.GetLength(1);     // number of nodes

                        // evaluate Phi
                        // -----------------------------
                        phi.Evaluate(j0, Len, NS, result);

                        // compute the pointwise values of the new level set
                        // -----------------------------

                        result.ApplyAll(x => 0.5 * Math.Log(Math.Max(1 + x, 1e-10) / Math.Max(1 - x, 1e-10)) * Math.Sqrt(2) * this.Control.cahn);
                        result.ApplyAll(x => Math.Tanh((x + correction * step) / (Math.Sqrt(2) * this.Control.cahn)));
                    }
                        );

                    // update LsTracker
                    CorrectionLevSet.Clear();
                    CorrectionLevSet.Acc(1.0, phiNew);
                    this.CorrectionLsTrk.UpdateTracker(0.0);

                    Qnts     = ComputeBenchmarkQuantities();
                    massDiff = Qnts_old[0] - Qnts[0];

                    if (massDiff.Abs() < (1 - 1e-4 * step) * initial.Abs())
                    {
                        finished = true;

                        // update field
                        phi.Clear();
                        phi.Acc(1.0, phiNew);

                        // update LsTracker
                        CorrectionLevSet.Clear();
                        CorrectionLevSet.Acc(1.0, phi);
                        this.CorrectionLsTrk.UpdateTracker(0.0);
                        Console.WriteLine($"" +
                                          $"converged with stepsize:  {step}, correction: {correction}\n" +
                                          $"                     dM:  {massDiff}");
                        if (k > 0)
                        {
                            Console.WriteLine($"Finished Linesearch in {k} iterations");
                        }
                    }
                    else if (Math.Abs(correction * step) < 1e-15)
                    {
                        // reset LsTracker
                        CorrectionLevSet.Clear();
                        CorrectionLevSet.Acc(1.0, phi);
                        this.CorrectionLsTrk.UpdateTracker(0.0);

                        Qnts     = ComputeBenchmarkQuantities();
                        massDiff = Qnts_old[0] - Qnts[0];

                        Console.WriteLine($" Linesearch failed after {k} iterations");
                        goto Failed;
                    }
                    else
                    {
                        k++;
                    }
                }
                i++;
            }

Failed:

            Console.WriteLine($"Performed Mass Correction in {i} iteratins: \n" +
                              $"\told mass:           {Qnts_old[0]:N4}\n" +
                              $"\tuncorrected mass:   {mass_uc:N4}\n" +
                              $"\tcorrected mass:     {Qnts[0]:N4}");
        }
Ejemplo n.º 24
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            //origin.ProjectField((x, y) => 1-x*x);
            origin.ProjectField((x, y) => x * x + y * y * y - x * y);

            specField.ProjectDGFieldCheaply(1.0, origin);
            //specField.ProjectDGField(1.0, origin);

            /*
             * if (this.MPIRank >= 0) {
             *  // specField.Coordinates[46] = 1;
             *  // specField.Coordinates[48] = -1;
             *  ilPSP.Environment.StdoutOnlyOnRank0 = false;
             *
             *  Random R = new Random();
             *
             *  for (int t = 1; t <= 2; t++) {
             *      int i0 = spec_basis.GetLocalOwnedNodesOffset(t);
             *      int L = spec_basis.GetNoOfOwnedNodes(t);
             *
             *
             *      for (int l = 0; l < L; l++) {
             *          double x = specField.Basis.GlobalNodes[i0 + l, 0];
             *          double y = specField.Basis.GlobalNodes[i0 + l, 1];
             *
             *          specField.Coordinates[i0 + l] = R.NextDouble();
             *
             *          //if (Math.Abs(x - (+2.0)) < 1.0e-8) {
             *          //    Console.WriteLine("Hi! R" + this.MPIRank + ", " + (l + i0) + " (" + x + "," + y + ")");
             *          //    specField.Coordinates[i0 + l] = y;
             *          //}
             *
             *      }
             *  }
             *
             *  //ilPSP.Environment.StdoutOnlyOnRank0 = true;
             *
             * }*/


            using (var m_transciever = new Foundation.SpecFEM.Transceiver(spec_basis)) {
                m_transciever.Scatter(specField.Coordinates);
            }

            specField.AccToDGField(1.0, Result);

            var ERR = origin.CloneAs();

            ERR.Acc(-1.0, Result);

            double L2Err  = ERR.L2Norm();
            double L2Jump = JumpNorm(Result);

            Console.WriteLine("L2 Error: " + L2Err);
            Console.WriteLine("L2 Norm of [[u]]: " + L2Jump);
            if ((L2Err < 1.0e-10 || this.Grid.PeriodicTrafo.Count > 0) && L2Jump < 1.0e-10)
            {
                Console.WriteLine("Test PASSED");
                Passed = true;
            }
            else
            {
                Console.WriteLine("Test FAILED");
                Passed = false;
            }

            Passed = true;

            base.TerminationKey = true;
            return(0.0);
        }