Ejemplo n.º 1
0
        /// <summary>
        /// Computes L2 norms between DG fields on different grid resolutions, i.e. for a
        /// convergence study, where the solution on the finest grid is assumed to be exact.
        /// </summary>
        /// <param name="FieldsToCompare">
        /// Identification (<see cref="DGField.Identification"/>) of the fields which should be compared.
        /// </param>
        /// <param name="timestepS">
        /// A collection of solutions on different grid resolutions.
        /// </param>
        /// <param name="GridRes">
        /// On exit, the resolution of the different grids.
        /// </param>
        /// <param name="L2Errors">
        /// On exit, the L2 error
        /// (for each field specified in <paramref name="FieldsToCompare"/>)
        /// in comparison to the solution on the finest grid.
        /// </param>
        /// <param name="__DOFs">
        /// On exit, the number of degrees-of-freedom
        /// (for each field specified in <paramref name="FieldsToCompare"/>).
        /// </param>
        /// <param name="timestepIds">
        /// on exit, the timestep id which correlate with the resolutions <paramref name="GridRes"/>
        /// (remarks: <paramref name="timestepIds"/> may be re-sorted internally according to grid resolution).
        /// </param>
        public static void ComputeErrors(IEnumerable <string> FieldsToCompare, IEnumerable <ITimestepInfo> timestepS,
                                         out double[] GridRes, out Dictionary <string, int[]> __DOFs, out Dictionary <string, double[]> L2Errors, out Guid[] timestepIds)
        {
            // load the DG-Fields
            List <IEnumerable <DGField> > fields = new List <IEnumerable <DGField> >();
            int i = 1;

            foreach (var timestep in timestepS)
            {
                Console.WriteLine("Loading timestep {0} of {1}, ({2})...", i, timestepS.Count(), timestep.ID);
                fields.Add(timestep.Fields);
                i++;
                Console.WriteLine("done (Grid has {0} cells).", fields.Last().First().GridDat.CellPartitioning.TotalLength);
            }


            // sort according to grid resolution
            {
                var s = fields.OrderBy(f => f.First().GridDat.CellPartitioning.TotalLength).ToArray();
                timestepIds = new Guid[s.Length];
                for (int z = 0; z < timestepIds.Length; z++)
                {
                    int idx = fields.IndexOf(s[z], (f1, f2) => object.ReferenceEquals(f1, f2));
                    timestepIds[z] = timestepS.ElementAt(idx).ID;
                }

                fields.Clear();
                fields.AddRange(s);
            }


            // Grids and coarse-to-fine -- mappings.
            GridData[] gDataS = fields.Select(fc => (GridData)(fc.First().GridDat)).ToArray();

            int[][] Fine2CoarseMapS = new int[gDataS.Length - 1][]; // 1st index: level; 2n index: cell index on finest level
            for (int iLevel = 0; iLevel < Fine2CoarseMapS.Length; iLevel++)
            {
                ComputeFine2CoarseMap(gDataS.Last(), gDataS[iLevel], out Fine2CoarseMapS[iLevel]);
            }

            // extrapolate to fine grid
            Dictionary <string, List <DGField> > injectedFields = new Dictionary <string, List <DGField> >();
            Dictionary <string, List <int> >     DOFs           = new Dictionary <string, List <int> >();

            foreach (string Identification in FieldsToCompare)
            {
                List <DGField> fields_Identification = new List <DGField>(); // fields for different resolutions
                List <int>     dofs_Idenitification  = new List <int>();

                DGField finestSolution = fields.Last().Single(f => f.Identification == Identification);

                for (int iLevel = 0; iLevel < gDataS.Length - 1; iLevel++)
                {
                    Console.WriteLine("Injecting '{0}' from level {1} to finest grid...", Identification, iLevel);

                    DGField coarseSolution = fields[iLevel].Single(f => f.Identification == Identification);

                    if (finestSolution.GetType() != coarseSolution.GetType())
                    {
                        throw new NotSupportedException();
                    }
                    if (coarseSolution.Basis.Degree != finestSolution.Basis.Degree)
                    {
                        throw new NotSupportedException();
                    }

                    if (finestSolution is XDGField)
                    {
                        XDGField _coarseSolution  = (XDGField)coarseSolution;
                        XDGField _finestSolution  = (XDGField)finestSolution;
                        XDGField injectedSolution = new XDGField(_finestSolution.Basis, Identification + "-inj-" + iLevel);

                        InjectXDGField(Fine2CoarseMapS[iLevel], injectedSolution, _coarseSolution);

                        fields_Identification.Add(injectedSolution);
                        dofs_Idenitification.Add(coarseSolution.Mapping.GetTotalNoOfDOFs());
                    }
                    else if (finestSolution is SinglePhaseField)
                    {
                        SinglePhaseField _coarseSolution  = (SinglePhaseField)coarseSolution;
                        SinglePhaseField _finestSolution  = (SinglePhaseField)finestSolution;
                        SinglePhaseField injectedSolution = new SinglePhaseField(_finestSolution.Basis, Identification + "-inj-" + iLevel);

                        InjectDGField(Fine2CoarseMapS[iLevel], injectedSolution, _coarseSolution);

                        fields_Identification.Add(injectedSolution);
                        dofs_Idenitification.Add(coarseSolution.Mapping.GetTotalNoOfDOFs());
                    }
                    else
                    {
                        throw new NotSupportedException("DG field type '" + finestSolution.GetType().FullName + "' not supported, Identification is '" + finestSolution.Identification + "'");
                    }

                    Console.WriteLine("done.");
                }

                fields_Identification.Add(finestSolution);
                injectedFields.Add(Identification, fields_Identification);
                DOFs.Add(Identification, dofs_Idenitification);
            }
            __DOFs = new Dictionary <string, int[]>();
            foreach (var kv in DOFs)
            {
                __DOFs.Add(kv.Key, kv.Value.ToArray());
            }


            // compute the errors
            L2Errors = new Dictionary <string, double[]>();
            foreach (string Identification in FieldsToCompare)
            {
                double[] L2Error = new double[gDataS.Length - 1];

                for (int iLevel = 0; iLevel < gDataS.Length - 1; iLevel++)
                {
                    Console.WriteLine("Computing L2 error of '{0}' on level {1} ...", Identification, iLevel);

                    DGField Error  = injectedFields[Identification].Last().CloneAs();
                    DGField injSol = injectedFields[Identification].ElementAt(iLevel);
                    Error.Acc(-1.0, injSol);

                    L2Error[iLevel] = Error.L2Norm();

                    Console.WriteLine("done (Error is {0:0.####E-00}).", L2Error[iLevel]);
                }

                L2Errors.Add(Identification, L2Error);
            }

            GridRes = gDataS.Take(gDataS.Length - 1).Select(gd => gd.Cells.h_minGlobal).ToArray();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Computes L2 norms between DG fields on different grid resolutions, i.e. for a
        /// convergence study, where the solution on the finest grid is assumed to be exact.
        /// </summary>
        /// <param name="FieldsToCompare">
        /// Identification (<see cref="DGField.Identification"/>) of the fields which should be compared.
        /// </param>
        /// <param name="timestepS">
        /// A collection of solutions on different grid resolutions.
        /// </param>
        /// <param name="GridRes">
        /// On exit, the resolution of the different grids.
        /// </param>
        /// <param name="L2Errors">
        /// On exit, the L2 error
        /// (for each field specified in <paramref name="FieldsToCompare"/>)
        /// in comparison to the solution on the finest grid.
        /// </param>
        public static void ComputeErrors(string[] FieldsToCompare, ITimestepInfo[] timestepS,
                                         out double[] GridRes, out Dictionary <string, double[]> L2Errors)
        {
            // load the DG-Fields
            List <IEnumerable <DGField> > fields = new List <IEnumerable <DGField> >();
            int i = 1;

            foreach (var timestep in timestepS)
            {
                Console.WriteLine("Loading timestep {0} of {1}, ({2})...", i, timestepS.Length, timestep.ID);
                fields.Add(timestep.Fields);
                i++;
                Console.WriteLine("done (Grid has {0} cells).", fields.Last().First().GridDat.CellPartitioning.TotalLength);
            }

            {
                var s = fields.OrderBy(f => f.First().GridDat.CellPartitioning.TotalLength).ToArray();
                fields.Clear();
                fields.AddRange(s);
            }

            // Grids and coarse-to-fine -- mappings.
            GridData[] gDataS = fields.Select(fc => (GridData)(fc.First().GridDat)).ToArray();

            int[][] Fine2CoarseMapS = new int[gDataS.Length - 1][];
            for (int iLevel = 0; iLevel < Fine2CoarseMapS.Length; iLevel++)
            {
                ComputeFine2CoarseMap(gDataS.Last(), gDataS[iLevel], out Fine2CoarseMapS[iLevel]);
            }

            // extrapolate to fine grid
            Dictionary <string, List <DGField> > injectedFields = new Dictionary <string, List <DGField> >();

            foreach (string Identification in FieldsToCompare)
            {
                List <DGField> blabla = new List <DGField>();

                DGField finestSolution = fields.Last().Single(f => f.Identification == Identification);

                for (int iLevel = 0; iLevel < gDataS.Length - 1; iLevel++)
                {
                    Console.WriteLine("Injecting '{0}' from level {1} to finest grid...", Identification, iLevel);

                    DGField coarseSolution = fields[iLevel].Single(f => f.Identification == Identification);

                    if (finestSolution.GetType() != coarseSolution.GetType())
                    {
                        throw new NotSupportedException();
                    }
                    if (coarseSolution.Basis.Degree != finestSolution.Basis.Degree)
                    {
                        throw new NotSupportedException();
                    }

                    if (finestSolution is XDGField)
                    {
                        XDGField _coarseSolution  = (XDGField)coarseSolution;
                        XDGField _finestSolution  = (XDGField)finestSolution;
                        XDGField injectedSolution = new XDGField(_finestSolution.Basis, Identification + "-inj-" + iLevel);

                        InjectXDGField(Fine2CoarseMapS[iLevel], injectedSolution, _coarseSolution);

                        blabla.Add(injectedSolution);
                    }
                    else if (finestSolution is SinglePhaseField)
                    {
                        SinglePhaseField _coarseSolution  = (SinglePhaseField)coarseSolution;
                        SinglePhaseField _finestSolution  = (SinglePhaseField)finestSolution;
                        SinglePhaseField injectedSolution = new SinglePhaseField(_finestSolution.Basis, Identification + "-inj-" + iLevel);

                        InjectDGField(Fine2CoarseMapS[iLevel], injectedSolution, _coarseSolution);

                        blabla.Add(injectedSolution);
                    }
                    else
                    {
                        throw new NotSupportedException("DG field type '" + finestSolution.GetType().FullName + "' not supported, Identification is '" + finestSolution.Identification + "'");
                    }

                    Console.WriteLine("done.");
                }

                blabla.Add(finestSolution);
                injectedFields.Add(Identification, blabla);
            }

            // compute the errors
            L2Errors = new Dictionary <string, double[]>();
            foreach (string Identification in FieldsToCompare)
            {
                double[] L2Error = new double[gDataS.Length - 1];

                for (int iLevel = 0; iLevel < gDataS.Length - 1; iLevel++)
                {
                    Console.WriteLine("Computing L2 error of '{0}' on level {1} ...", Identification, iLevel);

                    DGField Error  = injectedFields[Identification].Last().CloneAs();
                    DGField injSol = injectedFields[Identification].ElementAt(iLevel);
                    Error.Acc(-1.0, injSol);

                    L2Error[iLevel] = Error.L2Norm();

                    Console.WriteLine("done (Error is {0:0.####E-00}).", L2Error[iLevel]);
                }

                L2Errors.Add(Identification, L2Error);
            }

            GridRes = gDataS.Take(gDataS.Length - 1).Select(gd => gd.Cells.h_minGlobal).ToArray();

            // convert to table

            /*
             * MultidimensionalArray RES = MultidimensionalArray.Create(GridRes.Length, FieldsToCompare.Length + 1);
             * RES.SetColumn(0, GridRes);
             * for(int ii = 0; ii < FieldsToCompare.Length; ii++) {
             *  RES.SetColumn(ii + 1, L2Errors[FieldsToCompare[ii]]);
             * }
             *
             *
             * using(var fs = new FileStream("res.csv", FileMode.Append)) {
             *  var stw = new StreamWriter(fs);
             *  stw.Write("GridRes ");
             *  for(int ii = 0; ii < FieldsToCompare.Length; ii++) {
             *      stw.Write(FieldsToCompare[ii]);
             *      if(ii + 1 < FieldsToCompare.Length)
             *          stw.Write(" ");
             *  }
             *
             *  stw.Flush();
             *
             *  RES.WriteToStream(fs);
             *
             * }
             */
        }