/// <summary>
        /// accumulates the projection of some vector field to this field, i.e.
        /// \f[
        ///   this = this + \alpha \cdot \| \vec{vec} \|.
        /// \f]
        /// </summary>
        /// <param name="alpha">factor \f$ \alpha \f$ </param>
        /// <param name="vec">vector field \f$ \vec{vec} \f$ </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 computation power. If null, the computation is carried out in the whole domain;
        /// </param>
        virtual public void ProjectAbs(double alpha, CellMask em, params DGField[] vec)
        {
            int K = vec.Length;

            string[] args = new string[K];
            for (int k = 0; k < K; k++)
            {
                args[k] = "_" + k;
            }

            SpatialOperator powOp = new SpatialOperator(args, new string[] { "res" }, QuadOrderFunc.SumOfMaxDegrees());

            powOp.EquationComponents["res"].Add(new AbsSource(args));

            powOp.EdgeQuadraturSchemeProvider   = g => new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(this.Basis.GridDat));
            powOp.VolumeQuadraturSchemeProvider = g => new CellQuadratureScheme(true, em);

            powOp.Commit();

            CoordinateVector coDom = new CoordinateVector(this);

            var ev = powOp.GetEvaluatorEx(
                new CoordinateMapping(vec),
                null,
                coDom.Mapping);

            ev.Evaluate <CoordinateVector>(alpha, 1.0, coDom); // only sources, no edge integrals required
        }
        /// <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="accumulateResult">
        /// Tells this method whether to accumulate (true) or not (false)
        /// </param>
        /// <param name="cm">
        /// optional restriction to computational domain
        /// </param>
        virtual public void ProjectQuotient(
            double alpha, DGField a, DGField b, CellMask cm, 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 fracOp = new SpatialOperator(new string[] { "a", "b" },
                                                         new string[] { "res" },
                                                         QuadOrderFunc.Linear());

            //QuadOrderFunc.NonLinear(2));
            fracOp.EdgeQuadraturSchemeProvider   = g => new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(g));
            fracOp.VolumeQuadraturSchemeProvider = g => new CellQuadratureScheme(true, cm);
            fracOp.EquationComponents["res"].Add(new QuotientSource());
            fracOp.Commit();

            CoordinateVector coDom = this.CoordinateVector;

            var ev = fracOp.GetEvaluatorEx(
                new CoordinateMapping(a, b), null, coDom.Mapping);

            ev.Evaluate <CoordinateVector>(alpha, 1.0, coDom);
        }
Example #3
0
        /// <summary>
        /// Accumulates the DG-projection (with respect to the DG-basis
        /// of this field, <see cref="Basis"/>) of
        /// <paramref name="alpha"/>*<paramref name="f"/>^<paramref name="pow"/> to this field;
        /// </summary>
        /// <param name="alpha">scaling for accumulation</param>
        /// <param name="f">operand</param>
        /// <param name="pow">exponent</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 computation
        /// power. A proper execution mask would be see e.g.
        /// <see cref="GridData.BoundaryCells"/>.)
        /// if null, the computation is carried out in the whole domain;
        /// </param>
        virtual public void ProjectPow(double alpha, DGField f, double pow, CellMask em)
        {
            if (!object.ReferenceEquals(f.Basis.GridDat, this.Basis.GridDat))
            {
                throw new ArgumentException("field is associated to another context.", "a");
            }

            SpatialOperator powOp = new SpatialOperator(new string[] { "f" },
                                                        new string[] { "res" },
                                                        QuadOrderFunc.SumOfMaxDegrees());

            powOp.EquationComponents["res"].Add(new PowSource(pow));
            powOp.Commit();

            CoordinateVector coDom = this.CoordinateVector;

            var ev = powOp.GetEvaluatorEx(
                new CoordinateMapping(f), null, coDom.Mapping,
                edgeQrCtx: new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(this.Basis.GridDat)),
                volQrCtx: new CellQuadratureScheme(true, em));

            ev.Evaluate <CoordinateVector>(alpha, 1.0, coDom); // only sources, no edge integrals required
        }
Example #4
0
 public MyEnumerator(CoordinateVector owner)
 {
     m_Owner = owner;
 }
