示例#1
0
        /*
         * /// <summary>
         * /// initialized by the constructor to avoid MPI-deadlocks;
         * /// </summary>
         * Dictionary<RefElement, EdgeMask> m_Subgrid4Kref_AllEdges = new Dictionary<RefElement, EdgeMask>();
         */

        //LevelSetTracker lsTrk {
        //    get {
        //        return XDGSpaceMetrics.Tracker;
        //    }
        //}


        public EdgeQuadratureScheme Get_SurfaceElement_EdgeQuadScheme(SpeciesId sp)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species (id = " + sp.cntnt + ") is not supported.");
            }

            //var allRelevantEdges = this.m_SpeciesSubgrid_InnerAndDomainEdges[sp].Intersect(this.m_CutCellSubgrid_InnerEdges);

            var innerCutCellEdges    = this.XDGSpaceMetrics.LevelSetRegions.GetCutCellSubGrid().InnerEdgesMask;
            var boundaryCutCellEdges = ExecutionMask.Intersect(this.XDGSpaceMetrics.LevelSetRegions.GetCutCellSubGrid().BoundaryEdgesMask, this.XDGSpaceMetrics.GridDat.BoundaryEdges);
            var allRelevantEdges     = this.m_SpeciesSubgrid_InnerAndDomainEdges[sp].Intersect(ExecutionMask.Union(innerCutCellEdges, boundaryCutCellEdges));

            //EdgeMask AggEdges = this.CellAgglomeration != null ? this.CellAgglomeration.GetAgglomerator(sp).AggInfo.AgglomerationEdges : null;
            //if (AggEdges != null && AggEdges.NoOfItemsLocally > 0)
            //    allRelevantEdges = allRelevantEdges.Except(AggEdges);


            var edgeQrIns = new EdgeQuadratureScheme(false, allRelevantEdges);

            foreach (var Kref in XDGSpaceMetrics.GridDat.Grid.RefElements)
            {
                for (int iLevSet = 0; iLevSet < XDGSpaceMetrics.NoOfLevelSets; iLevSet++)   // loop over level sets...
                {
                    EdgeMask cutEdges = this.GetCutEdges(Kref, iLevSet);

                    var factory = this.XDGSpaceMetrics.XQuadFactoryHelper.GetSurfaceElement_BoundaryRuleFactory(iLevSet, Kref);

                    edgeQrIns.AddFactory(factory, cutEdges);
                }
            }

            return(edgeQrIns);
        }
示例#2
0
        protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L)
        {
            using (FuncTrace tr = new FuncTrace()) {
                // assemble system, create matrix
                // ------------------------------

                var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData));
                var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData));

                double D              = this.GridData.SpatialDimension;
                double penalty_base   = (T.Basis.Degree + 1) * (T.Basis.Degree + D) / D;
                double penalty_factor = base.Control.penalty_poisson;

                {
                    // equation assembly
                    // -----------------
                    tr.Info("creating sparse system...");
                    Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal);
                    Stopwatch stw = new Stopwatch();
                    stw.Start();

                    SpatialOperator LapaceIp = new SpatialOperator(1, 1, QuadOrderFunc.SumOfMaxDegrees(), "T", "T");
                    var             flux     = new ipFlux(penalty_base * base.Control.penalty_poisson, this.GridData.Cells.cj, base.Control);
                    LapaceIp.EquationComponents["T"].Add(flux);


                    LapaceIp.Commit();

#if DEBUG
                    var RefLaplaceMtx = new MsrMatrix(T.Mapping);
#endif
                    LaplaceMtx    = new BlockMsrMatrix(T.Mapping);
                    LaplaceAffine = new double[T.Mapping.LocalLength];

                    LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                             LaplaceMtx, LaplaceAffine,
                                             volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
#if DEBUG
                    LaplaceAffine.ClearEntries();
                    LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                             RefLaplaceMtx, LaplaceAffine,
                                             volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
                    MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs();
                    ErrMtx.Acc(-1.0, LaplaceMtx);
                    double err    = ErrMtx.InfNorm();
                    double infNrm = LaplaceMtx.InfNorm();
                    Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm);
                    Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed.");
#endif
                    //int q = LaplaceMtx._GetTotalNoOfNonZeros();
                    //tr.Info("finished: Number of non-zeros: " + q);
                    stw.Stop();
                    Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds);


                    //double condNo = LaplaceMtx.condest(BatchmodeConnector.Flavor.Octave);
                    //Console.WriteLine("condition number: {0:0.####E-00} ",condNo);
                }
            }
        }
        /// <summary>
        /// computes the affine offset and/or matrix of the operator, expert
        /// version;
        /// </summary>
        /// <param name="DomainMap">
        /// the mapping which is used to compute column indices into
        /// <paramref name="Matrix"/>;
        /// </param>
        /// <param name="Parameters">
        /// The parameter variables (of this differential operator);
        /// The number of elements in the list must match the parameter count
        /// of the differential operator (see
        /// <see cref="SpatialOperator.ParameterVar"/>);  It is allowed to set
        /// an entry to 'null', in this case the values of the parameter field
        /// are assumed to be 0.0; If the differential operator contains no
        /// parameters, this argument can be null;
        /// </param>
        /// <param name="CodomainMap">
        /// the mapping which is used to compute row indices into
        /// <paramref name="Matrix"/> and <paramref name="AffineOffset"/>.
        /// </param>
        /// <param name="Matrix">
        /// Acc output: the matrix which represents the linear part of this
        /// operator, according to the mapping given by
        /// <paramref name="DomainMap"/> and <paramref name="CodomainMap"/>,
        /// is <b>ACCUMULATED</b> here; <br/>
        /// Setting all matrix entries to 0.0 is left to the user;
        /// </param>
        /// <param name="AffineOffset">
        /// Acc output: the vector which represents the affine part of this
        /// operator, according to the mapping given by
        /// <paramref name="DomainMap"/> and <paramref name="CodomainMap"/>,
        /// is <b>ACCUMULATED</b> here; <br/>
        /// Setting all vector entries to 0.0 is left to the user;
        /// </param>
        /// <param name="OnlyAffine">
        /// If true, only the <paramref name="AffineOffset"/> is computed, and
        /// the <paramref name="Matrix"/> is not touched (can be null);
        /// </param>
        /// <remarks>
        /// The operator assembly must be finalized before by calling
        /// <see cref="Commit"/> before this method can be called.
        /// </remarks>
        /// <param name="edgeRule">
        /// Quadrature rule and domain for edge integration; specifying this is exclusive with <paramref name="edgeQuadScheme"/>, i.e. both cannot be unequal null at the same time.
        /// </param>
        /// <param name="edgeQuadScheme">
        /// Quadrature scheme for edge integration; specifying this is exclusive with <paramref name="edgeRule"/>, i.e. both cannot be unequal null at the same time.
        /// </param>
        /// <param name="volRule">
        /// Quadrature rule and domain for volume integration; specifying this is exclusive with <paramref name="volQuadScheme"/>, i.e. both cannot be unequal null at the same time.
        /// </param>
        /// <param name="volQuadScheme">
        /// Quadrature scheme for volume integration; specifying this is exclusive with <paramref name="volRule"/>, i.e. both cannot be unequal null at the same time.
        /// </param>
        /// <param name="SubGridBoundaryMask">
        /// </param>
        /// <param name="ParameterMPIExchange">
        /// Determines whether parameter fields have to exchange ghost cell
        /// data before the assembly of the operator.
        /// </param>
        /// <param name="time"></param>
        /// <param name="op"></param>
        static public void ComputeMatrixEx <M, V>(this SpatialOperator op,
                                                  UnsetteledCoordinateMapping DomainMap, IList <DGField> Parameters, UnsetteledCoordinateMapping CodomainMap,
                                                  M Matrix, V AffineOffset, bool OnlyAffine = false,
                                                  double time = 0.0,
                                                  EdgeQuadratureScheme edgeQuadScheme = null, CellQuadratureScheme volQuadScheme = null,
                                                  //ICompositeQuadRule<QuadRule> edgeRule = null, ICompositeQuadRule<QuadRule> volRule = null,
                                                  BitArray SubGridBoundaryMask = null,
                                                  bool ParameterMPIExchange    = true)
            where M : IMutableMatrixEx
            where V : IList <double> //
        {
            var ev = op.GetMatrixBuilder(DomainMap, Parameters, CodomainMap, edgeQuadScheme, volQuadScheme);

            ev.time           = time;
            ev.MPITtransceive = ParameterMPIExchange;
            if (SubGridBoundaryMask != null)
            {
                throw new NotSupportedException();
                //ev.ActivateSubgridBoundary(new Grid.CellMask(ev.GridData, SubGridBoundaryMask));
            }

            if (OnlyAffine)
            {
                ev.ComputeAffine(AffineOffset);
            }
            else
            {
                ev.ComputeMatrix(Matrix, AffineOffset);
            }
        }
