/// <summary> /// accumulates the Laplacian of field <paramref name="f"/> times /// <paramref name="alpha"/> to this field. /// </summary> /// <remarks> /// see <see cref="Laplacian(double, DGField,CellMask)"/>; /// </remarks> public void Laplacian(double alpha, DGField f) { Laplacian(alpha, f, null); }
/// <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); } }
/// <summary> /// symbolic derivation, cell-by-cell;<br/> /// accumulates the derivative of DG field <paramref name="f"/> /// (along the <paramref name="d"/>-th axis) times <paramref name="alpha"/> /// to this field, i.e. <br/> /// this = this + <paramref name="alpha"/> /// \f$ \cdot \frac{\partial}{\partial x_d} \f$ <paramref name="f"/>; /// </summary> /// <param name="f"></param> /// <param name="d"> /// 0 for the x-derivative, 1 for the y-derivative, 2 for the /// z-derivative /// </param> /// <param name="alpha"> /// scaling of <paramref name="f"/>; /// </param> /// <param name="em"> /// An optional restriction to the domain in which the derivative 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 for this case would be e.g. /// <see cref="BoSSS.Foundation.Grid.GridData.BoundaryCells"/>.)<br/> /// if null, the computation is carried out in the whole domain /// </param> /// <remarks> /// The derivative is calculated by a cell-by-cell (symbolic) /// derivation of the DG polynomials, therefor the (effective) DG /// polynomial degree is one lower than the degree of /// <paramref name="f"/>;<br/> /// In comparison to <see cref="DerivativeByFlux"/>, this method should /// be much faster, because no quadrature is involved; /// </remarks> abstract public void Derivative(double alpha, DGField f, int d, CellMask em);
/// <summary> /// accumulates the derivative of DG field <paramref name="f"/> /// (along the <paramref name="d"/>-th axis) times <paramref name="alpha"/> /// to this field, i.e. <br/> /// this = this + <paramref name="alpha"/>* \f$ \frac{\partial}{\partial x_d} \f$ <paramref name="f"/>; /// </summary> /// <param name="f"></param> /// <param name="d"> /// 0 for the x-derivative, 1 for the y-derivative, 2 for the z-derivative /// </param> /// <param name="alpha"> /// scaling of <paramref name="f"/>; /// </param> virtual public void Derivative(double alpha, DGField f, int d) { Derivative(alpha, f, d, null); }
/// <summary> /// Involves all <see cref="ISpatialOperator.ParameterFactories"/> events /// and all <see cref="IParameterHandling.MyParameterAlloc"/> methods in the operators equation components /// in order to allocate operator storage. /// </summary> public static DGField[] InvokeParameterFactory(this ISpatialOperator op, IEnumerable <DGField> __DomainFields) { if (!op.IsCommited) { throw new NotSupportedException("not allowed before commit."); } var _DomainFields = __DomainFields.ToArray(); if (_DomainFields.Length != op.DomainVar.Count) { throw new ArgumentException("Mismatch in number of domain variables."); } int NoOfParams = op.ParameterVar.Count; DGField[] ret = new DGField[NoOfParams]; var DomainVarsDict = new Dictionary <string, DGField>(); for (int iVar = 0; iVar < _DomainFields.Length; iVar++) { DomainVarsDict.Add(op.DomainVar[iVar], _DomainFields[iVar]); } // invoke factories by the operator if (op.ParameterFactories != null) { foreach (DelParameterFactory Factory in op.ParameterFactories) { var ttt = Factory(DomainVarsDict); foreach (var tt in ttt) { int idx = op.ParameterVar.IndexOf(tt.ParameterName); if (idx < 0) { throw new Exception($"Illegal parameter name {tt.ParameterName} provided by parameter factory -- not in the operator parameter list."); } ret[idx] = tt.ParamField; } } } bool ComponentFactoryUseful(IParameterHandling _ph, out int[] targidx) { var phParams = _ph.ParameterOrdering; if (phParams == null) { targidx = new int[0]; return(false); } targidx = new int[phParams.Count]; int c = 0; bool useful = false; foreach (string phParamName in phParams) { int idx = op.ParameterVar.IndexOf(phParamName); if (idx < 0) { throw new ApplicationException("should not happen if operator is committed and verified"); } targidx[c] = idx; if (ret[idx] == null) { useful = true; // some parameter has not been allocated yet } c++; } return(useful); } DGField[] GetArguments(IEquationComponent c) { var cArgs = c.ArgumentOrdering; if (cArgs == null) { return(new DGField[0]); } DGField[] rr = new DGField[cArgs.Count]; for (int i = 0; i < rr.Length; i++) { rr[i] = DomainVarsDict[cArgs[i]]; } return(rr); } // invoke factories in equation components foreach (string codName in op.CodomainVar) { foreach (IEquationComponent comp in op.EquationComponents[codName]) { if (comp is IParameterHandling ph) { if (ComponentFactoryUseful(ph, out int[] targIdx))
static string ColName_DGfield(DGField f, int n) { return(f.Identification + "_mode" + n); }
public LocalLxNormQuadrature(DGField owner, ScalarFunction func, Func <double[], double, double, double> Map, ICompositeQuadRule <QuadRule> rule) : base(owner, func, Map, rule) { m_localLxNorms = new double[rule.NumberOfItems]; }