예제 #1
0
            /// <summary>
            /// Returns the index of species '<paramref name="_SpeciesId"/>' in the cell '<paramref name="jCell"/>'.
            /// </summary>
            /// <param name="jCell">
            /// a local cell index
            /// </param>
            /// <param name="_SpeciesId">
            /// species identification
            /// </param>
            public int GetSpeciesIndex(SpeciesId _SpeciesId, int jCell)
            {
                ReducedRegionCode rrc;
                int NoOfSpc = this.GetNoOfSpecies(jCell, out rrc);

                return(m_owner.GetSpeciesIndex(rrc, _SpeciesId));
            }
예제 #2
0
        /// <summary>
        /// Interior quadrature for the surface elements, i.e. for each cut background-cell \f$ K_j \f$ a quadrature to approximate
        /// \f[
        ///    \oint_{K_j \cap \mathfrak{I} } \ldots \mathrm{dS} .
        /// \f]
        /// </summary>
        public CellQuadratureScheme Get_SurfaceElement_VolumeQuadScheme(SpeciesId sp)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species (id = " + sp.cntnt + ") is not supported.");
            }



            var spdom          = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(sp);
            var IntegrationDom = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask().Intersect(spdom);

            var LevSetQrIns = new CellQuadratureScheme(false, IntegrationDom);

            foreach (var Kref in XDGSpaceMetrics.GridDat.Grid.RefElements)
            {
                for (int iLevSet = 0; iLevSet < XDGSpaceMetrics.NoOfLevelSets; iLevSet++)   // loop over level sets...
                {
                    var surfaceFactory = this.XDGSpaceMetrics.XQuadFactoryHelper.GetSurfaceFactory(iLevSet, Kref);
                    LevSetQrIns = LevSetQrIns.AddFactory(surfaceFactory, XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet));
                }
            }

            return(LevSetQrIns);
        }
예제 #3
0
            /// <summary>
            /// Creates an execution mask (volume mask) which only contains cells
            /// that are at least partly occupied by species
            /// <paramref name="speciesId"/>;
            /// </summary>
            /// <remarks>
            /// Note: The method is so complex because we do <b>not</b> want to
            /// consider the whole narrow-band because it may contain additional
            /// cells on the "other" side of the level set!
            /// </remarks>
            /// <param name="speciesId">
            /// The name of the species
            /// </param>
            /// <returns>
            /// A volume mask containing only cells with at least a portion of
            /// species <paramref name="speciesId"/>
            /// </returns>
            public CellMask GetSpeciesMask(SpeciesId speciesId)
            {
                if (m_SpeciesMask == null)
                {
                    m_SpeciesMask = new Dictionary <SpeciesId, CellMask>();
                }
                if (!m_SpeciesMask.ContainsKey(speciesId))
                {
                    int                J         = m_owner.m_gDat.Grid.NoOfUpdateCells;
                    BitArray           mask      = new BitArray(J);
                    LevelSetSignCode[] signCodes = m_owner.GetLevelSetSignCodes(speciesId);

                    if (signCodes.Length == 0)
                    {
                        throw new ArgumentException("Unknown species " + speciesId, "speciesName");
                    }

                    for (int jCell = 0; jCell < J; jCell++)
                    {
                        bool matchesOne = IsSpeciesPresentInCell(speciesId, jCell);

                        // mask[i] = matches would also do it but a set operation on
                        // a BitMask is heavier than this ugly additional if statement
                        if (matchesOne)
                        {
                            mask[jCell] = true;
                        }
                    }

                    m_SpeciesMask.Add(speciesId, new CellMask(m_owner.m_gDat, mask));
                }

                return(m_SpeciesMask[speciesId]);
            }
예제 #4
0
 /// <summary>
 /// ctor
 /// </summary>
 public SpeciesShadowField(XDGField owner, SpeciesId specId) :
     base(new Basis(owner.GridDat, owner.m_CCBasis.Degree),
          owner.Identification + "-" + owner.m_CCBasis.Tracker.GetSpeciesName(specId))
 {
     m_Coordinates = new SpeciesCoordinates(owner, specId);
     m_Owner       = owner;
 }
예제 #5
0
        /// <summary>
        /// All edges that have to be considered for the integration of species <paramref name="sp"/>.
        /// </summary>
        /// <param name="sp"></param>
        /// <param name="IntegrationDomainRestriction">Optional restriction to the integration domain.</param>
        public EdgeMask GetEdgeMask(SpeciesId sp, EdgeMask IntegrationDomainRestriction = null)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species ( id = " + sp.cntnt + ") is not supported.");
            }

            EdgeMask allRelevantEdges;

            if (IntegrationDomainRestriction == null)
            {
                allRelevantEdges = this.m_SpeciesSubgrid_InnerAndDomainEdges[sp];
            }
            else
            {
                // user provides integration domain, intersect with that
                allRelevantEdges = this.m_SpeciesSubgrid_InnerAndDomainEdges[sp].Intersect(IntegrationDomainRestriction);
            }

            //// optionally, exclude edges between agglomerated cells
            //EdgeMask AggEdges = (this.CellAgglomeration != null) ? (this.CellAgglomeration.GetAgglomerator(sp).AggInfo.AgglomerationEdges) : (default(EdgeMask));
            //if (AggEdges != null && AggEdges.NoOfItemsLocally > 0)
            //    allRelevantEdges = allRelevantEdges.Except(AggEdges);
            return(allRelevantEdges);
        }
예제 #6
0
            public MiniMapping(UnsetteledCoordinateMapping Map, SpeciesId spId, LevelSetTracker.LevelSetRegions r)
            {
                m_Map = Map;
                m_spId = spId;
                m_LsRegion = r;

                Basis[] BS = Map.BasisS.ToArray();
                NS = new int[BS.Length];
                VarIsXdg = new bool[BS.Length];
                NoOfVars = BS.Length;

                for (int iVar = 0; iVar < BS.Length; iVar++) {
                    XDGBasis xBasis = BS[iVar] as XDGBasis;
                    if (xBasis != null) {
                        NS[iVar] = xBasis.NonX_Basis.Length;
                        //m_LsTrk = xBasis.Tracker;
                        VarIsXdg[iVar] = true;
                    } else {
                        NS[iVar] = BS[iVar].Length;
                        VarIsXdg[iVar] = false;
                    }

                    MaxDeg = Math.Max(MaxDeg, BS[iVar].Degree);
                }
            }
예제 #7
0
 /// <summary>
 /// ctor;
 /// </summary>
 internal SpeciesCoordinates(XDGField _owner, SpeciesId _SpeciesId)
 {
     owner      = _owner;
     NSep       = this.owner.m_CCBasis.DOFperSpeciesPerCell;
     LsTrk      = this.owner.m_CCBasis.Tracker;
     m_SpecisId = _SpeciesId;
 }
예제 #8
0
        /*
         * /// <summary>
         * /// initialized by the constructor to avoid MPI-deadlocks;
         * /// </summary>
         * Dictionary<RefElement, EdgeMask> m_Subgrid4Kref_AllEdges = new Dictionary<RefElement, EdgeMask>();
         */

        //LevelSetTracker lsTrk {
        //    get {
        //        return XDGSpaceMetrics.Tracker;
        //    }
        //}


        public EdgeQuadratureScheme Get_SurfaceElement_EdgeQuadScheme(SpeciesId sp)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species (id = " + sp.cntnt + ") is not supported.");
            }

            //var allRelevantEdges = this.m_SpeciesSubgrid_InnerAndDomainEdges[sp].Intersect(this.m_CutCellSubgrid_InnerEdges);

            var innerCutCellEdges    = this.XDGSpaceMetrics.LevelSetRegions.GetCutCellSubGrid().InnerEdgesMask;
            var boundaryCutCellEdges = ExecutionMask.Intersect(this.XDGSpaceMetrics.LevelSetRegions.GetCutCellSubGrid().BoundaryEdgesMask, this.XDGSpaceMetrics.GridDat.BoundaryEdges);
            var allRelevantEdges     = this.m_SpeciesSubgrid_InnerAndDomainEdges[sp].Intersect(ExecutionMask.Union(innerCutCellEdges, boundaryCutCellEdges));

            //EdgeMask AggEdges = this.CellAgglomeration != null ? this.CellAgglomeration.GetAgglomerator(sp).AggInfo.AgglomerationEdges : null;
            //if (AggEdges != null && AggEdges.NoOfItemsLocally > 0)
            //    allRelevantEdges = allRelevantEdges.Except(AggEdges);


            var edgeQrIns = new EdgeQuadratureScheme(false, allRelevantEdges);

            foreach (var Kref in XDGSpaceMetrics.GridDat.Grid.RefElements)
            {
                for (int iLevSet = 0; iLevSet < XDGSpaceMetrics.NoOfLevelSets; iLevSet++)   // loop over level sets...
                {
                    EdgeMask cutEdges = this.GetCutEdges(Kref, iLevSet);

                    var factory = this.XDGSpaceMetrics.XQuadFactoryHelper.GetSurfaceElement_BoundaryRuleFactory(iLevSet, Kref);

                    edgeQrIns.AddFactory(factory, cutEdges);
                }
            }

            return(edgeQrIns);
        }