示例#4
0
        /// <summary>
        /// computes <see cref="LaplaceMtx"/> and <see cref="LaplaceAffine"/>
        /// </summary>
        private void UpdateMatrices() {
            using (var tr = new FuncTrace()) {
                // time measurement for matrix assembly
                Stopwatch stw = new Stopwatch();
                stw.Start();

                // console
                Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal);

                // quadrature domain
                var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData, MaskType.Geometrical));
                var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData, MaskType.Geometrical));

#if DEBUG
                // in DEBUG mode, we compare 'MsrMatrix' (old, reference implementation) and 'BlockMsrMatrix' (new standard)
                var RefLaplaceMtx = new MsrMatrix(T.Mapping);
#endif
                using (new BlockTrace("SipMatrixAssembly", tr)) {
                    LaplaceMtx = new BlockMsrMatrix(T.Mapping);
                    LaplaceAffine = new double[T.Mapping.LocalLength];

                    LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                             LaplaceMtx, LaplaceAffine,
                                             volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
                }
#if DEBUG
                LaplaceAffine.ClearEntries();
                LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                         RefLaplaceMtx, LaplaceAffine,
                                         volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
                MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs();
                ErrMtx.Acc(-1.0, LaplaceMtx);
                double err = ErrMtx.InfNorm();
                double infNrm = LaplaceMtx.InfNorm();
                Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm);
                Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed.");
#endif
                stw.Stop();
                Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds);


                //var JB = LapaceIp.GetFDJacobianBuilder(T.Mapping.Fields, null, T.Mapping, edgQrSch, volQrSch);
                //var JacobiMtx = new BlockMsrMatrix(T.Mapping);
                //var JacobiAffine = new double[T.Mapping.LocalLength];
                //JB.ComputeMatrix(JacobiMtx, JacobiAffine);
                //double L2ErrAffine = GenericBlas.L2Dist(JacobiAffine, LaplaceAffine);
                //var ErrMtx2 = LaplaceMtx.CloneAs();
                //ErrMtx2.Acc(-1.0, JacobiMtx);
                //double LinfErrMtx2 = ErrMtx2.InfNorm();

                //JacobiMtx.SaveToTextFileSparse("D:\\tmp\\Jac.txt");
                //LaplaceMtx.SaveToTextFileSparse("D:\\tmp\\Lap.txt");

                //Console.WriteLine("FD Jacobi Mtx: {0:e14}, Affine: {1:e14}", LinfErrMtx2, L2ErrAffine);
            }
        }
示例#5
0
        /// <summary>
        /// the jump-seminorm of DG-field <paramref name="f"/>:
        /// <latex mode="display">
        ///
        /// </latex>
        /// </summary>
        /// <param name="f"></param>
        /// <param name="CM"></param>
        /// <returns></returns>
        public static double JumpSemiNorm(this Field f, EdgeMask CM = null)
        {
            using (new FuncTrace()) {
                var qi = new EdgeQuadratureScheme(CM);

                var quad = new JumpSemiNormIntegrator(f, qi);
                quad.Execute();
                return(Math.Sqrt(quad.overallResult));
            }
        }
        /// <summary>
        /// another legacy interface
        /// </summary>
        static public void ComputeAffine <V>(
            this SpatialOperator op,
            UnsetteledCoordinateMapping DomainMap,
            IList <DGField> Parameters,
            UnsetteledCoordinateMapping CodomainMap,
            V AffineOffset,
            bool OnlyBoundaryEdges      = true, double time = 0.0,
            EdgeQuadratureScheme edgeQr = null, CellQuadratureScheme volQr = null)
            where V : IList <double>
        {
            var GridDat = CodomainMap.GridDat;

            if (Parameters != null)
            {
                foreach (var prm in Parameters)
                {
                    if (!object.ReferenceEquals(prm.GridDat, GridDat))
                    {
                        throw new ArgumentException(string.Format("parameter field {0} is assigned to a different grid.", prm.Identification));
                    }
                }
            }

            //Using order zero for DomainMap will lead to inconsistent (and possibly insufficient) quadrature order!!!
            //UnsetteledCoordinateMapping DomainMap;
            //Basis b = new Basis(GridDat, 0);
            //Basis[] B = new Basis[this.DomainVar.Count];
            //B.SetAll(b);
            //DomainMap = new UnsetteledCoordinateMapping(B);


            if (OnlyBoundaryEdges)
            {
                if (edgeQr != null)
                {
                    throw new ArgumentException("If 'OnlyBoundaryEdges == true', 'edgeQr' must be null!", "edgeQr");
                }
                if (volQr != null)
                {
                    throw new ArgumentException("If 'OnlyBoundaryEdges == true', 'volQr' must be null!", "volQr");
                }

                volQr  = new CellQuadratureScheme(true, CellMask.GetEmptyMask(GridDat));
                edgeQr = new EdgeQuadratureScheme(true, GridDat.GetBoundaryEdgeMask());
            }

            op.ComputeMatrixEx(
                DomainMap, Parameters, CodomainMap,
                default(MsrMatrix), AffineOffset,
                OnlyAffine: true, time: time,
                volQuadScheme: volQr, edgeQuadScheme: edgeQr);
        }
