Пример #1
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            using (new FuncTrace()) {
                base.NoOfTimesteps = int.MaxValue;
                base.EndTime       = endTime;

                // Set time step size
                if (dt <= 0)
                {
                    dt = dtFixed;
                }

                Console.Write("Timestep " + TimestepNo + " ...");

                if (phystime >= ChangeMetricTime)
                {
                    CustomTimestepConstraint.FirstMetricActive = false;
                }

                timeStepper.UpdateTimeInfo(new TimeInformation(TimestepNo, phystime, dt));

                timeStepper.Perform(dt);

                Console.WriteLine("finished");

                // Print L2 Norm at the end of the simulation run
                if (EndTime - phystime - dt < 1E-10)
                {
                    energyNorm = c.L2Norm();
                    Console.WriteLine("Energy norm = {0:0.000000000000000E-00}", energyNorm);
                }

                return(dt);
            }
        }
Пример #2
0
        static private bool TestingReclusteringIndependency()
        {
            //TestCase: 5x4 grid, AV=false, dgdegree=0, Timestepping=LTS&RK
            CNSControl ctrRepON  = ShockTube_PartTest_Dynamic(5, 4, int.MaxValue, 2, true, 5);
            CNSControl ctrRepOFF = ShockTube_PartTest_Dynamic(5, 4, int.MaxValue, 2, false, 5);

            using (var solverRepON = new HilbertTest())
                using (var solverRepOFF = new HilbertTest()) {
                    solverRepON.Init(ctrRepON);
                    solverRepON.RunSolverMode();
                    solverRepOFF.Init(ctrRepOFF);
                    solverRepOFF.RunSolverMode();

                    bool     result  = true;
                    string[] varname = { "Desity", "x-Momentum", "y-Momentum", "Energy" };
                    for (int i = 0; i < 4; i++)
                    {
                        List <DGField> listOfDGFields_RepON  = (List <DGField>)solverRepON.IOFields;
                        DGField        variableRepON         = listOfDGFields_RepON[i];
                        double         L2NormRepON           = variableRepON.L2Norm();
                        List <DGField> listOfDGFields_RepOFF = (List <DGField>)solverRepOFF.IOFields;
                        DGField        vriableRepOFF         = listOfDGFields_RepOFF[i];
                        double         L2NormRepOFF          = vriableRepOFF.L2Norm();

                        Console.WriteLine("{0}-L2Norm Rep ON: {1}", varname[i], L2NormRepON);
                        Console.WriteLine("{0}-L2Norm Rep OFF: {1}", varname[i], L2NormRepOFF);
                        bool normequal = (Math.Abs(L2NormRepON - L2NormRepOFF) <= 1e-14);
                        result &= normequal;
                        Console.WriteLine("{0}-L2Norm equal: {1}", varname[i], normequal);
                    }
                    return(result);
                }
        }
        /// <summary>
        /// Can be used independent on the grid and the grid partitioning
        /// in constrast to <see cref="CompareErrors(CNSFieldSet, CNSFieldSet, double)"/>
        /// </summary>
        /// <param name="loadBalSolver"></param>
        /// <param name="refSolver"></param>
        /// <param name="differenceThreshold"></param>
        private static void CompareNorms(IProgram <CNSControl> refSolver, IList <IProgram <CNSControl> > loadBalSolvers, double differenceThreshold)
        {
            List <Action> assertions = new List <Action>();

            string[] varName = { "Density", "x-Momentum", "Energy" };

            for (int i = 0; i < varName.Length; i++)
            {
                List <DGField> listOfDGFields_RepOFF = (List <DGField>)refSolver.IOFields;
                DGField        variableRepOFF        = listOfDGFields_RepOFF[i];
                double         L2NormRepOFF          = variableRepOFF.L2Norm();

                for (int j = 0; j < loadBalSolvers.Count; j++)
                {
                    List <DGField> listOfDGFields_RepON = (List <DGField>)loadBalSolvers[j].IOFields;
                    DGField        variableRepON        = listOfDGFields_RepON[i];
                    double         L2NormRepON          = variableRepON.L2Norm();

                    double difference = Math.Abs(L2NormRepON - L2NormRepOFF);

                    string message = String.Format("{0}: Difference in {1} norm is {2} (Threshold is {3})", loadBalSolvers[j].Control.GridPartType.ToString(), varName[i], difference, differenceThreshold);
                    Console.WriteLine(message);
                    assertions.Add(() => Assert.IsTrue(difference < differenceThreshold, message));
                }
            }

            assertions.ForEach(a => a());
        }
