예제 #1
0
        /// <summary>
        /// Creates an array with an tanh spaced distribution of the mean
        /// values between maximum and minimum value of a given cell metric,
        /// e.g., minimal distance between two nodes in a cell <see cref="GridData.CellData.h_min"/>
        /// </summary>
        /// <param name="cellMetric">Given cell metric</param>
        /// <returns>Double[] with the length of the number of given sub-grids></returns>
        private MultidimensionalArray CreateInitialMeans(MultidimensionalArray cellMetric, int numOfClusters)
        {
            System.Diagnostics.Debug.Assert(
                cellMetric.Storage.All(d => double.IsNaN(d) == false),
                "Cell metrics contains f****d up entries");

            double h_min = cellMetric.Min();
            double h_max = cellMetric.Max();

            //Console.WriteLine("Clustering: Create tanh spaced means");

            // Getting global h_min and h_max
            ilPSP.MPICollectiveWatchDog.Watch();
            h_min = h_min.MPIMin();
            h_max = h_max.MPIMax();

            if (h_min == h_max)
            {
                h_max += 0.1 * h_max; // Dirty hack for IBM cases with equidistant grids
            }
            // Tanh Spacing, which yields to more cell cluster for smaller cells
            var means = Grid1D.TanhSpacing(h_min, h_max, numOfClusters, 4.0, true).Reverse().ToArray();

            // Equidistant spacing, in general not the best choice
            //means = GenericBlas.Linspace(h_min, h_max, NumOfSgrd).Reverse().ToArray();

            return(MultidimensionalArray.CreateWrapper(means, numOfClusters));
        }
예제 #2
0
            /// <summary>
            /// true if point <paramref name="pt"/> is inside cell <paramref name="j"/>
            /// </summary>
            public bool IsInCell(double[] pt, int j, double[] pt_Loc = null)
            {
                int D = m_owner.Grid.SpatialDimension;

                if (pt.Length != D)
                {
                    throw new ArgumentException("length must be equal to spatial dimension", "pt");
                }

                MultidimensionalArray _pt       = MultidimensionalArray.CreateWrapper(pt, 1, D); // point to search for
                MultidimensionalArray _pt_local = AllocHelper(ref pt_Loc, D);                    // .. in cell-local coordinate

                bool[] bb = new bool[1];
                this.m_owner.TransformGlobal2Local(_pt, _pt_local, j, bb);

                if (bb[0] == false)
                {
                    return(false);
                }

                for (int d = 0; d < D; d++)
                {
                    if (double.IsInfinity(pt_Loc[d]) || double.IsNaN(pt_Loc[d]))
                    {
                        return(false);
                    }
                }

                return(m_owner.Cells.GetRefElement(j).IsWithin(pt_Loc));
            }
예제 #3
0
        /// <summary>
        /// sets values for <see cref="Cell.CellFaceTags"/> by using a
        /// <paramref name="EdgeTagFunc"/>-function; also adds entries with empty names
        /// to the <see cref="EdgeTagNames"/>-dictionary, if the edge tag
        /// returned by the <paramref name="EdgeTagFunc"/>-function is not in
        /// the dictionary
        /// </summary>
        /// <param name="EdgeTagFunc"></param>
        public void DefineEdgeTags(Func <double[], byte> EdgeTagFunc)
        {
            int D = SpatialDimension;

            double[] x = new double[D];
            MultidimensionalArray GlobalVerticesOut = MultidimensionalArray.CreateWrapper(x, 1, D);

            for (int iEdge = 0; iEdge < m_GridData.iGeomEdges.Count; ++iEdge)
            {
                if (m_GridData.iGeomEdges.IsEdgeBoundaryEdge(iEdge))
                {
                    int jCell = m_GridData.iGeomEdges.CellIndices[iEdge, 0];
                    int iFace = m_GridData.iGeomEdges.FaceIndices[iEdge, 0];
                    var KRef  = m_GridData.iGeomCells.GetRefElement(jCell);

                    m_GridData.TransformLocal2Global(KRef.GetFaceCenter(iFace), GlobalVerticesOut, jCell);
                    byte et = EdgeTagFunc(x);

                    if (!EdgeTagNames.ContainsKey(et))
                    {
                        throw new ArgumentException("unable to find EdgeTagName for EdgeTag = " + et);
                    }
                    m_GridData.iGeomEdges.EdgeTags[iEdge] = et;
                }
            }
        }
예제 #4
0
            /// <summary>
            /// Computes, for point <paramref name="pt"/>, the closest point on
            /// the boundary of cell <paramref name="j"/>.
            /// </summary>
            /// <param name="j">local cell index</param>
            /// <param name="pt">
            /// input; some point in global coordinates.
            /// </param>
            /// <param name="pt_Loc">
            /// output, if unequal null: <paramref name="pt"/> in local
            /// coordinates of cell <paramref name="j"/>.
            /// </param>
            /// <param name="closestPoint_global">
            /// output, if unequal null: within the boundary of cell
            /// <paramref name="j"/>, the closest point to
            /// <paramref name="pt"/>.
            /// </param>
            /// <param name="closestPoint_local">
            /// output, if unequal null: <paramref name="closestPoint_global"/>
            /// in global coordinates.
            /// </param>
            /// <returns>
            /// the distance.
            /// </returns>
            public double ClosestPointInCell(double[] pt, int j, double[] pt_Loc = null, double[] closestPoint_global = null, double[] closestPoint_local = null)
            {
                int D = m_owner.SpatialDimension;

                if (pt.Length != D)
                {
                    throw new ArgumentException("length must be equal to spatial dimension", "pt");
                }

                // point to search for
                MultidimensionalArray _pt = MultidimensionalArray.CreateWrapper(pt, 1, D);

                MultidimensionalArray _pt_local = AllocHelper(ref pt_Loc, D);

                //MultidimensionalArray _closestPoint_local = AllocHelper(ref closestPoint_local, D);

                m_owner.TransformGlobal2Local(_pt, _pt_local, j, null);

                this.GetRefElement(j).ClosestPoint(pt_Loc, closestPoint_local);

                MultidimensionalArray _closestPoint_global = AllocHelper(ref closestPoint_global, D);

                m_owner.TransformLocal2Global(new NodeSet(this.GetRefElement(j), closestPoint_local), _closestPoint_global, j);

                return(GenericBlas.L2Dist(closestPoint_global, pt));
            }
예제 #5
0
        static bool CheckAllBoundaryTagsAre(byte tag, IGridData gridData)
        {
            int D = 2;

            double[] x = new double[D];
            MultidimensionalArray GlobalVerticesOut = MultidimensionalArray.CreateWrapper(x, 1, D);

            for (int iEdge = 0; iEdge < gridData.iGeomEdges.Count; ++iEdge)
            {
                if (gridData.iGeomEdges.IsEdgeBoundaryEdge(iEdge))
                {
                    int jCell = gridData.iGeomEdges.CellIndices[iEdge, 0];
                    int iFace = gridData.iGeomEdges.FaceIndices[iEdge, 0];
                    var KRef  = gridData.iGeomCells.GetRefElement(jCell);

                    gridData.TransformLocal2Global(KRef.GetFaceCenter(iFace), GlobalVerticesOut, jCell);

                    if (gridData.iGeomEdges.EdgeTags[iEdge] != tag)
                    {
                        Console.WriteLine("Did not find boundary with midpoint: " + x[0] + " " + x[1]);
                        return(false);
                    }
                    else
                    {
                        Console.WriteLine("Found boundary with midpoint: " + x[0] + " " + x[1]);
                    }
                }
            }
            return(true);
        }
예제 #6
0
        /// <summary>
        /// evaluation in standard cells (single phase cells)
        /// </summary>
        private void EvaluateStd(int j0, int Len, NodeSet NodeSet, MultidimensionalArray result, int ResultCellindexOffset, double ResultPreScale, EvaluateInternalSignature EvalFunc)
        {
            int M = this.Basis.NonX_Basis.Length;
            int K = NodeSet.NoOfNodes;        // number of nodes

            Debug.Assert(result.GetLength(1) == K, "rank 1 is assumed to correlate with node set");

            double[] CoördBase = m_Coordinates.m_BaseStorage;
            var      Coörd     = MultidimensionalArray.CreateWrapper(CoördBase, this.GridDat.iLogicalCells.NoOfCells, M);

            var C = Coörd.ExtractSubArrayShallow(new int[] { j0, 0 }, new int[] { j0 + Len - 1, M - 1 });

            int LL = result.Dimension;

            int[] I0 = new int[LL], IE = new int[LL];
            I0[0] = ResultCellindexOffset;
            I0[1] = 0;
            IE[0] = ResultCellindexOffset + Len - 1;
            IE[1] = K - 1;
            for (int ll = 2; ll < LL; ll++)
            {
                I0[ll] = 0;
                IE[ll] = result.GetLength(ll) - 1;
            }

            var resAcc = result.ExtractSubArrayShallow(I0, IE);

            EvalFunc(j0, Len, NodeSet,
                     this.Basis.NonX_Basis,
                     C, resAcc, ResultPreScale);
        }