示例#7
0
        internal void BuildEvaluatorsAndMasks()
        {
            CellMask fluidCells = speciesMap.SubGrid.VolumeMask.Intersect(ABSubGrid.VolumeMask);

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask().Intersect(ABSubGrid.VolumeMask);
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells).Intersect(ABSubGrid.VolumeMask);


            IBMControl control = speciesMap.Control;
            SpeciesId  species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName);

            CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme(
                species, true, fluidCells, control.LevelSetQuadratureOrder);


            // Does _not_ include agglomerated edges
            EdgeMask nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species);

            nonVoidEdges = nonVoidEdges.Intersect(ABSubGrid.AllEdgesMask.ToGeometicalMask());
            EdgeQuadratureScheme edgeScheme = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme(
                species, true, nonVoidEdges, control.LevelSetQuadratureOrder);

            this.m_Evaluator = new Lazy <IEvaluatorNonLin>(delegate() {
                this.Operator.EdgeQuadraturSchemeProvider   = g => edgeScheme;
                this.Operator.VolumeQuadraturSchemeProvider = g => volumeScheme;

                var opi = this.Operator.GetEvaluatorEx(
                    Mapping,
                    boundaryParameterMap,
                    Mapping);
                opi.ActivateSubgridBoundary(ABSubGrid.VolumeMask, subGridBoundaryTreatment: SubGridBoundaryModes.InnerEdgeLTS);
                return(opi);
            });

            // Evaluator for boundary conditions at level set zero contour
            CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme(
                0, cutCells, control.LevelSetQuadratureOrder);

            this.boundaryEvaluator = new Lazy <IEvaluatorNonLin>(delegate() {
                boundaryOperator.EdgeQuadraturSchemeProvider   = g => null; // Contains no boundary terms --> PROBLEM??????????
                boundaryOperator.VolumeQuadraturSchemeProvider = g => boundaryVolumeScheme;
                return(boundaryOperator.GetEvaluatorEx(
                           Mapping,
                           boundaryParameterMap,
                           Mapping));
            });
        }
示例#8
0
        internal void BuildEvaluatorsAndMasks()
        {
            CellMask fluidCells = speciesMap.SubGrid.VolumeMask.Intersect(ABSubGrid.VolumeMask);

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask().Intersect(ABSubGrid.VolumeMask);
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells).Intersect(ABSubGrid.VolumeMask);


            IBMControl control = speciesMap.Control;
            SpeciesId  species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName);

            CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme(
                species, true, fluidCells, control.LevelSetQuadratureOrder);


            // Does _not_ include agglomerated edges
            EdgeMask nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species);

            nonVoidEdges = nonVoidEdges.Intersect(ABSubGrid.AllEdgesMask);
            EdgeQuadratureScheme edgeScheme = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme(
                species, true, nonVoidEdges, control.LevelSetQuadratureOrder);

            this.m_Evaluator = new Lazy <SpatialOperator.Evaluator>(() =>
                                                                    this.Operator.GetEvaluatorEx(
                                                                        Mapping,
                                                                        boundaryParameterMap,
                                                                        Mapping,
                                                                        edgeScheme,
                                                                        volumeScheme,
                                                                        ABSubGrid,
                                                                        subGridBoundaryTreatment: SpatialOperator.SubGridBoundaryModes.InnerEdgeLTS));

            // Evaluator for boundary conditions at level set zero contour
            CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme(
                0, cutCells, control.LevelSetQuadratureOrder);

            this.boundaryEvaluator = new Lazy <SpatialOperator.Evaluator>(() =>
                                                                          boundaryOperator.GetEvaluatorEx(
                                                                              Mapping,
                                                                              boundaryParameterMap,
                                                                              Mapping,
                                                                              null, // Contains no boundary terms --> PROBLEM??????????
                                                                              boundaryVolumeScheme));
        }
        private void BuildEvaluatorsAndMasks()
        {
            CellMask fluidCells = speciesMap.SubGrid.VolumeMask;

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask();
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells);

            IBMControl control = speciesMap.Control;
            SpeciesId  species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName);

            CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme(
                species, true, fluidCells, control.LevelSetQuadratureOrder);

            // Does _not_ include agglomerated edges
            EdgeMask             nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species);
            EdgeQuadratureScheme edgeScheme   = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme(
                species, true, nonVoidEdges, control.LevelSetQuadratureOrder);

            this.m_Evaluator = new Lazy <IEvaluatorNonLin>(delegate() {
                this.Operator.EdgeQuadraturSchemeProvider   = g => edgeScheme;
                this.Operator.VolumeQuadraturSchemeProvider = g => volumeScheme;
                var opi = this.Operator.GetEvaluatorEx(
                    Mapping,
                    null, // TO DO: I SIMPLY REMOVE PARAMETERMAP HERE; MAKE THIS MORE PRETTY
                          //this.boundaryParameterMap, // TO DO: I SIMPLY REMOVE PARAMETERMAP HERE; MAKE THIS MORE PRETTY
                    Mapping);
                opi.ActivateSubgridBoundary(volumeScheme.Domain, subGridBoundaryTreatment: SubGridBoundaryModes.InnerEdgeLTS);
                //opi.ActivateSubgridBoundary(fluidCells, subGridBoundaryTreatment: SubGridBoundaryModes.InnerEdgeLTS);
                return(opi);
            });

            // Evaluator for boundary conditions at level set zero contour
            CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme(
                0, cutCells, control.LevelSetQuadratureOrder);

            this.boundaryEvaluator = new Lazy <IEvaluatorNonLin>(delegate() {
                boundaryOperator.EdgeQuadraturSchemeProvider   = g => null; // Contains no boundary terms
                boundaryOperator.VolumeQuadraturSchemeProvider = g => boundaryVolumeScheme;
                return(boundaryOperator.GetEvaluatorEx(
                           Mapping,
                           boundaryParameterMap,
                           Mapping));
            });
        }
示例#10
0
        /// <summary>
        /// Boundary quadrature for the surface elements, i.e. for each cut background-cell \f$ K_j \f$ a quadrature to approximate
        /// \f[
        ///    \int_{\partial K_j \cap \mathfrak{I} } \ldots \mathrm{dS} .
        /// \f]
        /// </summary>
        public EdgeQuadratureScheme GetEdgeQuadScheme(SpeciesId sp, bool UseDefaultFactories = true, EdgeMask IntegrationDomain = null, int?fixedOrder = null)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species (id = " + sp.cntnt + ") is not supported.");
            }


            // determine domain
            // ================
            var allRelevantEdges = GetEdgeMask(sp, IntegrationDomain);

            // create quadrature scheme
            // ========================
            {
                // default rules for all edges:
                EdgeQuadratureScheme edgeQrIns = new EdgeQuadratureScheme(UseDefaultFactories, allRelevantEdges);

                // overwrite with cut-cell-rules in cut-cells:
                foreach (var Kref in XDGSpaceMetrics.GridDat.Grid.RefElements)
                {
                    for (int iLevSet = 0; iLevSet < XDGSpaceMetrics.NoOfLevelSets; iLevSet++)   // loop over level sets...
                    {
                        EdgeMask cutEdges = this.GetCutEdges(Kref, iLevSet).Intersect(allRelevantEdges);
#if DEBUG
                        CellMask difference = cutEdges.GetAdjacentCells(XDGSpaceMetrics.GridDat).Except(XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet));
                        if (difference.Count() > 0)
                        {
                            throw new ArithmeticException("Edges of the Cells" + difference.GetSummary() + " are detected as cut, but these cells are not contained in the cut Cell-Mask of the Level-Set-Tracker");
                        }
#endif


                        var jmp     = IdentifyWing(iLevSet, sp);
                        var factory = this.XDGSpaceMetrics.XQuadFactoryHelper.GetEdgeRuleFactory(iLevSet, jmp, Kref);
                        edgeQrIns.AddFactoryDomainPair(factory, cutEdges, fixedOrder);
                    }
                }

                return(edgeQrIns);
            }
        }