Пример #4
0
 /// <summary>
 /// Computes the L2 error of field <paramref name="fieldName"/> with
 /// respect to the given <paramref name="referenceField"/> in the
 /// domain defined by <paramref name="maskFactory"/>.
 /// </summary>
 /// <param name="fieldName">
 /// The name of the field to be evaluated
 /// </param>
 /// <param name="referenceField">
 /// A DG field containing the exact solution.
 /// </param>
 /// <param name="maskFactory">
 /// A function that returns the domain of integration in terms of cells
 /// to be evaluated. If null, the full computational domain will be
 /// considered.
 /// </param>
 /// <returns>
 /// The error of <paramref name="fieldName"/> in the L2 norm.
 /// </returns>
 public static Query L2Error(string fieldName, DGField referenceField, Func <GridData, CellMask> maskFactory = null)
 {
     return(delegate(IApplication <AppControl> app, double time) {
         DGField differenceField = referenceField - GetField(app.IOFields, fieldName);
         return differenceField.L2Norm(GetMaskOrNull(maskFactory, app.GridData));
     });
 }
Пример #5
0
        /// <summary>
        /// L2Norm of given Field <paramref name="f"/>.
        /// </summary>
        /// <param name="f"></param>
        /// <param name="ResidualKey">
        /// Optional parameter for key of residual.
        /// If null, the name of <paramref name="f"/> will be used as key.
        /// </param>
        public void ComputeL2Norm(DGField f, string ResidualKey = null)
        {
            string key = GetDictionaryKey(Residualtype.L2Norm, f.Identification, ResidualKey);

            double L2Norm = f.L2Norm();

            m_Residuals[key] = L2Norm;
        }
        /// <summary>
        /// Can be used independent on the grid and the grid partitioning
        /// in constrast to <see cref="CompareErrors(CNSFieldSet, CNSFieldSet, double)"/>
        /// </summary>
        /// <param name="loadBalSolver"></param>
        /// <param name="refSolver"></param>
        /// <param name="differenceThreshold"></param>
        private static void CompareNorms(IProgram <CNSControl> loadBalSolver, IProgram <CNSControl> refSolver, double differenceThreshold, IProgram <CNSControl> hilbertSolver = null)
        {
            List <Action> assertions = new List <Action>();

            string[] varName = { "Density", "x-Momentum", "Energy" };

            for (int i = 0; i < 3; i++)
            {
                List <DGField> listOfDGFields_RepON = (List <DGField>)loadBalSolver.IOFields;
                DGField        variableRepON        = listOfDGFields_RepON[i];
                double         L2NormRepON          = variableRepON.L2Norm();

                List <DGField> listOfDGFields_RepOFF = (List <DGField>)refSolver.IOFields;
                DGField        variableRepOFF        = listOfDGFields_RepOFF[i];
                double         L2NormRepOFF          = variableRepOFF.L2Norm();

                double difference = Math.Abs(L2NormRepON - L2NormRepOFF);

                //Console.WriteLine("{0}-L2Norm Rep ON: {1}", varName[i], L2NormRepON);
                //Console.WriteLine("{0}-L2Norm Rep OFF: {1}", varName[i], L2NormRepOFF);

                string message = String.Format("METIS: Difference in {0} norm is {1} (Threshold is {2})", varName[i], difference, differenceThreshold);
                Console.WriteLine(message);
                assertions.Add(() => Assert.IsTrue(difference < differenceThreshold, message));

                // Duplicated code...
                double differenceHilbert;
                if (hilbertSolver != null)
                {
                    List <DGField> listOfDGFields_Hilbert = (List <DGField>)hilbertSolver.IOFields;
                    DGField        variableHilbert        = listOfDGFields_Hilbert[i];
                    double         L2NormHilbert          = variableHilbert.L2Norm();

                    differenceHilbert = Math.Abs(L2NormHilbert - L2NormRepOFF);

                    string messageHilbert = String.Format("Hilbert: Difference in {0} norm is {1} (Threshold is {2})", varName[i], differenceHilbert, differenceThreshold);
                    Console.WriteLine(messageHilbert);
                    assertions.Add(() => Assert.IsTrue(differenceHilbert < differenceThreshold, messageHilbert));
                }
            }

            assertions.ForEach(a => a());
        }
Пример #7
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();
        }
Пример #8
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);
             *
             * }
             */
        }