예제 #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="FLSproperty"></param>
        internal void setMaterialInterfacePoints(double[] FLSproperty)
        {
            //center = MultidimensionalArray.CreateWrapper(FLSproperty.GetSubVector(0, 2), new int[] { 1, 2 });
            switch (FourierEvolve)
            {
            case Fourier_Evolution.MaterialPoints:
                int numSp = FLSproperty.Length / 2;
                current_interfaceP = MultidimensionalArray.CreateWrapper(FLSproperty, new int[] { numSp, 2 });
                break;

            case Fourier_Evolution.FourierPoints:
                center         = MultidimensionalArray.CreateWrapper(FLSproperty.GetSubVector(0, 2), new int[] { 1, 2 });
                current_samplP = FLSproperty.GetSubVector(2, numFp);
                for (int p = 0; p < numFp; p++)
                {
                    current_interfaceP[p, 0] = current_samplP[p] * Math.Cos(FourierP[p]) + center[0, 0];
                    current_interfaceP[p, 1] = current_samplP[p] * Math.Sin(FourierP[p]) + center[0, 1];
                }
                break;

            case Fourier_Evolution.FourierModes:
                center = MultidimensionalArray.CreateWrapper(FLSproperty.GetSubVector(0, 2), new int[] { 1, 2 });
                for (int sp = 0; sp < numFp; sp++)
                {
                    DFT_coeff[sp] = new Complex(FLSproperty[2 + (sp * 2)], FLSproperty[2 + (sp * 2) + 1]);
                }
                SmoothSamplePoints();
                for (int sp = 0; sp < numFp; sp++)
                {
                    current_interfaceP[sp, 0] = center[0, 0] + current_samplP[sp] * Math.Cos(FourierP[sp]);
                    current_interfaceP[sp, 1] = center[0, 1] + current_samplP[sp] * Math.Sin(FourierP[sp]);
                }
                break;
            }
        }
예제 #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="_NoOfCells"></param>
        /// <param name="_Nmin"></param>
        /// <param name="_Nmax"></param>
        internal FieldStorage(int _NoOfCells, int _Nmin, int _Nmax)
        {
            m_NMin      = _Nmin;
            m_NoOfCells = _NoOfCells;
            m_NMax      = _Nmax;

            m_BaseStorage     = new double[m_NMin * m_NoOfCells];
            BaseStorageMda    = MultidimensionalArray.CreateWrapper(m_BaseStorage, m_NoOfCells, m_NMin);
            m_ExtendedStorage = new double[NoOfCells][];
        }
예제 #9
0
        public static NodeSet GetLocalNodeSet(GridData gridData, double[] globalPoint, int globalCellIndex)
        {
            int D = 2;
            MultidimensionalArray GlobalVerticesIn = MultidimensionalArray.CreateWrapper(globalPoint, 1, D);
            MultidimensionalArray LocalVerticesOut = MultidimensionalArray.CreateWrapper(new double[D], 1, D);

            gridData.TransformGlobal2Local(GlobalVerticesIn, LocalVerticesOut, globalCellIndex, NewtonConvergence: null);

            return(new NodeSet(gridData.Cells.GetRefElement(globalCellIndex), LocalVerticesOut));
        }
