コード例 #1
0
ファイル: FEWorld.cs プロジェクト: lulzzz/IvyFEM
        public void UpdateBubbleFieldValueValuesFromCoordValues(
            uint valueId, FieldDerivativeType dt, double[] coordValues)
        {
            System.Diagnostics.Debug.Assert(FieldValueArray.IsObjectId(valueId));
            FieldValue fv         = FieldValueArray.GetObject(valueId);
            uint       quantityId = fv.QuantityId;
            uint       dof        = fv.Dof;

            double[] values = fv.GetDoubleValues(dt);
            uint     coCnt  = GetCoordCount(quantityId);

            System.Diagnostics.Debug.Assert(coCnt * dof == coordValues.Length);

            IList <uint> feIds = GetTriangleFEIds(quantityId);

            foreach (uint feId in feIds)
            {
                TriangleFE triFE       = GetTriangleFE(quantityId, feId);
                int[]      coIds       = triFE.NodeCoordIds;
                uint       elemNodeCnt = triFE.NodeCount;
                double[]   bubbleValue = new double[dof];
                for (int iNode = 0; iNode < elemNodeCnt; iNode++)
                {
                    int coId = coIds[iNode];
                    for (int iDof = 0; iDof < dof; iDof++)
                    {
                        bubbleValue[iDof] += coordValues[coId * dof + iDof];
                    }
                }
                for (int iDof = 0; iDof < dof; iDof++)
                {
                    bubbleValue[iDof] /= (double)elemNodeCnt;
                }

                for (int iDof = 0; iDof < dof; iDof++)
                {
                    values[(feId - 1) * dof + iDof] = bubbleValue[iDof];
                }
            }
        }
コード例 #2
0
ファイル: FieldValue.cs プロジェクト: lulzzz/IvyFEM
        public void CopyValues(FieldValue src)
        {
            DoubleValues = null;
            if (src.DoubleValues != null)
            {
                DoubleValues = new double[src.DoubleValues.Length];
                src.DoubleValues.CopyTo(DoubleValues, 0);
            }
            DoubleVelocityValues = null;
            if (src.DoubleVelocityValues != null)
            {
                DoubleVelocityValues = new double[src.DoubleVelocityValues.Length];
                src.DoubleVelocityValues.CopyTo(DoubleVelocityValues, 0);
            }
            DoubleAccelerationValues = null;
            if (src.DoubleAccelerationValues != null)
            {
                DoubleAccelerationValues = new double[src.DoubleAccelerationValues.Length];
                src.DoubleAccelerationValues.CopyTo(DoubleAccelerationValues, 0);
            }

            ComplexValues = null;
            if (src.ComplexValues != null)
            {
                ComplexValues = new System.Numerics.Complex[src.ComplexValues.Length];
                src.ComplexValues.CopyTo(ComplexValues, 0);
            }
            ComplexVelocityValues = null;
            if (src.ComplexVelocityValues != null)
            {
                ComplexVelocityValues = new System.Numerics.Complex[src.ComplexVelocityValues.Length];
                src.ComplexVelocityValues.CopyTo(ComplexVelocityValues, 0);
            }
            ComplexAccelerationValues = null;
            if (src.ComplexAccelerationValues != null)
            {
                ComplexAccelerationValues = new System.Numerics.Complex[src.ComplexAccelerationValues.Length];
                src.ComplexAccelerationValues.CopyTo(ComplexAccelerationValues, 0);
            }
        }
コード例 #3
0
ファイル: VectorFieldDrawer.cs プロジェクト: lulzzz/IvyFEM
        private void Set(uint valueId, FieldDerivativeType valueDt, FEWorld world)
        {
            System.Diagnostics.Debug.Assert(world.IsFieldValueId(valueId));
            ValueId = valueId;
            var mesh = world.Mesh;

            uint dim = world.Dimension;
            {
                if (dim == 2)
                {
                    SutableRotMode = RotMode.RotMode2D;
                }
                else if (dim == 3)
                {
                    SutableRotMode = RotMode.RotMode3D;
                }
            }
            FieldValue fv = world.GetFieldValue(valueId);

            if (fv.Type == FieldValueType.Vector2 || fv.Type == FieldValueType.Vector3)
            {
                Type = VectorFieldDrawerType.Vector;
            }
            else if (fv.Type == FieldValueType.SymmetricTensor2)
            {
                Type = VectorFieldDrawerType.SymmetricTensor2;
            }

            {
                DrawParts.Clear();
                IList <uint> meshIds = mesh.GetIds();
                foreach (uint meshId in meshIds)
                {
                    VectorFieldDrawPart dp = new VectorFieldDrawPart(meshId, world);
                    DrawParts.Add(dp);
                }
            }

            Update(world);
        }