示例#11
0
        protected void UpdateEvaluatorsAndMasks()
        {
            CellMask fluidCells = speciesMap.SubGrid.VolumeMask;

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask();
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells);

            IBMControl control = speciesMap.Control;
            SpeciesId  species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName);

            CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme(
                species, true, fluidCells, control.LevelSetQuadratureOrder);

            // Does _not_ include agglomerated edges
            EdgeMask             nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species);
            EdgeQuadratureScheme edgeScheme   = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme(
                species, true, nonVoidEdges, control.LevelSetQuadratureOrder);

            this.m_Evaluator = new Lazy <IEvaluatorNonLin>(delegate() {
                var opi = this.Operator.GetEvaluatorEx(
                    Mapping,
                    boundaryParameterMap,
                    Mapping,
                    edgeScheme,
                    volumeScheme);
                opi.ActivateSubgridBoundary(volumeScheme.Domain.ToLogicalMask(), subGridBoundaryTreatment: SpatialOperator.SubGridBoundaryModes.InnerEdgeLTS);
                return(opi);
            });

            // Evaluator for boundary conditions at level set zero contour
            CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme(
                0, cutCells, control.LevelSetQuadratureOrder);

            this.boundaryEvaluator = new Lazy <IEvaluatorNonLin>(() =>
                                                                 boundaryOperator.GetEvaluatorEx(
                                                                     Mapping,
                                                                     boundaryParameterMap,
                                                                     Mapping,
                                                                     null, // Contains no boundary terms
                                                                     boundaryVolumeScheme));
        }
示例#12
0
        /// <summary>
        /// Calculates the drag (x-component) and lift (y-component) forces acting on a wall of a boundary fitted grid
        /// </summary>
        /// <param name="U"></param>
        /// <param name="P"></param>
        /// <param name="muA"></param>
        /// <returns></returns>
        static public double[] GetForces_BoundaryFitted(VectorField <SinglePhaseField> GradU, VectorField <SinglePhaseField> GradV, SinglePhaseField StressXX,
                                                        SinglePhaseField StressXY, SinglePhaseField StressYY, SinglePhaseField P, LevelSetTracker LsTrk, double muA, double beta)
        {
            int D = LsTrk.GridDat.SpatialDimension;

            if (D > 2)
            {
                throw new ArgumentException("Method GetForces_BoundaryFitted only implemented for 2D (viscoelastic)!");
            }
            // var UA = U.Select(u => u.GetSpeciesShadowField("A")).ToArray();
            //var UA = U.ToArray();
            MultidimensionalArray Grad_U = new MultidimensionalArray(D);
            var _GradU = GradU.ToArray();
            var _GradV = GradV.ToArray();


            int RequiredOrder = _GradU[0].Basis.Degree * 3 + 2;

            //int RequiredOrder = U[0].Basis.Degree * 3 + 2;
            //int RequiredOrder = LsTrk.GetXQuadFactoryHelper(momentFittingVariant).GetCachedSurfaceOrders(0).Max();
            //Console.WriteLine("Order reduction: {0} -> {1}", _RequiredOrder, RequiredOrder);

            //if (RequiredOrder > agg.HMForder)
            //    throw new ArgumentException();

            Console.WriteLine("Forces coeff: {0}, order = {1}", LsTrk.CutCellQuadratureType, RequiredOrder);

            SinglePhaseField _StressXX = StressXX;
            SinglePhaseField _StressXY = StressXY;
            SinglePhaseField _StressYY = StressYY;

            SinglePhaseField pA = null;

            //pA = P.GetSpeciesShadowField("A");
            pA = P;



            double[] forces = new double[D];
            for (int d = 0; d < D; d++)
            {
                ScalarFunctionEx ErrFunc = delegate(int j0, int Len, NodeSet Ns, MultidimensionalArray result) {
                    int K = result.GetLength(1); // No nof Nodes
                    MultidimensionalArray Grad_URes   = MultidimensionalArray.Create(Len, K, D);
                    MultidimensionalArray Grad_VRes   = MultidimensionalArray.Create(Len, K, D);
                    MultidimensionalArray pARes       = MultidimensionalArray.Create(Len, K);
                    MultidimensionalArray StressXXRes = MultidimensionalArray.Create(Len, K);
                    MultidimensionalArray StressXYRes = MultidimensionalArray.Create(Len, K);
                    MultidimensionalArray StressYYRes = MultidimensionalArray.Create(Len, K);

                    var Normals = LsTrk.GridDat.Edges.NormalsCache.GetNormals_Edge(Ns, j0, Len);
                    //var Normals = MultidimensionalArray.Create(1, Ns.Length, 1);
                    //var Normals = LsTrk.GridDat.Edges.NormalsForAffine;


                    for (int i = 0; i < D; i++)
                    {
                        _GradU[i].EvaluateEdge(j0, Len, Ns, Grad_URes.ExtractSubArrayShallow(-1, -1, i),
                                               Grad_URes.ExtractSubArrayShallow(-1, -1, i), ResultIndexOffset: 0, ResultPreScale: 1);

                        _GradV[i].EvaluateEdge(j0, Len, Ns, Grad_VRes.ExtractSubArrayShallow(-1, -1, i),
                                               Grad_VRes.ExtractSubArrayShallow(-1, -1, i), ResultIndexOffset: 0, ResultPreScale: 1);

                        //UA[i].EvaluateGradient(j0, Len, Ns, Grad_UARes.ExtractSubArrayShallow(-1, -1, i, -1), 0, 1);
                    }

                    //pA.Evaluate(j0, Len, Ns, pARes);
                    pA.EvaluateEdge(j0, Len, Ns, pARes, pARes, ResultIndexOffset: 0, ResultPreScale: 1);
                    _StressXX.EvaluateEdge(j0, Len, Ns, StressXXRes, StressXXRes, ResultIndexOffset: 0, ResultPreScale: 1);
                    _StressXY.EvaluateEdge(j0, Len, Ns, StressXYRes, StressXYRes, ResultIndexOffset: 0, ResultPreScale: 1);
                    _StressYY.EvaluateEdge(j0, Len, Ns, StressYYRes, StressYYRes, ResultIndexOffset: 0, ResultPreScale: 1);


                    //if (LsTrk.GridDat.SpatialDimension == 2)
                    //{

                    for (int j = 0; j < Len; j++)
                    {
                        for (int k = 0; k < K; k++)
                        {
                            double acc = 0.0;

                            // pressure
                            switch (d)
                            {
                            case 0:
                                acc += pARes[j, k] * Normals[j, k, 0];
                                acc -= (2 * muA * beta) * Grad_URes[j, k, 0] * Normals[j, k, 0];
                                acc -= (muA * beta) * Grad_URes[j, k, 1] * Normals[j, k, 1];
                                acc -= (muA * beta) * Grad_VRes[j, k, 0] * Normals[j, k, 1];
                                acc -= (muA * (1 - beta)) * StressXXRes[j, k] * Normals[j, k, 0];
                                acc -= (muA * (1 - beta)) * StressXYRes[j, k] * Normals[j, k, 1];
                                break;

                            case 1:
                                acc += pARes[j, k] * Normals[j, k, 1];
                                acc -= (2 * muA * beta) * Grad_VRes[j, k, 1] * Normals[j, k, 1];
                                acc -= (muA * beta) * Grad_VRes[j, k, 0] * Normals[j, k, 0];
                                acc -= (muA * beta) * Grad_URes[j, k, 1] * Normals[j, k, 0];
                                acc -= (muA * (1 - beta)) * StressXYRes[j, k] * Normals[j, k, 0];
                                acc -= (muA * (1 - beta)) * StressYYRes[j, k] * Normals[j, k, 1];
                                break;

                            default:
                                throw new NotImplementedException();
                            }

                            result[j, k] = acc;
                        }
                    }

                    //}
                    //else
                    //{
                    //    for (int j = 0; j < Len; j++)
                    //    {
                    //        for (int k = 0; k < K; k++)
                    //        {
                    //            double acc = 0.0;

                    //            // pressure
                    //            switch (d)
                    //            {
                    //                case 0:
                    //                    acc += pARes[j, k] * Normals[j, k, 0];
                    //                    acc -= (2 * muA) * Grad_UARes[j, k, 0, 0] * Normals[j, k, 0];
                    //                    acc -= (muA) * Grad_UARes[j, k, 0, 2] * Normals[j, k, 2];
                    //                    acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 1];
                    //                    acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 1];
                    //                    acc -= (muA) * Grad_UARes[j, k, 2, 0] * Normals[j, k, 2];
                    //                    break;
                    //                case 1:
                    //                    acc += pARes[j, k] * Normals[j, k, 1];
                    //                    acc -= (2 * muA) * Grad_UARes[j, k, 1, 1] * Normals[j, k, 1];
                    //                    acc -= (muA) * Grad_UARes[j, k, 1, 2] * Normals[j, k, 2];
                    //                    acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 0];
                    //                    acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 0];
                    //                    acc -= (muA) * Grad_UARes[j, k, 2, 1] * Normals[j, k, 2];
                    //                    break;
                    //                case 2:
                    //                    acc += pARes[j, k] * Normals[j, k, 2];
                    //                    acc -= (2 * muA) * Grad_UARes[j, k, 2, 2] * Normals[j, k, 2];
                    //                    acc -= (muA) * Grad_UARes[j, k, 2, 0] * Normals[j, k, 0];
                    //                    acc -= (muA) * Grad_UARes[j, k, 2, 1] * Normals[j, k, 1];
                    //                    acc -= (muA) * Grad_UARes[j, k, 0, 2] * Normals[j, k, 0];
                    //                    acc -= (muA) * Grad_UARes[j, k, 1, 2] * Normals[j, k, 1];
                    //                    break;
                    //                default:
                    //                    throw new NotImplementedException();
                    //            }

                    //    result[j, k] = acc;
                    //}
                    //}
                    //}
                };


                var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, RequiredOrder, 1).XQuadSchemeHelper;

                EdgeMask Mask = new EdgeMask(LsTrk.GridDat, "Wall_cylinder");

                EdgeQuadratureScheme eqs = SchemeHelper.GetEdgeQuadScheme(LsTrk.GetSpeciesId("A"), IntegrationDomain: Mask);

                EdgeQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat,
                                             eqs.Compile(LsTrk.GridDat, RequiredOrder), //  agg.HMForder),
                                             delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                    ErrFunc(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0));
                },
                                             delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                    for (int i = 0; i < Length; i++)
                    {
                        forces[d] += ResultsOfIntegration[i, 0];
                    }
                }
                                             ).Execute();
            }

            //for (int i = 0; i < D; i++)
            //    forces[i] = MPI.Wrappers.MPIExtensions.MPISum(forces[i]);

            return(forces);
        }