예제 #10
0
        /// <summary>
        /// Affine-linear flux function on a border edge; Boundary conditions
        /// are implemented here. An affine-linear flux must implemented as a
        /// matrix and an offset vector: The linear border flux, in a
        /// mathematical notation is defined as BorderFlux(U) =
        /// M_in*U + b, where U is a column vector containing function values
        /// of other fields. Which fields in which order is specified by
        /// <see cref="IEquationComponent.ArgumentOrdering" /> property. In
        /// this implementation, the resulting flux solely depends on the
        /// implementation of <see cref="INonlinearFlux.BorderEdgeFlux"/> that
        /// has been supplied to the constructor.
        /// </summary>
        /// <param name="inp">
        /// A set of input parameters such as time, coordinate and values of
        /// parameters. Given as reference for performance reasons; DO NOT
        /// WRITE to this structure.</param>
        /// <param name="Uin"></param>
        protected override double BorderEdgeFlux(ref CommonParamsBnd inp, double[] Uin)
        {
            MultidimensionalArray refFlux = MultidimensionalArray.Create(1, 1);

            baseFlux.BorderEdgeFlux(
                0.0,
                inp.iEdge,
                MultidimensionalArray.CreateWrapper(inp.X, 1, 1, inp.D),
                MultidimensionalArray.CreateWrapper(inp.Normal, 1, inp.D),
                false,
                new byte[] { inp.EdgeTag },
                0,
                inp.Parameters_IN.Select(p =>
                                         MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                0,
                1,
                refFlux);

            double[] FunctionMatrix = new double[inp.Parameters_IN.Length];
            for (int i = 0; i < inp.Parameters_IN.Length; i++)
            {
                double[] perturbedParameters = inp.Parameters_IN.CloneAs();
                double   stepSize            = GetStepSize(perturbedParameters[i]);
                perturbedParameters[i] += stepSize;

                MultidimensionalArray perturbedFlux = MultidimensionalArray.Create(1, 1);
                baseFlux.BorderEdgeFlux(
                    0.0,
                    inp.iEdge,
                    MultidimensionalArray.CreateWrapper(inp.X, 1, 1, inp.D),
                    MultidimensionalArray.CreateWrapper(inp.Normal, 1, inp.D),
                    false,
                    new byte[] { inp.EdgeTag },
                    0,
                    perturbedParameters.Select(p =>
                                               MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    0,
                    1,
                    perturbedFlux);

                FunctionMatrix[i] = (perturbedFlux[0, 0] - refFlux[0, 0]) / stepSize;
            }

            double result = refFlux[0, 0];

            for (int i = 0; i < inp.Parameters_IN.Length; i++)
            {
                result += FunctionMatrix[i] * (Uin[i] - inp.Parameters_IN[i]);
            }
            return(result);
        }
예제 #11
0
        public void Remap()
        {
            byte[] tags = { 1, 181, 1, 181 };
            SortedList <byte, string> tagNames = new SortedList <byte, string>(2)
            {
                { 181, "Periodic-X" },
                { 1, "bondary" }
            };

            VoronoiBoundary gridBoundary = new VoronoiBoundary
            {
                Polygon      = GridShapes.Rectangle(2, 2),
                EdgeTags     = tags,
                EdgeTagNames = tagNames
            };

            double[] positions = new double[]
            {
                -0.64874644688322713,
                0.83818004313993111,
                -0.39475947428553138,
                0.23663302374998896,
                0.58922918492853482,
                0.83854511946848365,
                -0.811382461267156,
                -0.4159610860057516,
                -0.19666215667077264,
                -0.24376388607043981,
                0.3385324063754323,
                0.086134041417832763,
                0.80498108279434089,
                0.22350558445791927,
                -0.68131747598283521,
                -0.87257764806623139,
                0.48863086193005234,
                -0.51183362983054159,
                0.99309783411349173,
                -0.10141430352239808,
            };
            MultidimensionalArray nodes = MultidimensionalArray.CreateWrapper(positions, 10, 2);

            for (int i = 0; i < 10; ++i)
            {
                nodes[i, 0] += 0.01;
            }

            VoronoiGrid grid = VoronoiGrid2D.Polygonal(nodes, gridBoundary, 0, 0);

            Plotter.Plot(grid);
        }
예제 #12
0
        /// <summary>
        /// First order approximation of  delta >= sup_x|psi(x) - psi(x_center)|
        /// </summary>
        /// <param name="Arg"></param>
        /// <param name="psi"></param>
        /// <param name="x_center"></param>
        /// <param name="cell"></param>
        /// <returns></returns>
        protected override double EvaluateBounds(LinearSayeSpace <Cube> Arg, LinearPSI <Cube> psi, NodeSet x_center, int cell)
        {
            double[] arr = new double[RefElement.SpatialDimension];
            Arg.Diameters.CopyTo(arr, 0);
            psi.SetInactiveDimsToZero(arr);
            MultidimensionalArray diameters = MultidimensionalArray.CreateWrapper(arr, 3);

            NodeSet nodeOnPsi          = psi.ProjectOnto(x_center);
            MultidimensionalArray grad = ReferenceGradient(nodeOnPsi, cell);

            grad.ApplyAll(x => Math.Abs(x));
            double delta = grad.InnerProduct(diameters);

            return(delta);
        }
예제 #13
0
        protected override bool HeightDirectionIsSuitable(SayeSquare arg, LinearPSI <Square> psi, NodeSet x_center,
                                                          int heightDirection, MultidimensionalArray gradient, int cell)
        {
            //Determine bounds
            //-----------------------------------------------------------------------------------------------------------------
            double[] arr = arg.Diameters;
            psi.SetInactiveDimsToZero(arr);
            MultidimensionalArray diameters = MultidimensionalArray.CreateWrapper(arr, new int[] { 2, 1 });

            NodeSet nodeOnPsi             = psi.ProjectOnto(x_center);
            MultidimensionalArray hessian = lsData.GetLevelSetReferenceHessian(nodeOnPsi, cell, 1);

            hessian = hessian.ExtractSubArrayShallow(new int[] { 0, 0, -1, -1 });

            MultidimensionalArray jacobian = grid.InverseJacobian.GetValue_Cell(nodeOnPsi, cell, 1);

            jacobian = jacobian.ExtractSubArrayShallow(new int[] { 0, 0, -1, -1 });
            hessian  = jacobian * hessian;

            hessian.ApplyAll(x => Math.Abs(x));

            //abs(Hessian) * diameters = delta
            MultidimensionalArray delta = hessian * diameters;

            delta = delta.ExtractSubArrayShallow(new int[] { -1, 0 });

            //Check if suitable
            //-----------------------------------------------------------------------------------------------------------------

            //|gk| > δk
            if (Math.Abs(gradient[heightDirection]) > delta[heightDirection])
            {
                bool suitable = true;
                // Sum_j( g_j + delta_j)^2 / (g_k - delta_k)^2 < 20
                double sum = 0;

                for (int j = 0; j < delta.Length; ++j)
                {
                    sum += Math.Pow(gradient[j] + delta[j], 2);
                }
                sum /= Math.Pow(gradient[heightDirection] - delta[heightDirection], 2);

                suitable &= sum < 20;

                return(suitable);
            }
            return(false);
        }
예제 #14
0
        /// <summary>
        /// First order approximation of  delta >= sup_x|psi(x) - psi(x_center)|
        /// </summary>
        /// <param name="Arg"></param>
        /// <param name="psi"></param>
        /// <param name="x_center"></param>
        /// <param name="cell"></param>
        /// <returns></returns>
        protected override double EvaluateBounds(SayeSquare Arg, LinearPSI <Square> psi, NodeSet x_center, int cell)
        {
            double[] arr = new double[Arg.Dimension];
            Arg.Diameters.CopyTo(arr, 0);
            psi.SetInactiveDimsToZero(arr);
            MultidimensionalArray diameters = MultidimensionalArray.CreateWrapper(arr, new int[] { 2 });

            NodeSet nodeOnPsi = psi.ProjectOnto(x_center);


            MultidimensionalArray grad = ScaledReferenceGradient(nodeOnPsi, cell);

            grad.ApplyAll(x => Math.Abs(x));
            double delta = grad.InnerProduct(diameters) * sqrt_2;

            return(delta);
        }
예제 #15
0
        /// <summary>
        /// The linear flux of the underlying PDE, expressed as F(U) =
        /// M * U + n. The flux may depend on the space
        /// variable <see cref="CommonParamsVol.Xglobal"/> and on the field
        /// values of <see cref="CommonParamsVol.Parameters" /> that can
        /// be defined in <see cref="IEquationComponent.ParameterOrdering" />.
        /// In this implementation, the resulting flux solely depends on the
        /// implementation of <see cref="INonlinearFlux.Flux"/> that
        /// has been supplied to the constructor.
        /// </summary>
        /// <param name="inp"></param>
        /// <param name="U"></param>
        /// <param name="output"></param>
        protected override void Flux(ref CommonParamsVol inp, double[] U, double[] output)
        {
            MultidimensionalArray refFlux = MultidimensionalArray.Create(1, 1, inp.D);

            baseFlux.Flux(
                0.0,
                MultidimensionalArray.CreateWrapper(inp.Xglobal, 1, 1, inp.D),
                inp.Parameters.Select(p =>
                                      MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                0,
                1,
                refFlux);

            double[,] FunctionMatrix = new double[inp.D, inp.Parameters.Length];
            for (int i = 0; i < inp.Parameters.Length; i++)
            {
                double[] perturbedParameters = inp.Parameters.CloneAs();
                double   stepSize            = GetStepSize(perturbedParameters[i]);
                perturbedParameters[i] += stepSize;

                MultidimensionalArray perturbedFlux = MultidimensionalArray.Create(1, 1, inp.D);
                baseFlux.Flux(
                    0.0,
                    MultidimensionalArray.CreateWrapper(inp.Xglobal, 1, 1, inp.D),
                    perturbedParameters.Select(p =>
                                               MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    0,
                    1,
                    perturbedFlux);

                for (int d = 0; d < inp.D; d++)
                {
                    FunctionMatrix[d, i] = (perturbedFlux[0, 0, d] - refFlux[0, 0, d]) / stepSize;
                }
            }

            for (int d = 0; d < inp.D; d++)
            {
                output[d] = refFlux[0, 0, d];
                for (int i = 0; i < inp.Parameters.Length; i++)
                {
                    output[d] += FunctionMatrix[d, i] * (U[i] - inp.Parameters[i]);
                }
            }
        }
예제 #16
0
            /// <summary>
            /// Helper for safely allocating a wrapped double array.
            /// </summary>
            /// <param name="pt_Loc"></param>
            /// <param name="D"></param>
            /// <returns></returns>
            private static MultidimensionalArray AllocHelper(ref double[] pt_Loc, int D)
            {
                if (pt_Loc != null)
                {
                    if (pt_Loc.Length != D)
                    {
                        throw new ArgumentException();
                    }
                }
                else
                {
                    pt_Loc = new double[D];
                }
                MultidimensionalArray _pt_local = MultidimensionalArray.CreateWrapper(
                    pt_Loc, 1, D); // .. in cell-local coordinate

                return(_pt_local);
            }
예제 #17
0
        private MultidimensionalArray ReadVariableValues(string variableName)
        {
            List <double> list = new List <double>();

            using (var stream = new BinaryReader(new FileStream(variableName + ".dbl", FileMode.Open), Encoding.ASCII)) {
                while (stream.PeekChar() != -1)
                {
                    list.Add(stream.ReadDouble());
                }
            }

            int noOfNodesX = noOfCellsX * (noOfNodesPerEdge - 1) + 1;
            int noOfNodesY = aspectRatio * noOfCellsX * (noOfNodesPerEdge - 1) + 1;

            Debug.Assert(noOfNodesX * noOfNodesY == list.Count);

            return(MultidimensionalArray.CreateWrapper(
                       list.ToArray(), noOfNodesY, noOfNodesX));
        }
예제 #18
0
        /*
         * /// <summary>
         * /// Comparison of reference data
         * /// </summary>
         * public (double[] AbsL2Errors, double[] RelL2Errors) Compare() {
         *  if(GridDat.MpiSize == ReferenceMPISize) {
         *      int N = m_CurrentData.Count;
         *      return (new double[N], new double[N]);
         *
         *  } else {
         *
         *
         *
         *      int D = this.GridDat.SpatialDimension;
         *
         *
         *      double[] AbsErrors = null;
         *      double[] RelErrors = null;
         *
         *      double[][] ReferenceData;
         *
         *      if(G.MpiRank == 0) {
         *
         *
         *
         *
         *
         *          AbsErrors = new double[infoFunc.Length];
         *          RelErrors = new double[infoFunc.Length];
         *
         *          if(!GatheredData.GlobalID.ListEquals(table["GlobalID"] as IEnumerable<long>))
         *              throw new IOException("Mismatch in GlobalID list - unable to compare.");
         *
         *          for(int d = 0; d < D; d++) {
         *              IEnumerable<double> Coord_d_ref = table[ColName_Coörd(d)] as IEnumerable<double>;
         *              IEnumerable<double> Coord_d = GatheredData.DataColumns[d];
         *
         *              double AbsErr = Coord_d.L2Distance(Coord_d_ref);
         *              double MaxL2 = Math.Max(Coord_d.L2Norm(), Coord_d_ref.L2Norm());
         *              double RelErr = AbsErr / MaxL2;
         *              if(RelErr > BLAS.MachineEps.Sqrt())
         *                  throw new IOException("Mismatch for cell center coordinates - unable to compare.");
         *
         *          }
         *
         *          double[][] Rank0Data = new double[infoFunc.Length][];
         *          if(ComparisonFile != null) {
         *              Dictionary<string, System.Collections.IEnumerable> CompTable = new Dictionary<string, System.Collections.IEnumerable>();
         *              CompTable.Add("GlobalID", GatheredData.GlobalID);
         *              for(int d = 0; d < D; d++) {
         *                  CompTable.Add(ColName_Coörd(d), table[ColName_Coörd(d)]);
         *              }
         *
         *              for(int iCol = D; iCol < infoFunc.Length + D; iCol++) {
         *                  string colname = "Col" + (iCol - D);
         *                  IEnumerable<double> Ref = table[colname] as IEnumerable<double>;
         *                  IEnumerable<double> Cur = GatheredData.DataColumns[iCol];
         *                  double[] Err = Cur.ToArray().CloneAs();
         *                  Err.AccV(-1.0, Ref.ToArray());
         *
         *                  CompTable.Add(colname + "(REF)", Ref);
         *                  CompTable.Add(colname + "(CUR)", Cur);
         *                  CompTable.Add(colname + "(ERR)", Err);
         *
         *                  Rank0Data[iCol] = Ref.ToArray();
         *              }
         *
         *              CompTable.SaveToCSVFile(ComparisonFile);
         *          }
         *
         *          Debug.Assert(infoFunc.Length + D == GatheredData.DataColumns.Length);
         *
         *          for(int iCol = D; iCol < infoFunc.Length + D; iCol++) {
         *              IEnumerable<double> Coord_d_comp = table["Col" + (iCol - D)] as IEnumerable<double>;
         *              IEnumerable<double> Coord_d = GatheredData.DataColumns[iCol];
         *
         *              double AbsErr = Coord_d.L2Distance(Coord_d_comp);
         *              double MaxL2 = Math.Max(Coord_d.L2Norm(), Coord_d_comp.L2Norm());
         *              double RelErr = AbsErr / MaxL2;
         *
         *              AbsErrors[iCol - D] = AbsErr;
         *              RelErrors[iCol - D] = RelErr;
         *          }
         *
         *          ReferenceData = ScatterSortedData(G, Rank0Data);
         *
         *      } else {
         *          ReferenceData = ScatterSortedData(G, null);
         *      }
         *
         *
         *      AbsErrors = AbsErrors.MPIBroadcast(0, G.CellPartitioning.MPI_Comm);
         *      RelErrors = RelErrors.MPIBroadcast(0, G.CellPartitioning.MPI_Comm);
         *      return (AbsErrors, RelErrors, ReferenceData);
         *  }
         * }
         */


        /// <summary>
        ///
        /// </summary>
        public void AddVector(string ColName, IEnumerable <double> data)
        {
            int J = this.GridDat.iLogicalCells.NoOfLocalUpdatedCells;
            int L = data.Count();
            int K = L / J;


            if (J * K != L || K < 1)
            {
                throw new ArgumentException("wrong length of input vector");
            }
            if (L == 1)
            {
                m_CurrentData.Add(ColName, data.ToArray());
            }
            else
            {
                var M = MultidimensionalArray.CreateWrapper(data.ToArray(), J, K);
                for (int k = 0; k < K; k++)
                {
                    m_CurrentData.Add(ColName + "-k" + k, M.GetColumn(k));
                }
            }
        }
예제 #19
0
        /// <summary>
        /// Computes Cell-volumes and edge areas before agglomeration.
        /// </summary>
        void ComputeNonAgglomeratedMetrics()
        {
            using (new FuncTrace()) {
                MPICollectiveWatchDog.Watch();
                var         gd      = XDGSpaceMetrics.GridDat;
                int         JE      = gd.iLogicalCells.Count;
                int         J       = gd.iLogicalCells.NoOfLocalUpdatedCells;
                int         D       = gd.SpatialDimension;
                int         EE      = gd.Edges.Count;
                SpeciesId[] species = this.SpeciesList.ToArray();
                int         NoSpc   = species.Count();
                int[,] E2C = gd.iLogicalEdges.CellIndices;

                var schH = new XQuadSchemeHelper(XDGSpaceMetrics);


                // collect all per-cell-metrics in the same MultidimArry, for MPI-exchange (only 1 exchange instead of three, saving some overhead)
                // 1st index: cell
                // 2nd index: species
                // 3rd index: 0 for interface surface per cell, 1 for cut-cell-volume, 2 for cut-cell surface
                double[] vec_cellMetrics          = new double[JE * NoSpc * 3];
                MultidimensionalArray cellMetrics = MultidimensionalArray.CreateWrapper(vec_cellMetrics, JE, NoSpc, 3);

                this.CutEdgeAreas   = new Dictionary <SpeciesId, MultidimensionalArray>();
                this.CutCellVolumes = new Dictionary <SpeciesId, MultidimensionalArray>();
                this.InterfaceArea  = new Dictionary <SpeciesId, MultidimensionalArray>();
                this.CellSurface    = new Dictionary <SpeciesId, MultidimensionalArray>();

                //var schS = new List<CellQuadratureScheme>();
                //var rulz = new List<ICompositeQuadRule<QuadRule>>();


                // edges and volumes
                // =================
                for (int iSpc = 0; iSpc < species.Length; iSpc++)
                {
                    var cellVol = cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1);
                    var spc     = species[iSpc];


                    // compute cut edge area
                    // ---------------------
                    MultidimensionalArray edgArea = MultidimensionalArray.Create(EE);
                    this.CutEdgeAreas.Add(spc, edgArea);

                    var edgeScheme = schH.GetEdgeQuadScheme(spc);
                    var edgeRule   = edgeScheme.Compile(gd, this.CutCellQuadratureOrder);

                    BoSSS.Foundation.Quadrature.EdgeQuadrature.GetQuadrature(
                        new int[] { 1 }, gd,
                        edgeRule,
                        _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                    {
                        EvalResult.SetAll(1.0);
                    },
                        _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                    {
                        for (int i = 0; i < Length; i++)
                        {
                            int iEdge = i + i0;
                            Debug.Assert(edgArea[iEdge] == 0);
                            edgArea[iEdge] = ResultsOfIntegration[i, 0];
                            Debug.Assert(!(double.IsNaN(edgArea[iEdge]) || double.IsInfinity(edgArea[iEdge])));
                        }
                    }).Execute();

                    // sum up edges for surface
                    // ------------------------

                    var cellSurf = cellMetrics.ExtractSubArrayShallow(-1, iSpc, 2);

                    for (int e = 0; e < EE; e++)
                    {
                        double a      = edgArea[e];
                        int    jCell0 = E2C[e, 0];
                        int    jCell2 = E2C[e, 1];
                        cellSurf[jCell0] += a;
                        if (jCell2 >= 0)
                        {
                            cellSurf[jCell2] += a;
                        }
                    }

                    // compute cut cell volumes
                    // ------------------------

                    var volScheme = schH.GetVolumeQuadScheme(spc);
                    var volRule   = volScheme.Compile(gd, this.CutCellQuadratureOrder);

                    BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                        new int[] { 1 }, gd,
                        volRule,
                        _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                    {
                        EvalResult.SetAll(1.0);
                    },
                        _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                    {
                        for (int i = 0; i < Length; i++)
                        {
                            int jCell = i + i0;
                            Debug.Assert(cellVol[jCell] == 0);
                            cellVol[jCell] = ResultsOfIntegration[i, 0];
                            Debug.Assert(!(double.IsNaN(cellVol[jCell]) || double.IsInfinity(cellVol[jCell])));
                        }
                    }).Execute();
                }


                // interface surface
                // =================

                // loop over level-sets
                if (species.Length > 0)
                {
                    // find domain of all species:
                    CellMask SpeciesCommonDom = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[0]);
                    for (int iSpc = 1; iSpc < species.Length; iSpc++)
                    {
                        SpeciesCommonDom = SpeciesCommonDom.Union(XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[iSpc]));
                    }
                    BitArray[] SpeciesBitMask = species.Select(spc => XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(spc).GetBitMask()).ToArray();

                    int NoOfLs  = XDGSpaceMetrics.NoOfLevelSets;
                    int NoOfSpc = species.Length;
                    for (int iLevSet = 0; iLevSet < NoOfLs; iLevSet++)
                    {
                        var LsDom          = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet);
                        var IntegrationDom = LsDom.Intersect(SpeciesCommonDom);

                        //if (IntegrationDom.NoOfItemsLocally > 0) { -> Doesn't work if Bjoerns HMF is used, eds up in an mpi dead lock
                        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                        // this level-set is actually relevant for someone in 'species'
                        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                        CellQuadratureScheme SurfIntegration = schH.GetLevelSetquadScheme(iLevSet, IntegrationDom);
                        var rule = SurfIntegration.Compile(gd, this.CutCellQuadratureOrder);

                        BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                            new int[] { 1 }, gd,
                            rule,
                            _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                            EvalResult.SetAll(1.0);
                        },
                            _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                            for (int i = 0; i < Length; i++)
                            {
                                int jCell = i + i0;



                                //if (cellMetrics[jCell, iSpcA, 0] != 0.0)
                                //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
                                //if (cellMetrics[jCell, iSpcB, 0] != 0.0)
                                //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");

                                //cellMetrics[jCell, iSpcA, 0] = ResultsOfIntegration[i, 0];
                                //cellMetrics[jCell, iSpcB, 0] = ResultsOfIntegration[i, 0];


                                for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)
                                {
                                    if (SpeciesBitMask[iSpc][jCell])
                                    {
                                        cellMetrics[jCell, iSpc, 0] += ResultsOfIntegration[i, 0];
                                        Debug.Assert(!(double.IsNaN(cellMetrics[jCell, iSpc, 0]) || double.IsInfinity(cellMetrics[jCell, iSpc, 0])));
                                    }
                                }
                            }
                        }).Execute();
                        //}
                    }
                }

                // MPI exchange & store
                // ====================

                if (species.Length > 0)
                {
#if DEBUG
                    int NoOfSpc       = species.Length;
                    var cellMetricsB4 = cellMetrics.ExtractSubArrayShallow(new[] { 0, 0, 0 }, new[] { J - 1, NoOfSpc - 1, 1 }).CloneAs();
#endif
                    vec_cellMetrics.MPIExchange(gd);
#if DEBUG
                    var cellMetricsComp = cellMetrics.ExtractSubArrayShallow(new[] { 0, 0, 0 }, new[] { J - 1, NoOfSpc - 1, 1 }).CloneAs();
                    cellMetricsComp.Acc(-1.0, cellMetricsB4);
                    Debug.Assert(cellMetricsComp.L2Norm() == 0.0);
#endif
                }
                for (int iSpc = 0; iSpc < species.Length; iSpc++)
                {
                    var spc = species[iSpc];
                    this.InterfaceArea.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 0).CloneAs());
                    this.CutCellVolumes.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1).CloneAs());
                    this.CellSurface.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 2).CloneAs());

                    this.CellSurface[spc].Acc(1.0, this.InterfaceArea[spc]);
                }
            }
        }
