Esempio n. 1
0
        /// <summary>
        /// Create DFS2 file with iterpolated values from the 3x3 quadrangles,
        /// with various delete values applied in each time step.
        /// </summary>
        public void DeleteValueVisualDfs2DoTest()
        {
            string   meshFileName = UnitTestHelper.TestDataDir + "small.mesh";
            MeshFile file         = MeshFile.ReadMesh(meshFileName);

            _meshVisual = file.ToSMeshData();

            DfsFactory  factory     = new DfsFactory();
            Dfs2Builder dfs2Builder = new Dfs2Builder();

            dfs2Builder.SetDataType(0);
            dfs2Builder.SetTemporalAxis(factory.CreateTemporalEqTimeAxis(eumUnit.eumUsec, 0, 1));
            dfs2Builder.SetSpatialAxis(factory.CreateAxisEqD2(eumUnit.eumUmeter, 80, 0, 0.01, 80, 0, 0.01));
            dfs2Builder.SetGeographicalProjection(factory.CreateProjectionUndefined());

            dfs2Builder.AddDynamicItem("DeleteValueSmooth", eumQuantity.UnDefined, DfsSimpleType.Float, DataValueType.Instantaneous);
            dfs2Builder.AddDynamicItem("DeleteValueBox", eumQuantity.UnDefined, DfsSimpleType.Float, DataValueType.Instantaneous);
            dfs2Builder.DeleteValueFloat = (float)d;

            dfs2Builder.CreateFile(UnitTestHelper.TestDataDir + "test_InterpTri.dfs2");

            Dfs2File dfs2File = dfs2Builder.GetFile();

            // Calculate interpolation weights
            MeshWeights[][] weights = new MeshWeights[80][];
            for (int j = 0; j < 80; j++)
            {
                double y = 0.2 + 0.01 * j + 0.005;
                weights[j] = new MeshWeights[80];
                for (int i = 0; i < 80; i++)
                {
                    double x = 0.4 + 0.01 * i + 0.005;

                    weights[j][i].QuadWeights = InterpQuadrangle.UndefinedWeights();
                    weights[j][i].TriWeights  = InterpTriangle.UndefinedWeights();
                    for (int ielmt = 0; ielmt < _meshVisual.NumberOfElements; ielmt++)
                    {
                        var elmtNodes = _meshVisual.ElementTable[ielmt];
                        if (elmtNodes.Length == 4)
                        {
                            double x0 = _meshVisual.X[elmtNodes[0]];
                            double x1 = _meshVisual.X[elmtNodes[1]];
                            double x2 = _meshVisual.X[elmtNodes[2]];
                            double x3 = _meshVisual.X[elmtNodes[3]];
                            double y0 = _meshVisual.Y[elmtNodes[0]];
                            double y1 = _meshVisual.Y[elmtNodes[1]];
                            double y2 = _meshVisual.Y[elmtNodes[2]];
                            double y3 = _meshVisual.Y[elmtNodes[3]];
                            if (MeshExtensions.IsPointInsideQuadrangle(x, y, x0, y0, x1, y1, x2, y2, x3, y3))
                            {
                                weights[j][i].ElmtIndex   = ielmt;
                                weights[j][i].QuadWeights = InterpQuadrangle.InterpolationWeights(x, y, x0, y0, x1, y1, x2, y2, x3, y3);
                            }
                        }
                        else
                        {
                            double x0 = _meshVisual.X[elmtNodes[0]];
                            double x1 = _meshVisual.X[elmtNodes[1]];
                            double x2 = _meshVisual.X[elmtNodes[2]];
                            double y0 = _meshVisual.Y[elmtNodes[0]];
                            double y1 = _meshVisual.Y[elmtNodes[1]];
                            double y2 = _meshVisual.Y[elmtNodes[2]];
                            if (MeshExtensions.IsPointInsideTriangle(x, y, x0, y0, x1, y1, x2, y2))
                            {
                                weights[j][i].ElmtIndex  = ielmt;
                                weights[j][i].TriWeights = InterpTriangle.InterpolationWeights(x, y, x0, y0, x1, y1, x2, y2);
                            }
                        }
                    }
                }
            }

            // Original center quadrangle values
            double z4 = _meshVisual.Z[3];
            double z6 = _meshVisual.Z[5];
            double z8 = _meshVisual.Z[7];

            float[] data = new float[80 * 80];
            VisualDfs2Data(weights, data, z4, z6, z8, true); dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, z4, z6, z8, false); dfs2File.WriteItemTimeStepNext(0, data);

            // One delete value
            VisualDfs2Data(weights, data, d, z6, z8, true); dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, d, z6, z8, false); dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, z4, d, z8, true); dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, z4, d, z8, false); dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, z4, z6, d, true);  dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, z4, z6, d, false); dfs2File.WriteItemTimeStepNext(0, data);

            // Two adjacent delete values
            VisualDfs2Data(weights, data, d, d, z8, true);  dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, d, d, z8, false); dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, z4, d, d, true);  dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, z4, d, d, false); dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, d, z6, d, true);  dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, d, z6, d, false); dfs2File.WriteItemTimeStepNext(0, data);

            // All delete values
            VisualDfs2Data(weights, data, d, d, d, true);     dfs2File.WriteItemTimeStepNext(0, data);
            VisualDfs2Data(weights, data, d, d, d, false);    dfs2File.WriteItemTimeStepNext(0, data);

            dfs2File.Close();
        }
