Ejemplo n.º 1
0
 /// <summary>
 /// translates a time-stepping scheme code
 /// </summary>
 /// <param name="Scheme"></param>
 /// <param name="rksch">if <paramref name="Scheme"/> denotes a Runge-Kutta scheme, well, the Runge-Kutta scheme</param>
 /// <param name="bdfOrder">if <paramref name="Scheme"/> denotes a BDF-scheme, its order</param>
 static public void DecodeScheme(TimeSteppingScheme Scheme, out RungeKuttaScheme rksch, out int bdfOrder)
 {
     rksch    = null;
     bdfOrder = -1000;
     if (Scheme == TimeSteppingScheme.CrankNicolson)
     {
         bdfOrder = -1;
     }
     else if (Scheme == TimeSteppingScheme.ExplicitEuler)
     {
         bdfOrder = 0;
     }
     else if (Scheme == TimeSteppingScheme.ImplicitEuler)
     {
         bdfOrder = 1;
     }
     else if (Scheme.ToString().StartsWith("BDF"))
     {
         bdfOrder = Convert.ToInt32(Scheme.ToString().Substring(3));
     }
     else if (Scheme == TimeSteppingScheme.RK1)
     {
         rksch = RungeKuttaScheme.ExplicitEuler;
     }
     else if (Scheme == TimeSteppingScheme.RK1u1)
     {
         rksch = RungeKuttaScheme.ExplicitEuler2;
     }
     else if (Scheme == TimeSteppingScheme.RK2)
     {
         rksch = RungeKuttaScheme.Heun2;
     }
     else if (Scheme == TimeSteppingScheme.RK3)
     {
         rksch = RungeKuttaScheme.TVD3;
     }
     else if (Scheme == TimeSteppingScheme.RK4)
     {
         rksch = RungeKuttaScheme.RungeKutta1901;
     }
     else if (Scheme == TimeSteppingScheme.RK_ImplicitEuler)
     {
         rksch = RungeKuttaScheme.ImplicitEuler;
     }
     else if (Scheme == TimeSteppingScheme.RK_CrankNic)
     {
         rksch = RungeKuttaScheme.CrankNicolson;
     }
     else if (Scheme == TimeSteppingScheme.RK_IMEX3)
     {
         rksch = RungeKuttaScheme.IMEX3;
     }
     else
     {
         throw new NotImplementedException();
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Control"></param>
        /// <param name="currentState"></param>
        public FourierLevSetTimestepper(FourierLevSetControl Control, RungeKuttaScheme _RKscheme, double[] currentState, DelComputeChangerate _DelCompChange, DelEvolveFourier _DelEvolveFourier)
        {
            this.Timestepper      = Control.Timestepper;
            this.RKscheme         = _RKscheme;
            this.underrelaxation  = Control.UnderRelax;
            this.DelCompChange    = _DelCompChange;
            this.DelEvolveFourier = _DelEvolveFourier;

            current_FLSproperty = currentState;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Constructor;
        /// </summary>
        /// <param name="Fields"></param>
        /// <param name="IterationResiduals"></param>
        /// <param name="LsTrk"></param>
        /// <param name="_ComputeOperatorMatrix">See <see cref="ComputeOperatorMatrix"/>.</param>
        /// <param name="_UpdateLevelset">See <see cref="UpdateLevelset"/>.</param>
        /// <param name="BDForder">
        /// The order of the BDF scheme from 1 to 6; in addition, 0 encodes Explicit Euler and -1 encodes Crank-Nicolson.
        /// </param>
        /// <param name="_LevelSetHandling"></param>
        /// <param name="_MassMatrixShapeandDependence"></param>
        /// <param name="_SpatialOperatorType"></param>
        /// <param name="_MassScale"></param>
        /// <param name="_AgglomerationThreshold"></param>
        /// <param name="_RKscheme"></param>
        /// <param name="useX">
        /// U dont want to know!
        /// </param>
        /// <param name="_MultigridSequence"></param>
        /// <param name="_CutCellQuadOrder">Order of quadrature in cut cells, required e.g. for <see cref="LevelSetTracker.GetXDGSpaceMetrics(SpeciesId[], int, int)"/></param>
        /// <param name="_SpId">Species to compute, actually a subset of <see cref="LevelSetTracker.SpeciesIdS"/></param>
        /// <param name="_MultigridOperatorConfig">
        /// Configuration of block-preconditioner, if null a default value is chosen.
        /// </param>
        public XdgRKTimestepping(DGField[] Fields,
                                 DGField[] IterationResiduals,
                                 LevelSetTracker LsTrk,
                                 DelComputeOperatorMatrix _ComputeOperatorMatrix,
                                 DelUpdateLevelset _UpdateLevelset,
                                 RungeKuttaScheme _RKscheme,
                                 LevelSetHandling _LevelSetHandling,
                                 MassMatrixShapeandDependence _MassMatrixShapeandDependence,
                                 SpatialOperatorType _SpatialOperatorType,
                                 IDictionary <SpeciesId, IEnumerable <double> > _MassScale,
                                 MultigridOperator.ChangeOfBasisConfig[][] _MultigridOperatorConfig,
                                 AggregationGridData[] _MultigridSequence,
                                 SpeciesId[] _SpId,
                                 int _CutCellQuadOrder,
                                 double _AgglomerationThreshold, bool useX,
                                 Control.NonLinearSolverConfig nonlinconfig,
                                 Control.LinearSolverConfig linearconfig) : base(nonlinconfig, linearconfig)
        {
            // check args, set internals
            // -------------------------

            if (Fields.Length != IterationResiduals.Length)
            {
                throw new ArgumentException("Expecting the same number of fields and residuals.");
            }
            for (int iFld = 0; iFld < Fields.Length; iFld++)
            {
                if (!Fields[iFld].Basis.Equals(IterationResiduals[iFld].Basis))
                {
                    throw new ArgumentException(string.Format("Mismatch between {0}-th basis of fields and residuals.", iFld));
                }
            }

            if (_MassScale != null)
            {
                if (!IEnumerableExtensions.SetEquals(_SpId, _MassScale.Keys))
                {
                    throw new ArgumentException();
                }
            }

            base.Residuals = new CoordinateVector(IterationResiduals);

            if (!(_RKscheme.IsExplicit || _RKscheme.IsDiagonallyImplicit))
            {
                throw new NotSupportedException("Only supporting explicit or diagonally implicit schemes.");
            }

            base.m_LsTrk = LsTrk;
            base.Config_LevelSetHandling             = _LevelSetHandling;
            base.Config_MassMatrixShapeandDependence = _MassMatrixShapeandDependence;
            base.Config_SpatialOperatorType          = _SpatialOperatorType;
            base.ComputeOperatorMatrix         = _ComputeOperatorMatrix;
            base.UpdateLevelset                = _UpdateLevelset;
            base.Config_MassScale              = _MassScale;
            base.Config_AgglomerationThreshold = _AgglomerationThreshold;
            this.m_RKscheme                    = _RKscheme.CloneAs();
            base.MultigridSequence             = _MultigridSequence;
            base.Config_SpeciesToCompute       = _SpId;
            base.Config_CutCellQuadratureOrder = _CutCellQuadOrder;
            if (_MultigridSequence == null || _MultigridSequence.Length < 1)
            {
                throw new ArgumentException("At least one grid level is required.");
            }

            m_CurrentState = new CoordinateVector(Fields);

            if (_MultigridOperatorConfig != null)
            {
                Config_MultigridOperator = _MultigridOperatorConfig;
            }
            else
            {
                SetConfig_MultigridOperator_Default(Fields);
            }

            base.CommonConfigurationChecks();

            // configure stack of level-set-tracker
            // ------------------------------------

            if (Config_LevelSetHandling == LevelSetHandling.None)
            {
                m_LsTrk.IncreaseHistoryLength(0);
            }
            else if (Config_LevelSetHandling == LevelSetHandling.LieSplitting ||
                     Config_LevelSetHandling == LevelSetHandling.StrangSplitting)
            {
                m_LsTrk.IncreaseHistoryLength(1);
            }
            else
            {
                m_LsTrk.IncreaseHistoryLength(m_RKscheme.Stages);
            }
            //m_LsTrk.IncreaseHistoryLength(1);

            // multigrid - init
            // ----------------

            InitMultigrid(Fields, useX);
        }
Ejemplo n.º 4
0
        protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L)
        {
            if (Operator != null)
            {
                return;
            }

            // create operator
            // ---------------

            Func <double[], double, double> S;

            switch (this.Control.InterfaceMode)
            {
            case InterfaceMode.MovingInterface:
                S = this.Control.S;
                break;

            case InterfaceMode.Splitting:
                S = (X, t) => 0.0;
                break;

            default:
                throw new NotImplementedException();
            }

            int quadOrder;

            if (this.Control.Eq == Equation.ScalarTransport)
            {
                quadOrder = this.LinearQuadratureDegree;

                Func <double[], double, double>[] uBnd = new Func <double[], double, double> [this.Grid.EdgeTagNames.Keys.Max() + 1];
                for (int iEdgeTag = 1; iEdgeTag < uBnd.Length; iEdgeTag++)
                {
                    string nameEdgeTag;
                    if (this.Grid.EdgeTagNames.TryGetValue((byte)iEdgeTag, out nameEdgeTag))
                    {
                        if (!this.Control.BoundaryValues[nameEdgeTag].Evaluators.TryGetValue("u", out uBnd[iEdgeTag]))
                        {
                            uBnd[iEdgeTag] = (X, t) => 0.0;
                        }
                    }
                }

                Operator = new XSpatialOperator(1, 2, 1, (A, B, C) => quadOrder, "u", "Vx", "Vy", "Cod1");
                Operator.EquationComponents["Cod1"].Add(new TranportFlux_Bulk()
                {
                    Inflow = uBnd
                });
                Operator.EquationComponents["Cod1"].Add(new TransportFlux_Interface(this.LsTrk, S));
                Operator.Commit();
            }
            else if (this.Control.Eq == Equation.HeatEq)
            {
                quadOrder = this.LinearQuadratureDegree;

                Operator = new XSpatialOperator(1, 0, 1, (A, B, C) => quadOrder, "u", "Cod1");

                var bulkFlx = new HeatFlux_Bulk()
                {
                    m_muA = this.Control.muA, m_muB = this.Control.muB, m_rhsA = this.Control.rhsA, m_rhsB = this.Control.rhsB
                };
                var intfFlx = new HeatFlux_Interface(this.LsTrk, S)
                {
                    m_muA = this.Control.muA, m_muB = this.Control.muB
                };

                Operator.EquationComponents["Cod1"].Add(bulkFlx);
                Operator.EquationComponents["Cod1"].Add(intfFlx);
                Operator.Commit();
            }
            else if (this.Control.Eq == Equation.Burgers)
            {
                quadOrder = this.NonlinearQuadratureDegree;

                Operator = new XSpatialOperator(1, 1, 1, (A, B, C) => quadOrder, "u", "u0", "Cod1");
                Operator.EquationComponents["Cod1"].Add(new BurgersFlux_Bulk()
                {
                    Direction = this.Control.BurgersDirection, Inflow = this.Control.u_Ex
                });
                Operator.EquationComponents["Cod1"].Add(new BurgersFlux_Interface(this.LsTrk, S, this.Control.BurgersDirection));
                Operator.Commit();
            }
            else
            {
                throw new NotImplementedException();
            }

            // create timestepper
            // ------------------

            LevelSetHandling lsh;

            switch (this.Control.InterfaceMode)
            {
            case InterfaceMode.MovingInterface:
                lsh = LevelSetHandling.Coupled_Once;
                break;

            case InterfaceMode.Splitting:
                lsh = LevelSetHandling.LieSplitting;
                break;

            default:
                throw new NotImplementedException();
            }

            RungeKuttaScheme rksch = null;
            int bdfOrder           = -1000;

            if (this.Control.TimeSteppingScheme == TimeSteppingScheme.CrankNicolson)
            {
                bdfOrder = -1;
            }
            else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.ExplicitEuler)
            {
                bdfOrder = 0;
            }
            else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.ImplicitEuler)
            {
                bdfOrder = 1;
            }
            else if (this.Control.TimeSteppingScheme.ToString().StartsWith("BDF"))
            {
                bdfOrder = Convert.ToInt32(this.Control.TimeSteppingScheme.ToString().Substring(3));
            }
            else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK1)
            {
                rksch = RungeKuttaScheme.ExplicitEuler;
            }
            else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK1u1)
            {
                rksch = RungeKuttaScheme.ExplicitEuler2;
            }
            else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK2)
            {
                rksch = RungeKuttaScheme.Heun2;
            }
            else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK3)
            {
                rksch = RungeKuttaScheme.TVD3;
            }
            else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK4)
            {
                rksch = RungeKuttaScheme.RungeKutta1901;
            }
            else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK_ImplicitEuler)
            {
                rksch = RungeKuttaScheme.ImplicitEuler;
            }
            else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK_CrankNic)
            {
                rksch = RungeKuttaScheme.CrankNicolson;
            }
            else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK_IMEX3)
            {
                rksch = RungeKuttaScheme.IMEX3;
            }
            else
            {
                throw new NotImplementedException();
            }


            if (bdfOrder > -1000)
            {
                m_BDF_Timestepper = new XdgBDFTimestepping(new DGField[] { this.u }, new DGField[] { this.Residual }, LsTrk, true,
                                                           DelComputeOperatorMatrix, DelUpdateLevelset,
                                                           bdfOrder,
                                                           lsh,
                                                           MassMatrixShapeandDependence.IsTimeDependent,
                                                           SpatialOperatorType.LinearTimeDependent,
                                                           MassScale,
                                                           null, base.MultigridSequence,
                                                           this.LsTrk.SpeciesIdS.ToArray(), quadOrder,
                                                           this.Control.AgglomerationThreshold, false);
            }
            else
            {
                m_RK_Timestepper = new XdgRKTimestepping(new DGField[] { this.u }, new DGField[] { this.Residual }, LsTrk,
                                                         DelComputeOperatorMatrix, DelUpdateLevelset,
                                                         rksch,
                                                         lsh,
                                                         MassMatrixShapeandDependence.IsTimeDependent,
                                                         SpatialOperatorType.LinearTimeDependent,
                                                         MassScale,
                                                         null, base.MultigridSequence,
                                                         this.LsTrk.SpeciesIdS.ToArray(), quadOrder,
                                                         this.Control.AgglomerationThreshold, false);
            }
        }