示例#13
0
        /// <summary>
        /// checks whether the linear and nonlinear implementation of operator evaluation are mathematically equal
        /// </summary>
        void LinearNonlinComparisonTest()
        {
            int L = this.bnd.CoordinateVector.Count();

            // need to assure to use the same quadrature oder on both evaluation variants
            var volQrSch = (new CellQuadratureScheme(false, CellMask.GetFullMask(this.GridData, MaskType.Geometrical)))
                           .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3);
            var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData, MaskType.Geometrical))
                           .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3);

            //var volQrSch = new CellQuadratureScheme(true, CellMask.GetEmptyMask(this.GridData));
            //var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(this.GridData));
            //var edgQrSch = new EdgeQuadratureScheme(true, this.GridData.BoundaryEdges)
            //                        .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3);
            //var edgQrSch = new EdgeQuadratureScheme(true, this.GridData.BoundaryEdges.Complement())
            //                          .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3);



            for (int run = 0; run < 1; run++)
            {
                // setup a random test vector
                Random rnd          = new Random();
                var    TestArgument = this.bnd.CloneAs().CoordinateVector;
                for (int i = 0; i < L; i++)
                {
                    TestArgument[i] = rnd.NextDouble();
                }

                Stopwatch lin = new Stopwatch();
                Stopwatch nol = new Stopwatch();

                // linear evaluation
                CoordinateVector LinResult = this.ViscU_linear.CoordinateVector;
                LinResult.Clear();
                lin.Start();
                {
                    var map             = this.U.Mapping;
                    var tempOperatorMtx = new MsrMatrix(map, map);
                    var tempAffine      = new double[L];
                    Operator.ComputeMatrixEx(map, new DGField[] { this.mu }, map,
                                             tempOperatorMtx, tempAffine,
                                             volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);


                    tempOperatorMtx.SpMVpara(1.0, TestArgument, 0.0, LinResult);
                    LinResult.AccV(1.0, tempAffine);
                }
                lin.Stop();

                // nonliner evaluation
                CoordinateVector NolResult = this.ViscU_nonlinear.CoordinateVector;
                NolResult.Clear();
                nol.Start();
                {
                    var evaluator = Operator.GetEvaluatorEx(TestArgument.Mapping, new DGField[] { this.mu }, this.Residual.Mapping,
                                                            volQrCtx: volQrSch, edgeQrCtx: edgQrSch);
                    evaluator.Evaluate(1.0, 0.0, NolResult);
                }
                nol.Stop();

                double L2Dist = GenericBlas.L2DistPow2(LinResult, NolResult).MPISum().Sqrt();
                Console.WriteLine("L2 dist of linear/Nonlinear evaluation comparison: {0}", L2Dist);

                LinResult.Acc(-1.0, NolResult);

                foreach (SinglePhaseField DGfield in LinResult.Mapping.Fields)
                {
                    for (int p = 0; p <= DGfield.Basis.Degree; p++)
                    {
                        double L2err_p = DGfield.L2NormPerMode(p);
                        Console.WriteLine("   ERR{2} {1} \t{0}", L2err_p, DGfield.Identification, p);
                    }
                }

                Console.WriteLine("Time linear {0}, time nonlinear: {1}", lin.Elapsed, nol.Elapsed);

                Assert.LessOrEqual(L2Dist, 1.0e-4, "L2 distance between linear and nonlinear evaluation of the same flux.");
            }
        }