Esempio n. 2
0
        /// <summary>
        /// Calculate interpolation weights for the point (x,y) inside the element"/>
        /// <para>
        /// The weights returned can be used to calculate a value v at the point (x,y) using the
        /// <code>GetValue</code> methods
        /// </para>
        /// <para>
        /// if the point (x,y) is not inside the element, results are undefined.
        /// </para>
        /// </summary>
        /// <returns>Interpolation weights</returns>

        public static Weights InterpolationWeights(double x, double y, int element, SMeshData smesh)
        {
            Weights weights = new Weights();

            // Setting "out-of-bounds" index
            weights.Element1Index = -1;

            bool found = false;

            weights.Element1Index = element;

            // Check which face the point belongs to, and which "side" of the face
            bool isQuad   = smesh.IsQuadrilateral(element);
            int  numFaces = isQuad ? 4 : 3;

            for (int j = 0; j < numFaces; j++)
            {
                SMeshFace elementFace = smesh.Faces[smesh.ElementsFaces[element][j]];
                // From the element (x,y), looking towards the face,
                // figure out wich node is right and which is left.
                int rightNode, leftNode;
                if (elementFace.LeftElement == element)
                {
                    rightNode = elementFace.FromNode;
                    leftNode  = elementFace.ToNode;
                }
                else
                {
                    rightNode = elementFace.ToNode;
                    leftNode  = elementFace.FromNode;
                }

                double elementXCenter = smesh.ElementXCenter[element];
                double elementYCenter = smesh.ElementYCenter[element];
                double rightNodeX     = smesh.X[rightNode];
                double rightNodeY     = smesh.Y[rightNode];
                double leftNodeX      = smesh.X[leftNode];
                double leftNodeY      = smesh.Y[leftNode];

                // Find also the element on the other side of the face
                double otherElementX, otherElementY;
                int    otherElement = elementFace.OtherElement(element);
                if (otherElement >= 0)
                {
                    otherElementX         = smesh.ElementXCenter[otherElement];
                    otherElementY         = smesh.ElementYCenter[otherElement];
                    weights.Element2Index = otherElement;
                }
                else
                {
                    // No other element - boundary face, use center of face.
                    otherElementX = 0.5 * (rightNodeX + leftNodeX);
                    otherElementY = 0.5 * (rightNodeY + leftNodeY);
                    // Use "itself" as element-2
                    weights.Element2Index = element;
                }


                // Check if point is on the right side of the line between element and other-element
                if (MeshExtensions.IsPointInsideLines(x, y,
                                                      elementXCenter, elementYCenter,
                                                      rightNodeX, rightNodeY,
                                                      otherElementX, otherElementY))
                {
                    (double w1, double w2, double w3) =
                        MeshExtensions.InterpolationWeights(
                            x, y, elementXCenter, elementYCenter,
                            rightNodeX, rightNodeY, otherElementX, otherElementY);
                    weights.NodeIndex      = rightNode;
                    weights.Element1Weight = w1;
                    weights.NodeWeight     = w2;
                    weights.Element2Weight = w3;
                    found = true;
                    break;
                }

                // Check if point is on the left side of the line between element and other-element
                if (MeshExtensions.IsPointInsideLines(x, y,
                                                      elementXCenter, elementYCenter,
                                                      otherElementX, otherElementY,
                                                      leftNodeX, leftNodeY))
                {
                    (double w1, double w2, double w3) =
                        MeshExtensions.InterpolationWeights(
                            x, y, elementXCenter, elementYCenter,
                            otherElementX, otherElementY, leftNodeX, leftNodeY);
                    weights.NodeIndex      = leftNode;
                    weights.Element1Weight = w1;
                    weights.Element2Weight = w2;
                    weights.NodeWeight     = w3;
                    found = true;
                    break;
                }
            }

            if (!found) // Should never happen, but just in case
            {
                weights.Element1Weight = 1;
                weights.Element2Weight = 0;
                weights.NodeWeight     = 0;
                weights.Element2Index  = element;
                weights.NodeIndex      = smesh.ElementTable[element][0];
            }

            return(weights);
        }