コード例 #4
0
ファイル: FEWorld.cs プロジェクト: lulzzz/IvyFEM
        public uint AddFieldValue(FieldValueType fieldType, FieldDerivativeType derivativeType,
                                  uint quantityId, bool isBubble, FieldShowType showType)
        {
            uint pointCnt = 0;

            if (isBubble)
            {
                pointCnt = (uint)GetTriangleFEIds(quantityId).Count;
            }
            else
            {
                pointCnt = GetCoordCount(quantityId);
            }
            FieldValue fv = new FieldValue(quantityId, fieldType, derivativeType,
                                           isBubble, showType, pointCnt);

            uint freeId  = FieldValueArray.GetFreeObjectId();
            uint valueId = FieldValueArray.AddObject(freeId, fv);

            System.Diagnostics.Debug.Assert(valueId == freeId);
            return(valueId);
        }
コード例 #5
0
        private void UpdateVector(uint valueId, FieldDerivativeType dt, FEWorld world)
        {
            ValueDof = 2;

            FieldValue fv         = world.GetFieldValue(valueId);
            uint       quantityId = fv.QuantityId;
            uint       dof        = fv.Dof;

            System.Diagnostics.Debug.Assert(fv.IsBubble == true);
            var      mesh = world.Mesh;
            MeshType meshType;

            int[] vertexs;
            mesh.GetConnectivity(MeshId, out meshType, out vertexs);

            if (Type == ElementType.Tri)
            {
                Values = new double[ElemCount * ValueDof];
                for (int iTri = 0; iTri < ElemCount; iTri++)
                {
                    // Bubble
                    uint feId = world.GetTriangleFEIdFromMesh(quantityId, MeshId, (uint)iTri);
                    System.Diagnostics.Debug.Assert(feId != 0);
                    System.Diagnostics.Debug.Assert(dof >= ValueDof);
                    for (int iDof = 0; iDof < ValueDof; iDof++)
                    {
                        double u = fv.GetShowValue((int)(feId - 1), iDof, dt);
                        Values[iTri * ValueDof + iDof] = u;
                    }
                }
            }
            else if (Type == ElementType.Quad)
            {
                // TRIと同じでよいが要素IDを取得するメソッドが現状ない
                throw new NotImplementedException();
            }
        }
コード例 #6
0
ファイル: FEWorld.cs プロジェクト: lulzzz/IvyFEM
        public void UpdateFieldValueValuesFromNodeValues(
            uint valueId, FieldDerivativeType dt, double[] nodeValues)
        {
            System.Diagnostics.Debug.Assert(FieldValueArray.IsObjectId(valueId));
            FieldValue fv         = FieldValueArray.GetObject(valueId);
            uint       quantityId = fv.QuantityId;
            uint       dof        = fv.Dof;

            System.Diagnostics.Debug.Assert(fv.Dof == GetDof(quantityId));
            double[] values     = fv.GetDoubleValues(dt);
            uint     coCnt      = GetCoordCount(quantityId);
            uint     offsetNode = 0;

            for (uint qId = 0; qId < quantityId; qId++)
            {
                offsetNode += GetNodeCount(qId) * GetDof(qId);
            }

            for (int coId = 0; coId < coCnt; coId++)
            {
                int nodeId = Coord2Node(quantityId, coId);
                if (nodeId == -1)
                {
                    for (int iDof = 0; iDof < dof; iDof++)
                    {
                        values[coId * dof + iDof] = 0;
                    }
                }
                else
                {
                    for (int iDof = 0; iDof < dof; iDof++)
                    {
                        values[coId * dof + iDof] = nodeValues[offsetNode + nodeId * dof + iDof];
                    }
                }
            }
        }
