Beispiel #1
0
        private void AssembleMatrix(double dt, out BlockMsrMatrix SystemMatrix, out double[] SystemAffine)
        {
            // Init Matrix and Affine Part
            SystemMatrix = new BlockMsrMatrix(Mapping);
            SystemAffine = new double[Mapping.LocalLength];

            // choose TimeStepping-Scheme, based on what has been pushed to the stack,yet
            int Smax = TSCchain[0].S;

            Debug.Assert(Smax == TSCchain.Length);
            Tsc = TSCchain[Smax - PopulatedStackDepth];

            UpdateOperatorMatrix();



            //Implicit Part of RHS
            SystemMatrix.Acc(Tsc.theta1, Stack_OpMatrix[1]);
            SystemAffine.AccV(Tsc.theta1, Stack_OpAffine[1]);



            //Implicit Part of LHS
            SystemMatrix.AccEyeSp(1 / dt);

            // Explicit part of RHS
            Stack_OpMatrix[0].SpMV(-Tsc.theta0, CurrentState, 1.0, SystemAffine);
            SystemAffine.AccV(-Tsc.theta0, Stack_OpAffine[0]);

            //Explicit parts of LHS
            for (int i = 0; i < Tsc.beta.Length; i++)
            {
                SystemAffine.AccV(Tsc.beta[i] * 1 / dt, Stack_u[i]);
            }

            Debug.Assert(SystemMatrix.InfNorm() > 0);
            Debug.Assert(SystemAffine.L2Norm() > 0);

            if (subGrid != null)
            {
                int[] SubVecIdx = Mapping.GetSubvectorIndices(subGrid, true, new int[] { 0 });
                int   L         = SubVecIdx.Length;

                for (int i = 0; i < L; i++)
                {
                    SystemMatrix.ClearRow(SubVecIdx[i]);
                    SystemMatrix[SubVecIdx[i], SubVecIdx[i]] = 1;
                    SystemAffine[SubVecIdx[i]] = 0;
                }
            }
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="spatialOp">
        /// The Spatial Discretization,
        /// also supports nonconstant operators,
        /// which are linear in the unknown variable
        /// </param>
        /// <param name="UnknownFields"></param>
        /// <param name="ParameterFields"></param>
        /// <param name="BDForder">
        /// The Temporal Discretization Order
        /// >=1 : BDF-Scheme
        /// 0: Explicit Euler
        /// -1: Crank-Nicholson
        /// </param>
        /// <param name="SolverFactory">
        /// The Linear solver for the resulting systems
        /// </param>
        /// <param name="DelayInit">TODO: Delayed Initialization for restarts etc.</param>
        /// <param name="subGrid">TODO: Perform Time-Marching only on Substep</param>
        public BDFTimestepper(SpatialOperator spatialOp, IEnumerable <DGField> UnknownFields, IEnumerable <DGField> ParameterFields, int BDForder, Func <ISparseSolver> SolverFactory, bool DelayInit, SubGrid subGrid = null)
        {
            using (new ilPSP.Tracing.FuncTrace()) {
                //if (spatialOp.ContainsNonlinear) { throw new NotImplementedException("No Inversion of Nonlinear Operators implemented, yet."); };

                if (DelayInit)
                {
                    throw new NotImplementedException();
                }
                if (subGrid != null)
                {
                    throw new NotImplementedException();
                }

                this.Mapping          = new CoordinateMapping(UnknownFields.ToArray());
                this.ParameterMapping = new CoordinateMapping(ParameterFields.ToArray());

                // verify input
                // ============
                TimeStepperCommon.VerifyInput(spatialOp, Mapping, ParameterMapping);

                // Initialize
                CurrentState       = new CoordinateVector(UnknownFields.ToArray());
                Operator           = spatialOp;
                this.SolverFactory = SolverFactory;

                this.subGrid = subGrid;

                // Initialize Matrix
                SpatialMatrix = new BlockMsrMatrix(Mapping);

                TSCchain = BDFCommon.GetChain(BDForder);
                int S = TSCchain[0].S;
                Debug.Assert(S == TSCchain.Length);

                // Set coarsest BDF-Scheme to CrankNicholson, since this is more accurate than Implicit Euler
                Console.WriteLine("Warning! - 1st Initialization Step set to Crank-Nicholson!");
                TSCchain[S - 1] = BDFSchemeCoeffs.CrankNicolson();

                InitStacks(Mapping, S);

                // other stuff
                // -----------

                if (!DelayInit)
                {
                    InitTimestepping(true);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// final initialization for the BDF timestepper scheme, all necessary timesteps have to be initialized
        /// </summary>
        /// <param name="OpInit"></param>
        private void InitTimestepping(bool OpInit)
        {
            // operator matrix update
            // ----------------------

            if (OpInit && TSCchain[0].theta0 != 0.0)
            {
                if (Stack_OpAffine[0] == null)
                {
                    Stack_OpAffine[0] = new double[Stack_u[0].Mapping.LocalLength];
                }

                Debug.Assert(Stack_OpMatrix[0].InfNorm() == 0);
                Debug.Assert(Stack_OpAffine[0].L2Norm() == 0);

                Tsc = TSCchain.Last();
            }
        }