Esempio n. 1
0
        /// <summary>
        /// Estimates the errors of the fields with name
        /// <paramref name="fieldName"/> in the given
        /// <paramref name="timesteps"/> by computing the errors with respect
        /// to the solution on the finest corresponding grid by making use of
        /// <see cref="BoSSS.Solution.Statistic.DGFieldComparison.ComputeErrors"/>.
        /// The result is then grouped according to the polynomial degree of field
        /// <paramref name="fieldName"/>.
        /// </summary>
        /// <param name="timesteps">
        /// The time-steps containing the fields whose errors should be
        /// estimated.
        /// </param>
        /// <param name="fieldName">
        /// The name of the DG field whose error should be estimated.
        /// </param>
        /// <returns>
        /// A data set containing information about the grid resolution and the
        /// corresponding errors with respect to the finest corresponding grid,
        /// grouped by the polynomial degree. Obviously, the time-step
        /// associated with the finest grid for each polynomial degree has an
        /// estimated error of zero (by definition) and is thus excluded from
        /// the result.
        /// </returns>
        public static Plot2Ddata ToEstimatedGridConvergenceData(this IEnumerable <ITimestepInfo> timesteps, string fieldName)
        {
            Dictionary <string, double[][]> dataGroups = new Dictionary <string, double[][]>();

            foreach (var group in timesteps.GroupBy(t => t.Fields.Find(fieldName).Basis.Degree))
            {
                double[] resolution;
                Dictionary <string, double[]> errors;
                Guid[] tsiIds;

                DGFieldComparison.ComputeErrors(
                    new string[] { fieldName },
                    group.ToArray(),
                    out resolution,
                    out errors,
                    out tsiIds);

                Debug.Assert(errors.ContainsKey(fieldName));
                Debug.Assert(errors[fieldName].Length == resolution.Length);

                double[][] resolutionsAndErrors = new double[2][] { resolution, errors[fieldName] };
                dataGroups.Add(group.Key.ToString(), resolutionsAndErrors);
            }

            return(new Plot2Ddata(dataGroups.ToArray()).WithLogX().WithLogY());
        }