예제 #9
0
        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="lsTrk">level set tracker</param>
        /// <param name="spcId">species which should be framed</param>
        /// <param name="__FullMap"></param>
        /// <param name="SupportExternal">
        /// true: support also indices related to external/ghost cells
        /// </param>
        public FrameBase(LevelSetTracker.LevelSetRegions regions, SpeciesId spcId, UnsetteledCoordinateMapping __FullMap, bool SupportExternal)
        {
            m_Regions         = regions;
            m_spcId           = spcId;
            FrameMap          = CreateMap(__FullMap);
            FullMap           = __FullMap;
            m_supportExternal = SupportExternal;

            Setup_Frame2Full(); // Frame2Full is almost used every time, so we set it up immediately
            //                     (in contrast, Full2Frame is set up on demand)
        }
예제 #10
0
            /// <summary>
            /// Equivalent to <see cref="GetSpeciesSubGrid(string)"/>
            /// </summary>
            public SubGrid GetSpeciesSubGrid(SpeciesId specId)
            {
                MPICollectiveWatchDog.Watch();

                if (m_SpeciesSubGrids == null)
                {
                    m_SpeciesSubGrids = new Dictionary <SpeciesId, SubGrid>();
                }

                if (!m_SpeciesSubGrids.ContainsKey(specId))
                {
                    CellMask cm = GetSpeciesMask(specId);
                    m_SpeciesSubGrids.Add(specId, new SubGrid(cm));
                }
                return(this.m_SpeciesSubGrids[specId]);
            }
예제 #11
0
        /*
         * /// <summary>
         * /// computes the mass matrices for a given mapping.
         * /// </summary>
         * /// <param name="mapping">
         * /// </param>
         * /// <param name="alpha">
         * /// 'Fine-grained' scaling for blocks, for each species and each variable in the <paramref name="mapping"/>.
         * /// The default value of null maps to 1.0 for each species and variable.
         * /// </param>
         * /// <param name="VariableAgglomerationSwitch">
         * /// Switch to turn agglomeration on/off for each variable; default=null=on.
         * /// </param>
         * /// <param name="inverse">
         * /// Return the inverse mass matrix.
         * /// </param>
         * public BlockDiagonalMatrix GetMassMatrix_depr(UnsetteledCoordinateMapping mapping, IDictionary<SpeciesId, IEnumerable<double>> alpha = null, bool inverse = false, bool[] VariableAgglomerationSwitch = null) {
         *  if (alpha == null) {
         *      int NoVar = mapping.NoOfVariables;
         *      alpha = new Dictionary<SpeciesId, IEnumerable<double>>();
         *      double[] AllOne = new double[NoVar];
         *      AllOne.SetAll(1.0);
         *      foreach (var spc in this.m_LsTrk.SpeciesIdS) {
         *          alpha.Add(spc, AllOne);
         *      }
         *  }
         *  var Return = new BlockDiagonalMatrix(mapping.LocalLength, mapping.MaxTotalNoOfCoordinatesPerCell);
         *  AccMassMatrix(Return, mapping, alpha, inverse, VariableAgglomerationSwitch);
         *  return Return;
         * }
         */

        /// <summary>
        /// Provides access to a 'raw' form of the mass matrix, where only blocks for the cut cells
        /// are stored
        /// </summary>
        /// <returns>
        /// don't mess with those values
        /// </returns>
        public MassMatrixBlockContainer GetMassMatrixBlocks(Basis b, SpeciesId spc)
        {
            if (!b.IsSubBasis(this.MaxBasis))
            {
                throw new NotSupportedException("requested basis exceeds maximally supported basis.");
            }

            UpdateBlocks(b.Degree, new SpeciesId[] { spc });

            var MMB = this.MassBlocks[spc];

//#if DEBUG
//            {
//                var CCBit = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask().GetBitMask();
//                //var AggCells = this.Agglomerator.GetAgglomerator(spc).AggInfo.SourceCells;
//                //var AggCellsBit = AggCells.GetBitMask();
//                //var AggAffectedBit = this.Agglomerator.GetAgglomerator(spc).AggInfo.AllAffectedCells.GetBitMaskWithExternal();

//                int J = XDGSpaceMetrics.GridDat.Cells.NoOfLocalUpdatedCells;

//                int JSUB = MMB.jSub2jCell.Length;
//                for (int jSub = 0; jSub < JSUB; jSub++) {
//                    var Block = MMB.MassMatrixBlocks.ExtractSubArrayShallow(jSub, -1, -1);
//                    int jCell = MMB.jSub2jCell[jSub];
//                    double BlockNorm = Block.InfNorm();

//                    //if (jCell < J) {
//                    //    Debug.Assert(CCBit[jCell] || AggAffectedBit[jCell]);
//                    //    Debug.Assert(AggCellsBit[jCell] == (BlockNorm == 0));
//                    //}
//                }

//                //foreach (var jCellAgg in AggCells.ItemEnum) {
//                //    int jSub = MMB.jCell2jSub[jCellAgg];
//                //    var Block = MMB.MassMatrixBlocks.ExtractSubArrayShallow(jSub, -1, -1);
//                //    double BlockNorm = Block.InfNorm();

//                //    Debug.Assert(BlockNorm == 0.0);
//                //}
//            }

//#endif
            return(MMB);
        }
예제 #12
0
        /// <summary>
        /// Fills up the volume scheme for species <paramref name="sp"/>.
        /// </summary>
        public CellQuadratureScheme GetVolumeQuadScheme(SpeciesId sp, bool UseDefaultFactories = true, CellMask IntegrationDomain = null, int?fixedOrder = null)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species (id = " + sp.cntnt + ") is not supported.");
            }

            if (IntegrationDomain != null)
            {
                if (IntegrationDomain.MaskType != MaskType.Logical)
                {
                    throw new ArgumentException();
                }
            }

            CellMask CellMask = GetCellMask(sp, IntegrationDomain);

            /// Debugging Code
            //if (IntegrationDomain != null) {
            //    CellMask.ToTxtFile("VolDom-" + this.lsTrk.GridDat.MyRank + "of" + this.lsTrk.GridDat.Size + ".csv", false);
            //}

            // default rule for "normal" cells
            var volQrIns = (new CellQuadratureScheme(UseDefaultFactories, CellMask));

            // now: rules for the cut-cells:
            for (int iLevSet = 0; iLevSet < XDGSpaceMetrics.NoOfLevelSets; iLevSet++)   // loop over level sets
            {
                var cutDom   = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet).ToGeometicalMask();
                var cutCells = cutDom.Intersect(CellMask);

                var jmp = IdentifyWing(iLevSet, sp);

                for (int iKref = 0; iKref < XDGSpaceMetrics.GridDat.Grid.RefElements.Length; iKref++)
                {
                    RefElement Kref    = XDGSpaceMetrics.GridDat.Grid.RefElements[iKref];
                    var        _cutDom = cutCells.Intersect(XDGSpaceMetrics.GridDat.Cells.GetCells4Refelement(iKref));
                    var        factory = this.XDGSpaceMetrics.XQuadFactoryHelper.GetVolRuleFactory(iLevSet, jmp, Kref);
                    volQrIns.AddFactoryDomainPair(factory, _cutDom, fixedOrder);
                }
            }

            return(volQrIns);
        }
예제 #13
0
        /// <summary>
        /// writes the dammed result of the integration to the sparse matrix
        /// </summary>
        protected override void SaveIntegrationResults(int i0, int Length, MultidimensionalArray ResultsOfIntegration)
        {
            int GAMMA = this.m_CodomainMap.BasisS.Count;  // GAMMA: number of codom/row/test variables

            LECQuadratureLevelSet <IMutableMatrixEx, double[]> .CompOffsets(i0, Length, out int[] offsetRow, out int[] RowNonxN, m_CodomainMap);

            SpeciesId[] spcS = new[] { this.SpeciesA, this.SpeciesB };

            int[] _i0aff = new int[2];
            int[] _iEaff = new int[2];

            // loop over cells...
            for (int i = 0; i < Length; i++)
            {
                int jCell = i + i0;
#if DEBUG
                Debug.Assert(RowNonxN.ListEquals(m_CodomainMap.GetNonXBasisLengths(jCell)));
#endif

                _i0aff[0] = i;
                _iEaff[0] = -1;

                for (int gamma = 0; gamma < GAMMA; gamma++) // loop over rows...
                {
                    for (int cr = 0; cr < 2; cr++)          // loop over neg/pos species row...
                    {
                        SpeciesId rowSpc = spcS[cr];
                        int       Row0   = m_CodomainMap.LocalUniqueCoordinateIndex(m_lsTrk, gamma, jCell, rowSpc, 0);

                        _i0aff[1] = offsetRow[gamma] + RowNonxN[gamma] * cr; // the 'RowXbSw' is 0 for non-xdg, so both species will be added
                        _iEaff[1] = _i0aff[1] + RowNonxN[gamma] - 1;


                        var BlockRes = ResultsOfIntegration.ExtractSubArrayShallow(_i0aff, _iEaff);

                        for (int r = BlockRes.GetLength(0) - 1; r >= 0; r--)
                        {
                            ResultVector[Row0 + r] += BlockRes[r];
                        }
                    }
                }
            }
        }
