/// <summary> /// Updating the <see cref="CurrentLin"/> -- operator; /// </summary> /// <param name="CurrentState">linearization point</param> protected void Update(IEnumerable <DGField> CurrentState) { if (!(this.ProblemMapping.BasisS.Count == CurrentState.Count())) { throw new ArgumentException("missmatch in number of fields."); } BlockMsrMatrix OpMtxRaw, MassMtxRaw; double[] OpAffineRaw; this.m_AssembleMatrix(out OpMtxRaw, out OpAffineRaw, out MassMtxRaw, CurrentState.ToArray()); CurrentLin = new MultigridOperator(this.m_AggBasisSeq, this.ProblemMapping, OpMtxRaw.CloneAs(), MassMtxRaw, this.m_MultigridOperatorConfig); OpAffineRaw = OpAffineRaw.CloneAs(); if (this.RHSRaw != null) { OpAffineRaw.AccV(-1.0, this.RHSRaw); } if (LinearizationRHS == null || LinearizationRHS.Length != this.CurrentLin.Mapping.LocalLength) { LinearizationRHS = new double[this.CurrentLin.Mapping.LocalLength]; } else { LinearizationRHS.ClearEntries(); } CurrentLin.TransformRhsInto(OpAffineRaw, this.LinearizationRHS); this.LinearizationRHS.ScaleV(-1.0); }
/// <summary> /// Updating the <see cref="CurrentLin"/> -- operator; /// </summary> /// <param name="CurrentState">linearization point</param> /// <param name="HomotopyValue"> /// <see cref="ISpatialOperator.CurrentHomotopyValue"/> /// </param> protected void UpdateLinearization(IEnumerable <DGField> CurrentState, double HomotopyValue) { if (!(this.ProblemMapping.BasisS.Count == CurrentState.Count())) { throw new ArgumentException("mismatch in number of fields."); } SetHomotopyValue(HomotopyValue); // the real call: this.m_AssembleMatrix(out BlockMsrMatrix OpMtxRaw, out double[] OpAffineRaw, out BlockMsrMatrix MassMtxRaw, CurrentState.ToArray(), true, out ISpatialOperator abstractOperator); AbstractOperator = abstractOperator; // blabla: CurrentLin = new MultigridOperator(this.m_AggBasisSeq, this.ProblemMapping, OpMtxRaw.CloneAs(), MassMtxRaw, this.m_MultigridOperatorConfig, AbstractOperator.DomainVar.Select(varName => AbstractOperator.FreeMeanValue[varName]).ToArray()); OpAffineRaw = OpAffineRaw.CloneAs(); if (this.RHSRaw != null) { OpAffineRaw.AccV(-1.0, this.RHSRaw); } if (LinearizationRHS == null || LinearizationRHS.Length != this.CurrentLin.Mapping.LocalLength) { LinearizationRHS = new double[this.CurrentLin.Mapping.LocalLength]; } else { LinearizationRHS.ClearEntries(); } CurrentLin.TransformRhsInto(OpAffineRaw, this.LinearizationRHS, true); this.LinearizationRHS.ScaleV(-1.0); }
/// <summary> /// Finite difference directional derivative Approximate f'(x) w /// C.T.Kelley, April 1, 2003 /// This code comes with no guarantee or warranty of any kind. /// </summary> /// <param name="SolutionVec">Solution point</param> /// <param name="w">Direction</param> /// <param name="f0">f0, usally has been calculated earlier</param> /// <returns></returns> public double[] dirder(CoordinateVector SolutionVec, double[] currentX, double[] w, double[] f0) { using (var tr = new FuncTrace()) { double epsnew = 1E-7; int n = SolutionVec.Length; double[] fx = new double[f0.Length]; // Scale the step if (w.L2Norm().MPISum() == 0) { fx.Clear(); return(fx); } var normw = w.L2NormPow2().MPISum().Sqrt(); double xs = GenericBlas.InnerProd(currentX, w).MPISum() / normw; if (xs != 0) { epsnew = epsnew * Math.Max(Math.Abs(xs), 1) * Math.Sign(xs); } epsnew = epsnew / w.L2Norm().MPISum(); var del = currentX.CloneAs(); del.AccV(epsnew, w); double[] temp = new double[SolutionVec.Length]; temp.CopyEntries(SolutionVec); this.CurrentLin.TransformSolFrom(SolutionVec, del); // Just evaluate linearized operator //var OpAffineRaw = this.LinearizationRHS.CloneAs(); //this.CurrentLin.OperatorMatrix.SpMV(1.0, new CoordinateVector(SolutionVec.Mapping.Fields.ToArray()), 1.0, OpAffineRaw); //CurrentLin.TransformRhsInto(OpAffineRaw, fx); //EvaluateOperator(1.0, SolutionVec.Mapping.Fields, fx); this.m_AssembleMatrix(out OpMtxRaw, out OpAffineRaw, out MassMtxRaw, SolutionVec.Mapping.Fields.ToArray()); OpMtxRaw.SpMV(1.0, new CoordinateVector(SolutionVec.Mapping.Fields.ToArray()), 1.0, OpAffineRaw); CurrentLin.TransformRhsInto(OpAffineRaw, fx); SolutionVec.CopyEntries(temp); // (f1 - f0) / epsnew fx.AccV(1, f0); fx.ScaleV(1 / epsnew); return(fx); } }
/// <summary> /// Evaluation of the nonlinear operator. /// </summary> /// <param name="alpha"></param> /// <param name="CurrentState"> /// Current state of DG fields /// </param> /// <param name="beta"> /// Pre-scaling of <paramref name="Output"/>. /// </param> /// <param name="Output"></param> protected void EvaluateOperator(double alpha, IEnumerable <DGField> CurrentState, double[] Output) { BlockMsrMatrix OpMtxRaw, MassMtxRaw; double[] OpAffineRaw; this.m_AssembleMatrix(out OpMtxRaw, out OpAffineRaw, out MassMtxRaw, CurrentState.ToArray()); OpMtxRaw.SpMV(alpha, new CoordinateVector(CurrentState.ToArray()), 1.0, OpAffineRaw); CurrentLin.TransformRhsInto(OpAffineRaw, Output); }