コード例 #7
0
        // Linear / Saint Venant
        public void SetStressValue(
            uint displacementValueId, uint stressValueId, uint equivStressValueId)
        {
            System.Diagnostics.Debug.Assert(World.IsFieldValueId(displacementValueId));
            FieldValue uFV         = World.GetFieldValue(displacementValueId);
            uint       uQuantityId = uFV.QuantityId;

            FieldValue sigmaFV = null;

            if (stressValueId != 0)
            {
                System.Diagnostics.Debug.Assert(World.IsFieldValueId(stressValueId));
                sigmaFV = World.GetFieldValue(stressValueId);
                System.Diagnostics.Debug.Assert(sigmaFV.Type == FieldValueType.SymmetricTensor2);
                System.Diagnostics.Debug.Assert(sigmaFV.Dof == 3);
            }
            FieldValue eqSigmaFV = null;

            if (equivStressValueId != 0)
            {
                System.Diagnostics.Debug.Assert(World.IsFieldValueId(equivStressValueId));
                eqSigmaFV = World.GetFieldValue(equivStressValueId);
                System.Diagnostics.Debug.Assert(eqSigmaFV.Type == FieldValueType.Scalar);
                System.Diagnostics.Debug.Assert(eqSigmaFV.Dof == 1);
            }

            IList <uint> feIds = World.GetTriangleFEIds(uQuantityId);

            foreach (uint feId in feIds)
            {
                TriangleFE triFE  = World.GetTriangleFE(uQuantityId, feId);
                int[]      coIds  = triFE.NodeCoordIds;
                Material   ma     = World.GetMaterial(triFE.MaterialId);
                double     lambda = 0;
                double     mu     = 0;
                if (ma is LinearElasticMaterial)
                {
                    var ma1 = ma as LinearElasticMaterial;
                    lambda = ma1.LameLambda;
                    mu     = ma1.LameMu;
                }
                else if (ma is SaintVenantHyperelasticMaterial)
                {
                    var ma1 = ma as SaintVenantHyperelasticMaterial;
                    lambda = ma1.LameLambda;
                    mu     = ma1.LameMu;
                }
                else
                {
                    System.Diagnostics.Debug.Assert(false);
                    throw new NotImplementedException();
                }

                var ip = TriangleFE.GetIntegrationPoints(TriangleIntegrationPointCount.Point1);
                System.Diagnostics.Debug.Assert(ip.PointCount == 1);
                double[]   L  = ip.Ls[0];
                double[][] Nu = triFE.CalcNu(L);
                double[]   Nx = Nu[0];
                double[]   Ny = Nu[1];
                double[,] uu = new double[2, 2];
                for (int iNode = 0; iNode < coIds.Length; iNode++)
                {
                    int      coId = coIds[iNode];
                    double[] u    = uFV.GetDoubleValue(coId, FieldDerivativeType.Value);
                    uu[0, 0] += u[0] * Nx[iNode];
                    uu[0, 1] += u[0] * Ny[iNode];
                    uu[1, 0] += u[1] * Nx[iNode];
                    uu[1, 1] += u[1] * Ny[iNode];
                }

                //ε strain
                double[,] eps = new double[2, 2];
                if (ma is LinearElasticMaterial)
                {
                    eps[0, 0] = (1.0 / 2.0) * (uu[0, 0] + uu[0, 0]);
                    eps[0, 1] = (1.0 / 2.0) * (uu[0, 1] + uu[1, 0]);
                    eps[1, 0] = (1.0 / 2.0) * (uu[1, 0] + uu[0, 1]);
                    eps[1, 1] = (1.0 / 2.0) * (uu[1, 1] + uu[1, 1]);
                }
                else if (ma is SaintVenantHyperelasticMaterial)
                {
                    eps[0, 0] = (1.0 / 2.0) * (uu[0, 0] + uu[0, 0] + uu[0, 0] * uu[0, 0] + uu[1, 0] * uu[1, 0]);
                    eps[0, 1] = (1.0 / 2.0) * (uu[0, 1] + uu[1, 0] + uu[0, 0] * uu[0, 1] + uu[1, 1] * uu[1, 0]);
                    eps[1, 0] = (1.0 / 2.0) * (uu[1, 0] + uu[0, 1] + uu[0, 1] * uu[0, 0] + uu[1, 0] * uu[1, 1]);
                    eps[1, 1] = (1.0 / 2.0) * (uu[1, 1] + uu[1, 1] + uu[0, 1] * uu[0, 1] + uu[1, 1] * uu[1, 1]);
                }
                else
                {
                    System.Diagnostics.Debug.Assert(false);
                }

                // σ stress
                double[,] sigma = new double[2, 2];
                {
                    sigma[0, 0] = mu * eps[0, 0];
                    sigma[0, 1] = mu * eps[0, 1];
                    sigma[1, 0] = mu * eps[1, 0];
                    sigma[1, 1] = mu * eps[1, 1];
                    double tmp = lambda * (eps[0, 0] + eps[1, 1]);
                    sigma[0, 0] += tmp;
                    sigma[1, 1] += tmp;
                }

                double misesStress = Math.Sqrt(
                    (1.0 / 2.0) * (
                        sigma[0, 0] * sigma[0, 0] + sigma[1, 1] * sigma[1, 1] +
                        (sigma[1, 1] - sigma[0, 0]) * (sigma[1, 1] - sigma[0, 0])
                        ) +
                    3.0 * sigma[0, 1] * sigma[0, 1]);
                if (stressValueId != 0)
                {
                    double[] Sigma = sigmaFV.GetDoubleValues(FieldDerivativeType.Value);
                    uint     dof   = sigmaFV.Dof;
                    Sigma[(feId - 1) * dof + 0] = sigma[0, 0]; // σxx
                    Sigma[(feId - 1) * dof + 1] = sigma[1, 1]; // σyy
                    Sigma[(feId - 1) * dof + 2] = sigma[0, 1]; // τxy
                }
                if (equivStressValueId != 0)
                {
                    double[] EqSigma = eqSigmaFV.GetDoubleValues(FieldDerivativeType.Value);
                    EqSigma[feId - 1] = misesStress;
                }
            }
        }