예제 #14
0
        /// <summary>
        /// Boundary quadrature for the surface elements, i.e. for each cut background-cell \f$ K_j \f$ a quadrature to approximate
        /// \f[
        ///    \int_{\partial K_j \cap \mathfrak{I} } \ldots \mathrm{dS} .
        /// \f]
        /// </summary>
        public EdgeQuadratureScheme GetEdgeQuadScheme(SpeciesId sp, bool UseDefaultFactories = true, EdgeMask IntegrationDomain = null, int?fixedOrder = null)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species (id = " + sp.cntnt + ") is not supported.");
            }


            // determine domain
            // ================
            var allRelevantEdges = GetEdgeMask(sp, IntegrationDomain);

            // create quadrature scheme
            // ========================
            {
                // default rules for all edges:
                EdgeQuadratureScheme edgeQrIns = new EdgeQuadratureScheme(UseDefaultFactories, allRelevantEdges);

                // overwrite with cut-cell-rules in cut-cells:
                foreach (var Kref in XDGSpaceMetrics.GridDat.Grid.RefElements)
                {
                    for (int iLevSet = 0; iLevSet < XDGSpaceMetrics.NoOfLevelSets; iLevSet++)   // loop over level sets...
                    {
                        EdgeMask cutEdges = this.GetCutEdges(Kref, iLevSet).Intersect(allRelevantEdges);
#if DEBUG
                        CellMask difference = cutEdges.GetAdjacentCells(XDGSpaceMetrics.GridDat).Except(XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet));
                        if (difference.Count() > 0)
                        {
                            throw new ArithmeticException("Edges of the Cells" + difference.GetSummary() + " are detected as cut, but these cells are not contained in the cut Cell-Mask of the Level-Set-Tracker");
                        }
#endif


                        var jmp     = IdentifyWing(iLevSet, sp);
                        var factory = this.XDGSpaceMetrics.XQuadFactoryHelper.GetEdgeRuleFactory(iLevSet, jmp, Kref);
                        edgeQrIns.AddFactoryDomainPair(factory, cutEdges, fixedOrder);
                    }
                }

                return(edgeQrIns);
            }
        }
예제 #15
0
        private CellMask GetCellMask(SpeciesId sp, CellMask IntegrationDomain)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species (sp = " + sp.cntnt + ") is not supported.");
            }


            CellMask OutCellMask;

            if (IntegrationDomain == null)
            {
                OutCellMask = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(sp);
            }
            else
            {
                OutCellMask = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(sp).Intersect(IntegrationDomain);
            }
            return(OutCellMask);
        }
예제 #16
0
        /// <summary>
        /// stores XDG coordinates species-wise and retains backward compatibility using a mysterious magic header
        /// </summary>
        public override double[] SerializeDGcoords(int j)
        {
            int Ndg     = this.Basis.NonX_Basis.GetLength(j);
            var trk     = this.Basis.Tracker;
            int NoOfSpc = trk.Regions.GetNoOfSpecies(j);



            double[] Ret = new double[4 + NoOfSpc * (Ndg + 1)];

            // write the magic header
            Ret[0] = double.NegativeInfinity;
            Ret[1] = double.MaxValue;
            Ret[2] = double.NaN;
            Ret[3] = Ndg;

            int Ptr = 4;

            for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)
            {
                int       n0  = iSpc * Ndg;
                SpeciesId spc = trk.Regions.GetSpeciesIdFromIndex(j, iSpc);
                if (trk.Regions.IsSpeciesPresentInCell(spc, j))
                {
                    Ret[Ptr] = spc.cntnt; Ptr++;
                    for (int n = 0; n < Ndg; n++)
                    {
                        Ret[Ptr] = this.Coordinates[j, n + n0];
                        Ptr++;
                    }
                }
            }

            if (Ptr < Ret.Length)
            {
                Array.Resize(ref Ret, Ptr);
            }

            return(Ret);
        }
예제 #17
0
            /// <summary>
            /// Tests if a species  \f$\mathfrak{s}\f$ is actually \f$ \emph{present} \f$ in some cell \f$K_{\text{\tt jCell}}\f$,
            /// i.e. if
            /// the measure of the species in the cell is positive, i.e.
            /// \f[
            ///   \int_{K_{\text{\tt jCell}} \cap \mathfrak{s} } 1 \dV > 0
            /// \f]
            /// </summary>
            /// <param name="speciesId">The id of species \mathfrak{s}.</param>
            /// <param name="jCell">a cell index</param>
            /// <returns></returns>
            /// <remarks>
            /// Note that
            /// a species may not be 'present' in some cell
            /// although
            /// the index of a species (e.g. obtained by <see cref="GetSpeciesIndex(SpeciesId,int)"/>)
            /// may be positive.
            /// In the near-field however, some species index may be allocated (on the 'other' side of the level-set),
            /// but the species may not be present.
            /// </remarks>
            public bool IsSpeciesPresentInCell(SpeciesId speciesId, int jCell)
            {
                bool matchesOne = false;

                LevelSetSignCode[] signCodes = m_owner.GetLevelSetSignCodes(speciesId);

                // Check if at least one of the sign codes matches the
                // situation in the current cell
                for (int k = 0; k < signCodes.Length; k++)
                {
                    bool matches = true;
                    for (int j = 0; j < m_owner.NoOfLevelSets; j++)
                    {
                        int sign = Math.Sign(DecodeLevelSetDist(m_LevSetRegions[jCell], j));

                        // Cell is cut, both signs exist and thus the mask
                        // matches for sure
                        if (sign == 0)
                        {
                            continue;
                        }

                        int signCodeEntry = (signCodes[k].val & 0x1 << j) >> j;

                        // Code translation: 2 * {0, 1} - 1 = {-1, 1}
                        if (sign != 2 * signCodeEntry - 1)
                        {
                            matches = false;
                            break;
                        }
                    }

                    matchesOne = matchesOne || matches;
                }
                return(matchesOne);
            }
예제 #18
0
        private CellMask GetCellMask(SpeciesId sp, CellMask IntegrationDomain)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species (sp = " + sp.cntnt + ") is not supported.");
            }
            Debug.Assert(IntegrationDomain == null || IntegrationDomain.MaskType == MaskType.Logical);

            CellMask OutCellMask;

            if (IntegrationDomain == null)
            {
                OutCellMask = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(sp);
                Debug.Assert(OutCellMask.MaskType == MaskType.Logical);
            }
            else
            {
                OutCellMask = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(sp).Intersect(IntegrationDomain);
            }

            OutCellMask = OutCellMask.ToGeometicalMask();

            return(OutCellMask);
        }