Esempio n. 2
0
        /// <summary>
        /// Estimates the errors of the fields with name
        /// <paramref name="fieldName"/> in the given
        /// <paramref name="timesteps"/> by computing the errors with respect
        /// to the solution on the finest corresponding grid by making use of
        /// <see cref="BoSSS.Solution.Statistic.DGFieldComparison.ComputeErrors"/>.
        /// The result is then grouped according to the polynomial degree of field
        /// <paramref name="fieldName"/>.
        /// </summary>
        /// <param name="timesteps">
        /// The time-steps containing the fields whose errors should be
        /// estimated.
        /// </param>
        /// <param name="fieldName">
        /// The name of the DG field whose error should be estimated.
        /// </param>
        /// <param name="xAxis_Is_hOrDof">
        /// - true: the x-axis (<see cref="Plot2Ddata.XYvalues.Abscissas"/>) is the grid resolution \f$ h \f$
        /// - false: the x-axis (<see cref="Plot2Ddata.XYvalues.Abscissas"/>) is the number of degrees-of-freedom
        /// </param>
        /// <returns>
        /// A data set containing information about the grid resolution and the
        /// corresponding errors with respect to the finest corresponding grid,
        /// grouped by the polynomial degree. Obviously, the time-step
        /// associated with the finest grid for each polynomial degree has an
        /// estimated error of zero (by definition) and is thus excluded from
        /// the result.
        /// </returns>
        public static Plot2Ddata ToEstimatedGridConvergenceData(this IEnumerable <ITimestepInfo> timesteps, string fieldName, bool xAxis_Is_hOrDof = true)
        {
            Dictionary <string, double[][]> dataGroups = new Dictionary <string, double[][]>();

            foreach (var group in timesteps.GroupBy(t => t.Fields.Find(fieldName).Basis.Degree))
            {
                DGFieldComparison.ComputeErrors(
                    new string[] { fieldName },
                    group.ToArray(),
                    out double[] resolution,
                    out Dictionary <string, int[]> DOFs,
                    out Dictionary <string, double[]> errors,
                    out Guid[] tsiIds);
Esempio n. 3
0
            /// <summary>
            /// Updates all columns related to convergence plots
            /// </summary>
            public void Update()
            {
                // Get all sessions which are successfully terminated
                // ==================================================
                var SuccSessions = owner.Sessions.Where(sess => sess.SuccessfulTermination == true).ToArray();

                // Group the sessions according to polynomial degree
                // =================================================
                System.Func <int[], int[], bool> eqFunc = (A, B) => ArrayTools.AreEqual(A, B);
                var comp          = eqFunc.ToEqualityComparer();
                var SessionGroups = SuccSessions.GroupBy(GetDGDegreeKey, comp).ToArray();


                // Spatial convergence for each session group
                // ==========================================

                // intermediate result storage
                // 1st key: Field name
                // 2nd key: session name
                // value: error norm
                var Errors = new Dictionary <string, Dictionary <Guid, double> >();


                foreach (IEnumerable <ISessionInfo> spatialSeries in SessionGroups)
                {
                    if (spatialSeries.Count() <= 1)
                    {
                        continue;
                    }

                    ITimestepInfo[] tsiS = spatialSeries.Select(sess => sess.Timesteps.Last()).ToArray();

                    // find DG field identifications which are present in _all_ timesteps
                    var commonFieldIds = new HashSet <string>();
                    foreach (var fi in tsiS[0].FieldInitializers)
                    {
                        string id = fi.Identification;

                        bool containedInOthers = true;
                        foreach (var tsi in tsiS.Skip(1))
                        {
                            if (tsi.FieldInitializers.Where(fii => fii.Identification == id).Count() <= 0)
                            {
                                containedInOthers = false;
                            }
                        }

                        if (containedInOthers)
                        {
                            commonFieldIds.Add(id);
                        }
                    }

                    string[] fieldIds = commonFieldIds.ToArray();

                    // compute L2-errors
                    DGFieldComparison.ComputeErrors(fieldIds, tsiS, out double[] hS, out var DOFs, out var ERRs, out var tsiIdS);


                    // record errors
                    foreach (var id in fieldIds)
                    {
                        Dictionary <Guid, double> err_id;
                        if (!Errors.TryGetValue(id, out err_id))
                        {
                            err_id = new Dictionary <Guid, double>();
                            Errors.Add(id, err_id);
                        }

                        for (int iGrd = 0; iGrd < hS.Length; iGrd++)
                        {
                            ITimestepInfo tsi  = tsiS.Single(t => t.ID == tsiIdS[iGrd]);
                            ISessionInfo  sess = tsi.Session;

                            err_id.Add(sess.ID, ERRs[id][iGrd]);
                        }
                    }
                }



                // Set L2 error columns in session table
                // =====================================
                foreach (string fieldName in Errors.Keys)
                {
                    string colName = "L2Error_" + fieldName;

                    if (owner.AdditionalSessionTableColums.ContainsKey(colName))
                    {
                        owner.AdditionalSessionTableColums.Remove(colName);
                    }

                    var ErrorsCol = Errors[fieldName];

                    owner.AdditionalSessionTableColums.Add(colName, delegate(ISessionInfo s) {
                        object ret = 0.0;

                        if (ErrorsCol.ContainsKey(s.ID))
                        {
                            ret = ErrorsCol[s.ID];
                        }

                        return(ret);
                    });
                }
            }
Esempio n. 4
0
        /// <summary>
        /// Addition/Subtraction of DG fields on different grids
        /// </summary>
        /// <param name="A"></param>
        /// <param name="scaleA"></param>
        /// <param name="B"></param>
        /// <param name="scaleB"></param>
        /// <returns>
        /// <paramref name="scaleA"/>*<paramref name="A"/> + <paramref name="scaleB"/>*<paramref name="B"/>
        /// </returns>
        static public DGField ScaledSummation(this DGField A, double scaleA, DGField B, double scaleB)
        {
            if (object.ReferenceEquals(A.GridDat, B.GridDat))
            {
                // ++++++++++++++++++++++++++++
                // both fields on the same grid
                // ++++++++++++++++++++++++++++

                DGField sum;

                if (A.Basis.IsSubBasis(B.Basis))
                {
                    sum = (DGField)B.Clone();
                    sum.Scale(scaleB);
                    sum.AccLaidBack(1.0, A);
                }
                else if (B.Basis.IsSubBasis(A.Basis))
                {
                    sum = (DGField)A.Clone();
                    sum.Scale(scaleA);
                    sum.AccLaidBack(1.0, B);
                }
                else
                {
                    throw new ApplicationException("can't add the two fields, because their basis are incompatible");
                }


                sum.Identification = "(" + scaleA + "*" + A.Identification + "+" + scaleB + "*" + B.Identification + ")";

                return(sum);
            }
            else
            {
                // ++++++++++++++++++++++++++
                // fields on different grids
                // ++++++++++++++++++++++++++

                DGField fine, coarse;
                double  aF, aC;
                if (A.GridDat.CellPartitioning.TotalLength > B.GridDat.CellPartitioning.TotalLength)
                {
                    fine   = A;
                    coarse = B;
                    aF     = scaleA;
                    aC     = scaleB;
                }
                else
                {
                    coarse = A;
                    fine   = B;
                    aC     = scaleA;
                    aF     = scaleB;
                }

                DGFieldComparison.ComputeFine2CoarseMap(
                    (Foundation.Grid.Classic.GridData)(fine.GridDat),
                    (Foundation.Grid.Classic.GridData)(coarse.GridDat),
                    out var Fine2CoarseMapS);

                DGField injected;
                if (coarse is ConventionalDGField)
                {
                    ConventionalDGField _injected = new SinglePhaseField(
                        new Basis(fine.GridDat, Math.Max(coarse.Basis.Degree, fine.Basis.Degree)),
                        coarse.Identification);

                    DGFieldComparison.InjectDGField(Fine2CoarseMapS, _injected, coarse as ConventionalDGField);
                    injected = _injected;
                }
                else if (coarse is XDGField)
                {
                    XDGField _injected = new XDGField(
                        new XDGBasis((fine as XDGField).Basis.Tracker, Math.Max(coarse.Basis.Degree, fine.Basis.Degree)),
                        coarse.Identification);

                    DGFieldComparison.InjectXDGField(Fine2CoarseMapS, _injected, coarse as XDGField);
                    injected = _injected;
                }
                else
                {
                    throw new NotSupportedException();
                }

                return(ScaledSummation(injected, aC, fine, aF));
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Estimates the errors of the fields with name
        /// <paramref name="fieldName"/> in the given
        /// <paramref name="timesteps"/> by computing the errors with respect
        /// to the solution on the finest corresponding grid by making use of
        /// <see cref="BoSSS.Solution.Statistic.DGFieldComparison.ComputeErrors"/>.
        /// The result is then grouped according to the polynomial degree of field
        /// <paramref name="fieldName"/>.
        /// </summary>
        /// <param name="timesteps">
        /// The time-steps containing the fields whose errors should be
        /// estimated.
        /// </param>
        /// <param name="fieldName">
        /// The name of the DG field whose error should be estimated.
        /// </param>
        /// <param name="xAxis_Is_hOrDof">
        /// - true: the x-axis (<see cref="Plot2Ddata.XYvalues.Abscissas"/>) is the grid resolution \f$ h \f$
        /// - false: the x-axis (<see cref="Plot2Ddata.XYvalues.Abscissas"/>) is the number of degrees-of-freedom
        /// </param>
        /// <param name="normType">
        /// H1, L2, etc.
        /// </param>
        /// <returns>
        /// A data set containing information about the grid resolution and the
        /// corresponding errors with respect to the finest corresponding grid,
        /// grouped by the polynomial degree. Obviously, the time-step
        /// associated with the finest grid for each polynomial degree has an
        /// estimated error of zero (by definition) and is thus excluded from
        /// the result.
        /// </returns>
        public static Plot2Ddata ToEstimatedGridConvergenceData(this IEnumerable <ITimestepInfo> timesteps, string fieldName, bool xAxis_Is_hOrDof = true, NormType normType = NormType.L2_approximate)
        {
            Dictionary <string, double[][]> dataGroups = new Dictionary <string, double[][]>();

            foreach (var group in timesteps.GroupBy(t => t.Fields.Find(fieldName).Basis.Degree))
            {
                Dictionary <string, int[]>    DOFs;
                Dictionary <string, double[]> errors;
                double[] resolution;
                Guid[]   tsiIds;

                if (normType == NormType.L2_embedded)
                {
                    DGFieldComparison.ComputeErrors(
                        new string[] { fieldName },
                        group.ToArray(),
                        out resolution,
                        out DOFs,
                        out errors,
                        out tsiIds);
                }
                else if (normType == NormType.L2_approximate)
                {
                    DGFieldComparisonNonEmb.ComputeErrors_L2(
                        new string[] { fieldName },
                        group.ToArray(),
                        out resolution,
                        out DOFs,
                        out errors,
                        out tsiIds);
                }
                else if (normType == NormType.L2noMean_approximate)
                {
                    DGFieldComparisonNonEmb.ComputeErrors_L2noMean(
                        new string[] { fieldName },
                        group.ToArray(),
                        out resolution,
                        out DOFs,
                        out errors,
                        out tsiIds);
                }
                else if (normType == NormType.H1_approximate)
                {
                    DGFieldComparisonNonEmb.ComputeErrors_H1(
                        new string[] { fieldName },
                        group.ToArray(),
                        out resolution,
                        out DOFs,
                        out errors,
                        out tsiIds);
                }
                else
                {
                    throw new NotImplementedException();
                }

                double dim = timesteps.First().Grid.SpatialDimension;

                Debug.Assert(errors.ContainsKey(fieldName));
                Debug.Assert(errors[fieldName].Length == resolution.Length);

                Debug.Assert(DOFs.ContainsKey(fieldName));
                Debug.Assert(DOFs[fieldName].Length == resolution.Length);


                //double[][] resolutionsAndErrors = new double[2][] {
                //    xAxis_Is_hOrDof ? resolution : DOFs[fieldName].Select(ix => (double)ix).ToArray(),
                //    errors[fieldName] };

                double[] xValues = xAxis_Is_hOrDof ? resolution : DOFs[fieldName].Select(ix => Math.Pow((double)ix, 1.0 / dim)).ToArray();
                double[] yValues = errors[fieldName];
                if (xAxis_Is_hOrDof == false)
                {
                    // data is sorted according to mesh width, this may not be equal to sorting according to No. of. DOF
                    Array.Sort(xValues, yValues);
                }

                dataGroups.Add(group.Key.ToString(), new double[2][] { xValues, yValues });
            }

            return(new Plot2Ddata(dataGroups.ToArray()).WithLogX().WithLogY());
        }