示例#14
0
        // Local Variables for Iteration

        // <summary>
        // Counter for Iteration Steps
        // </summary>


        //double OldResidual = double.MaxValue;
        //int divergencecounter = 0;
        ///// <summary>
        ///// Checks for Reaching Max. Number of Iterations and Divergence of Algorithm
        ///// </summary>
        ///// <param name="Residual">Change Rate of the Algorithm</param>
        ///// <returns>Reaching Max Iterations, Aborts when diverged</returns>
        //public bool CheckAbortCriteria(double Residual, int IterationCounter) {
        //    if (Residual <= ConvergenceCriterion) {
        //        Console.WriteLine("EllipticReInit converged after {0} Iterations ", IterationCounter);
        //        return true;
        //    }
        //    if (Residual >= OldResidual) divergencecounter++;
        //    else divergencecounter = 0;
        //    if (IterationCounter >= MaxIteration) {
        //        Console.WriteLine("Elliptic Reinit Max Iterations Reached");
        //        return true;
        //    };
        //    if (divergencecounter > MaxIteration / 2) {
        //        Console.WriteLine("Elliptic Reinit diverged - Aborting");
        //        throw new ApplicationException();
        //    }

        //    OldResidual = Residual;
        //    IterationCounter++;
        //    return false;
        //}


        //bool PreviouslyOnSubgrid = false;

        /// <summary>
        /// Updates the Operator Matrix after level-set motion
        /// </summary>
        /// <param name="Restriction">
        /// The subgrid, on which the ReInit is performed
        /// </param>
        /// <param name="IncludingInterface">
        /// !! Not yet functional !!
        /// True, if the subgrid contains the interface, this causes all external edges of the subgrid to be treated as boundaries
        /// False, for the rest of the domain, thus the flux to the adjacent cells wil be evaluated
        /// </param>
        public void UpdateOperators(SubGrid Restriction = null, bool IncludingInterface = true)
        {
            if (!IncludingInterface)
            {
                throw new NotImplementedException("Untested, not yet functional!");
            }
            using (new FuncTrace()) {
                //using (var slv = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) {
                //using (var slv = new ilPSP.LinSolvers.PARDISO.PARDISOSolver()) {
                //using (var slv = new ilPSP.LinSolvers.HYPRE.GMRES()) {

                if (Control.Upwinding)
                {
                    OldPhi.Clear();
                    OldPhi.Acc(1.0, Phi);
                    //Calculate
                    LevelSetGradient.Clear();
                    LevelSetGradient.Gradient(1.0, Phi, Restriction?.VolumeMask);
                    //LevelSetGradient.Gradient(1.0, Phi);

                    //LevelSetGradient.GradientByFlux(1.0, Phi);
                    MeanLevelSetGradient.Clear();
                    MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient, Restriction?.VolumeMask);
                    //MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient);
                }

                if (slv != null)
                {
                    slv.Dispose();
                }

                slv = Control.solverFactory();

                OpMatrix_interface.Clear();
                OpAffine_interface.Clear();


                // Build the Quadrature-Scheme for the interface operator
                // Note: The HMF-Quadrature over a surface is formally a volume quadrature, since it uses the volume quadrature nodes.
                //XSpatialOperatorExtensions.ComputeMatrixEx(Operator_interface,
                ////Operator_interface.ComputeMatrixEx(
                //    LevelSetTracker,
                //    Phi.Mapping,
                //    null,
                //    Phi.Mapping,
                //    OpMatrix_interface,
                //    OpAffine_interface,
                //    false,
                //    0,
                //    false,
                //    subGrid:Restriction,
                //    whichSpc: LevelSetTracker.GetSpeciesId("A")
                //    );
                XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Operator_interface.GetMatrixBuilder(LevelSetTracker, Phi.Mapping, null, Phi.Mapping);

                MultiphaseCellAgglomerator dummy = LevelSetTracker.GetAgglomerator(LevelSetTracker.SpeciesIdS.ToArray(), Phi.Basis.Degree * 2 + 2, 0.0);
                //mtxBuilder.SpeciesOperatorCoefficients[LevelSetTracker.GetSpeciesId("A")].CellLengthScales = dummy.CellLengthScales[LevelSetTracker.GetSpeciesId("A")];
                mtxBuilder.CellLengthScales.Add(LevelSetTracker.GetSpeciesId("A"), dummy.CellLengthScales[LevelSetTracker.GetSpeciesId("A")]);


                mtxBuilder.time           = 0;
                mtxBuilder.MPITtransceive = false;
                mtxBuilder.ComputeMatrix(OpMatrix_interface, OpAffine_interface);

                // Regenerate OpMatrix for subgrid -> adjacent cells must be trated as boundary
                if (Restriction != null)
                {
                    OpMatrix_bulk.Clear();
                    OpAffine_bulk.Clear();

                    //Operator_bulk.ComputeMatrix(
                    //    Phi.Mapping,
                    //    parameterFields,
                    //    Phi.Mapping,
                    //    OpMatrix_bulk, OpAffine_bulk,
                    //    OnlyAffine: false, sgrd: Restriction);
                    EdgeQuadratureScheme edgescheme;
                    //if (Control.Upwinding) {
                    //    edgescheme = new EdgeQuadratureScheme(true, IncludingInterface ? Restriction.AllEdgesMask : null);
                    //}
                    //else {
                    edgescheme = new EdgeQuadratureScheme(true, IncludingInterface ? Restriction.InnerEdgesMask : null);
                    //}
                    Operator_bulk.ComputeMatrixEx(Phi.Mapping,
                                                  parameterFields,
                                                  Phi.Mapping, OpMatrix_bulk, OpAffine_bulk, false, 0,
                                                  edgeQuadScheme: edgescheme,
                                                  volQuadScheme: new CellQuadratureScheme(true, IncludingInterface ? Restriction.VolumeMask : null)
                                                  );
                    //PreviouslyOnSubgrid = true;
                }
                // recalculate full Matrix
                //else if (PreviouslyOnSubgrid) {
                else
                {
                    OpMatrix_bulk.Clear();
                    OpAffine_bulk.Clear();


                    Operator_bulk.ComputeMatrixEx(Phi.Mapping,
                                                  parameterFields,
                                                  Phi.Mapping, OpMatrix_bulk, OpAffine_bulk, false, 0
                                                  );
                    //PreviouslyOnSubgrid = false;
                }


                /// Compose the Matrix
                /// This is symmetric due to the symmetry of the SIP and the penalty term
                OpMatrix.Clear();
                OpMatrix.Acc(1.0, OpMatrix_bulk);
                OpMatrix.Acc(1.0, OpMatrix_interface);
                OpMatrix.AssumeSymmetric = !Control.Upwinding;
                //OpMatrix.AssumeSymmetric = false;

                /// Compose the RHS of the above operators. (-> Boundary Conditions)
                /// This does NOT include the Nonlinear RHS, which will be added later
                OpAffine.Clear();
                OpAffine.AccV(1.0, OpAffine_bulk);
                OpAffine.AccV(1.0, OpAffine_interface);


#if Debug
                ilPSP.Connectors.Matlab.BatchmodeConnector matlabConnector;
                matlabConnector = new BatchmodeConnector();
#endif

                if (Restriction != null)
                {
                    SubVecIdx = Phi.Mapping.GetSubvectorIndices(Restriction, true, new int[] { 0 });
                    int L = SubVecIdx.Length;
                    SubMatrix   = new MsrMatrix(L);
                    SubRHS      = new double[L];
                    SubSolution = new double[L];

                    OpMatrix.AccSubMatrixTo(1.0, SubMatrix, SubVecIdx, default(int[]), SubVecIdx, default(int[]));

                    slv.DefineMatrix(SubMatrix);
#if Debug
                    Console.WriteLine("ConditionNumber of ReInit-Matrix is " + SubMatrix.condest().ToString("E"));
#endif
                }
                else
                {
                    slv.DefineMatrix(OpMatrix);
#if Debug
                    Console.WriteLine("ConditionNumber of ReInit-Matrix is " + OpMatrix.condest().ToString("E"));
#endif
                }
            }
        }