예제 #19
0
        void ILinearLevelSetComponent_V.LevelSetForm_V(LevSetIntParams inp, MultidimensionalArray Koeff_V)
        {
            int             j0       = inp.i0;
            int             Len      = inp.Len;
            int             N        = inp.X.GetLength(1); // nodes per cell
            int             D        = inp.X.GetLength(2); // spatial dim.
            int             NoOfVars = this.ArgumentOrdering.Count;
            LevelSetTracker lsTrk    = m_LsTrk;

            // check dimension of input array
            Koeff_V.CheckLengths(Len, N, 2);


            // create temp mem:
            double[] node   = new double[D];
            double[] normal = new double[D];
            int      NP     = (this.ParameterOrdering != null) ? this.ParameterOrdering.Count : 0;

            double[]       ParamsPos = new double[NP];
            double[]       ParamsNeg = new double[NP];
            CommonParamsLs cp        = default(CommonParamsLs);

            cp.n         = normal;
            cp.x         = node;
            cp.ParamsNeg = ParamsNeg;
            cp.ParamsPos = ParamsPos;
            cp.time      = inp.time;


            // temp mem.
            double[] uA = new double[NoOfVars];
            double[] uB = new double[NoOfVars];
            double[,] Grad_uA = new double[NoOfVars, D];
            double[,] Grad_uB = new double[NoOfVars, D];
            double vA = 0;
            double vB = 0;

            double[] Grad_vA = new double[D];
            double[] Grad_vB = new double[D];
            var      h_min   = this.m_LsTrk.GridDat.Cells.h_min;


            //LevelSetSignCode pos;
            //LevelSetSignCode neg;
            //GetSignCode(out neg, out pos);
            SpeciesId posSpc = this.PositiveSpecies;
            SpeciesId negSpc = this.NegativeSpecies;

            var Reg = lsTrk.Regions;

            for (int j = 0; j < Len; j++)   // loop over items...
            {
                ReducedRegionCode rrc;
                int NoOf = Reg.GetNoOfSpecies(j + inp.i0, out rrc);
                Debug.Assert(NoOf == 2);
                //int iSpcPos = lsTrk.GetSpeciesIndex(rrc, pos);
                //int iSpcNeg = lsTrk.GetSpeciesIndex(rrc, neg);
                int iSpcPos = lsTrk.GetSpeciesIndex(rrc, posSpc);
                int iSpcNeg = lsTrk.GetSpeciesIndex(rrc, negSpc);
                cp.jCell = j + inp.i0;
                if (inp.PosCellLengthScale != null)
                {
                    cp.PosCellLengthScale = inp.PosCellLengthScale[cp.jCell];
                }
                else
                {
                    cp.PosCellLengthScale = double.NaN;
                }
                if (inp.NegCellLengthScale != null)
                {
                    cp.NegCellLengthScale = inp.NegCellLengthScale[cp.jCell];
                }
                else
                {
                    cp.NegCellLengthScale = double.NaN;
                }

                for (int n = 0; n < N; n++)   // loop over nodes...
                {
                    inp.Normal.CopyTo(normal, j, n, -1);
                    inp.X.CopyTo(node, j, n, -1);
                    for (int i = 0; i < NP; i++)
                    {
                        ParamsPos[i] = inp.ParamsPos[i][j, n];
                        ParamsNeg[i] = inp.ParamsNeg[i][j, n];
                    }

                    Koeff_V[j, n, iSpcNeg] = GetSourceCoeff(ref vA, ref cp, uA, uB, Grad_uA, Grad_uB, ref vA, ref vB, Grad_vA, Grad_vB);
                    Koeff_V[j, n, iSpcPos] = GetSourceCoeff(ref vB, ref cp, uA, uB, Grad_uA, Grad_uB, ref vA, ref vB, Grad_vA, Grad_vB);
                }
            }
        }
예제 #20
0
            static bool IsCellCut(int iEdge, int[,] E2C, LevelSetTracker.LevelSetRegions regions, SpeciesId mySp)
            {
                int jCell0 = E2C[iEdge, 0];

                int iSpc_cell0 = regions.GetSpeciesIndex(mySp, jCell0);

                if (iSpc_cell0 != 0)
                {
                    return(true);
                }

                int jCell1 = E2C[iEdge, 1];

                if (jCell1 >= 0)
                {
                    int iSpc_cell1 = regions.GetSpeciesIndex(mySp, jCell1);

                    if (iSpc_cell1 != 0)
                    {
                        return(true);
                    }
                }

                return(false);
            }
예제 #21
0
        /// <summary>
        /// Initializes <see cref="CellLengthScales"/>.
        /// </summary>
        void LengthScaleAgg()
        {
            SpeciesId[] species = this.SpeciesList.ToArray();

            int J = this.Tracker.GridDat.Cells.NoOfLocalUpdatedCells;
            int JE = this.Tracker.GridDat.Cells.Count;
            int[][] C2E = this.Tracker.GridDat.Cells.Cells2Edges;

            var CellLengthScalesMda = MultidimensionalArray.Create(JE, species.Length, 2); // 1st index: cell, 2nd index: species
            var CellVolumeFracMda = MultidimensionalArray.Create(JE, species.Length); // 1st index: cell, 2nd index: species
            for (int iSpc = 0; iSpc < species.Length; iSpc++) {
                SpeciesId spc = species[iSpc];
                var agginfo = this.GetAgglomerator(spc).AggInfo;
                BitArray aggEdgesBitMask = agginfo.AgglomerationEdges.GetBitMask();

                MultidimensionalArray CellSurface = CellLengthScalesMda.ExtractSubArrayShallow(-1, iSpc, 0);
                MultidimensionalArray CellVolume = CellLengthScalesMda.ExtractSubArrayShallow(-1, iSpc, 1);

                MultidimensionalArray CellVolume2 = CellVolumeFracMda.ExtractSubArrayShallow(-1, iSpc);

                CellSurface.Set(this.NonAgglomeratedMetrics.InterfaceArea[spc]);
                CellVolume.Set(this.NonAgglomeratedMetrics.CutCellVolumes[spc]);
                CellVolume2.Set(this.NonAgglomeratedMetrics.CutCellVolumes[spc]);

                MultidimensionalArray EdgeArea = this.NonAgglomeratedMetrics.CutEdgeAreas[spc];

                // accumulate cell surface
                for (int j = 0; j < J; j++) {
                    int[] edges = C2E[j];
                    int NE = edges.Length;

                    for (int ne = 0; ne < NE; ne++) {
                        int iEdg = Math.Abs(edges[ne]) - 1;

                        Debug.Assert(this.Tracker.GridDat.Edges.CellIndices[iEdg, 0] == j || this.Tracker.GridDat.Edges.CellIndices[iEdg, 1] == j);

                        if (!aggEdgesBitMask[iEdg]) {
                            Debug.Assert(!(double.IsNaN(CellSurface[j]) || double.IsInfinity(CellSurface[j])));
                            Debug.Assert(!(double.IsNaN(EdgeArea[iEdg]) || double.IsInfinity(EdgeArea[iEdg])));
                            CellSurface[j] += EdgeArea[iEdg];
                            Debug.Assert(!(double.IsNaN(CellSurface[j]) || double.IsInfinity(CellSurface[j])));
                        }
                    }
                }
            }

            // MPI exchange
            // Needed, such that all ExternalCells (i.e. Ghost cells) have the correct CellSurface
            CellLengthScalesMda.Storage.MPIExchange(this.Tracker.GridDat);
            CellVolumeFracMda.Storage.MPIExchange(this.Tracker.GridDat);

            var AggCellLengthScalesMda = MultidimensionalArray.Create(JE, species.Length); // 1st index: cell, 2nd index: species
            for (int iSpc = 0; iSpc < species.Length; iSpc++) {
                SpeciesId spc = species[iSpc];
                var agginfo = this.GetAgglomerator(spc).AggInfo;

                MultidimensionalArray CellSurface = CellLengthScalesMda.ExtractSubArrayShallow(-1, iSpc, 0);
                MultidimensionalArray CellVolume = CellLengthScalesMda.ExtractSubArrayShallow(-1, iSpc, 1);

                MultidimensionalArray CellVolume2 = CellVolumeFracMda.ExtractSubArrayShallow(-1, iSpc);

                // sum agglomeration sources to targets
                foreach (var agg_pair in agginfo.AgglomerationPairs) {
                    CellSurface[agg_pair.jCellTarget] += CellSurface[agg_pair.jCellSource];
                    CellVolume[agg_pair.jCellTarget] += CellVolume[agg_pair.jCellSource];
                }

                MultidimensionalArray LengthScales = AggCellLengthScalesMda.ExtractSubArrayShallow(-1, iSpc);

                // Loop includes external cells
                for (int j = 0; j < JE; j++) {
                    LengthScales[j] = CellVolume[j] / CellSurface[j];
                    CellVolume2[j] = CellVolume2[j] / this.Tracker.GridDat.Cells.GetCellVolume(j);
                }

                // set values in agglomeration sources to be equal to agglomeration targets
                foreach (var agg_pair in agginfo.AgglomerationPairs) {
                    LengthScales[agg_pair.jCellSource] = LengthScales[agg_pair.jCellTarget];
                    CellVolume2[agg_pair.jCellSource] = CellVolume2[agg_pair.jCellTarget];
                }

                if (this.AgglomerationThreshold <= 1e-6) {
                    // special treatment for no agglomeration -- which is anyway not recommended at all
                    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                    CellMask spcDom = this.Tracker.Regions.GetSpeciesMask(spc);

                    foreach (int j in spcDom.ItemEnum) {

                        double unCut = this.Tracker.GridDat.Cells.GetCellVolume(j);
                        double Fraction = CellVolume[j] / unCut;

                        if (Fraction <= 1.0e-10)
                            LengthScales[j] = 1e10;
                    }
                }

            #if DEBUG
                foreach (int jCell in this.Tracker.Regions.GetSpeciesMask(spc).ItemEnum) {
                    Debug.Assert(!(double.IsNaN(LengthScales[jCell]) || double.IsInfinity(LengthScales[jCell])));
                }

            #endif

            }

            // MPI exchange -> Is it really needed now???
            AggCellLengthScalesMda.Storage.MPIExchange(this.Tracker.GridDat);

            // store
            this.CellLengthScales = new Dictionary<SpeciesId, MultidimensionalArray>();
            this.CellVolumeFrac = new Dictionary<SpeciesId, MultidimensionalArray>();
            for (int iSpc = 0; iSpc < species.Length; iSpc++) {
                SpeciesId spc = species[iSpc];
                this.CellLengthScales.Add(spc, AggCellLengthScalesMda.ExtractSubArrayShallow(-1, iSpc).CloneAs());
                this.CellVolumeFrac.Add(spc, CellVolumeFracMda.ExtractSubArrayShallow(-1, iSpc).CloneAs());
            }
        }