예제 #20
0
        /// <summary>
        /// sets values for <see cref="Cell.CellFaceTags"/> by using a
        /// <paramref name="EdgeTagFunc"/>-function; also adds entries with empty names
        /// to the <see cref="EdgeTagNames"/>-dictionary, if the edge tag
        /// returned by the <paramref name="EdgeTagFunc"/>-function is not in
        /// the dictionary
        /// </summary>
        static public void DefineEdgeTags(this IGrid g, Func <Vector, string> EdgeTagFunc, params string[] EdgeTagNamesToEnsure)
        {
            int D = g.SpatialDimension;

            double[] x = new double[D];
            MultidimensionalArray GlobalVerticesOut = MultidimensionalArray.CreateWrapper(x, 1, D);

            Dictionary <string, byte> EdgeTagNames_Reverse = new Dictionary <string, byte>();

            EdgeTagNames_Reverse.Add("inner edge", 0);
            int[] etUseCount = new int[byte.MaxValue];
            foreach (var kv in g.EdgeTagNames)
            {
                if (kv.Key == 0)
                {
                }
                else
                {
                    EdgeTagNames_Reverse.Add(kv.Value, kv.Key);

                    if (kv.Key >= GridCommons.FIRST_PERIODIC_BC_TAG)
                    {
                        etUseCount[kv.Key] = 1;
                    }
                }
            }



            GridCommons baseGrid = null;

            if (g is GridCommons gcm)
            {
                baseGrid = gcm;
            }
            else if (g is Aggregation.AggregationGrid ag)
            {
                baseGrid = ag.RootGrid as GridCommons;
            }
            var GrdDatTmp = g.iGridData;

            // loop over edges...
            bool LoopOverEdges(Func <int, int, int, byte> GetEt)
            {
                bool _GridChanged = false;
                int  NoOfEdges    = GrdDatTmp.iGeomEdges.Count;

                for (int iEdge = 0; iEdge < NoOfEdges; ++iEdge)
                {
                    if (GrdDatTmp.iGeomEdges.IsEdgeBoundaryEdge(iEdge))
                    {
                        int jCell = GrdDatTmp.iGeomEdges.CellIndices[iEdge, 0];
                        int iFace = GrdDatTmp.iGeomEdges.FaceIndices[iEdge, 0];

                        // get edge tag
                        byte et = GetEt(iEdge, jCell, iFace);

                        // record edge tag
                        if (baseGrid != null)
                        {
                            var _Cell   = baseGrid.Cells[jCell];
                            var allCFTs = _Cell.CellFaceTags;
                            int found   = 0;
                            if (allCFTs != null)
                            {
                                for (int i = 0; i < allCFTs.Length; i++)
                                {
                                    if (allCFTs[i].NeighCell_GlobalID < 0 && allCFTs[i].FaceIndex == iFace)
                                    {
                                        found++;
                                        if (allCFTs[i].EdgeTag == et)
                                        {
                                            // nop
                                        }
                                        else
                                        {
                                            allCFTs[i].EdgeTag = et;
                                            _GridChanged       = true;
                                        }
                                    }
                                }
                            }

                            if (found > 1)
                            {
                                throw new ApplicationException(string.Format("Cell face tags inconsistent in cell (GlId={0},LocIdx={1}): found {2} boundary tags for face {3}.", _Cell.GlobalID, jCell, found, iFace));
                            }
                            if (found <= 0)
                            {
                                CellFaceTag CFT = new CellFaceTag()
                                {
                                    EdgeTag            = et,
                                    FaceIndex          = iFace,
                                    NeighCell_GlobalID = long.MinValue
                                };

                                CFT.AddToArray(ref baseGrid.Cells[jCell].CellFaceTags);
                                _GridChanged = true;
                            }
                        }
                        GrdDatTmp.iGeomEdges.EdgeTags[iEdge] = et;

                        etUseCount[et]++;
                    }
                }

                return(_GridChanged);
            }

            byte RecordTag(int iedge, int jCell, int iFace)
            {
                var KRef = GrdDatTmp.iGeomCells.GetRefElement(jCell);

                // call edge-tag-name function
                GrdDatTmp.TransformLocal2Global(KRef.GetFaceCenter(iFace), GlobalVerticesOut, jCell);
                string EdgeTagName = EdgeTagFunc(x);

                // obtain edge tag
                if (!EdgeTagNames_Reverse.ContainsKey(EdgeTagName))
                {
                    int NewTag = EdgeTagNames_Reverse.Count;
                    Debug.Assert(NewTag > 0);
                    if (NewTag >= GridCommons.FIRST_PERIODIC_BC_TAG)
                    {
                        throw new ApplicationException("To many different edge tag names; at maximum " + (Classic.GridCommons.FIRST_PERIODIC_BC_TAG - 1) + " different tags for non-periodic boundaries.");
                    }
                    EdgeTagNames_Reverse.Add(EdgeTagName, (byte)NewTag);
                }
                var et = EdgeTagNames_Reverse[EdgeTagName];

                return(et);
            }

            // pass 1: assign edge tags locally
            bool GridChanged = LoopOverEdges(RecordTag);

            GridChanged = GridChanged.MPIOr();



            // pass 2: MPI syncronization
            if (GridChanged && g.Size > 1)
            {
                byte[] ETTranslation = SyncEdgeTagsOverMPI(EdgeTagNames_Reverse);
                if (ETTranslation != null)
                {
                    LoopOverEdges(delegate(int iedge, int jCell, int iFace) {
                        byte oldEt = GrdDatTmp.iGeomEdges.EdgeTags[iedge];
                        byte newEt = ETTranslation[oldEt];
                        return(newEt);
                    });
                }
            }


            // store & return
            etUseCount = etUseCount.MPISum();
            g.EdgeTagNames.Clear();
            foreach (var kv in EdgeTagNames_Reverse)
            {
                if (kv.Value == 0 || etUseCount[kv.Value] > 0)
                {
                    g.EdgeTagNames.Add(kv.Value, kv.Key);
                }
            }

            if (GridChanged)
            {
                g.InvalidateGridData();
                Console.WriteLine("Grid Edge Tags changed.");
            }

            foreach (string EdgeTagName in EdgeTagNamesToEnsure)
            {
                g.AddEdgeTag(EdgeTagName);
            }
        }