示例#15
0
        /// <summary>
        /// computes <see cref="LaplaceMtx"/> and <see cref="LaplaceAffine"/>
        /// </summary>
        private void UpdateMatrices()
        {
            using (var tr = new FuncTrace()) {
                // time measurement for matrix assembly
                Stopwatch stw = new Stopwatch();
                stw.Start();

                // Stats:
                {
                    int BlkSize       = T.Mapping.MaxTotalNoOfCoordinatesPerCell;
                    int NoOfMtxBlocks = 0;
                    foreach (int[] Neigs in this.GridData.iLogicalCells.CellNeighbours)
                    {
                        NoOfMtxBlocks++;               //               diagonal block
                        NoOfMtxBlocks += Neigs.Length; // off-diagonal block
                    }
                    NoOfMtxBlocks = NoOfMtxBlocks.MPISum();

                    int MtxBlockSize = BlkSize * BlkSize;
                    int MtxSize      = MtxBlockSize * NoOfMtxBlocks;

                    double MtxStorage = MtxSize * (8.0 + 4.0) / (1024 * 1024); // 12 bytes (double+int) per entry

                    Console.WriteLine("   System size:                 {0}", T.Mapping.TotalLength);
                    Console.WriteLine("   No of blocks:                {0}", T.Mapping.TotalNoOfBlocks);
                    Console.WriteLine("   No of blocks in matrix:      {0}", NoOfMtxBlocks);
                    Console.WriteLine("   DG coordinates per cell:     {0}", BlkSize);
                    Console.WriteLine("   Non-zeros per matrix block:  {0}", MtxBlockSize);
                    Console.WriteLine("   Total non-zeros in matrix:   {0}", MtxSize);
                    Console.WriteLine("   Approx. matrix storage (MB): {0}", MtxStorage);


                    base.QueryHandler.ValueQuery("MtxBlkSz", MtxBlockSize, true);
                    base.QueryHandler.ValueQuery("NNZMtx", MtxSize, true);
                    base.QueryHandler.ValueQuery("NNZblk", NoOfMtxBlocks, true);
                    base.QueryHandler.ValueQuery("MtxMB", MtxStorage, true);
                }


                Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal);


                // quadrature domain
                var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData, MaskType.Geometrical));
                var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData, MaskType.Geometrical));

                using (new BlockTrace("SipMatrixAssembly", tr)) {
                    LaplaceMtx    = new BlockMsrMatrix(T.Mapping);
                    LaplaceAffine = new double[T.Mapping.LocalLength];

                    LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                             LaplaceMtx, LaplaceAffine,
                                             volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
                }

                stw.Stop();

                //Print process information
                Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds);
                LaplaceMtx.GetMemoryInfo(out long AllocatedMem, out long UsedMem);
                Console.WriteLine("   Used   matrix storage (MB): {0}", UsedMem / (1024.0 * 1024));
                Console.WriteLine("   Alloc. matrix storage (MB): {0}", AllocatedMem / (1024.0 * 1024));
            }
        }
示例#16
0
        /// <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);
            }
        }
示例#17
0
        /// <summary>
        /// Includes assembly of the matrix.
        /// </summary>
        /// <param name="L"></param>
        protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L)
        {
            using (FuncTrace tr = new FuncTrace()) {
                // create operator
                // ===============
                SpatialOperator LapaceIp;
                {
                    double D              = this.GridData.SpatialDimension;
                    double penalty_base   = (T.Basis.Degree + 1) * (T.Basis.Degree + D) / D;
                    double penalty_factor = base.Control.penalty_poisson;

                    BoundaryCondMap <BoundaryType> PoissonBcMap = new BoundaryCondMap <BoundaryType>(this.GridData, this.Control.BoundaryValues, "T");

                    LapaceIp = new SpatialOperator(1, 1, QuadOrderFunc.SumOfMaxDegrees(), "T", "T");
                    var flux = new ipFlux(penalty_base * base.Control.penalty_poisson, this.GridData.Cells.cj, PoissonBcMap);
                    LapaceIp.EquationComponents["T"].Add(flux);

                    LapaceIp.Commit();
                }

                // Create Matrices
                // ===============

                {
                    // time measurement for matrix assembly
                    Stopwatch stw = new Stopwatch();
                    stw.Start();

                    // console
                    Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal);

                    // quadrature domain
                    var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData));
                    var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData));

#if DEBUG
                    // in DEBUG mode, we compare 'MsrMatrix' (old, reference implementation) and 'BlockMsrMatrix' (new standard)
                    var RefLaplaceMtx = new MsrMatrix(T.Mapping);
#endif
                    using (new BlockTrace("SipMatrixAssembly", tr)) {
                        LaplaceMtx    = new BlockMsrMatrix(T.Mapping);
                        LaplaceAffine = new double[T.Mapping.LocalLength];

                        LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                                 LaplaceMtx, LaplaceAffine,
                                                 volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
                    }
#if DEBUG
                    LaplaceAffine.ClearEntries();
                    LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping,
                                             RefLaplaceMtx, LaplaceAffine,
                                             volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);
                    MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs();
                    ErrMtx.Acc(-1.0, LaplaceMtx);
                    double err    = ErrMtx.InfNorm();
                    double infNrm = LaplaceMtx.InfNorm();
                    Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm);
                    Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed.");
#endif
                    stw.Stop();
                    Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds);
                }


                //double condNo = LaplaceMtx.condest(BatchmodeConnector.Flavor.Octave);
                //Console.WriteLine("condition number: {0:0.####E-00} ",condNo);
            }
        }