예제 #22
0
            /// <summary>
            /// Not implemented yet.
            /// </summary>
            public override void EvaluateEdge(int e0, int Len, NodeSet NS,
                                              MultidimensionalArray ValueIN, MultidimensionalArray ValueOT,
                                              MultidimensionalArray MeanValueIN, MultidimensionalArray MeanValueOT,
                                              MultidimensionalArray GradientIN, MultidimensionalArray GradientOT, int ResultIndexOffset, double ResultPreScale)
            {
                // check arguments
                // ===============
                int D = GridDat.SpatialDimension; // spatial dimension
                int N = m_Basis.Length;           // number of coordinates per cell
                int K = NS.NoOfNodes;             // number of nodes

                {
                    if ((ValueIN != null) != (ValueOT != null))
                    {
                        throw new ArgumentException();
                    }
                    if ((MeanValueIN != null) != (MeanValueOT != null))
                    {
                        throw new ArgumentException();
                    }
                    if ((GradientIN != null) != (GradientOT != null))
                    {
                        throw new ArgumentException();
                    }

                    if (ValueIN != null)
                    {
                        if (ValueIN.Dimension != 2)
                        {
                            throw new ArgumentException("result", "dimension of result array must be 2");
                        }
                        if (Len > ValueIN.GetLength(0) + ResultIndexOffset)
                        {
                            throw new ArgumentException("mismatch between Len and 0-th length of result");
                        }
                        if (ValueIN.GetLength(1) != K)
                        {
                            throw new ArgumentException();
                        }
                        if (ValueOT.Dimension != 2)
                        {
                            throw new ArgumentException("result", "dimension of result array must be 2");
                        }
                        if (Len > ValueOT.GetLength(0) + ResultIndexOffset)
                        {
                            throw new ArgumentException("mismatch between Len and 0-th length of result");
                        }
                        if (ValueOT.GetLength(1) != K)
                        {
                            throw new ArgumentException();
                        }

                        if (!(ResultIndexOffset == 0 && Len == ValueIN.GetLength(0)))
                        {
                            ValueIN = ValueIN.ExtractSubArrayShallow(new int[] { ResultIndexOffset, 0 }, new int[] { ResultIndexOffset + Len - 1, K - 1 });
                        }

                        if (!(ResultIndexOffset == 0 && Len == ValueOT.GetLength(0)))
                        {
                            ValueOT = ValueOT.ExtractSubArrayShallow(new int[] { ResultIndexOffset, 0 }, new int[] { ResultIndexOffset + Len - 1, K - 1 });
                        }
                    }

                    if (MeanValueIN != null)
                    {
                        if (MeanValueIN.Dimension != 1)
                        {
                            throw new ArgumentException("Dimension of mean-value result array must be 1.");
                        }
                        if (Len > MeanValueIN.GetLength(0) + ResultIndexOffset)
                        {
                            throw new ArgumentException("mismatch between Len and 0-th length of result");
                        }
                        if (MeanValueOT.Dimension != 1)
                        {
                            throw new ArgumentException("Dimension of mean-value result array must be 1.");
                        }
                        if (Len > MeanValueOT.GetLength(0) + ResultIndexOffset)
                        {
                            throw new ArgumentException("mismatch between Len and 0-th length of result");
                        }

                        if (!(ResultIndexOffset == 0 && Len == MeanValueIN.GetLength(0)))
                        {
                            MeanValueIN = MeanValueIN.ExtractSubArrayShallow(new int[] { ResultIndexOffset }, new int[] { ResultIndexOffset + Len - 1 });
                        }

                        if (!(ResultIndexOffset == 0 && Len == MeanValueOT.GetLength(0)))
                        {
                            MeanValueOT = MeanValueOT.ExtractSubArrayShallow(new int[] { ResultIndexOffset }, new int[] { ResultIndexOffset + Len - 1 });
                        }
                    }

                    if (GradientIN != null)
                    {
                        if (GradientIN.Dimension != 3)
                        {
                            throw new ArgumentException("Dimension of gradient result array must be 3.");
                        }
                        if (Len > GradientIN.GetLength(0) + ResultIndexOffset)
                        {
                            throw new ArgumentException("mismatch between Len and 0-th length of result");
                        }
                        if (GradientIN.GetLength(1) != K)
                        {
                            throw new ArgumentException();
                        }
                        if (GradientIN.GetLength(2) != D)
                        {
                            throw new ArgumentException();
                        }
                        if (GradientOT.Dimension != 3)
                        {
                            throw new ArgumentException("Dimension of gradient result array must be 3.");
                        }
                        if (Len > GradientOT.GetLength(0) + ResultIndexOffset)
                        {
                            throw new ArgumentException("mismatch between Len and 0-th length of result");
                        }
                        if (GradientOT.GetLength(1) != K)
                        {
                            throw new ArgumentException();
                        }
                        if (GradientOT.GetLength(2) != D)
                        {
                            throw new ArgumentException();
                        }

                        if (!(ResultIndexOffset == 0 && Len == GradientIN.GetLength(0)))
                        {
                            GradientIN = GradientIN.ExtractSubArrayShallow(new int[] { ResultIndexOffset, 0, 0 }, new int[] { ResultIndexOffset + Len - 1, K - 1, D - 1 });
                        }

                        if (!(ResultIndexOffset == 0 && Len == GradientOT.GetLength(0)))
                        {
                            GradientOT = GradientOT.ExtractSubArrayShallow(new int[] { ResultIndexOffset, 0, 0 }, new int[] { ResultIndexOffset + Len - 1, K - 1, D - 1 });
                        }
                    }


                    var coöSys = NS.GetNodeCoordinateSystem(this.GridDat);

                    if (coöSys != NodeCoordinateSystem.EdgeCoord)
                    {
                        throw new ArgumentOutOfRangeException();
                    }
                }


                // real evaluation


                int[,] E2C = this.GridDat.iGeomEdges.CellIndices;                  // geometric edges to geometric cells
                int[][] cellL2C = this.GridDat.iLogicalCells.AggregateCellToParts; // logical cells to geometrical
                if (cellL2C != null)
                {
                    throw new NotImplementedException("todo");
                }
                int[,] TrfIdx = this.GridDat.iGeomEdges.Edge2CellTrafoIndex;

                LevelSetTracker lsTrk   = this.Owner.Basis.Tracker;
                var             regions = lsTrk.Regions;
                var             gdat    = this.GridDat;
                SpeciesId       mySp    = this.SpeciesId;

                int i = 0;

                while (i < Len)
                {
                    int ChunkLen = 1;
                    int iEdge    = i + e0;

                    bool CutOrNot = IsCellCut(iEdge, E2C, regions, mySp);
                    if (CutOrNot == false)
                    {
                        // both Neighbor cells are *not* cut
                        // standard evaluation

                        // try to find vectorization
                        while ((ChunkLen + i < Len) && (IsCellCut(iEdge + ChunkLen, E2C, regions, mySp) == false))
                        {
                            ChunkLen++;
                        }

                        //EvaluateEdgeInternal(iEdge, ChunkLen, NS, m_Owner.Basis.NonX_Basis,
                        //    m_Owner.m_Coordinates
                        //    )
                    }
                    else
                    {
                        // one or both neighbors are cut cells;
                        // non-vectorized evaluation
                        Debug.Assert(ChunkLen == 1);
                    }
                    Debug.Assert(i + ChunkLen <= Len);

                    int I0 = ResultIndexOffset + i;
                    int IE = ResultIndexOffset + i + ChunkLen - 1;

                    MultidimensionalArray chunkValueIN, chunkValueOT;
                    if (ValueIN != null)
                    {
                        chunkValueIN = ValueIN.ExtractSubArrayShallow(new[] { I0, 0 }, new[] { IE, K - 1 });
                        chunkValueOT = ValueOT.ExtractSubArrayShallow(new[] { I0, 0 }, new[] { IE, K - 1 });
                    }
                    else
                    {
                        chunkValueIN = ValueIN;
                        chunkValueOT = ValueOT;
                    }

                    MultidimensionalArray chunkMeanValueIN, chunkMeanValueOT;
                    if (MeanValueIN != null)
                    {
                        chunkMeanValueIN = MeanValueIN.ExtractSubArrayShallow(new[] { I0 }, new[] { IE });
                        chunkMeanValueOT = MeanValueOT.ExtractSubArrayShallow(new[] { I0 }, new[] { IE });
                    }
                    else
                    {
                        chunkMeanValueIN = MeanValueIN;
                        chunkMeanValueOT = MeanValueOT;
                    }

                    MultidimensionalArray chunkGradientIN, chunkGradientOT;
                    if (GradientIN != null)
                    {
                        chunkGradientIN = GradientIN.ExtractSubArrayShallow(new[] { I0, 0, 0 }, new[] { IE, K - 1, D - 1 });
                        chunkGradientOT = GradientOT.ExtractSubArrayShallow(new[] { I0, 0, 0 }, new[] { IE, K - 1, D - 1 });
                    }
                    else
                    {
                        chunkGradientIN = GradientIN;
                        chunkGradientOT = GradientOT;
                    }

                    if (CutOrNot)
                    {
                        Debug.Assert(ChunkLen == 1);

                        int jCell0 = E2C[iEdge, 0];
                        int jCell1 = E2C[iEdge, 1];

                        NodeSet NSvol0, NSvol1;
                        NSvol0 = NS.GetVolumeNodeSet(gdat, TrfIdx[iEdge, 0]);
                        if (jCell1 >= 0)
                        {
                            NSvol1 = NS.GetVolumeNodeSet(gdat, TrfIdx[iEdge, 1]);
                        }
                        else
                        {
                            NSvol1 = null;
                        }

                        if (ValueIN != null)
                        {
                            this.Evaluate(jCell0, 1, NSvol0, chunkValueIN, ResultPreScale);
                        }
                        if (ValueOT != null && jCell1 >= 0)
                        {
                            this.Evaluate(jCell1, 1, NSvol1, chunkValueOT, ResultPreScale);
                        }

                        if (MeanValueIN != null)
                        {
                            this.EvaluateMean(jCell0, 1, chunkMeanValueIN, 0, ResultPreScale);
                        }
                        if (MeanValueOT != null && jCell1 >= 0)
                        {
                            this.EvaluateMean(jCell1, 1, chunkMeanValueOT, 0, ResultPreScale);
                        }

                        if (GradientIN != null)
                        {
                            this.EvaluateGradient(jCell0, 1, NSvol0, chunkGradientIN, 0, ResultPreScale);
                        }
                        if (GradientOT != null && jCell1 >= 0)
                        {
                            this.EvaluateGradient(jCell1, 1, NSvol1, chunkGradientOT, 0, ResultPreScale);
                        }
                    }
                    else
                    {
                        // for edges 'iEdge' through 'iEdge + ChunkLen - 1', this shadow field is the 0-th species for IN and OT cell


                        EvaluateEdgeInternal(iEdge, ChunkLen, NS, m_Owner.Basis.NonX_Basis,
                                             m_Owner.m_Coordinates.BaseStorageMda,
                                             chunkValueIN, chunkValueOT,
                                             chunkMeanValueIN, chunkMeanValueOT,
                                             chunkGradientIN, chunkGradientOT,
                                             ResultPreScale);
                    }

                    i += ChunkLen;
                }
                Debug.Assert(i == Len);
            }