Esempio n. 3
0
    public static bool SplitMeshData(SMeshData meshData, List <SMeshData> subMeshDataList)
    {
        const int VLIMIT = 60000;

        int icount = meshData.indices.Length;
        int vcount = meshData.vertices.Length;

        subMeshDataList.Clear();
        int minv    = 0;
        int maxv    = 0;
        int iOffset = 0;

        for (int i = 0; i < icount; i += 3)
        {
            int idx0 = meshData.indices[i];
            int idx1 = meshData.indices[i + 1];
            int idx2 = meshData.indices[i + 2];

            int minIndex = minv;
            int maxIndex = maxv;
            maxIndex = System.Math.Max(maxIndex, idx0);
            maxIndex = System.Math.Max(maxIndex, idx1);
            maxIndex = System.Math.Max(maxIndex, idx2);

            if ((maxIndex - minIndex) >= VLIMIT)             //split
            {
                SMeshData subMeshData = new SMeshData();

                int cvcount = maxv - minv + 1;
                int cicount = i - iOffset;

                subMeshData.vertices = new Vector3[cvcount];
                subMeshData.indices  = new int[cicount];

                System.Array.Copy(meshData.vertices, minv, subMeshData.vertices, 0, cvcount);
                System.Array.Copy(meshData.indices, iOffset, subMeshData.indices, 0, cicount);

                for (int t = 0; t < cicount; ++t)
                {
                    subMeshData.indices[t] -= minv;
                }

                subMeshDataList.Add(subMeshData);

                //recalculate
                iOffset = i;
                minv    = minv + cvcount;
                maxv    = minv;

                continue;
            }

            maxv = maxIndex;

            if (i + 3 >= icount && maxv - minv > 0)           //last
            {
                SMeshData subMeshData = new SMeshData();

                int cvcount = maxv - minv + 1;
                int cicount = i + 3 - iOffset;

                subMeshData.vertices = new Vector3[cvcount];
                subMeshData.indices  = new int[cicount];

                System.Array.Copy(meshData.vertices, minv, subMeshData.vertices, 0, cvcount);
                System.Array.Copy(meshData.indices, iOffset, subMeshData.indices, 0, cicount);

                for (int t = 0; t < cicount; ++t)
                {
                    subMeshData.indices[t] -= minv;
                }

                subMeshDataList.Add(subMeshData);

                iOffset = i;
            }
        }

        return(true);
    }