예제 #21
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="current_FLSproperty"></param>
        public override void EvolveFourierLS(ref double[] current_FLSproperty)
        {
            switch (FourierEvolve)
            {
            case Fourier_Evolution.MaterialPoints:
                current_interfaceP = MultidimensionalArray.CreateWrapper(current_FLSproperty, new int[] { numFp, 2 });
                //Reseeding();
                RearrangeOntoPeriodicDomain(current_interfaceP);
                // interpolation onto the equidistant Fourier points
                InterpolateOntoFourierPoints(current_interfaceP, current_samplP);
                //setProjectingFourierModes();
                setDFTcoeff();
                SmoothSamplePoints();

                current_FLSproperty = new double[numFp * 2];
                for (int sp = 0; sp < numFp; sp++)
                {
                    current_interfaceP[sp, 0]         = FourierP[sp];
                    current_interfaceP[sp, 1]         = current_samplP[sp];
                    current_FLSproperty[sp * 2]       = current_interfaceP[sp, 0];
                    current_FLSproperty[(sp * 2) + 1] = current_interfaceP[sp, 1];
                }

                break;

            case Fourier_Evolution.FourierPoints:
                current_samplP = current_FLSproperty;
                // set material points on Fourier points
                for (int p = 0; p < numFp; p++)
                {
                    current_interfaceP[p, 1] = current_samplP[p];
                }
                setDFTcoeff();
                break;

            case Fourier_Evolution.FourierModes:
                for (int sp = 0; sp < numFp; sp++)
                {
                    DFT_coeff[sp] = new Complex(current_FLSproperty[sp * 2], current_FLSproperty[sp * 2 + 1]);
                }
                // project onto Fourier points
                for (int fp = 0; fp < numFp; fp++)
                {
                    if (mode == -1)
                    {
                        //constant values
                        current_samplP[fp] = DFT_coeff[0].Real;
                        if (cf_end == numFp / 2)
                        {
                            current_samplP[fp] += Complex.Multiply(DFT_coeff[numFp / 2],
                                                                   Complex.Exp(Complex.Multiply(Complex.ImaginaryOne, FourierP[fp] * (2 * Math.PI / DomainSize) * (numFp / 2)))
                                                                   ).Real;
                        }
                        for (int cf = 1; cf < cf_end; cf++)
                        {
                            Complex cmplx_res = DFT_coeff[cf] * Complex.Exp(Complex.Multiply(Complex.ImaginaryOne, FourierP[fp] * (2 * Math.PI / DomainSize) * cf));
                            current_samplP[fp] += 2.0 * cmplx_res.Real;      //-f(x) for  k=1... numSp/2-1 , values for k=numSp/2+1...k= numSp-1 are complex conjugated, thus the same real part
                        }
                    }
                    else
                    {
                        if (mode == 0)
                        {
                            current_samplP[fp] += DFT_coeff[0].Real;
                        }
                        else
                        {
                            current_samplP[fp] += Complex.Multiply(DFT_coeff[mode], Complex.Exp(Complex.Multiply(Complex.ImaginaryOne, FourierP[fp] * (2 * Math.PI / DomainSize) * mode))).Real;
                        }
                        if (mode > 0 && mode < numFp / 2)
                        {
                            current_samplP[fp] *= 2.0;
                        }
                    }

                    current_samplP[fp]       /= (double)numFp;
                    current_interfaceP[fp, 1] = current_samplP[fp];
                }
                break;

            default:
                throw new ArgumentException();
            }
        }