예제 #23
0
        /// <summary>
        /// returns global unique indices which correlate to a certain sub-set of ...
        /// <list type="bullet">
        /// <item>the mappings's basis (<paramref name="mapping"/>, <see cref="UnsetteledCoordinateMapping.BasisS"/>).</item>
        /// <item>species (<paramref name="_SpcIds"/>).</item>
        /// <item>cells (<paramref name="cm"/>).</item>
        /// </list>
        /// </summary>
        /// <param name="mapping">
        /// the mapping
        /// </param>
        /// <param name="Fields">
        /// determines which fields should be in the sub-vector-indices-list
        /// </param>
        /// <param name="_SpcIds">
        /// determines which species should be in the sub-vector-indices-list; null indicates all species.
        /// </param>
        /// <param name="cm">
        /// determines which cells should be in the sub-vector-indices-list; null indicates all cells.
        /// </param>
        /// <param name="regions">
        /// Determines which XDG-coordinate belongs to which species.
        /// </param>
        /// <param name="presenceTest">
        /// if true, cells where some species has zero measure are excluded from the sub-vector-indices-list.
        /// </param>
        /// <param name="drk">
        /// a cell-agglomeration object: if null, ignored; if provided,
        /// cells which are eliminated by the agglomeration are excluded from the sub-vector-indices-list
        /// </param>
        /// <returns>a list of global (over all MPI processes) unique indices.</returns>
        static public int[] GetSubvectorIndices(this UnsetteledCoordinateMapping mapping, LevelSetTracker.LevelSetRegions regions, int[] Fields,
                                                ICollection <SpeciesId> _SpcIds = null, CellMask cm = null, bool presenceTest = true, MultiphaseCellAgglomerator drk = null)
        {
            #region Check Arguments
            // =========
            SpeciesId[] SpcIds = null;
            if (_SpcIds == null)
            {
                // take all species, if arg is null
                SpcIds = regions.SpeciesIdS.ToArray();
            }
            else
            {
                SpcIds = _SpcIds.ToArray();
            }

            if (SpcIds.Length <= 0)
            {
                // return will be empty for no species
                return(new int[0]);
            }
            #endregion

            #region collect cells which are excluded by agglomeration
            // =================================================

            int[][] ExcludeLists;
            if (drk != null)
            {
                ExcludeLists = new int[regions.SpeciesIdS.Count][]; //  new Dictionary<SpeciesId, int[]>();
                foreach (var id in SpcIds)
                {
                    int[] ExcludeList = drk.GetAgglomerator(id).AggInfo.AgglomerationPairs.Select(pair => pair.jCellSource).ToArray();
                    Array.Sort(ExcludeList);
                    ExcludeLists[id.cntnt - LevelSetTracker.___SpeciesIDOffest] = ExcludeList;
                }
            }
            else
            {
                ExcludeLists = null;
            }
            #endregion

            #region determine over which cells we want to loop
            // ==========================================
            CellMask loopCells;
            if ((new HashSet <SpeciesId>(regions.SpeciesIdS)).SetEquals(new HashSet <SpeciesId>(SpcIds)))
            {
                if (cm == null)
                {
                    loopCells = CellMask.GetFullMask(regions.GridDat);
                }
                else
                {
                    loopCells = cm;
                }
            }
            else
            {
                loopCells = regions.GetSpeciesMask(SpcIds[0]);
                for (int i = 1; i < SpcIds.Length; i++)
                {
                    loopCells = loopCells.Intersect(regions.GetSpeciesMask(SpcIds[i]));
                }
                if (cm != null)
                {
                    loopCells = loopCells.Intersect(cm);
                }
            }
            #endregion

            #region build list
            // ==========

            var R = new List <int>();

            // which basis is XDG?
            var        _BasisS  = mapping.BasisS.ToArray();
            XDGBasis[] _XBasisS = new XDGBasis[_BasisS.Length];
            for (int i = 0; i < _BasisS.Length; i++)
            {
                _XBasisS[i] = _BasisS[i] as XDGBasis;
            }


            Tuple <int, SpeciesId>[] iSpcS = new Tuple <int, SpeciesId> [SpcIds.Length];
            int KK;
            int Len_iSpcS = iSpcS.Length;


            int[] ExcludeListsPointer = new int[regions.SpeciesIdS.Count];


            // loop over cells?
            foreach (int jCell in loopCells.ItemEnum)
            {
                int NoOfSpc = regions.GetNoOfSpecies(jCell);

                #region
                //
                // in cell 'jCell', for each species in 'SpcIds' ...
                // * is the species present in 'jCell'?
                // * what is the species index in 'jCell'?
                // * we also have to consider that due to agglomeration, the respective cut-cell for the species might have been agglomerated.
                // so we determine
                // * 'KK' is the number of species (from 'SpcIds') which is actually present and not agglomerated in 'jCell'
                // * for i in (0 ... KK-1), iSpcS[i] is a tuple of (Species-index-in-cell, SpeciesID)
                //
                // yes, the following code sucks:
                KK = 0;
                for (int k = 0; k < Len_iSpcS; k++)   // loop over all species (provided as argument)...
                {
                    SpeciesId id      = SpcIds[k];
                    int       __iSpcS = regions.GetSpeciesIndex(id, jCell);
                    if (__iSpcS >= 0)
                    {
                        // species index is non-negative, so indices for the species are allocated ...
                        if (!presenceTest || regions.IsSpeciesPresentInCell(id, jCell))
                        {
                            // species is also present (i.e. has a greater-than-zero measure ...

                            if (drk == null)
                            {
                                // no agglomeration exclution
                                iSpcS[KK] = new Tuple <int, SpeciesId>(__iSpcS, id);
                                KK++;
                            }
                            else
                            {
                                int q  = id.cntnt - LevelSetTracker.___SpeciesIDOffest;
                                var el = ExcludeLists[q];

                                while (ExcludeListsPointer[q] < el.Length &&
                                       el[ExcludeListsPointer[q]] < jCell)
                                {
                                    ExcludeListsPointer[q]++;
                                }
                                Debug.Assert(ExcludeListsPointer[q] >= el.Length || el[ExcludeListsPointer[q]] >= jCell);

                                if (ExcludeListsPointer[q] >= el.Length || el[ExcludeListsPointer[q]] != jCell)
                                {
                                    // cell is also not agglomerated ...
                                    iSpcS[KK] = new Tuple <int, SpeciesId>(__iSpcS, id);
                                    KK++;
                                }
                            }
                        }
                    }
                }
                if (KK > 1)
                {
                    Array.Sort <Tuple <int, SpeciesId> >(iSpcS, 0, KK, new ilPSP.FuncComparer <Tuple <int, SpeciesId> >((a, b) => a.Item1 - b.Item1));
                }
                // --------- esc (end of sucking code)
                #endregion

                for (int k = 0; k < KK; k++)   // loop over species in cell
                {
                    int iSpc = iSpcS[k].Item1;

                    for (int i = 0; i < Fields.Length; i++)
                    {
                        int iField = Fields[i];

                        if (_XBasisS[iField] == null)
                        {
                            int N  = _BasisS[iField].GetLength(jCell);
                            int i0 = mapping.LocalUniqueCoordinateIndex(iField, jCell, 0);
                            for (int n = 0; n < N; n++)
                            {
                                R.Add(i0 + n);
                            }
                        }
                        else
                        {
                            int N  = _XBasisS[iField].DOFperSpeciesPerCell;
                            int i0 = mapping.LocalUniqueCoordinateIndex(iField, jCell, 0) + iSpc * N;
                            for (int n = 0; n < N; n++)
                            {
                                R.Add(i0 + n);
                            }
                        }
                    }
                }
            }
            #endregion

            return(R.ToArray());
        }
