Ejemplo n.º 1
0
        /// <summary>
        /// Solves the Reinitialisation-problem locally, i.e. cell by cell.
        /// </summary>
        /// <param name="Accepted">
        /// </param>
        /// <param name="Recalc"></param>
        /// <param name="phi_accepted">
        /// Input: level-set field values for the accepted cells/vallues in these cells are unchanged on exit.
        /// Output: level-set-field values for cells in <see cref="Recalc"/>.
        /// </param>
        /// <param name="_sign"></param>
        /// <param name="gradPhi"></param>
        void LocalSolve(CellMask Accepted, CellMask Recalc, SinglePhaseField phi_accepted, VectorField <SinglePhaseField> gradPhi, double _sign, SinglePhaseField DiffusionCoeff)
        {
            // loop over 'Recalc' - cells...
            foreach (int jCell in Recalc.ItemEnum)
            {
                double mini, maxi;
                this.Stpw_geomSolver.Start();
                this.lsGeom.LocalSolve(jCell, Accepted.GetBitMaskWithExternal(), phi_accepted, _sign, out mini, out maxi);
                this.Stpw_geomSolver.Stop();
                this.Stpw_reinitSolver.Start();
                this.lsEllipt.LocalSolve(jCell, Accepted.GetBitMaskWithExternal(), phi_accepted, gradPhi);
                this.Stpw_reinitSolver.Stop();

                //bool q = LocalSolve_Iterative(jCell, Accepted.GetBitMask(), phi_accepted, gradPhi);
                //if(!q)
                //    Console.WriteLine("Local solver not converged.");
            }
        }
Ejemplo n.º 2
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;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Polynomial extrapolation between cells.
        /// </summary>
        /// <param name="ExtrapolateTo">contains all cells for which extrapolated values should be computed</param>
        /// <param name="ExtrapolateFrom">contains all cells with "known values"</param>
        /// <returns>
        /// The number of cells (locally) for which the algorithm was not able to extrapolate a value
        /// </returns>
        virtual public int CellExtrapolation(CellMask ExtrapolateTo, CellMask ExtrapolateFrom)
        {
            MPICollectiveWatchDog.Watch();
            int J = this.GridDat.iLogicalCells.NoOfLocalUpdatedCells;
            int NoOfNeigh;

            int[]   NeighIdx;
            int[][] CN = this.GridDat.iLogicalCells.CellNeighbours;


            // mark all cells in which species 'Id' is known
            // ---------------------------------------------
            BitArray ValueIsKnown    = ExtrapolateFrom.GetBitMaskWithExternal().CloneAs();
            CellMask _ExtrapolateTo  = ExtrapolateTo.Except(ExtrapolateFrom);
            BitArray NeedToKnowValue = _ExtrapolateTo.GetBitMask();

            this.Clear(_ExtrapolateTo);

            // repeat until (for species 'Id' the DOF' of) all cells
            // that contain (at least a fraction of) species 'Id' are known...
            // ------------------------------------------------------------------
            int NoOfCells_ToExtrapolate       = _ExtrapolateTo.NoOfItemsLocally;
            int NoOfCells_ExtrapolatedInSweep = 1;
            int sweepcnt = 0;

            List <double> scaling            = new List <double>();
            List <int[]>  CellPairs          = new List <int[]>();
            BitArray      cells_mod_in_sweep = new BitArray(J);

            while (true)
            {
                // MPI-parallel evaluation of termination criterion
                // ------------------------------------------------

                int bool_LocalRun  = ((NoOfCells_ToExtrapolate > 0) && (NoOfCells_ExtrapolatedInSweep > 0)) ? 1 : 0;
                int bool_GlobalRun = 0;
                unsafe
                {
                    csMPI.Raw.Allreduce((IntPtr)(&bool_LocalRun), (IntPtr)(&bool_GlobalRun), 1, csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.MAX, csMPI.Raw._COMM.WORLD);
                }

                if (bool_GlobalRun <= 0)
                {
                    // finished on all MPI processors
                    break;
                }

                // MPI-update before local sweep: necessary for consistent result of alg.
                this.MPIExchange();
                if (sweepcnt > 0)
                {
                    ValueIsKnown.MPIExchange(this.GridDat);
                }



                // local work
                // ----------
                if (bool_LocalRun > 0)
                {
                    sweepcnt++;
                    NoOfCells_ExtrapolatedInSweep = 0;

                    scaling.Clear();
                    CellPairs.Clear();

                    cells_mod_in_sweep.SetAll(false);

                    for (int j = 0; j < J; j++)
                    {
                        // determine whether there is something to do for cell 'j' or not ...
                        bool needToKnowSpecies   = NeedToKnowValue[j];
                        bool _mustbeExtrapolated = needToKnowSpecies && !ValueIsKnown[j];

                        if (_mustbeExtrapolated)
                        {
                            // continuation for this cell is needed
                            // ++++++++++++++++++++++++++++++++++++


                            // try to find a neighbour
                            NeighIdx  = CN[j].CloneAs();
                            NoOfNeigh = NeighIdx.Length;
                            int FoundNeighs = 0;
                            for (int nn = 0; nn < NoOfNeigh; nn++)
                            {
                                if (ValueIsKnown[NeighIdx[nn]])
                                {
                                    // bingo
                                    FoundNeighs++;
                                }
                                else
                                {
                                    NeighIdx[nn] = -1; // not usable
                                }
                            }

                            if (FoundNeighs <= 0)
                            {
                                // hope for better luck in next sweep
                                continue;
                            }

                            //Array.Clear(u2, 0, N);

                            for (int nn = 0; nn < NoOfNeigh; nn++)
                            {
                                if (NeighIdx[nn] < 0)
                                {
                                    continue;
                                }

                                int _2 = j;            // cell to extrapolate TO
                                int _1 = NeighIdx[nn]; // cell to extrapolate FROM

                                CellPairs.Add(new int[] { _1, _2 });
                                double ooFoundNeighs = 1.0 / (double)FoundNeighs;
                                scaling.Add(ooFoundNeighs);
                            }

                            cells_mod_in_sweep[j] = true;
                            NoOfCells_ExtrapolatedInSweep++;
                        }
                    }

                    int E = CellPairs.Count;
                    int[,] _CellPairs = new int[E, 2];
                    for (int e = 0; e < E; e++)
                    {
                        _CellPairs.SetRow(e, CellPairs[e]);
                    }

                    double[] preScale = new double[scaling.Count];
                    preScale.SetAll(1.0);

                    this.CellExtrapolation(_CellPairs, scaling, preScale);

                    for (int j = 0; j < J; j++)
                    {
                        if (cells_mod_in_sweep[j] == true)
                        {
                            ValueIsKnown[j] = true;
                        }
                    }

                    NoOfCells_ToExtrapolate -= NoOfCells_ExtrapolatedInSweep;
                }
            }

            // return
            // ------

            return(NoOfCells_ToExtrapolate);
        }
Ejemplo n.º 4
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;
            }
            }
        }