Example #5
0
 public MyGenericEnumerator(CoordinateVector owner)
     : base(owner)
 {
 }
        /// <summary>
        /// Evaluates this operator for given DG fields;
        /// </summary>
        /// <param name="DomainMapping">
        /// the domain variables, or "input data" for the operator; the number
        /// of elements must be equal to the number of elements in the
        /// <see cref="DomainVar"/>-list;
        /// </param>
        /// <param name="Params">
        /// List of parameter fields; May be null
        /// </param>
        /// <param name="CodomainMapping">
        /// the co-domain variables, or "output" for the evaluation of the
        /// operator; the number of elements must be equal to the number of
        /// elements in the <see cref="CodomainVar"/>-list;
        /// </param>
        /// <param name="alpha">
        /// scaling of the operator
        /// </param>
        /// <param name="beta">
        /// scaling of the accumulator (<paramref name="CodomainMapping"/>);
        /// </param>
        /// <param name="sgrd">
        /// subgrid, for restricted evaluation; null indicates evaluation on
        /// the full grid.
        /// </param>
        /// <param name="bndMode">
        /// Treatment of subgrid boundaries, if <paramref name="sgrd"/> is not
        /// null. See <see cref="Evaluator"/>
        /// </param>
        /// <param name="qInsEdge">
        /// Optional definition of the edge quadrature scheme. Since this
        /// already implies a domain of integration, must be null if
        /// <paramref name="sgrd"/> is not null.
        /// </param>
        /// <param name="qInsVol">
        /// Optional definition of the volume quadrature scheme. Since this
        /// already implies a domain of integration, must be null if
        /// <paramref name="sgrd"/> is not null.
        /// </param>
        /// <remarks>
        /// If some of the input data, <paramref name="DomainMapping"/>, is
        /// contained in the  output data, <paramref name="CodomainMapping"/>,
        /// these DG fields will be cloned to ensure correct operation of the
        /// operator evaluation.<br/>
        /// It is not a good choice to use this function if this operator
        /// should be evaluated multiple times and  contains linear components
        /// (i.e. <see cref="ContainsLinear"/> returns true); If the latter is
        /// the case, the matrix which represents the linear components of the
        /// operator must be computed first, which is computational- and
        /// memory-intensive; After execution of this method, the matrix will
        /// be lost; If multiple evaluation is desired, the
        /// <see cref="Evaluator"/>-class should be used, in which the matrix
        /// of the operator will persist; However, if no linear components are
        /// present, the performance of this function should be almost
        /// comparable to the use of the <see cref="Evaluator"/>-class;
        /// </remarks>
        static public void Evaluate(
            this SpatialOperator op,
            double alpha, double beta,
            CoordinateMapping DomainMapping, IList <DGField> Params, CoordinateMapping CodomainMapping,
            SubGrid sgrd = null,
            EdgeQuadratureScheme qInsEdge = null,
            CellQuadratureScheme qInsVol  = null,
            SpatialOperator.SubGridBoundaryModes bndMode = SubGridBoundaryModes.OpenBoundary,
            double time = double.NaN)                  //
        {
            using (new FuncTrace()) {
                if (sgrd != null && (qInsEdge != null || qInsVol != null))
                {
                    throw new ArgumentException("Specification of Subgrid and quadrature schemes is exclusive: not allowed to specify both at the same time.", "sgrd");
                }
#if DEBUG
                op.Verify(); //this has already been done during this.Commit()
#endif

                IList <DGField> _DomainFields          = DomainMapping.Fields;
                IList <DGField> _CodomainFields        = CodomainMapping.Fields;
                DGField[]       _DomainFieldsRevisited = new DGField[_DomainFields.Count];

                bool a = false;
                for (int i = 0; i < _DomainFields.Count; i++)
                {
                    DGField f = _DomainFields[i];

                    if (_CodomainFields.Contains(f))
                    {
                        // some of the domain variables (input data)
                        // is also a member of the codomain variables (output);
                        // the data need to be cloned to provide correct results
                        a = true;
                        _DomainFieldsRevisited[i] = (DGField)f.Clone();
                    }
                    else
                    {
                        _DomainFieldsRevisited[i] = f;
                    }
                }

                CoordinateMapping domainMappingRevisited;
                if (a)
                {
                    domainMappingRevisited = new CoordinateMapping(_DomainFieldsRevisited);
                }
                else
                {
                    domainMappingRevisited = DomainMapping;
                }

                if (sgrd != null)
                {
                    CellMask cm = (sgrd == null) ? null : sgrd.VolumeMask;
                    EdgeMask em = (sgrd == null) ? null : sgrd.AllEdgesMask;

                    qInsEdge = new EdgeQuadratureScheme(true, em);
                    qInsVol  = new CellQuadratureScheme(true, cm);
                }

                var ev = op.GetEvaluatorEx(
                    domainMappingRevisited, Params, CodomainMapping,
                    qInsEdge,
                    qInsVol);

                if (sgrd != null)
                {
                    ev.ActivateSubgridBoundary(sgrd.VolumeMask, bndMode);
                }
                CoordinateVector outp = new CoordinateVector(CodomainMapping);
                ev.time = time;
                ev.Evaluate <CoordinateVector>(alpha, beta, outp);
            }
        }