예제 #22
0
        protected override bool HeightDirectionIsSuitable(
            LinearSayeSpace <Cube> arg,
            LinearPSI <Cube> psi, NodeSet
            x_center,
            int heightDirection,
            MultidimensionalArray agradient, int cell)
        {
            //throw new NotImplementedException();

            //Determine bounds
            //-----------------------------------------------------------------------------------------------------------------
            NodeSet nodeOnPsi = psi.ProjectOnto(x_center);

            MultidimensionalArray jacobian = grid.Jacobian.GetValue_Cell(nodeOnPsi, cell, 1);

            jacobian = jacobian.ExtractSubArrayShallow(new int[] { 0, 0, -1, -1 });

            LevelSet levelSet             = lsData.LevelSet as LevelSet;
            MultidimensionalArray hessian = MultidimensionalArray.Create(1, 1, 3, 3);

            levelSet.EvaluateHessian(cell, 1, nodeOnPsi, hessian);
            hessian = hessian.ExtractSubArrayShallow(new int[] { 0, 0, -1, -1 }).CloneAs();

            //hessian = jacobian * hessian;
            hessian.ApplyAll(x => Math.Abs(x));

            MultidimensionalArray gradient = lsData.GetLevelSetGradients(nodeOnPsi, cell, 1);

            gradient = gradient.ExtractSubArrayShallow(0, 0, -1).CloneAs();



            //abs(Hessian) * 0,5 * diameters.^2 = delta ,( square each entry of diameters) ,
            //this bounds the second error term from taylor series
            //+ + + +
            double[] arr = arg.Diameters.CloneAs();
            psi.SetInactiveDimsToZero(arr);
            MultidimensionalArray diameters = MultidimensionalArray.CreateWrapper(arr, 3, 1);

            diameters = jacobian * diameters;
            diameters.ApplyAll(x => 0.5 * x * x);
            MultidimensionalArray delta = hessian * diameters;

            delta = delta.ExtractSubArrayShallow(-1, 0);

            //Check if suitable
            //-----------------------------------------------------------------------------------------------------------------

            //|gk| > δk
            //Gradient should be able to turn arround
            psi.SetInactiveDimsToZero(gradient.Storage);
            if (Math.Abs(gradient[heightDirection]) > delta[heightDirection])
            {
                bool suitable = true;
                // ||Grad + maxChange|| should be smaller than 20 *
                // Sum_j( g_j + delta_j)^2 / (g_k - delta_k)^2 < 20
                double sum = 0;

                for (int j = 0; j < delta.Length; ++j)
                {
                    sum += Math.Pow(Math.Abs(gradient[j]) + delta[j], 2);
                }
                sum /= Math.Pow(Math.Abs(gradient[heightDirection]) - delta[heightDirection], 2);

                suitable &= sum < 20;

                return(suitable);
            }
            return(false);
        }
예제 #23
0
        public IEnumerable <IChunkRulePair <QuadRule> > GetQuadRuleSet(ExecutionMask mask, int order)
        {
            if (mask == null)
            {
                mask = EdgeMask.GetFullMask(tracker.Ctx.GridDat);
            }

            if (mask is EdgeMask == false)
            {
                throw new Exception();
            }

            QuadRule baseRule = lineSimplex.GetQuadratureRule(order);
            int      D        = tracker.Ctx.Grid.GridSimplex.SpatialDimension;

            var result = new List <ChunkRulePair <QuadRule> >(mask.NoOfItemsLocally);

            foreach (Chunk chunk in mask)
            {
                for (int i = 0; i < chunk.Len; i++)
                {
                    List <double[]> nodes            = new List <double[]>();
                    List <double>   weights          = new List <double>();
                    int[]           noOfNodesPerEdge = new int[referenceLineSegments.Length];

                    int edge = i + chunk.i0;

                    // Always choose 'left' edge
                    int cell      = tracker.Ctx.GridDat.Edges[edge, 0];
                    int localEdge = tracker.Ctx.GridDat.EdgeIndices[edge, 0];

                    LineSegment referenceSegment = referenceLineSegments[localEdge];
                    double[]    roots            = referenceSegment.GetRoots(tracker.LevelSets[levSetIndex], cell);

                    LineSegment[] subSegments = referenceSegment.Split(roots);

                    for (int k = 0; k < subSegments.Length; k++)
                    {
                        for (int m = 0; m < baseRule.NoOfNodes; m++)
                        {
                            // Base rule _always_ is a line rule, thus Nodes[*, _0_]
                            double[] point = subSegments[k].GetPointOnSegment(baseRule.Nodes[m, 0]);

                            uint lh = tracker.Ctx.NSC.LockNodeSetFamily(
                                tracker.Ctx.NSC.CreateContainer(
                                    MultidimensionalArray.CreateWrapper(point, 1, D), -1.0));
                            MultidimensionalArray levelSetValue = tracker.GetLevSetValues(levSetIndex, 0, cell, 1);
                            tracker.Ctx.NSC.UnlockNodeSetFamily(lh);

                            // Only positive volume
                            if (levelSetValue[0, 0] <= 0.0)
                            {
                                continue;
                            }

                            weights.Add(baseRule.Weights[m] * subSegments[k].Length / referenceSegment.Length);
                            nodes.Add(point);
                        }
                    }

                    if (weights.Count == 0)
                    {
                        continue;
                    }

                    MultidimensionalArray localNodes = MultidimensionalArray.Create(nodes.Count, D);
                    for (int j = 0; j < nodes.Count; j++)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            localNodes[j, d] = nodes[j][d];
                        }
                    }

                    MultidimensionalArray localEdgeNodes = MultidimensionalArray.Create(nodes.Count, 1);
                    tracker.Ctx.Grid.GridSimplex.VolumeToEdgeCoordinates(localEdge, localNodes, localEdgeNodes);

                    QuadRule subdividedRule = new QuadRule()
                    {
                        OrderOfPrecision = order,
                        Weights          = MultidimensionalArray.Create(weights.Count),
                        Nodes            = localEdgeNodes.CloneAs()
                    };
                    subdividedRule.Weights.SetV(weights, -1);

                    result.Add(new ChunkRulePair <QuadRule>(
                                   Chunk.GetSingleElementChunk(edge), subdividedRule));
                }
            }

            return(result);
        }
