Ejemplo n.º 1
0
        /// <summary>
        /// TE 右键单击事件
        /// </summary>
        /// <param name="Flags"></param>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="pbHandled"></param>
        void TE_OnRButtonDown(int Flags, int X, int Y, ref object pbHandled)
        {
            if (En == "DrawGeo" && !this.LockRButton)
            {
                try
                {
                    ITerraExplorerObject61 pp = this.SgWorld.Creator.GetObject(this.CurrObjectID);
                    this.mTerrainPolygon61 = pp as ITerrainPolygon61;
                    IGeometry        geo              = this.mTerrainPolygon61.Geometry;
                    IPolygon         pPolygon         = geo as IPolygon;
                    ISpatialOperator _SpatialOperator = pPolygon.SpatialOperator;

                    uint nLineColor = 0xFF00FF00; // Abgr value -> solid green
                    uint nFillColor = 0x7FFF0000; // Abgr value -> 50% transparent blue

                    this.geo = _SpatialOperator.buffer((double)this.spinEdit1.Value);
                    this.SgWorld.Creator.CreatePolygon(this.geo, nLineColor, nFillColor, AltitudeTypeCode.ATC_ON_TERRAIN, GroupID, "Buffer" + System.Guid.NewGuid().ToString().Substring(0, 6));
                    this.LockRButton = true;
                    //Program.TE.Save();

                    this.En = null;
                    this.simpleButton2.Checked = false;
                }
                catch (Exception)
                {
                }
            }
        }
        /// <summary>
        /// returns a collection of equation components of a certain type (<typeparamref name="T"/>)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="CatParams">
        /// if true, parameter variables (see <see cref="IEquationComponent.ParameterOrdering"/>)
        /// are concatenated with domain variable names (see <see cref="IEquationComponent.ArgumentOrdering"/>).
        /// </param>
        /// <param name="F">
        /// optional filter;
        /// should return true, if the component should be added, false if not;
        /// </param>
        /// <param name="vectorizer">
        /// vectorizer option: translate some equation component to another one
        /// </param>
        static public EquationComponentArgMapping <T>[] GetArgMapping(ISpatialOperator op, bool CatParams = false, Func <T, bool> F = null, Func <IEquationComponent, IEquationComponent> vectorizer = null)
        {
//             public EquationComponentArgMapping<T>[] GetArgMapping<T>(                  bool CatParams = false, Func<T, bool> F = null, Func<IEquationComponent, IEquationComponent> vectorizer = null) where T : IEquationComponent {

            if (!op.IsCommited)
            {
                throw new ApplicationException("Commit() has to be called prior to this method.");
            }

            int Gamma = op.CodomainVar.Count;

            var ret = new EquationComponentArgMapping <T> [Gamma];

            for (int i = 0; i < Gamma; i++)
            {
                var codName = op.CodomainVar[i];
                ret[i] = new EquationComponentArgMapping <T>(op,
                                                             codName,
                                                             op.DomainVar,
                                                             CatParams ? op.ParameterVar : null,
                                                             F, vectorizer);
            }

            return(ret);
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
        protected void SetHomotopyValue(double HomotopyValue)
        {
            if (HomotopyValue < 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            if (HomotopyValue > 1)
            {
                throw new ArgumentOutOfRangeException();
            }


            if (AbstractOperator == null && HomotopyValue != 1)
            {
                // do one call just to attain the spatial operator;
                // not very efficient, but ok for the moment

                var dummyState = this.CurrentLin.BaseGridProblemMapping.BasisS.Select(delegate(Basis b) {
                    DGField r;
                    if (b is XDGBasis xb)
                    {
                        r = new XDGField(xb);
                    }
                    else
                    {
                        r = new SinglePhaseField(b);
                    }
                    return(r);
                }).ToArray();

                this.m_AssembleMatrix(out var OpMtxRaw, out _, out _, dummyState, false, out var _Dummy);
                Debug.Assert(OpMtxRaw == null); // only evaluation ==> OpMatrix must be null
                this.AbstractOperator = _Dummy;
            }

            if (AbstractOperator == null && HomotopyValue != 1.0)
            {
                throw new NotSupportedException("unable to attain operator for homotopy update");
            }

            if (AbstractOperator != null && HomotopyValue != AbstractOperator.CurrentHomotopyValue)
            {
                // set homotopy value
                AbstractOperator.CurrentHomotopyValue = HomotopyValue;
            }
        }
Ejemplo n.º 5
0
        /// <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>
        /// <param name="HomotopyValue">
        /// <see cref="ISpatialOperator.CurrentHomotopyValue"/>
        /// </param>
        protected void EvaluateOperator(double alpha, IEnumerable <DGField> CurrentState, double[] Output, double HomotopyValue)
        {
            if (alpha != 1.0)
            {
                throw new NotSupportedException("some moron has removed this");
            }

            SetHomotopyValue(HomotopyValue);

            // the real call:
            this.m_AssembleMatrix(out BlockMsrMatrix OpMtxRaw, out double[] OpAffineRaw, out BlockMsrMatrix MassMtxRaw, CurrentState.ToArray(), false, out var Dummy);
            if (OpMtxRaw != null)
            {
                // only evaluation ==> OpMatrix must be null
                throw new ApplicationException($"The provided {typeof(OperatorEvalOrLin).Name} is not correctly implemented.");
            }
            this.AbstractOperator = Dummy;

            CurrentLin.TransformRhsInto(OpAffineRaw, Output, false);
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Callback-routine (<see cref="OperatorEvalOrLin"/>) to update the linear resp. linearized system,
 /// see <see cref="OperatorEvalOrLin"/> resp. <see cref="NonlinearSolver.m_AssembleMatrix"/>.
 /// </summary>
 /// <param name="argCurSt">Input, current state of solution.</param>
 /// <param name="System">Output.</param>
 /// <param name="Affine">Output.</param>
 /// <param name="MassMatrix">
 /// Mass matrix including agglomeration, without any scaling,
 /// required for block-precond.
 /// </param>
 /// <param name="Linearization">
 /// - true: assemble matrix and affine vector
 /// - false: evaluate operator (<paramref name="System"/> will be null)
 /// </param>
 /// <param name="abstractOperator">
 ///  the original operator that somehow produced the matrix; yes, this API is convoluted piece-of-shit
 /// </param>
 abstract protected void AssembleMatrixCallback(out BlockMsrMatrix System, out double[] Affine, out BlockMsrMatrix MassMatrix, DGField[] argCurSt, bool Linearization, out ISpatialOperator abstractOperator);
Ejemplo n.º 7
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="rootQuery">Root query</param>
 /// <param name="predicate">Predicate</param>
 /// <param name="operator">Operator</param>
 /// <param name="value">Value</param>
 public SpatialSingleCriteria(IQuery <T> rootQuery, IPredicate <T> predicate, ISpatialOperator @operator, IGeometry value)
     : base(rootQuery, predicate, @operator, value)
 {
 }
Ejemplo n.º 8
0
        /*
         * /// <summary>
         * /// Legacy-Constructor for user-specified <see cref="DelComputeOperatorMatrix"/>
         * /// </summary>
         * public XdgTimestepping(
         *  DelComputeOperatorMatrix userComputeOperatorMatrix,
         *  IEnumerable<DGField> Fields,
         *  IEnumerable<DGField> IterationResiduals,
         *  TimeSteppingScheme __Scheme,
         *  DelUpdateLevelset _UpdateLevelset,
         *  LevelSetHandling _LevelSetHandling,
         *  MultigridOperator.ChangeOfBasisConfig[][] _MultigridOperatorConfig,
         *  AggregationGridData[] _MultigridSequence,
         *  double _AgglomerationThreshold,
         *  LinearSolverConfig LinearSolver, NonLinearSolverConfig NonLinearSolver) //
         * {
         *  this.Scheme = __Scheme;
         *  this.XdgOperator = op;
         *
         *  this.Parameters = op.InvokeParameterFactory(Fields);
         *
         *
         *  foreach (var f in Fields.Cat(IterationResiduals).Cat(Parameters)) {
         *      if (f != null && f is XDGField xf) {
         *          if (LsTrk == null) {
         *              LsTrk = xf.Basis.Tracker;
         *          } else {
         *              if (!object.ReferenceEquals(LsTrk, xf.Basis.Tracker))
         *                  throw new ArgumentException();
         *          }
         *      }
         *  }
         *  if (LsTrk == null)
         *      throw new ArgumentException("unable to get Level Set Tracker reference");
         *
         *  bool UseX = Fields.Any(f => f is XDGField) || IterationResiduals.Any(f => f is XDGField);
         *
         *  ConstructorCommon(op, UseX,
         *      Fields, this.Parameters, IterationResiduals,
         *      myDelComputeXOperatorMatrix,
         *      _UpdateLevelset,
         *      _LevelSetHandling,
         *      _MultigridOperatorConfig,
         *      _MultigridSequence,
         *      _AgglomerationThreshold,
         *      LinearSolver, NonLinearSolver);
         *
         * }
         */


        private void ConstructorCommon(
            ISpatialOperator op, bool UseX,
            IEnumerable <DGField> Fields, IEnumerable <DGField> __Parameters, IEnumerable <DGField> IterationResiduals,
            SpeciesId[] spcToCompute,
            DelUpdateLevelset _UpdateLevelset, LevelSetHandling _LevelSetHandling,
            MultigridOperator.ChangeOfBasisConfig[][] _MultigridOperatorConfig, AggregationGridData[] _MultigridSequence,
            double _AgglomerationThreshold,
            LinearSolverConfig LinearSolver, NonLinearSolverConfig NonLinearSolver) //
        {
            RungeKuttaScheme rksch;
            int bdfOrder;

            DecodeScheme(this.Scheme, out rksch, out bdfOrder);

            SpatialOperatorType _SpatialOperatorType = SpatialOperatorType.Nonlinear;


            int quadOrder = op.QuadOrderFunction(
                Fields.Select(f => f.Basis.Degree).ToArray(),
                Parameters.Select(f => f != null ? f.Basis.Degree : 0).ToArray(),
                IterationResiduals.Select(f => f.Basis.Degree).ToArray());

            // default solvers
            // ===============
            if (LinearSolver == null)
            {
                LinearSolver = new LinearSolverConfig()
                {
                    SolverCode = LinearSolverCode.automatic
                };
            }
            if (NonLinearSolver == null)
            {
                NonLinearSolver = new NonLinearSolverConfig()
                {
                    SolverCode = NonLinearSolverCode.Newton
                };
            }

            // default Multi-Grid
            // ==================

            if (_MultigridSequence == null)
            {
                _MultigridSequence = new[] { CoarseningAlgorithms.ZeroAggregation(this.GridDat) };
            }

            // default level-set treatment
            // ===========================

            if (_UpdateLevelset == null)
            {
                _UpdateLevelset = this.UpdateLevelsetWithNothing;
                if (_LevelSetHandling != LevelSetHandling.None)
                {
                    throw new ArgumentException($"If level-set handling is set to {_LevelSetHandling} (anything but {LevelSetHandling.None}) an updating routine must be specified.");
                }
            }

            // default multigrid operator config
            // =================================
            if (_MultigridOperatorConfig == null)
            {
                int NoOfVar = Fields.Count();
                _MultigridOperatorConfig    = new MultigridOperator.ChangeOfBasisConfig[0][];
                _MultigridOperatorConfig[0] = new MultigridOperator.ChangeOfBasisConfig[NoOfVar];
                for (int iVar = 0; iVar < NoOfVar; iVar++)
                {
                    _MultigridOperatorConfig[0][iVar] = new MultigridOperator.ChangeOfBasisConfig()
                    {
                        DegreeS  = new int[] { Fields.ElementAt(iVar).Basis.Degree },
                        mode     = MultigridOperator.Mode.Eye,
                        VarIndex = new int[] { iVar }
                    };
                }
            }

            // finally, create timestepper
            // ===========================

            if (bdfOrder > -1000)
            {
                m_BDF_Timestepper = new XdgBDFTimestepping(Fields, __Parameters, IterationResiduals,
                                                           LsTrk, true,
                                                           this.ComputeOperatorMatrix, op, _UpdateLevelset,
                                                           bdfOrder,
                                                           _LevelSetHandling,
                                                           MassMatrixShapeandDependence.IsTimeDependent,
                                                           _SpatialOperatorType,
                                                           _MultigridOperatorConfig, _MultigridSequence,
                                                           spcToCompute, quadOrder,
                                                           _AgglomerationThreshold, UseX,
                                                           NonLinearSolver,
                                                           LinearSolver);

                m_BDF_Timestepper.Config_AgglomerationThreshold = _AgglomerationThreshold;
            }
            else
            {
                m_RK_Timestepper = new XdgRKTimestepping(Fields.ToArray(), __Parameters, IterationResiduals.ToArray(),
                                                         LsTrk,
                                                         this.ComputeOperatorMatrix, op, _UpdateLevelset,
                                                         rksch,
                                                         _LevelSetHandling,
                                                         MassMatrixShapeandDependence.IsTimeDependent,
                                                         _SpatialOperatorType,
                                                         _MultigridOperatorConfig, _MultigridSequence,
                                                         spcToCompute, quadOrder,
                                                         _AgglomerationThreshold, UseX,
                                                         NonLinearSolver,
                                                         LinearSolver);

                m_RK_Timestepper.Config_AgglomerationThreshold = _AgglomerationThreshold;
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 鼠标左键按下时发生的事件(建立缓冲区的主要方法)
        /// </summary>
        /// <param name="Flags"></param>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="pbHandled"></param>
        void TE_OnLButtonDown(int Flags, int X, int Y, ref object pbHandled)
        {
            if (En == "DrawGeo")
            {
            }
            else if (En == "SelectModle")
            {
                // 2012-9-20 张航宇
                // 若成功的完成了一次缓冲分析,则将状态释放,要求重新点击
                IWorldPointInfo61 pIWorldPointInfo = this.SgWorld.Window.PixelToWorld(X, Y, WorldPointType.WPT_MODEL);
                if (pIWorldPointInfo.ObjectID != "" && pIWorldPointInfo.ObjectID != null)
                {
                    try
                    {
                        ITerraExplorerObject61 pp = this.SgWorld.Creator.GetObject(pIWorldPointInfo.ObjectID);
                        if (pp.ObjectType == ObjectTypeCode.OT_FEATURE)
                        {
                            IFeature61 pIF = pp as IFeature61;
                            this.geo = pIF.GeometryZ.SpatialOperator.buffer((double)this.spinEdit1.Value);
                            ITerrainPolygon61 polygon = this.SgWorld.Creator.CreatePolygon(this.geo, -16711936, -10197916, cbRelative.Checked?AltitudeTypeCode.ATC_TERRAIN_RELATIVE: AltitudeTypeCode.ATC_ON_TERRAIN, GroupID, "Buffer" + System.Guid.NewGuid().ToString().Substring(0, 6));

                            if (cbRelative.Checked)
                            {
                                polygon.Position.Altitude = (double)speHeight.Value;
                            }

                            this.En             = null;
                            this.Select.Checked = false;
                        }
                        else
                        {
                            ITerrainModel61 pITerrainModel = this.SgWorld.Creator.GetObject(pIWorldPointInfo.ObjectID) as ITerrainModel61;
                            IBBox3D61       pBBox          = pITerrainModel.Terrain.BBox;
                            cVerticesArray = new double[] {
                                pBBox.MaxX, pBBox.MinY, 0,
                                pBBox.MaxX, pBBox.MaxY, 0,
                                pBBox.MinX, pBBox.MaxY, 0,
                                pBBox.MinX, pBBox.MinY, 0,
                            };
                            ILinearRing cRing            = this.SgWorld.Creator.GeometryCreator.CreateLinearRingGeometry(cVerticesArray);
                            IPolygon    cPolygonGeometry = this.SgWorld.Creator.GeometryCreator.CreatePolygonGeometry(cRing, null);
                            //this.geo = cPolygonGeometry as IGeometry;
                            ISpatialOperator _SpatialOperator = cPolygonGeometry.SpatialOperator;

                            this.geo = _SpatialOperator.buffer((double)this.spinEdit1.Value);
                            ITerrainPolygon61 polygon = this.SgWorld.Creator.CreatePolygon(this.geo, -16711936, -10197916, cbRelative.Checked ? AltitudeTypeCode.ATC_TERRAIN_RELATIVE : AltitudeTypeCode.ATC_ON_TERRAIN, GroupID, "Buffer" + System.Guid.NewGuid().ToString().Substring(0, 6));

                            if (cbRelative.Checked)
                            {
                                polygon.Position.Altitude = (double)speHeight.Value;
                            }

                            this.En             = null;
                            this.Select.Checked = false;
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Constructor for XDG solvers
        /// </summary>
        public OpAnalysisBase(LevelSetTracker LsTrk, BlockMsrMatrix Mtx, double[] RHS, UnsetteledCoordinateMapping Mapping, MultiphaseCellAgglomerator CurrentAgglomeration, BlockMsrMatrix _mass, IEnumerable <MultigridOperator.ChangeOfBasisConfig[]> OpConfig, ISpatialOperator abstractOperator)
        {
            int RHSlen = Mapping.TotalLength;

            m_map    = Mapping;                              // mapping
            VarGroup = Mapping.BasisS.Count.ForLoop(i => i); //default: all dependent variables are included in operator matrix

            m_LsTrk = LsTrk;

            m_OpMtx  = Mtx.CloneAs();
            localRHS = RHS.CloneAs();

            // create the Dummy XDG aggregation basis
            var baseGrid = Mapping.GridDat;
            var mgSeq    = Foundation.Grid.Aggregation.CoarseningAlgorithms.CreateSequence(baseGrid, 1);

            AggregationGridBasis[][] XAggB = AggregationGridBasis.CreateSequence(mgSeq, Mapping.BasisS);

            //
            XAggB.UpdateXdgAggregationBasis(CurrentAgglomeration);

            // create multigrid operator
            m_MultigridOp = new MultigridOperator(XAggB, Mapping,
                                                  m_OpMtx,
                                                  _mass,
                                                  OpConfig,
                                                  abstractOperator.DomainVar.Select(varName => abstractOperator.FreeMeanValue[varName]).ToArray());
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Constructor for DG solvers
 /// </summary>
 public OpAnalysisBase(BlockMsrMatrix Mtx, double[] RHS, UnsetteledCoordinateMapping Mapping, IEnumerable <MultigridOperator.ChangeOfBasisConfig[]> OpConfig, ISpatialOperator abstractOperator)
     : this(null, Mtx, RHS, Mapping, null, null, OpConfig, abstractOperator) //
 {
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Constructor;
        /// </summary>
        /// <param name="Fields"></param>
        /// <param name="IterationResiduals"></param>
        /// <param name="LsTrk"></param>
        /// <param name="_ComputeOperatorMatrix">See <see cref="ComputeOperatorMatrix"/>.</param>
        /// <param name="_UpdateLevelset">See <see cref="UpdateLevelset"/>.</param>
        /// <param name="_LevelSetHandling"></param>
        /// <param name="_MassMatrixShapeandDependence"></param>
        /// <param name="_SpatialOperatorType"></param>
        /// <param name="_AgglomerationThreshold"></param>
        /// <param name="_RKscheme"></param>
        /// <param name="useX">
        /// U dont want to know!
        /// </param>
        /// <param name="_MultigridSequence"></param>
        /// <param name="_CutCellQuadOrder">Order of quadrature in cut cells, required e.g. for <see cref="LevelSetTracker.GetXDGSpaceMetrics(SpeciesId[], int, int)"/></param>
        /// <param name="_SpId">Species to compute, actually a subset of <see cref="LevelSetTracker.SpeciesIdS"/></param>
        /// <param name="_MultigridOperatorConfig">
        /// Configuration of block-preconditioner, if null a default value is chosen.
        /// </param>
        /// <param name="abstractOperator"></param>
        /// <param name="linearconfig"></param>
        /// <param name="nonlinconfig"></param>
        /// <param name="__Parameters"></param>
        public XdgRKTimestepping(DGField[] Fields,
                                 IEnumerable <DGField> __Parameters,
                                 DGField[] IterationResiduals,
                                 LevelSetTracker LsTrk,
                                 DelComputeOperatorMatrix _ComputeOperatorMatrix,
                                 ISpatialOperator abstractOperator,
                                 DelUpdateLevelset _UpdateLevelset,
                                 RungeKuttaScheme _RKscheme,
                                 LevelSetHandling _LevelSetHandling,
                                 MassMatrixShapeandDependence _MassMatrixShapeandDependence,
                                 SpatialOperatorType _SpatialOperatorType,
                                 MultigridOperator.ChangeOfBasisConfig[][] _MultigridOperatorConfig,
                                 AggregationGridData[] _MultigridSequence,
                                 SpeciesId[] _SpId,
                                 int _CutCellQuadOrder,
                                 double _AgglomerationThreshold, bool useX,
                                 Control.NonLinearSolverConfig nonlinconfig,
                                 Control.LinearSolverConfig linearconfig) : base(nonlinconfig, linearconfig)
        {
            // check args, set internals
            // -------------------------

            if (Fields.Length != IterationResiduals.Length)
            {
                throw new ArgumentException("Expecting the same number of fields and residuals.");
            }
            for (int iFld = 0; iFld < Fields.Length; iFld++)
            {
                if (!Fields[iFld].Basis.Equals(IterationResiduals[iFld].Basis))
                {
                    throw new ArgumentException(string.Format("Mismatch between {0}-th basis of fields and residuals.", iFld));
                }
            }

            base.Residuals = new CoordinateVector(IterationResiduals);

            if (!(_RKscheme.IsExplicit || _RKscheme.IsDiagonallyImplicit))
            {
                throw new NotSupportedException("Only supporting explicit or diagonally implicit schemes.");
            }

            base.m_LsTrk = LsTrk;
            base.Config_LevelSetHandling             = _LevelSetHandling;
            base.Config_MassMatrixShapeandDependence = _MassMatrixShapeandDependence;
            base.Config_SpatialOperatorType          = _SpatialOperatorType;
            base.ComputeOperatorMatrix         = _ComputeOperatorMatrix;
            base.UpdateLevelset                = _UpdateLevelset;
            base.AbstractOperator              = abstractOperator;
            base.Config_AgglomerationThreshold = _AgglomerationThreshold;
            this.m_RKscheme                    = _RKscheme.CloneAs();
            base.MultigridSequence             = _MultigridSequence;
            base.Config_SpeciesToCompute       = _SpId;
            base.Config_CutCellQuadratureOrder = _CutCellQuadOrder;
            base.CurrentParameters             = __Parameters.ToArray();
            if (_MultigridSequence == null || _MultigridSequence.Length < 1)
            {
                throw new ArgumentException("At least one grid level is required.");
            }

            m_CurrentState = new CoordinateVector(Fields);

            if (_MultigridOperatorConfig != null)
            {
                Config_MultigridOperator = _MultigridOperatorConfig;
            }
            else
            {
                SetConfig_MultigridOperator_Default(Fields);
            }

            base.CommonConfigurationChecks();

            // configure stack of level-set-tracker
            // ------------------------------------

            if (Config_LevelSetHandling == LevelSetHandling.None)
            {
                m_LsTrk.IncreaseHistoryLength(0);
            }
            else if (Config_LevelSetHandling == LevelSetHandling.LieSplitting ||
                     Config_LevelSetHandling == LevelSetHandling.StrangSplitting)
            {
                m_LsTrk.IncreaseHistoryLength(1);
            }
            else
            {
                m_LsTrk.IncreaseHistoryLength(m_RKscheme.Stages);
            }
            //m_LsTrk.IncreaseHistoryLength(1);

            // multigrid - init
            // ----------------

            InitMultigrid(Fields, useX);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Matrix/Affine assembly in the case of an implicit RK stage.
        /// </summary>
        protected override void AssembleMatrixCallback(out BlockMsrMatrix System, out double[] Affine, out BlockMsrMatrix PcMassMatrix, DGField[] argCurSt, bool Linearization, out ISpatialOperator abstractOp)
        {
            abstractOp = base.AbstractOperator;
            if (Linearization == false)
            {
                throw new NotImplementedException("todo");
            }

            int Ndof = m_CurrentState.Count;

            // copy data from 'argCurSt' to 'CurrentStateMapping', if necessary
            // -----------------------------------------------------------
            DGField[] locCurSt = CurrentStateMapping.Fields.ToArray();
            if (locCurSt.Length != argCurSt.Length)
            {
                throw new ApplicationException();
            }
            int NF = locCurSt.Length;

            for (int iF = 0; iF < NF; iF++)
            {
                if (object.ReferenceEquals(locCurSt[iF], argCurSt[iF]))
                {
                    // nothing to do
                }
                else
                {
                    locCurSt[iF].Clear();
                    locCurSt[iF].Acc(1.0, argCurSt[iF]);
                }
            }

            // update of level-set
            // ----------------------

            bool updateAgglom = false;

            if (this.Config_LevelSetHandling == LevelSetHandling.Coupled_Once && m_ImplStParams.m_IterationCounter == 0 ||
                this.Config_LevelSetHandling == LevelSetHandling.Coupled_Iterative)
            {
                //MoveLevelSetAndRelatedStuff(locCurSt, m_CurrentPhystime, m_CurrentDt, 1.0);
                if (Math.Abs(m_ImplStParams.m_ActualLevSetRelTime - m_ImplStParams.m_RelTime) > 1.0e-14)
                {
                    if (m_ImplStParams.m_IterationCounter <= 0)// only push tracker in the first iter
                    {
                        m_LsTrk.PushStacks();
                    }
                    MoveLevelSetAndRelatedStuff(locCurSt,
                                                m_ImplStParams.m_CurrentPhystime, m_ImplStParams.m_CurrentDt * m_ImplStParams.m_RelTime, IterUnderrelax,
                                                m_ImplStParams.m_Mass, m_ImplStParams.m_k);

                    // note that we need to update the agglomeration
                    updateAgglom = true;
                }
            }

            // update agglomeration
            // --------------------
#if DEBUG
            if (this.Config_LevelSetHandling == LevelSetHandling.LieSplitting || this.Config_LevelSetHandling == LevelSetHandling.StrangSplitting)
            {
                Debug.Assert(m_CurrentAgglomeration != null);
                Debug.Assert(m_PrecondMassMatrix != null);
                // ensure, that, when splitting is used we update the agglomerator in the very first iteration.
            }
#endif
            if (updateAgglom || m_CurrentAgglomeration == null)
            {
                this.UpdateAgglom(m_ImplStParams.m_IterationCounter > 0);

                // update Multigrid-XDG basis
                base.MultigridBasis.UpdateXdgAggregationBasis(m_CurrentAgglomeration);
            }


            // mass matrix update
            // ------------------

            if (this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsIdentity)
            {
                // may occur e.g. if one runs the FSI solver as a pure single-phase solver,
                // i.e. if the Level-Set is outside the domain.

                PcMassMatrix = null;
            }
            else
            {
                // checks:
                Debug.Assert(this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsNonIdentity ||
                             this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsTimeDependent ||
                             this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsTimeAndSolutionDependent,
                             "Something is not implemented here.");
                if (this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsNonIdentity &&
                    Config_LevelSetHandling != LevelSetHandling.None)
                {
                    throw new NotSupportedException("Illegal configuration;");
                }

                if (this.Config_LevelSetHandling == LevelSetHandling.Coupled_Once || this.Config_LevelSetHandling == LevelSetHandling.Coupled_Iterative)
                {
                    if ((this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsNonIdentity && m_PrecondMassMatrix == null) || // compute mass matrix (only once in application lifetime)
                        (this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsTimeDependent && m_ImplStParams.m_IterationCounter == 0) || // compute mass matrix once per timestep
                        (this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsTimeAndSolutionDependent) // re-compute mass matrix in every iteration
                        )
                    {
                        BlockMsrMatrix PM, SM;
                        UpdateMassMatrix(out PM, out SM, m_ImplStParams.m_CurrentPhystime + m_ImplStParams.m_CurrentDt * m_ImplStParams.m_RelTime);
                        m_ImplStParams.m_Mass[1] = SM;
                        m_PrecondMassMatrix      = PM;
                    }
                }

                PcMassMatrix = m_PrecondMassMatrix;
            }

            // operator matrix update
            // ----------------------

            // we perform the extrapolation to have valid parameters if
            // - the operator matrix depends on these values
            this.m_CurrentAgglomeration.Extrapolate(CurrentStateMapping);

            var OpMatrix = new BlockMsrMatrix(CurrentStateMapping);
            var OpAffine = new double[Ndof];

            this.ComputeOperatorMatrix(OpMatrix, OpAffine, CurrentStateMapping, locCurSt, base.GetAgglomeratedLengthScales(), m_ImplStParams.m_CurrentPhystime + m_ImplStParams.m_CurrentDt * m_ImplStParams.m_RelTime);


            // assemble system
            // ---------------

            double dt = m_ImplStParams.m_CurrentDt;

            // select mass matrix (and some checks)
            double[]       RHS = new double[Ndof];
            BlockMsrMatrix MamaRHS, MamaLHS;
            if (this.Config_LevelSetHandling == LevelSetHandling.Coupled_Once ||
                this.Config_LevelSetHandling == LevelSetHandling.Coupled_Iterative)
            {
                Debug.Assert(m_ImplStParams.m_Mass.Length == 2);
                MamaRHS = m_ImplStParams.m_Mass[0];
                MamaLHS = m_ImplStParams.m_Mass[1];
            }
            else if (this.Config_LevelSetHandling == LevelSetHandling.LieSplitting ||
                     this.Config_LevelSetHandling == LevelSetHandling.StrangSplitting ||
                     this.Config_LevelSetHandling == LevelSetHandling.None)
            {
                Debug.Assert(m_ImplStParams.m_Mass.Length == 1);
                MamaRHS = m_ImplStParams.m_Mass[0];
                MamaLHS = m_ImplStParams.m_Mass[0];
            }
            else
            {
                throw new NotImplementedException();
            }

            // right-hand-side, resp. affine vector
            if (MamaRHS != null)
            {
                MamaRHS.SpMV(1.0 / dt, m_ImplStParams.m_u0, 0.0, RHS);
            }
            else
            {
                Debug.Assert(this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsIdentity);
                RHS.SetV(m_ImplStParams.m_u0, 1.0 / dt);
            }
            for (int l = 0; l < m_ImplStParams.m_s; l++)
            {
                if (m_ImplStParams.m_RK_as[l] != 0.0)
                {
                    RHS.AccV(-m_ImplStParams.m_RK_as[l], m_ImplStParams.m_k[l]);
                }
            }

            Affine = RHS;
            Affine.ScaleV(-1.0);
            Affine.AccV(m_ImplStParams.m_RK_as[m_ImplStParams.m_s], OpAffine);

            // left-hand-side
            System = OpMatrix.CloneAs();
            System.Scale(m_ImplStParams.m_RK_as[m_ImplStParams.m_s]);
            if (MamaLHS != null)
            {
                System.Acc(1.0 / dt, MamaLHS);
            }
            else
            {
                System.AccEyeSp(1.0 / dt);
            }

            // perform agglomeration
            // ---------------------
            Debug.Assert(object.ReferenceEquals(m_CurrentAgglomeration.Tracker, m_LsTrk));
            m_CurrentAgglomeration.ManipulateMatrixAndRHS(System, Affine, CurrentStateMapping, CurrentStateMapping);

            // increase iteration counter
            // --------------------------
            m_ImplStParams.m_IterationCounter++;
        }
        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="DiffOp"></param>
        /// <param name="CoDomVarName">
        /// the name of the variable in the codomain (<see cref="SpatialOperator.CodomainVar"/>-member
        /// of <paramref name="DiffOp"/>, for which this object should be defined;
        /// </param>
        /// <param name="_fieldList">
        /// list of domain variable names
        /// </param>
        /// <param name="_fieldList2">
        /// optional (i.e. can be null)
        /// list of parameter variable names;
        /// will be concatenated with <paramref name="_fieldList"/>
        /// </param>
        /// <param name="F">optional filter, can be null.</param>
        /// <param name="vectorizer">
        /// Function for the vectorization of the evaluation of <paramref name="F"/>
        /// </param>
        public EquationComponentArgMapping(ISpatialOperator DiffOp, string CoDomVarName,
                                           IList <string> _fieldList, IList <string> _fieldList2, Func <T, bool> F, Func <IEquationComponent, IEquationComponent> vectorizer)
        {
            m_CoDomVarName = CoDomVarName;
            //m_DomainFields = DomainMapping.Fields;


            // =================
            // concat field list
            // =================
            IList <string> fieldList;

            if (_fieldList2 != null)
            {
                fieldList = Enumerable.Concat(_fieldList, _fieldList2).ToList();
            }
            else
            {
                fieldList = _fieldList;
            }

            // =========================================
            // collect all equation components of type T
            // =========================================

            ICollection <IEquationComponent> eqCompS = DiffOp.EquationComponents[CoDomVarName];

            List <T> AllComponentsofMyType = new List <T>();

            foreach (IEquationComponent eqComp in eqCompS)
            {
                T optComp = (eqComp is T) ? (T)eqComp : default;                    //                    optimized component (user-optimized)
                T vecComp = (vectorizer != null) ? (T)vectorizer(eqComp) : default; // default vectorization (non-optimized)

                // check if component fits at all
                if (optComp == null && vecComp == null)
                {
                    // component just does not fit
                    continue;
                }

                if (vectorizer != null)
                {
                    if (optComp != null && vecComp == null)
                    {
                        throw new ArgumentException("Error in vectorizer implementation.");
                    }
                }

                // check the filter
                if (F != null)
                {
                    if (optComp != null)
                    {
                        if (!F(optComp))
                        {
                            // component should be ignored
                            continue;
                        }
                    }
                    else
                    {
                        if (!F(vecComp))
                        {
                            // component should be ignored
                            continue;
                        }
                    }
                }

                // determine whether to use the optimized component
                bool useOptComp = true;
                if (optComp == null)
                {
                    // cannot use optimized component if there is no
                    Debug.Assert(vecComp != null);
                    useOptComp = false;
                }
                if (eqComp is IEquationComponentChecking cc)
                {
                    // check if user selected to ignore vectorization
                    if (cc.IgnoreVectorizedImplementation == true && vecComp != null)
                    {
                        useOptComp = false;
                    }
                }
#if DEBUG
                // in DEBUG mode, we always use the vectorizer (if supported)
                // because it implements a verification
                if (vecComp != null)
                {
                    useOptComp = false;
                }
#endif
                // special case for INonlinearFlux, INonlinearFluxEx
                if (vecComp == null)
                {
                    Debug.Assert(optComp != null);
                    useOptComp = true;
                }

                if (useOptComp)
                {
                    AllComponentsofMyType.Add(optComp);
                }
                else
                {
                    AllComponentsofMyType.Add(vecComp);
                }
            }

            m_AllComponentsOfMyType = AllComponentsofMyType.ToArray();

            // ======================
            // build argument mapping
            // ======================

            int argMapMaxCount = 0;
            foreach (var w in m_AllComponentsOfMyType)
            {
                int c = w.ArgumentOrdering.Count;
                if (w.ParameterOrdering != null)
                {
                    c += w.ParameterOrdering.Count;
                }
                argMapMaxCount = Math.Max(argMapMaxCount, c);
            }
            AllToSub       = new int[m_AllComponentsOfMyType.Length, argMapMaxCount];
            NoOfArguments  = new int[m_AllComponentsOfMyType.Length];
            NoOfParameters = new int[m_AllComponentsOfMyType.Length];
            //ArrayTools.SetAll(AllToSub, int.MinValue);
            AllToSub.SetAll(int.MinValue);

            //IList<string> fieldList = DiffOp.DomainVar;
            for (int i = 0; i < AllToSub.GetLength(0); i++)
            {
                // arguments...
                IList <string> argMap = m_AllComponentsOfMyType[i].ArgumentOrdering;
                NoOfArguments[i] = argMap.Count;
                for (int j = 0; j < NoOfArguments[i]; j++)
                {
                    int ifound = fieldList.IndexOf(argMap[j]);
                    AllToSub[i, j] = ifound;
                    Debug.Assert(AllToSub[i, j] >= 0);
                }

                // parameters...
                IList <string> paramMap = m_AllComponentsOfMyType[i].ParameterOrdering;
                if (paramMap != null)
                {
                    NoOfParameters[i] = paramMap.Count;

                    for (int j = 0; j < NoOfParameters[i]; j++)
                    {
                        AllToSub[i, j + NoOfArguments[i]] = fieldList.IndexOf(paramMap[j]);
                        Debug.Assert(AllToSub[i, j + NoOfArguments[i]] >= 0);
                    }
                }
            }
        }
Ejemplo n.º 15
0
        /// <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))