예제 #24
0
        /// <summary>
        /// computes a local unique coordinate index ("local" means local on this processor);
        /// this index is unique over all fields (in this mapping), over all cells, over all basis functions,
        /// but it's only locally (on this processor) valid.
        /// A local index in the update range (smaller than <see cref="NUpdate"/>) can be converted into
        /// a global index by adding <see cref="Partitioning.i0"/>.
        /// </summary>
        /// <param name="find">
        /// the field or basis index (see <see cref="BasisS"/>);
        /// </param>
        /// <param name="j">local cell index</param>
        /// <param name="n">DG mode index</param>
        /// <param name="lsTrk"></param>
        /// <param name="map"></param>
        /// <param name="spc">species</param>
        public static int LocalUniqueCoordinateIndex(this UnsetteledCoordinateMapping map, LevelSetTracker lsTrk, int find, int j, SpeciesId spc, int n)
        {
            int spcIdx = lsTrk.Regions.GetSpeciesIndex(spc, j);

            return(LocalUniqueCoordinateIndex(map, lsTrk, find, j, spcIdx, n));
        }
예제 #25
0
        /*
         *
         * static int Jmp2Idx(JumpTypes jmp) {
         *  switch (jmp) {
         *      case JumpTypes.OneMinusHeaviside:
         *          return 0;
         *      case JumpTypes.Heaviside:
         *          return 1;
         *      default:
         *          throw new NotSupportedException();
         *  }
         * }
         *
         * static internal double Jmp2Sign(JumpTypes jmp) {
         *  return (double)Math.Sign(((double)Jmp2Idx(jmp)) - 0.5);
         * }
         */

        ///// <summary>
        ///// Writes diagnostic information about quadrature rules into csv-textfiles.
        ///// </summary>
        //public void RuleInfo(string spc, string volruleName, string levsetRuleName, string cellBndRule, string edgeRuleName, int order) {
        //    RuleInfo(lsTrk.GetSpeciesId(spc), volruleName, levsetRuleName, cellBndRule, edgeRuleName, order);
        //}

        /// <summary>
        /// Writes diagnostic information about quadrature rules into csv-textfiles.
        /// </summary>
        public void RuleInfo(SpeciesId spc, string volruleName, string levsetRuleName, string cellBndRule, string edgeRuleName, int order, int iLevSet)
        {
            var _Context = this.XDGSpaceMetrics.GridDat;

            // test parameters
            var jmp  = Foundation.XDG.Quadrature.HMF.JumpTypes.Heaviside;
            var sch  = this.XDGSpaceMetrics.XQuadFactoryHelper;
            var spNm = this.XDGSpaceMetrics.LevelSetRegions.GetSpeciesName(spc);
            //var spId = LsTrk.GetSpeciesId(spNm);
            var DomainOfInterest = XDGSpaceMetrics.LevelSetRegions.GetCutCellSubgrid4LevSet(iLevSet);


            if (volruleName != null)
            {
                int      J          = _Context.Cells.NoOfLocalUpdatedCells;
                double[] TotWeights = new double[J];

                foreach (var Kref in this.XDGSpaceMetrics.GridDat.Grid.RefElements)
                {
                    var volfactory = sch.GetVolRuleFactory(0, jmp, Kref);
                    var qrset      = volfactory.GetQuadRuleSet(DomainOfInterest.VolumeMask, order);
                    foreach (var chk in qrset)
                    {
                        for (int j = chk.Chunk.i0; j < chk.Chunk.JE; j++)
                        {
                            TotWeights[j] = chk.Rule.Weights.Sum();
                        }
                    }
                }

                DomainOfInterest.VolumeMask.SaveToTextFile(volruleName + "-" + spNm + ".csv", false,
                                                           delegate(double[] x, int jL, int iG) {
                    return(TotWeights[jL]);
                });
            }


            if (levsetRuleName != null)
            {
                int      J          = _Context.Cells.NoOfLocalUpdatedCells;
                double[] TotWeights = new double[J];

                foreach (var Kref in this.XDGSpaceMetrics.GridDat.Grid.RefElements)
                {
                    var levsetFactory = sch.GetSurfaceFactory(0, Kref);
                    var qrset         = levsetFactory.GetQuadRuleSet(DomainOfInterest.VolumeMask, order);

                    foreach (var chk in qrset)
                    {
                        for (int j = chk.Chunk.i0; j < chk.Chunk.JE; j++)
                        {
                            TotWeights[j] = chk.Rule.Weights.Sum();
                        }
                    }
                }

                DomainOfInterest.VolumeMask.SaveToTextFile(levsetRuleName + "-" + spNm + ".csv", false,
                                                           delegate(double[] x, int jL, int iG) {
                    return(TotWeights[jL]);
                });
            }



            {
                int      NoEdg      = this.XDGSpaceMetrics.GridDat.Edges.Count;
                double[] TotWeights = new double[NoEdg];

                foreach (var Kref in this.XDGSpaceMetrics.GridDat.Grid.RefElements)
                {
                    var edgeFactory = sch.GetEdgeRuleFactory(0, jmp, Kref);
                    var qrset       = edgeFactory.GetQuadRuleSet(DomainOfInterest.AllEdgesMask, order);

                    foreach (var chk in qrset)
                    {
                        for (int j = chk.Chunk.i0; j < chk.Chunk.JE; j++)
                        {
                            TotWeights[j] = chk.Rule.Weights.Sum();
                        }
                    }
                }

                DomainOfInterest.AllEdgesMask.SaveToTextFile(edgeRuleName + "-" + spNm + ".csv", false,
                                                             delegate(double[] x, int jL, int iG) {
                    return(TotWeights[jL]);
                });
            } // */

            /*
             * if (cellBndRule != null) {
             *  int J = _Context.Cells.NoOfLocalUpdatedCells;
             *  var FaceWeightSum = MultidimensionalArray.Create(J, this.lsTrk.GridDat.Grid.RefElements.Max(Kref => Kref.NoOfFaces));
             *
             *  foreach (var Kref in this.lsTrk.GridDat.Grid.RefElements) {
             *      var ruleConv = sch.GetVolumeEdgeRuleFactory(0, Kref);
             *      var qrset = ruleConv.GetQuadRuleSet(DomainOfInterest.VolumeMask, order);
             *
             *
             *      int F = Kref.NoOfFaces;
             *
             *
             *      foreach (var chk in qrset) {
             *          for (int j = chk.Chunk.i0; j < chk.Chunk.JE; j++) {
             *              var Rule = chk.Rule;
             *              var NodesPerFace = Rule.NumbersOfNodesPerFace;
             *
             *              int N0 = 0;
             *
             *              for (int f = 0; f < F; f++) {
             *                  for (int n = N0; n < N0 + NodesPerFace[f]; n++) {
             *                      FaceWeightSum[j, f] += Rule.Weights[n];
             *                  }
             *                  N0 += NodesPerFace[f];
             *              }
             *          }
             *      }
             *  }
             *
             *  //DomainOfInterest.VolumeMask.ToTxtFile("cellBndRule-" + jmp + ".csv", false,
             *  //    delegate(double[] x, int j) { return FaceWeightSum[j, 0]; },
             *  //    delegate(double[] x, int j) { return FaceWeightSum[j, 1]; },
             *  //    delegate(double[] x, int j) { return FaceWeightSum[j, 2]; },
             *  //    delegate(double[] x, int j) { return FaceWeightSum[j, 3]; });
             *
             *  ToTxtFile(cellBndRule + ".csv", FaceWeightSum, DomainOfInterest.VolumeMask);
             * }*/
        }