コード例 #8
0
ファイル: FieldValue.cs プロジェクト: lulzzz/IvyFEM
 public FieldValue(FieldValue src)
 {
     Copy(src);
 }
コード例 #9
0
ファイル: FaceFieldDrawer.cs プロジェクト: lulzzz/IvyFEM
        public void Update(FEWorld world)
        {
            FieldValue fv         = world.GetFieldValue(ValueId);
            uint       quantityId = fv.QuantityId;
            uint       dim        = world.Dimension;

            uint ptCnt = 0;

            if (IsNsvDraw)
            {
                ptCnt = fv.GetPointCount();
                // あとで実装する
                throw new NotImplementedException();
            }
            else
            {
                ptCnt = world.GetCoordCount(quantityId);
            }
            System.Diagnostics.Debug.Assert(VertexArray.PointCount == ptCnt);

            if (!IsntDisplacementValue)
            {
                // 変位を伴う場合

                if (dim == 2 &&
                    (fv.Type == FieldValueType.Scalar || fv.Type == FieldValueType.ZScalar))
                {
                    // 垂直方向の変位として捉える

                    System.Diagnostics.Debug.Assert(VertexArray.Dimension == 3);
                    for (int coId = 0; coId < ptCnt; coId++)
                    {
                        double[]            coord = world.GetCoord(quantityId, coId);
                        FieldDerivativeType dt    = ValueDt;
                        double value = fv.GetShowValue(coId, 0, dt);
                        VertexArray.VertexCoordArray[coId * 3 + 0] = coord[0];
                        VertexArray.VertexCoordArray[coId * 3 + 1] = coord[1];
                        VertexArray.VertexCoordArray[coId * 3 + 2] = value;
                    }
                }
                else
                {
                    System.Diagnostics.Debug.Assert(VertexArray.Dimension == dim);
                    for (int coId = 0; coId < ptCnt; coId++)
                    {
                        double[]            coord = world.GetCoord(quantityId, coId);
                        FieldDerivativeType dt    = ValueDt;
                        for (int iDim = 0; iDim < dim; iDim++)
                        {
                            double value = fv.GetShowValue(coId, iDim, dt);
                            VertexArray.VertexCoordArray[coId * dim + iDim] = coord[iDim] + value;
                        }
                    }
                }
            }
            else
            {
                System.Diagnostics.Debug.Assert(VertexArray.Dimension == dim);
                for (int coId = 0; coId < ptCnt; coId++)
                {
                    double[] coord = world.GetCoord(quantityId, coId);
                    for (int iDim = 0; iDim < dim; iDim++)
                    {
                        VertexArray.VertexCoordArray[coId * dim + iDim] = coord[iDim];
                    }
                }
            }

            if (world.IsFieldValueId(ColorValueId))
            {
                FieldValue          colorfv = world.GetFieldValue(ColorValueId);
                FieldDerivativeType dt      = ColorValueDt;
                bool isBubble        = colorfv.IsBubble;
                uint colorQuantityId = colorfv.QuantityId;
                uint colorPtCnt      = world.GetCoordCount(colorQuantityId);
                if (!ColorMap.IsFixedMinMax)
                {
                    double min;
                    double max;

                    colorfv.GetMinMaxShowValue(out min, out max, 0, dt);
                    ColorMap.MinValue = min;
                    ColorMap.MaxValue = max;
                }

                if (!isBubble)
                {
                    // color is assigned to vertex
                    if (ColorArray == null)
                    {
                        ColorArray = new float[colorPtCnt * 4];
                    }
                    for (int coId = 0; coId < colorPtCnt; coId++)
                    {
                        double   value = colorfv.GetShowValue(coId, 0, dt);
                        double[] color = ColorMap.GetColor(value);
                        ColorArray[coId * 4]     = (float)color[0];
                        ColorArray[coId * 4 + 1] = (float)color[1];
                        ColorArray[coId * 4 + 2] = (float)color[2];
                        ColorArray[coId * 4 + 3] = 0.0f;
                    }
                }
                else
                {
                    // color is assigned to face
                    for (int idp = 0; idp < DrawParts.Count; idp++)
                    {
                        FaceFieldDrawPart dp = DrawParts[idp];
                        dp.SetColors(ColorValueId, dt, world, ColorMap);
                    }
                }
            }

            if (NormalArray != null)
            {
                MakeNormal();
            }


            if (UVArray != null)
            {
                for (int coId = 0; coId < ptCnt; coId++)
                {
                    double[] coord = world.GetCoord(quantityId, coId);
                    UVArray[coId * 2 + 0] = coord[0] * TexScale;
                    UVArray[coId * 2 + 1] = coord[1] * TexScale;
                }
            }
        }