示例#18
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="jCell">
        /// Local index of cell which should be recalculated.
        /// </param>
        /// <param name="AcceptedMask">
        /// Bitmask which marks accepted cells - if any neighbor of
        /// <paramref name="jCell"/> is _accepted_, this defines a Dirichlet
        /// boundary; otherwise, the respective cell face is a free boundary.
        /// </param>
        /// <param name="Phi">
        /// Input and output:
        /// - input for _accepted_ cells, i.e. Dirichlet boundary values
        /// - input and output for <paramref name="jCell"/>: an initial value for the iterative procedure, resp. on exit the result of the iteration.
        /// </param>
        /// <param name="gradPhi">
        /// Auxillary variable to store the gradient of the level-set-field.
        /// </param>
        /// <returns></returns>
        public bool LocalSolve(int jCell, BitArray AcceptedMask, SinglePhaseField Phi, VectorField <SinglePhaseField> gradPhi)
        {
            Stpw_tot.Start();

            int    N           = this.LevelSetBasis.GetLength(jCell);
            int    i0G         = this.LevelSetMapping.GlobalUniqueCoordinateIndex(0, jCell, 0);
            int    i0L         = this.LevelSetMapping.LocalUniqueCoordinateIndex(0, jCell, 0);
            double penaltyBase = ((double)(this.LevelSetBasis.Degree + 2)).Pow2();
            double CellVolume  = this.GridDat.Cells.GetCellVolume(jCell);
            int    p           = Phi.Basis.Degree;

            // subgrid on which we are working, consisting only of one cell
            SubGrid jCellGrid = new SubGrid(new CellMask(this.GridDat, Chunk.GetSingleElementChunk(jCell)));
            var     VolScheme = new CellQuadratureScheme(domain: jCellGrid.VolumeMask);
            var     EdgScheme = new EdgeQuadratureScheme(domain: jCellGrid.AllEdgesMask);

            //var VolRule = VolScheme.SaveCompile(GridDat, 3 * p);
            //var EdgRule = EdgScheme.SaveCompile(GridDat, 3 * p);

            // parameter list for operator
            DGField[] Params = new DGField[] { Phi };
            gradPhi.ForEach(f => f.AddToArray(ref Params));

            // build operator
            var comp = new EllipticReinitForm(AcceptedMask, jCell, penaltyBase, this.GridDat.Cells.cj);

            comp.LhsSwitch = 1.0;  // matrix is constant -- Lhs Matrix only needs to be computed once
            comp.RhsSwitch = -1.0; //                   Rhs must be updated in every iteration
            var op = comp.Operator((DomDeg, ParamDeg, CodDeg) => 3 * p);

            // iteration loop:
            MultidimensionalArray Mtx = MultidimensionalArray.Create(N, N);

            double[] Rhs        = new double[N];
            double   ChangeNorm = 0;
            int      iIter;

            for (iIter = 0; iIter < 100; iIter++)
            {
                // update gradient
                gradPhi.Clear(jCellGrid.VolumeMask);
                gradPhi.Gradient(1.0, Phi, jCellGrid.VolumeMask);

                // assemble matrix and rhs
                {
                    // clear
                    for (int n = 0; n < N; n++)
                    {
                        if (iIter == 0)
                        {
                            m_LaplaceMatrix.ClearRow(i0G + n);
                        }
                        this.m_LaplaceAffine[i0L + n] = 0;
                    }

                    // compute matrix (only in iteration 0) and rhs
                    if (iIter == 0)
                    {
                        Stpw_Mtx.Start();
                    }
                    Stpw_Rhs.Start();
                    op.ComputeMatrixEx(this.LevelSetMapping, Params, this.LevelSetMapping,
                                       iIter == 0 ? this.m_LaplaceMatrix : null, this.m_LaplaceAffine,
                                       OnlyAffine: iIter > 0,
                                       volQuadScheme: VolScheme, edgeQuadScheme: EdgScheme,
                                       //volRule: VolRule, edgeRule: EdgRule,
                                       ParameterMPIExchange: false);
                    //op.Internal_ComputeMatrixEx(this.GridDat,
                    //    this.LevelSetMapping, Params, this.LevelSetMapping,
                    //    iIter == 0 ? this.m_LaplaceMatrix : default(MsrMatrix), this.m_LaplaceAffine, iIter > 0,
                    //    0.0,
                    //    EdgRule, VolRule,
                    //    null, false);


                    if (iIter == 0)
                    {
                        Stpw_Mtx.Stop();
                    }
                    Stpw_Rhs.Stop();

                    // extract matrix for 'jCell'
                    for (int n = 0; n < N; n++)
                    {
#if DEBUG
                        int      Lr;
                        int[]    row_cols = null;
                        double[] row_vals = null;
                        Lr = this.m_LaplaceMatrix.GetRow(i0G + n, ref row_cols, ref row_vals);
                        for (int lr = 0; lr < Lr; lr++)
                        {
                            int    ColIndex = row_cols[lr];
                            double Value    = row_vals[lr];
                            Debug.Assert((ColIndex >= i0G && ColIndex < i0G + N) || (Value == 0.0), "Matrix is expected to be block-diagonal.");
                        }
#endif
                        if (iIter == 0)
                        {
                            for (int m = 0; m < N; m++)
                            {
                                Mtx[n, m] = this.m_LaplaceMatrix[i0G + n, i0G + m];
                            }
                        }
                        else
                        {
#if DEBUG
                            for (int m = 0; m < N; m++)
                            {
                                Debug.Assert(Mtx[n, m] == this.m_LaplaceMatrix[i0G + n, i0G + m]);
                            }
#endif
                        }
                        Rhs[n] = -this.m_LaplaceAffine[i0L + n];
                    }
                }

                // solve
                double[] sol = new double[N];
                Mtx.Solve(sol, Rhs);
                ChangeNorm = GenericBlas.L2Dist(sol, Phi.Coordinates.GetRow(jCell));
                Phi.Coordinates.SetRow(jCell, sol);

                if (ChangeNorm / CellVolume < 1.0e-10)
                {
                    break;
                }
            }


            //Console.WriteLine("Final change norm: {0}, \t iter: {1}", ChangeNorm, iIter );

            if (ChangeNorm > 1.0e-6)
            {
                Console.WriteLine("  local solver funky in cell: " + jCell + ", last iteration change norm = " + ChangeNorm);
            }


            Stpw_tot.Stop();
            return(true);
        }
示例#19
0
        protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L)
        {
            using (FuncTrace tr = new FuncTrace()) {
                this.BcMap = new IncompressibleBoundaryCondMap(this.GridData, grid.GetBoundaryConfig(), PhysicsMode.Incompressible);


                // assemble system, create matrix
                // ------------------------------

                var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData));
                var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData));

                //var volQrSch = new CellQuadratureScheme(true, CellMask.GetEmptyMask(this.GridData));
                //var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(this.GridData));
                //var edgQrSch = new EdgeQuadratureScheme(true, this.GridDat.BoundaryEdges);
                //var edgQrSch = new EdgeQuadratureScheme(true, this.GridDat.BoundaryEdges.Complement());

                int    D              = GridData.SpatialDimension;
                double penalty_base   = ((double)((U[0].Basis.Degree + 1) * (U[0].Basis.Degree + D))) / ((double)D);
                double penalty_factor = 1.2;



                // equation assembly
                // -----------------
                string[] CodNames = D.ForLoop(i => "C" + i);
                Operator = new SpatialOperator(VariableNames.VelocityVector(D), new string[] { VariableNames.ViscosityMolecular }, CodNames, QuadOrderFunc.Linear());

                for (int d = 0; d < D; d++)
                {
                    if ((this.whichTerms & Terms.T1) != 0)
                    {
                        var flx1 = new swipViscosity_Term1(penalty_base * penalty_factor, this.GridData.Cells.cj, d, D, BcMap, this.viscOption, ViscosityOption.VariableViscosity);

                        flx1.g_Diri_Override = this.solution.U;
                        flx1.g_Neu_Override  = this.solution.dU;
                        Operator.EquationComponents[CodNames[d]].Add(flx1);
                    }
                    if ((this.whichTerms & Terms.T2) != 0)
                    {
                        var flx2 = new swipViscosity_Term2(penalty_base * penalty_factor, this.GridData.Cells.cj, d, D, BcMap, this.viscOption, ViscosityOption.VariableViscosity);

                        flx2.g_Diri_Override = this.solution.U;
                        flx2.g_Neu_Override  = this.solution.dU;
                        Operator.EquationComponents[CodNames[d]].Add(flx2);
                    }
                    if ((this.whichTerms & Terms.T3) != 0)
                    {
                        var flx3 = new swipViscosity_Term3(penalty_base * penalty_factor, this.GridData.Cells.cj, d, D, BcMap, this.viscOption, ViscosityOption.VariableViscosity);

                        flx3.g_Diri_Override = this.solution.U;
                        flx3.g_Neu_Override  = this.solution.dU;
                        Operator.EquationComponents[CodNames[d]].Add(flx3);
                    }
                } // */
                Operator.Commit();


                var map = this.U.Mapping;
                OperatorMtx = new MsrMatrix(map, map);
                Operator.ComputeMatrixEx(map, new DGField[] { this.mu }, map,
                                         OperatorMtx, this.bnd.CoordinateVector,
                                         volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);

                // test for matrix symmetry
                // ========================

                if (base.MPISize == 1)
                {
                    double MatrixAssymmetry = OperatorMtx.SymmetryDeviation();
                    Console.WriteLine("Matrix asymmetry: " + MatrixAssymmetry);
                    Assert.LessOrEqual(Math.Abs(MatrixAssymmetry), 1.0e-10);
                }
            }
        }
示例#20
0
 public JumpSemiNormIntegrator(Field _f, EdgeQuadratureScheme eq) :
     base(new int[] { 1 }, _f.Basis.Context, eq, _f.Basis.Degree * 2)
 {
     f = _f;
 }