예제 #26
0
            /// <summary>
            /// Creates an subgrid which only contains cells
            /// that are at least partly occupied by species
            /// <paramref name="speciesName"/>;
            /// </summary>
            /// <param name="speciesName">
            /// The name of the species
            /// </param>
            /// <returns>
            /// A subgrid containing only cells with at least a portion of
            /// species <paramref name="speciesName"/>
            /// </returns>
            public SubGrid GetSpeciesSubGrid(string speciesName)
            {
                SpeciesId id = m_owner.GetSpeciesId(speciesName);

                return(GetSpeciesSubGrid(id));// this.SubGrids[id];
            }
예제 #27
0
            /// <summary>
            /// see <see cref="GetSpeciesMask(SpeciesId)"/>
            /// </summary>
            /// <param name="speciesName"></param>
            /// <returns></returns>
            public CellMask GetSpeciesMask(string speciesName)
            {
                SpeciesId id = m_owner.GetSpeciesId(speciesName);

                return(GetSpeciesMask(id));
            }
예제 #28
0
        /// <summary>
        /// Quadrature scheme which is used for the penalty components in <see cref="XSpatialOperator.GhostEdgesOperator"/>, for species <paramref name="sp"/>.
        /// </summary>
        public EdgeQuadratureScheme GetEdgeGhostScheme(SpeciesId sp, EdgeMask IntegrationDomainRestriction = null)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species (" + sp.cntnt + ") is not supported.");
            }

            // select all edges for species sp with a positive measure
            // =======================================================
            var EdgBitMask = this.GetEdgeMask(sp, IntegrationDomainRestriction).GetBitMask().CloneAs();
            var EdgArea    = this.NonAgglomeratedMetrics.CutEdgeAreas[sp];

            int L = EdgBitMask.Length;

            for (int e = 0; e < L; e++)
            {
                if (EdgArea[e] <= 0)
                {
                    EdgBitMask[e] = false;
                }
            }

            // return
            // ======
            return(new EdgeQuadratureScheme(true, new EdgeMask(this.XDGSpaceMetrics.GridDat, EdgBitMask)));


            /*
             *
             * if (!this.GhostSupport)
             *  throw new NotSupportedException();
             *
             *
             * // determine domain
             * // ================
             *
             * var allRelevantEdges = this.GhostIntegrationDomain[sp];
             * if (IntegrationDomain != null) {
             *  allRelevantEdges = allRelevantEdges.Intersect(IntegrationDomain);
             * }
             *
             * // special treatment for the edges of agglomerated cells
             * // =====================================================
             * EdgeMask fuckedEdges = null;
             * {
             *
             *  var AggCells = this.CellAgglomeration.GetAgglomerator(sp).AggInfo.SourceCells;
             *  if (AggCells != null && AggCells.NoOfItemsLocally > 0) {
             *      //int EdgB4 = allRelevantEdges.NoOfItemsGlobally;
             *
             *      //allRelevantEdges = allRelevantEdges.Except(AggCellsSgrd.InnerEdgesMask); // option 1
             *      //allRelevantEdges = allRelevantEdges.Except(AggCellsSgrd.AllEdgesMask);   // option 2
             *      //                                                                          option 3: überhaupt nix
             *
             *      fuckedEdges = allRelevantEdges.Intersect(this.CellAgglomeration.GetAgglomerator(sp).AggInfo.SourceCellsEdges);
             *  }
             * }
             *
             * // create Scheme
             * // =============
             * {
             *  var GhostScheme = new EdgeQuadratureScheme(true, allRelevantEdges);
             *
             *  // use the HMF-rule on the edges of the agglomerated cells:
             *  if (fuckedEdges != null) {
             *      foreach (var Kref in lsTrk.GridDat.Grid.RefElements) {
             *          for (int iLevSet = 0; iLevSet < lsTrk.LevelSets.Count; iLevSet++) { // loop over level sets...
             *              var cutEdges = fuckedEdges;
             *              cutEdges = cutEdges.Intersect(this.m_Subgrid4Kref_AllEdges[Kref]);
             *              var jmp = IdentifyWing(iLevSet, sp);
             *              var factory = this.lsTrk.GetXQuadFactoryHelper(MomentFittingVariant).GetEdgeRuleFactory(iLevSet, jmp, Kref);
             *              GhostScheme.AddFactory(factory, cutEdges);
             *          }
             *      }
             *  }
             *
             *  // return
             *  return GhostScheme;
             * }
             */
        }
예제 #29
0
        /// <summary>
        /// For some species <paramref name="sp"/>,
        /// this function computes on which side/wing
        /// of level-set no. <paramref name="levSetIdx"/>)
        /// the species is located.
        /// </summary>
        /// <remarks>
        /// Nur ein Provisorium, das ganze Konzept ist noch etwas unausgereift. (Habe einen Nachmittag lang darueber nachgedacht, keinen bessere Idee gehabt,
        /// und darum...).
        /// </remarks>
        public JumpTypes IdentifyWing(int levSetIdx, SpeciesId sp)
        {
            int NoOfLevSets = this.XDGSpaceMetrics.NoOfLevelSets;

            if (levSetIdx < 0 || levSetIdx > NoOfLevSets)
            {
                throw new ArgumentOutOfRangeException();
            }

            if (NoOfLevSets == 1)
            {
                string[] speciesTable = (string[])(this.XDGSpaceMetrics.LevelSetRegions.SpeciesTable);
                Debug.Assert(speciesTable.Length == 2);

                string spN = this.XDGSpaceMetrics.LevelSetRegions.GetSpeciesName(sp);

                if (spN == speciesTable[0])
                {
                    return(JumpTypes.OneMinusHeaviside);
                }
                else if (spN == speciesTable[1])
                {
                    return(JumpTypes.Heaviside);
                }
                else
                {
                    throw new Exception("should not happen.");
                }
            }
            else if (NoOfLevSets == 2)
            {
                string[,] speciesTable = (string[, ])(this.XDGSpaceMetrics.LevelSetRegions.SpeciesTable);
                Debug.Assert(speciesTable.GetLength(0) == 2);
                Debug.Assert(speciesTable.GetLength(1) == 2);

                string spN = this.XDGSpaceMetrics.LevelSetRegions.GetSpeciesName(sp);

                int       cnt    = 0;
                JumpTypes jmpRet = JumpTypes.Implicit;
                int[]     _i     = new int[2];
                for (_i[0] = 0; _i[0] < 2; _i[0]++)     // loop over signs of level-set 0 ...
                {
                    for (_i[1] = 0; _i[1] < 2; _i[1]++) // loop over signs of level-set 1 ...
                    {
                        if (speciesTable[_i[0], _i[1]] == spN)
                        {
                            cnt++;

                            if (_i[levSetIdx] == 0)
                            {
                                jmpRet = JumpTypes.OneMinusHeaviside;
                            }
                            else if (_i[levSetIdx] == 1)
                            {
                                jmpRet = JumpTypes.Heaviside;
                            }
                            else
                            {
                                throw new ApplicationException();
                            }
                        }
                    }
                }

                if (cnt != 1)
                {
                    throw new NotImplementedException("unable to identify.");
                }


                return(jmpRet);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
예제 #30
0
 /// <summary>
 /// Equal to <see cref="LevelSetTracker.GetSpeciesName(SpeciesId)"/>.
 /// </summary>
 public String GetSpeciesName(SpeciesId id)
 {
     return(m_owner.GetSpeciesName(id));
 }