Exemplo n.º 1
0
        public void UpdateDomain(CellMask cm, bool RestrictToCellMask = true)
        {
            var GridDat = m_bInput.GridDat;
            int J       = GridDat.iLogicalCells.NoOfLocalUpdatedCells;

            this.Domain = cm;

            int[][] newStencils = new int[J][];

            var Mask = cm.GetBitMaskWithExternal();

            foreach (int jCell in cm.ItemEnum)
            {
                int[] NeighCells, dummy;
                GridDat.GetCellNeighbours(jCell, GetCellNeighbours_Mode.ViaVertices, out NeighCells, out dummy);

                if (RestrictToCellMask == true)
                {
                    NeighCells = NeighCells.Where(j => Mask[j]).ToArray();
                }
                Array.Sort(NeighCells);
                int[] newStencil = ArrayTools.Cat(new int[] { jCell }, NeighCells);

                if (this.Stencils == null ||
                    this.Stencils[jCell] == null && newStencil.Length > 0 ||
                    !ArrayTools.AreEqual(this.Stencils[jCell], newStencil))
                {
                    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    // a re-computation of the aggregate cell basis is necessary
                    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    ComputeAggregateBasis(jCell, NeighCells);
                }
                newStencils[jCell] = newStencil;
            }

            for (int j = 0; j < J; j++)
            {
                if (newStencils[j] == null && this.AggregateBasisTrafo[j] != null)
                {
                    this.AggregateBasisTrafo[j] = null;
                }

                Debug.Assert((newStencils[j] == null) == (this.AggregateBasisTrafo[j] == null));
                if (newStencils[j] != null)
                {
                    Debug.Assert(newStencils[j].Length == this.AggregateBasisTrafo[j].GetLength(0));
                }
            }


            this.Stencils = newStencils;
        }
Exemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="output">output</param>
        /// <param name="cm">mask on which the filtering should be performed</param>
        /// <param name="input">input</param>
        /// <param name="mode"></param>
        public static void FilterStencilProjection(SinglePhaseField output, CellMask cm, SinglePhaseField input, PatchRecoveryMode mode)
        {
            var GridDat = input.GridDat;

            if (!object.ReferenceEquals(output.GridDat, GridDat))
            {
                throw new ArgumentException();
            }
            if (!object.ReferenceEquals(input.GridDat, GridDat))
            {
                throw new ArgumentException();
            }

            if (cm == null)
            {
                cm = CellMask.GetFullMask(GridDat);
            }

            switch (mode)
            {
            case PatchRecoveryMode.L2_unrestrictedDom:
            case PatchRecoveryMode.L2_restrictedDom: {
                var  Mask = cm.GetBitMaskWithExternal();
                bool RestrictToCellMask = mode == PatchRecoveryMode.L2_restrictedDom;
                foreach (int jCell in cm.ItemEnum)
                {
                    int[] NeighCells, dummy;
                    GridDat.GetCellNeighbours(jCell, GetCellNeighbours_Mode.ViaVertices, out NeighCells, out dummy);

                    if (RestrictToCellMask == true)
                    {
                        NeighCells = NeighCells.Where(j => Mask[j]).ToArray();
                    }

                    FilterStencilProjection(output, jCell, NeighCells, input);
                }

                return;
            }

            case PatchRecoveryMode.ChebychevInteroplation: {
                int P = input.Basis.Degree * 3;

                double[] ChebyNodes = ChebyshevNodes(P);
                NodeSet  Nds        = new NodeSet(GridDat.iGeomCells.RefElements[0], P, 1);
                Nds.SetColumn(0, ChebyNodes);
                Nds.LockForever();
                Polynomial[] Polynomials = GetNodalPolynomials(ChebyNodes);

                MultidimensionalArray PolyVals = MultidimensionalArray.Create(P, P);


                for (int p = 0; p < P; p++)
                {
                    Polynomials[p].Evaluate(PolyVals.ExtractSubArrayShallow(p, -1), Nds);

                    for (int i = 0; i < P; i++)
                    {
                        Debug.Assert(Math.Abs(((i == p) ? 1.0 : 0.0) - PolyVals[p, i]) <= 1.0e-8);
                    }
                }


                foreach (int jCell in cm.ItemEnum)
                {
                    AffineTrafo T;
                    var         NodalValues = NodalPatchRecovery(jCell, ChebyNodes, input, out T);

                    /*
                     * MultidimensionalArray Nodes2D = MultidimensionalArray.Create(P, P, 2);
                     * for (int i = 0; i < P; i++) {
                     *  for (int j = 0; j < P; j++) {
                     *      Nodes2D[i, j, 0] = ChebyNodes[i];
                     *      Nodes2D[i, j, 1] = ChebyNodes[j];
                     *  }
                     * }
                     * var _Nodes2D = Nodes2D.ResizeShallow(P*P, 2);
                     * var xNodes = _Nodes2D.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { P*P - 1, 0 });
                     * var yNodes = _Nodes2D.ExtractSubArrayShallow(new int[] { 0, 1 }, new int[] { P*P - 1, 1 });
                     * int K = P*P;
                     *
                     * MultidimensionalArray xPolyVals = MultidimensionalArray.Create(P, K);
                     * MultidimensionalArray yPolyVals = MultidimensionalArray.Create(P, K);
                     *
                     * for (int p = 0; p < P; p++) {
                     *  Polynomials[p].Evaluate(yPolyVals.ExtractSubArrayShallow(p, -1), yNodes);
                     *  Polynomials[p].Evaluate(xPolyVals.ExtractSubArrayShallow(p, -1), xNodes);
                     *
                     * }
                     *
                     *
                     * double ERR = 0;
                     * for (int k = 0; k < K; k++) {
                     *
                     *  double x = xNodes[k, 0];
                     *  double y = yNodes[k, 0];
                     *
                     *  double acc = 0;
                     *  double BasisHits = 0.0;
                     *  for (int i = 0; i < P; i++) {
                     *      for (int j = 0; j < P; j++) {
                     *
                     *          bool isNode = (Math.Abs(x - ChebyNodes[i]) < 1.0e-8) && (Math.Abs(y - ChebyNodes[j]) < 1.0e-8);
                     *          double BasisSoll = isNode ? 1.0 : 0.0;
                     *          if (isNode)
                     *              Console.WriteLine();
                     *
                     *          double Basis_ij = xPolyVals[i, k]*yPolyVals[j, k];
                     *
                     *          Debug.Assert((Basis_ij - BasisSoll).Abs() < 1.0e-8);
                     *
                     *          BasisHits += Math.Abs(Basis_ij);
                     *
                     *          acc += Basis_ij*NodalValues[i, j];
                     *      }
                     *  }
                     *  Debug.Assert(Math.Abs(BasisHits - 1.0) < 1.0e-8);
                     *
                     *
                     *
                     *
                     *  double soll = yNodes[k,0];
                     *  Debug.Assert((soll - acc).Pow2() < 1.0e-7);
                     *  ERR = (soll - acc).Pow2();
                     * }
                     * Console.WriteLine(ERR);
                     */

                    output.ProjectField(1.0,
                                        delegate(int j0, int Len, NodeSet Nodes, MultidimensionalArray result) {
                            var K = Nodes.NoOfNodes;

                            MultidimensionalArray NT = T.Transform(Nodes);

                            var xNodes = new NodeSet(null, NT.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { K - 1, 0 }));
                            var yNodes = new NodeSet(null, NT.ExtractSubArrayShallow(new int[] { 0, 1 }, new int[] { K - 1, 1 }));

                            MultidimensionalArray xPolyVals = MultidimensionalArray.Create(P, K);
                            MultidimensionalArray yPolyVals = MultidimensionalArray.Create(P, K);

                            for (int p = 0; p < P; p++)
                            {
                                Polynomials[p].Evaluate(yPolyVals.ExtractSubArrayShallow(p, -1), yNodes);
                                Polynomials[p].Evaluate(xPolyVals.ExtractSubArrayShallow(p, -1), xNodes);
                            }


                            for (int k = 0; k < K; k++)
                            {
                                double acc = 0;
                                for (int i = 0; i < P; i++)
                                {
                                    for (int j = 0; j < P; j++)
                                    {
                                        acc += xPolyVals[i, k] * yPolyVals[j, k] * NodalValues[i, j];
                                    }
                                }
                                result[0, k] = acc;
                            }
                        },
                                        new CellQuadratureScheme(true, new CellMask(input.GridDat, Chunk.GetSingleElementChunk(jCell))));
                }


                return;
            }
            }
        }