예제 #1
0
            /// <summary>
            /// Computation of mass matrix, makes use of <see cref="MassMatrixFactory"/>
            /// </summary>
            public void ComputeMatrix <M, V>(M MassMatrix, V AffineOffset, double oodt = 1.0)
                where M : IMutableMatrixEx
                where V : IList <double>
            {
                if (!MassMatrix.RowPartitioning.EqualsPartition(this.CodomainMapping))
                {
                    throw new ArgumentException("Mismatch between matrix columns and domain variable mapping.");
                }
                if (!MassMatrix.ColPartition.EqualsPartition(this.DomainMapping))
                {
                    throw new ArgumentException("Mismatch between matrix columns and domain variable mapping.");
                }
                if (DomainMapping.NoOfVariables != CodomainMapping.NoOfVariables)
                {
                    throw new NotSupportedException($"Mismatch between number of variables in domain ({DomainMapping.NoOfVariables}) and codomain ({CodomainMapping.NoOfVariables}).");
                }

                int             QuadratureOrder = m_Owner.owner.GetOrderFromQuadOrderFunction(DomainMapping.BasisS, XSpatialOperatorMk2.GetBasisS(Parameters), CodomainMapping.BasisS);
                LevelSetTracker _LsTrk;

                if (m_Owner.m_lstrk != null)
                {
                    _LsTrk = m_Owner.m_lstrk;
                }
                else
                {
                    _LsTrk = XSpatialOperatorMk2.GetTracker(DomainMapping.BasisS, XSpatialOperatorMk2.GetBasisS(Parameters), CodomainMapping.BasisS);
                }
                SpeciesId[] _SpeciesToCompute = m_Owner.owner.Species.Select(spcName => _LsTrk.GetSpeciesId(spcName)).ToArray();


                Dictionary <SpeciesId, IEnumerable <double> > MassScale = new Dictionary <SpeciesId, IEnumerable <double> >();

                foreach (var spc in _SpeciesToCompute)
                {
                    double[] diag = m_Owner.m_DiagonalScale[_LsTrk.GetSpeciesName(spc)].CloneAs();
                    diag.ScaleV(oodt);
                    MassScale.Add(spc, diag);
                }

                //double MaxTime = _LsTrk.RegionsHistory.AvailabelIndices.Max((int iHist) => _LsTrk.RegionsHistory[iHist].Time.Abs());
                double[] AvailableTimes = _LsTrk.TimeLevelsInStack;
                int      ii             = AvailableTimes.IndexOfMin((double t) => Math.Abs(t - this.time));
                int      BestTimeIdx    = _LsTrk.RegionsHistory.AvailabelIndices[ii];

                if (Math.Abs(Math.Abs(time - _LsTrk.RegionsHistory[BestTimeIdx].Time)) >= time * 1e-10 + 1e-10)
                {
                    Console.WriteLine("unknown time level");
                }


                //BestTimeIdx = 1;
                MassMatrixFactory MassFact = _LsTrk.GetXDGSpaceMetrics(_SpeciesToCompute, QuadratureOrder, HistoryIndex: BestTimeIdx).MassMatrixFactory;

                MassFact.AccMassMatrix(MassMatrix, DomainMapping, MassScale);
            }