コード例 #10
0
ファイル: EdgeFieldDrawer.cs プロジェクト: lulzzz/IvyFEM
        public void Update(FEWorld world)
        {
            FieldValue fv         = world.GetFieldValue(ValueId);
            uint       quantityId = fv.QuantityId;
            uint       dim        = world.Dimension;
            uint       ptCnt      = LineCount * LinePtCount;
            uint       lineCnt    = LineCount;
            uint       drawDim    = VertexArray.Dimension;

            if (IsntDisplacementValue)
            {
                System.Diagnostics.Debug.Assert(drawDim == 2); // いまはそうなってる
                for (int iEdge = 0; iEdge < lineCnt; iEdge++)
                {
                    LineFE lineFE = LineFEs[iEdge];
                    for (int iPt = 0; iPt < LinePtCount; iPt++)
                    {
                        int      coId = lineFE.NodeCoordIds[iPt];
                        double[] co   = world.GetCoord(quantityId, coId);
                        VertexArray.VertexCoordArray[(iEdge * LinePtCount + iPt) * drawDim + 0] = co[0];
                        VertexArray.VertexCoordArray[(iEdge * LinePtCount + iPt) * drawDim + 1] = co[1];
                    }
                }
            }
            else
            {
                // 変位を伴う場合

                if (dim == 2 && drawDim == 3)
                {
                    for (int iEdge = 0; iEdge < LineCount; iEdge++)
                    {
                        LineFE lineFE = LineFEs[iEdge];
                        System.Diagnostics.Debug.Assert(lineFE.NodeCoordIds.Length == LinePtCount);
                        for (int iPt = 0; iPt < LinePtCount; iPt++)
                        {
                            int                 coId  = lineFE.NodeCoordIds[iPt];
                            double[]            coord = world.GetCoord(quantityId, coId);
                            FieldDerivativeType dt    = ValueDt;
                            double              value = fv.GetShowValue(coId, 0, dt);
                            VertexArray.VertexCoordArray[(iEdge * LinePtCount + iPt) * drawDim + 0] = coord[0];
                            VertexArray.VertexCoordArray[(iEdge * LinePtCount + iPt) * drawDim + 1] = coord[1];
                            VertexArray.VertexCoordArray[(iEdge * LinePtCount + iPt) * drawDim + 2] = value;
                        }
                    }
                }
                else
                {
                    for (int iEdge = 0; iEdge < lineCnt; iEdge++)
                    {
                        LineFE lineFE = LineFEs[iEdge];
                        System.Diagnostics.Debug.Assert(lineFE.NodeCoordIds.Length == LinePtCount);
                        for (int iPt = 0; iPt < LinePtCount; iPt++)
                        {
                            int                 coId  = lineFE.NodeCoordIds[iPt];
                            double[]            coord = world.GetCoord(quantityId, coId);
                            FieldDerivativeType dt    = ValueDt;
                            for (int iDim = 0; iDim < drawDim; iDim++)
                            {
                                double value = fv.GetShowValue(coId, iDim, dt);
                                VertexArray.VertexCoordArray[(iEdge * LinePtCount + iPt) * drawDim + iDim] =
                                    coord[iDim] + value;
                            }
                        }
                    }
                }
            }
        }