/// <summary>
        /// Calculates the DG-projection (with respect to the DG-basis
        /// of this field, <see cref="Basis"/>) of
        /// <paramref name="alpha"/>*<paramref name="a"/>*<paramref name="b"/>
        /// and, depending on the value of <paramref name="accumulateResult"/>,
        /// either adds or assigns it to this field.
        /// </summary>
        /// <param name="a">1st multiplicand</param>
        /// <param name="b">2nd multiplicand</param>
        /// <param name="alpha">scaling for <paramref name="a"/>*<paramref name="b"/></param>
        /// <param name="em">
        /// An optional restriction to the domain in which the projection is
        /// computed (it may, e.g. be only required in boundary cells, so a
        /// computation over the whole domain would be a waste of computational
        /// power. A proper execution mask would be see e.g.
        /// <see cref="GridData.BoundaryCells"/>.)<br/>
        /// if null, the computation is carried out in the whole domain;
        /// </param>
        /// <param name="accumulateResult">
        /// Tells this method whether to accumulate (true) or not (false)
        /// </param>
        virtual public void ProjectProduct(double alpha, DGField a, DGField b, CellMask em, bool accumulateResult)
        {
            if (!object.ReferenceEquals(a.Basis.GridDat, this.Basis.GridDat))
            {
                throw new ArgumentException("field is associated to another grid.", "a");
            }
            if (!object.ReferenceEquals(b.Basis.GridDat, this.Basis.GridDat))
            {
                throw new ArgumentException("field is associated to another grid.", "b");
            }

            if (!accumulateResult)
            {
                if (a == this)
                {
                    a = (DGField)a.Clone();

                    if (b == this)
                    {
                        b = a;
                    }
                }
                else if (b == this)
                {
                    b = (DGField)b.Clone();
                }

                this.Clear();
            }

            SpatialOperator multOp = new SpatialOperator(new string[] { "a", "b" },
                                                         new string[] { "res" },
                                                         QuadOrderFunc.NonLinear(2));

            multOp.EdgeQuadraturSchemeProvider   = g => new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(g));
            multOp.VolumeQuadraturSchemeProvider = g => new CellQuadratureScheme(true, em);
            multOp.EquationComponents["res"].Add(new MultiplySource());
            multOp.Commit();

            var ev = multOp.GetEvaluatorEx(
                new[] { a, b }, null, this.Mapping);

            ev.Evaluate <CoordinateVector>(alpha, 1.0, this.CoordinateVector);
        }
        /// <summary>
        /// accumulates
        /// <paramref name="alpha"/>*<paramref name="f"/>(<paramref name="U"/>)
        /// to this field;
        /// </summary>
        /// <param name="alpha">scaling</param>
        /// <param name="f">
        /// some function
        /// - 1st argument: position in physical space
        /// - 2nd argument: values of fields in <paramref name="U"/> at respective position
        /// - 3rd argument: cell index
        /// - return value: value of function that should be projected at the respective position
        /// </param>
        /// <param name="cqs">
        /// cell quadrature scheme: domain and quadrature rule
        /// </param>
        /// <param name="U">
        /// arguments for <paramref name="f"/>
        /// </param>
        public void ProjectFunction(double alpha, Func <Vector, double[], int, double> f, CellQuadratureScheme cqs, params DGField[] U)
        {
            string[] Dom = new string[U.Length];
            for (int i = 0; i < Dom.Length; i++)
            {
                Dom[i] = "_" + i;
            }

            string[] Cod = new string[] { "res" };

            SpatialOperator src = new SpatialOperator(Dom, Cod, QuadOrderFunc.NonLinear(3));

            src.EquationComponents[Cod[0]].Add(new ProjectFunctionSource(Dom, f));
            src.EdgeQuadraturSchemeProvider   = g => new EdgeQuadratureScheme(false, EdgeMask.GetEmptyMask(this.Basis.GridDat));
            src.VolumeQuadraturSchemeProvider = g => cqs;
            src.Commit();

            var ev = src.GetEvaluatorEx(
                new CoordinateMapping(U), null, this.Mapping);

            ev.Evaluate(alpha, 1.0, this.CoordinateVector);
        }
Esempio n. 3
0
 /// <summary>
 /// creates the spatial operator that consists only of component <paramref name="c"/>
 /// </summary>
 public static SpatialOperator Operator(this IEquationComponent c, int DegreeOfNonlinearity = 1)
 {
     return(Operator(c, QuadOrderFunc.NonLinear(DegreeOfNonlinearity)));
 }
 /// <summary>
 /// creates the spatial operator that consists only of component <paramref name="c"/>
 /// </summary>
 public static SpatialOperator Operator(this IEquationComponent c, int DegreeOfNonlinearity = 1, Func <IGridData, EdgeQuadratureScheme> edgeSchemeProvider = null, Func <IGridData, CellQuadratureScheme> cellSchemeProvider = null)
 {
     return(Operator(c, QuadOrderFunc.NonLinear(DegreeOfNonlinearity), edgeSchemeProvider, cellSchemeProvider));
 }