예제 #24
0
        /// <summary>
        /// Affine-linear flux function on an inner edge. An affine-linear flux
        /// must implemented as two matrices and an offset vector: The linear
        /// flux, in a mathematical notation is defined as InnerFlux(Uin,Uout) =
        /// BorderFlux(U) =  M_in*Uin + M_out*Uout + b
        /// where Uin and Uout are column vectors containing function values of
        /// other fields on the respective side of the concerned edge. Which
        /// fields in which order is specified by
        /// <see cref="IEquationComponent.ArgumentOrdering" /> property. In
        /// this implementation, the resulting flux solely depends on the
        /// implementation of <see cref="INonlinearFlux.InnerEdgeFlux"/> that
        /// has been supplied to the constructor.
        /// </summary>
        /// <param name="inp">
        /// A set of input parameters such as time, coordinate and values of
        /// parameters. Given as reference for performance reasons; DO NOT
        /// WRITE to this structure.
        /// </param>
        /// <param name="Uin"></param>
        /// <param name="Uout"></param>
        protected override double InnerEdgeFlux(ref CommonParams inp, double[] Uin, double[] Uout)
        {
            MultidimensionalArray refFlux = MultidimensionalArray.Create(1, 1);

            baseFlux.InnerEdgeFlux(
                0.0,
                inp.iEdge,
                MultidimensionalArray.CreateWrapper(inp.X, 1, 1, inp.X.Length),
                MultidimensionalArray.CreateWrapper(inp.Normale, 1, inp.Normale.Length),
                inp.Parameters_IN.Select(p =>
                                         MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                inp.Parameters_OUT.Select(p =>
                                          MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                0,
                1,
                refFlux);

            double[] FunctionMatrixIn = new double[inp.Parameters_IN.Length];
            for (int i = 0; i < inp.Parameters_IN.Length; i++)
            {
                double[] perturbedParameters = inp.Parameters_IN.CloneAs();
                double   stepSize            = GetStepSize(perturbedParameters[i]);
                perturbedParameters[i] += stepSize;

                MultidimensionalArray perturbedFlux = MultidimensionalArray.Create(1, 1);
                baseFlux.InnerEdgeFlux(
                    0.0,
                    inp.iEdge,
                    MultidimensionalArray.CreateWrapper(inp.X, 1, 1, inp.X.Length),
                    MultidimensionalArray.CreateWrapper(inp.Normale, 1, inp.Normale.Length),
                    perturbedParameters.Select(p =>
                                               MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    inp.Parameters_OUT.Select(p =>
                                              MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    0,
                    1,
                    perturbedFlux);

                FunctionMatrixIn[i] = (perturbedFlux[0, 0] - refFlux[0, 0]) / stepSize;
            }

            double[] FunctionMatrixOut = new double[inp.Parameters_OUT.Length];
            for (int i = 0; i < inp.Parameters_OUT.Length; i++)
            {
                double[] perturbedParameters = inp.Parameters_OUT.CloneAs();
                double   stepSize            = GetStepSize(perturbedParameters[i]);
                perturbedParameters[i] += stepSize;

                MultidimensionalArray perturbedFlux = MultidimensionalArray.Create(1, 1);
                baseFlux.InnerEdgeFlux(
                    0.0,
                    inp.iEdge,
                    MultidimensionalArray.CreateWrapper(inp.X, 1, 1, inp.X.Length),
                    MultidimensionalArray.CreateWrapper(inp.Normale, 1, inp.Normale.Length),
                    inp.Parameters_IN.Select(p =>
                                             MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    perturbedParameters.Select(p =>
                                               MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    0,
                    1,
                    perturbedFlux);

                FunctionMatrixOut[i] = (perturbedFlux[0, 0] - refFlux[0, 0]) / stepSize;
            }

            double result = refFlux[0, 0];

            for (int i = 0; i < inp.Parameters_IN.Length; i++)
            {
                result += FunctionMatrixIn[i] * (Uin[i] - inp.Parameters_IN[i])
                          + FunctionMatrixOut[i] * (Uout[i] - inp.Parameters_OUT[i]);
            }
            return(result);
        }
예제 #25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="current_FLSproperty"></param>
        public override void EvolveFourierLS(ref double[] current_FLSproperty)
        {
            switch (FourierEvolve)
            {
            case Fourier_Evolution.MaterialPoints:
                int numSp = current_FLSproperty.Length / 2;
                current_interfaceP = MultidimensionalArray.CreateWrapper(current_FLSproperty, new int[] { numSp, 2 });
                //MultidimensionalArray prescribed_center = MultidimensionalArray.CreateWrapper(current_FLSproperty.GetSubVector(0, 2), new int[] { 1, 2 });

                //Console.WriteLine("center_VelAtC = ({0}, {1})", prescribed_center[0, 0], prescribed_center[0, 1]);


                SetRefCenter();

                //bool reseed = Reseeding();
                //if (reseed == true) {
                //    Console.WriteLine("reseeding done");
                //}

                //RelocateOnInterface();

                //MultidimensionalArray center_geom = GetGeometricCenter(current_interfaceP);
                //Console.WriteLine("center_geometric = ({0}, {1})", center_geom[0, 0], center_geom[0, 1]);



                int numP = current_interfaceP.Lengths[0];
                current_FLSproperty = new double[numP * 2];
                for (int sp = 0; sp < numP; sp++)
                {
                    current_interfaceP[sp, 0]         = current_samplP[sp] * Math.Cos(FourierP[sp]) + center[0, 0];
                    current_interfaceP[sp, 1]         = current_samplP[sp] * Math.Sin(FourierP[sp]) + center[0, 1];
                    current_FLSproperty[sp * 2]       = current_interfaceP[sp, 0];
                    current_FLSproperty[(sp * 2) + 1] = current_interfaceP[sp, 1];
                }

                break;

            case Fourier_Evolution.FourierPoints:
                current_samplP = current_FLSproperty.GetSubVector(2, numFp);

                setDFTcoeff();
                SmoothSamplePoints();

                for (int sp = 0; sp < numFp; sp++)
                {
                    current_FLSproperty[sp + 2] = current_samplP[sp];
                }

                // set material points on Fourier points
                center = MultidimensionalArray.CreateWrapper(current_FLSproperty.GetSubVector(0, 2), new int[] { 1, 2 });
                //Console.WriteLine("center_prescribed = ({0}, {1})", center[0, 0], center[0, 1]);
                for (int p = 0; p < numFp; p++)
                {
                    current_interfaceP[p, 0] = current_samplP[p] * Math.Cos(FourierP[p]) + center[0, 0];
                    current_interfaceP[p, 1] = current_samplP[p] * Math.Sin(FourierP[p]) + center[0, 1];
                }
                //MultidimensionalArray center_interP = GetCenter(current_interfaceP);
                //double center_diff = Math.Sqrt((center_new[0, 0] - center_interP[0, 0]).Pow2() + (center_new[0, 1] - center_interP[0, 1]).Pow2());
                //if (center_diff > 1e-9)
                //    Console.WriteLine("Warning: significant change of the center point after smoothing: center_diff 0 {0}", center_diff);
                //MultidimensionalArray center_geomFP = GetGeometricCenter(current_interfaceP);
                //Console.WriteLine("center_geometric = ({0}, {1})", center_geomFP[0, 0], center_geomFP[0, 1]);


                break;

            case Fourier_Evolution.FourierModes:
                for (int sp = 0; sp < numFp; sp++)
                {
                    DFT_coeff[sp] = new Complex(current_FLSproperty[2 + (sp * 2)], current_FLSproperty[2 + (sp * 2) + 1]);
                }
                SmoothSamplePoints();

                // relocate Material points in kartesian coordinates on the interface
                center = MultidimensionalArray.CreateWrapper(current_FLSproperty.GetSubVector(0, 2), new int[] { 1, 2 });
                for (int sp = 0; sp < current_interfaceP.Lengths[0]; sp++)
                {
                    current_interfaceP[sp, 0] = center[0, 0] + current_samplP[sp] * Math.Cos(FourierP[sp]);
                    current_interfaceP[sp, 1] = center[0, 1] + current_samplP[sp] * Math.Sin(FourierP[sp]);
                }


                break;

            default:
                throw new ArgumentException();
            }

            //int kmax = 1;
            //for (int c = 2; c < cf_end; c++) {
            //    if (DFT_coeff[c].Imaginary > DFT_coeff[kmax].Imaginary)
            //        kmax = c;
            //}
            //Console.WriteLine("max Fourier mode imaginary part: k = {0}: {1}", kmax, DFT_coeff[kmax].Imaginary);
        }
예제 #26
0
        /// <summary>
        /// Computes Cell-volumes and edge areas before agglomeration.
        /// </summary>
        void ComputeNonAgglomeratedMetrics()
        {
            var gd = XDGSpaceMetrics.GridDat;
            int JE = gd.Cells.NoOfCells;
            int J  = gd.Cells.NoOfLocalUpdatedCells;
            int D  = gd.SpatialDimension;
            int EE = gd.Edges.Count;

            SpeciesId[] species = this.SpeciesList.ToArray();
            int         NoSpc   = species.Count();

            int[,] E2C = gd.Edges.CellIndices;

            var schH = new XQuadSchemeHelper(XDGSpaceMetrics);

            double[] vec_cellMetrics = new double[JE * NoSpc * 2];

            // collect all per-cell-metrics in the same MultidimArry, for MPI-exchange
            // 1st index: cell
            // 2nd index: species
            // 3rd index: 0 for interface surface per cell, 1 for cut-cell-volume
            MultidimensionalArray cellMetrics = MultidimensionalArray.CreateWrapper(vec_cellMetrics, JE, NoSpc, 2);

            this.CutEdgeAreas   = new Dictionary <SpeciesId, MultidimensionalArray>();
            this.CutCellVolumes = new Dictionary <SpeciesId, MultidimensionalArray>();
            this.InterfaceArea  = new Dictionary <SpeciesId, MultidimensionalArray>();

            //var schS = new List<CellQuadratureScheme>();
            //var rulz = new List<ICompositeQuadRule<QuadRule>>();


            // edges and volumes
            // =================
            for (int iSpc = 0; iSpc < species.Length; iSpc++)
            {
                var cellVol = cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1);
                var spc     = species[iSpc];

                MultidimensionalArray edgArea = MultidimensionalArray.Create(EE);
                this.CutEdgeAreas.Add(spc, edgArea);

                // compute cut edge area
                // ---------------------

                var edgeScheme = schH.GetEdgeQuadScheme(spc);
                var edgeRule   = edgeScheme.Compile(gd, this.CutCellQuadratureOrder);

                BoSSS.Foundation.Quadrature.EdgeQuadrature.GetQuadrature(
                    new int[] { 1 }, gd,
                    edgeRule,
                    _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                {
                    EvalResult.SetAll(1.0);
                },
                    _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                {
                    for (int i = 0; i < Length; i++)
                    {
                        int iEdge = i + i0;
                        Debug.Assert(edgArea[iEdge] == 0);
                        edgArea[iEdge] = ResultsOfIntegration[i, 0];
                        Debug.Assert(!(double.IsNaN(edgArea[iEdge]) || double.IsInfinity(edgArea[iEdge])));
                    }
                }).Execute();

                // compute cut cell volumes
                // ------------------------

                var volScheme = schH.GetVolumeQuadScheme(spc);
                var volRule   = volScheme.Compile(gd, this.CutCellQuadratureOrder);

                //schS.Add(volScheme);
                //rulz.Add(volRule);

                BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                    new int[] { 1 }, gd,
                    volRule,
                    _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                {
                    EvalResult.SetAll(1.0);
                },
                    _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                {
                    for (int i = 0; i < Length; i++)
                    {
                        int jCell = i + i0;
                        Debug.Assert(cellVol[jCell] == 0);
                        cellVol[jCell] = ResultsOfIntegration[i, 0];
                        Debug.Assert(!(double.IsNaN(cellVol[jCell]) || double.IsInfinity(cellVol[jCell])));
                    }
                }).Execute();
            }


            // interface surface
            // =================

            // loop over all possible pairs of species

            /*
             * for (int iSpcA = 0; iSpcA < species.Length; iSpcA++) {
             *  var SpeciesA = species[iSpcA];
             *  var SpeciesADom = lsTrk.GetSpeciesMask(SpeciesA);
             *  if (SpeciesADom.NoOfItemsLocally <= 0)
             *      continue;
             *
             *  for (int iSpcB = iSpcA + 1; iSpcB < species.Length; iSpcB++) {
             *      var SpeciesB = species[iSpcB];
             *      var SpeciesBDom = lsTrk.GetSpeciesMask(SpeciesB);
             *      if (SpeciesBDom.NoOfItemsLocally <= 0)
             *          continue;
             *
             *      var SpeciesCommonDom = SpeciesADom.Intersect(SpeciesBDom);
             *      if (SpeciesCommonDom.NoOfItemsLocally <= 0)
             *          continue;
             *
             *      // loop over level-sets
             *      int NoOfLs = lsTrk.LevelSets.Count;
             *      for (int iLevSet = 0; iLevSet < NoOfLs; iLevSet++) {
             *
             *
             *          var LsDom = lsTrk.GetCutCellMask4LevSet(iLevSet);
             *          var IntegrationDom = LsDom.Intersect(SpeciesCommonDom);
             *
             *          if (IntegrationDom.NoOfItemsLocally > 0) {
             *              CellQuadratureScheme SurfIntegration = schH.GetLevelSetquadScheme(iLevSet, IntegrationDom);
             *              var rule = SurfIntegration.Compile(gd, this.HMForder);
             *
             *
             *              BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
             *                  new int[] { 1 }, gd,
             *                  rule,
             *                  _Evaluate: delegate (int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
             *                  {
             *                      EvalResult.SetAll(1.0);
             *                  },
             *                  _SaveIntegrationResults: delegate (int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
             *                  {
             *                      for (int i = 0; i < Length; i++) {
             *                          int jCell = i + i0;
             *                          if (cellMetrics[jCell, iSpcA, 0] != 0.0)
             *                              throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
             *                          if (cellMetrics[jCell, iSpcB, 0] != 0.0)
             *                              throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
             *
             *                          cellMetrics[jCell, iSpcA, 0] = ResultsOfIntegration[i, 0];
             *                          cellMetrics[jCell, iSpcB, 0] = ResultsOfIntegration[i, 0];
             *                      }
             *                  }).Execute();
             *          }
             *      }
             *  }
             * }*/

            // loop over level-sets
            if (species.Length > 0)
            {
                // find domain of all species:
                CellMask SpeciesCommonDom = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[0]);
                for (int iSpc = 1; iSpc < species.Length; iSpc++)
                {
                    SpeciesCommonDom = SpeciesCommonDom.Union(XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[iSpc]));
                }
                BitArray[] SpeciesBitMask = species.Select(spc => XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(spc).GetBitMask()).ToArray();

                int NoOfLs  = XDGSpaceMetrics.NoOfLevelSets;
                int NoOfSpc = species.Length;
                for (int iLevSet = 0; iLevSet < NoOfLs; iLevSet++)
                {
                    var LsDom          = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet);
                    var IntegrationDom = LsDom.Intersect(SpeciesCommonDom);

                    //if (IntegrationDom.NoOfItemsLocally > 0) { -> Doesn't work if Bjoerns HMF is used, eds up in an mpi dead lock
                    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    // this level-set is actually relevant for someone in 'species'
                    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                    CellQuadratureScheme SurfIntegration = schH.GetLevelSetquadScheme(iLevSet, IntegrationDom);
                    var rule = SurfIntegration.Compile(gd, this.CutCellQuadratureOrder);

                    BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                        new int[] { 1 }, gd,
                        rule,
                        _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                        EvalResult.SetAll(1.0);
                    },
                        _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                        for (int i = 0; i < Length; i++)
                        {
                            int jCell = i + i0;



                            //if (cellMetrics[jCell, iSpcA, 0] != 0.0)
                            //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
                            //if (cellMetrics[jCell, iSpcB, 0] != 0.0)
                            //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");

                            //cellMetrics[jCell, iSpcA, 0] = ResultsOfIntegration[i, 0];
                            //cellMetrics[jCell, iSpcB, 0] = ResultsOfIntegration[i, 0];


                            for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)
                            {
                                if (SpeciesBitMask[iSpc][jCell])
                                {
                                    cellMetrics[jCell, iSpc, 0] += ResultsOfIntegration[i, 0];
                                    Debug.Assert(!(double.IsNaN(cellMetrics[jCell, iSpc, 0]) || double.IsInfinity(cellMetrics[jCell, iSpc, 0])));
                                }
                            }
                        }
                    }).Execute();
                    //}
                }
            }

            // MPI exchange & store
            // ====================

            if (species.Length > 0)
            {
                vec_cellMetrics.MPIExchange(gd);
            }

            for (int iSpc = 0; iSpc < species.Length; iSpc++)
            {
                var spc = species[iSpc];
                this.InterfaceArea.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 0).CloneAs());
                this.CutCellVolumes.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1).CloneAs());
            }

            //Console.WriteLine("Erinn - debug code.");
            //for(int j = 0; j < J; j++) {
            //    double totVol = gd.Cells.GetCellVolume(j);

            //    double blaVol = 0;
            //    for(int iSpc = 0; iSpc < species.Length; iSpc++) {
            //        var spc = species[iSpc];
            //        var cellVolS = this.CutCellVolumes[spc][j];
            //        blaVol += cellVolS;
            //    }

            //    Debug.Assert(Math.Abs(totVol - blaVol) / totVol < 1.0e-8);

            //}
        }