Ejemplo n.º 1
0
        /// <summary>
        /// Consistency and penalty term
        /// </summary>
        void INonlinEdgeForm_V.BoundaryEdge(ref EdgeFormParams efp,
                                            MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin,
                                            MultidimensionalArray fin)
        {
            int NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1); // no of nodes per cell
            int dimension  = efp.GridDat.SpatialDimension;

            for (int cell = 0; cell < NumOfCells; cell++)   // loop over cells...
            {
                int iEdge = efp.e0 + cell;

                // Penalty is calculated according to the formula in background cells
                int    jCellIn = this.GridData.Edges.CellIndices[iEdge, 0];
                double penalty = 2 * this.penalties[jCellIn];

                byte          edgeTag  = this.GridData.iGeomEdges.EdgeTags[iEdge];
                XDGHeatBcType edgeType = this.boundaryCondMap.EdgeTag2Type[edgeTag];
                Func <double[], double, double> dirichletFunction = this.boundaryCondMap.bndFunction["u"][edgeTag];

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...

                // Global node coordinates
                {
                    double[] X = new double[dimension];
                    for (int i = 0; i < dimension; i++)
                    {
                        X[i] = efp.NodesGlobal[cell, node, i];
                    }

                    // SIPG Flux Loops
                    double viscosityIn = efp.ParameterVars_IN[0][cell, node];

                    switch (edgeType)
                    {
                    case XDGHeatBcType.Dirichlet:
                        double g_D = dirichletFunction(X, efp.time);

                        double flux = 0.0;
                        for (int d = 0; d < GridData.SpatialDimension; d++)
                        {
                            double n = efp.Normals[cell, node, d];
                            flux -= viscosityIn * GradUin[0][cell, node, d] * n;               // Consistency term
                        }
                        flux            += viscosityIn * (Uin[0][cell, node] - g_D) * penalty; // Penalty term
                        fin[cell, node] += flux;
                        break;

                    default:
                        // Boundary value is zero neumann boundary, i.e. do nothing
                        break;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Symmetry term
        /// </summary>
        void INonlinEdgeForm_GradV.BoundaryEdge(ref EdgeFormParams efp,
                                                MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin,
                                                MultidimensionalArray fin)
        {
            int NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1); // no of nodes per cell
            int dimension  = efp.GridDat.SpatialDimension;

            for (int cell = 0; cell < NumOfCells; cell++)   // loop over cells...
            {
                int iEdge = efp.e0 + cell;

                byte          edgeTag  = this.GridData.iGeomEdges.EdgeTags[iEdge];
                XDGHeatBcType edgeType = this.boundaryCondMap.EdgeTag2Type[edgeTag];
                Func <double[], double, double> dirichletFunction = this.boundaryCondMap.bndFunction["u"][edgeTag];

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...

                // Global node coordinates
                {
                    double[] X = new double[dimension];
                    for (int i = 0; i < dimension; i++)
                    {
                        X[i] = efp.NodesGlobal[cell, node, i];
                    }

                    switch (edgeType)
                    {
                    case XDGHeatBcType.Dirichlet:
                        double g_D = dirichletFunction(X, efp.time);
                        //double uJump = 0.5 * (Uin[0][cell, node] - g_D);
                        double uJump  = 1.0 * (Uin[0][cell, node] - g_D);
                        double fluxIn = efp.ParameterVars_IN[0][cell, node] * uJump;

                        for (int d = 0; d < GridData.SpatialDimension; d++)
                        {
                            double n = efp.Normals[cell, node, d];
                            fin[cell, node, d] -= fluxIn * n;
                        }
                        break;

                    default:
                        // Boundary value is zero neumann boundary, i.e. do nothing
                        break;
                    }
                }
            }
        }
        public override double BoundaryEdgeForm(ref CommonParamsBnd inp, double[] _uA, double[,] _Grad_uA, double _vA, double[] _Grad_vA)
        {
            double Acc = 0.0;

            double pnlty = 2 * this.GetPenalty(inp.jCellIn, -1);
            double nuA   = this.Nu(inp.X, inp.Parameters_IN, inp.jCellIn);

            XDGHeatBcType edgeType = this.boundaryCondMap.EdgeTag2Type[inp.EdgeTag];

            switch (edgeType)
            {
            case XDGHeatBcType.Dirichlet:
                Func <double[], double, double> dirichletFunction = this.boundaryCondMap.bndFunction["u"][inp.EdgeTag];
                double g_D = dirichletFunction(inp.X, inp.time);

                for (int d = 0; d < inp.D; d++)
                {
                    double nd = inp.Normal[d];
                    Acc += (nuA * _Grad_uA[0, d]) * (_vA) * nd;            // consistency
                    Acc += (nuA * _Grad_vA[d]) * (_uA[0] - g_D) * nd;      // symmetry
                }
                Acc *= this.m_alpha;

                Acc -= nuA * (_uA[0] - g_D) * (_vA - 0) * pnlty;     // penalty
                break;

            case XDGHeatBcType.ZeroNeumann:
                double g_N = 0.0;

                Acc += nuA * g_N * _vA * this.m_alpha;          // consistency
                break;

            default:
                throw new NotSupportedException();
            }

            return(Acc);
        }