예제 #1
0
        public IBMABevolve(
            SpatialOperator standardOperator,
            SpatialOperator boundaryOperator,
            CoordinateMapping fieldsMap,
            CoordinateMapping parametersMap,
            ISpeciesMap ibmSpeciesMap,
            int explicitOrder,
            int levelSetQuadratureOrder,
            XQuadFactoryHelper.MomentFittingVariants momentFittingVariant,
            SubGrid sgrd,
            bool adaptive = false)
            : base(standardOperator, fieldsMap, parametersMap, explicitOrder, adaptive: adaptive, sgrd: sgrd)
        {
            speciesMap = ibmSpeciesMap as ImmersedSpeciesMap;
            if (speciesMap == null)
            {
                throw new ArgumentException(
                          "Only supported for species maps of type 'ImmersedSpeciesMap'",
                          "speciesMap");
            }

            this.boundaryOperator          = boundaryOperator;
            this.boundaryParameterMap      = parametersMap;
            agglomerationPatternHasChanged = true;
        }
예제 #2
0
        public static void AllUp(
            [Values(XQuadFactoryHelper.MomentFittingVariants.OneStepGauss, XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes)]
            XQuadFactoryHelper.MomentFittingVariants variant
            )
        {
            //static void Main(string[] args) {


            var Tests = new ITest[] { new Schraeg(XdgNastyLevsetLocationTest.GetTestRange(), XdgNastyLevsetLocationTest.GetTestRange()),
                                      new Parallel(XdgNastyLevsetLocationTest.GetTestRange(), XdgNastyLevsetLocationTest.GetTestRange()) };

            XQuadFactoryHelper.MomentFittingVariants[] Variants = new[] {
                XQuadFactoryHelper.MomentFittingVariants.OneStepGauss,
                XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes
            };


            foreach (var tst in Tests)
            {
                XdgNastyLevsetLocationTest p = null;

                tst.ResetTest();

                BoSSS.Solution.Application._Main(new string[0], true, delegate() {
                    p      = new XdgNastyLevsetLocationTest();
                    p.test = tst;
                    p.momentFittingVariant = variant;
                    return(p);
                });

                Assert.IsTrue(p.IsPassed);
            }
        }
예제 #3
0
        public static void XDG_MatrixPolynomialRestAndPrlgTest_2(
            [Values(0, 1, 2, 3)] int p,
            [Values(0.0, 0.3)] double AggregationThreshold)
        {
            var mode = MultigridOperator.Mode.IdMass; // !!!!! Test work only with orthonormalization at each level. !!!!

            if (AggregationThreshold < 0.1 && p >= 3 && mode == MultigridOperator.Mode.IdMass)
            {
                // this test combination is not supposed to work:
                // without agglomeration, for high p, the mass matrix may be indefinite in small cut-cells
                // => Cholesky decomposition on mass matrix fails, i.e. 'mode == IdMass' cannot succeed.
                return;
            }

            XQuadFactoryHelper.MomentFittingVariants variant = XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes;
            var xt = new XDGTestSetup(p, AggregationThreshold, 1, mode, variant);


            // Restriction & prolongation together with orthonormalization
            // -----------------------------------------------------------


            for (var mgop = xt.XdgMultigridOp.CoarserLevel; mgop != null; mgop = mgop.CoarserLevel)
            {
                Assert.GreaterOrEqual(mgop.LevelIndex, 1);

                //var Itself = mgop.Mapping.FromOtherLevelMatrix(mgop.Mapping);
                //Itself.AccEyeSp(-1.0);
                //double Itslef_Norm = Itself.InfNorm();
                //Console.WriteLine("Level {0}, Restriction onto itself {1}", mgop.Mapping.AggGrid.MgLevel, Itslef_Norm);
                //Assert.LessOrEqual(Itslef_Norm, 1.0e-8);

                var map_fine = mgop.FinerLevel.Mapping;

                int L_fine   = map_fine.LocalLength;
                int L_coarse = mgop.Mapping.LocalLength;

                // create random test vector
                Random   rnd       = new Random(mgop.LevelIndex);
                double[] vecCoarse = new double[L_coarse];
                for (int l = 0; l < L_coarse; l++)
                {
                    vecCoarse[l] = rnd.NextDouble();
                }

                // prolongate & restrict
                double[] vecFine = new double[L_fine];
                mgop.Prolongate(1.0, vecFine, 0.0, vecCoarse); // uses matrix
                double[] vecCoarse_check = new double[L_coarse];
                mgop.Restrict(vecFine, vecCoarse_check);

                // for 'MultigridOperator.Mode.IdMass', prolongation->restriction must be the identity
                double err = GenericBlas.L2Dist(vecCoarse, vecCoarse_check);
                double Ref = Math.Max(vecCoarse.L2Norm(), vecCoarse_check.L2Norm());
                Console.WriteLine("Restriction/prolongation error: " + err / Ref);
                Assert.LessOrEqual(err / Ref, 1.0e-8);
            }
        }
예제 #4
0
        /// <summary>
        /// Central 'factory' for creating Level Set - related quadrature.
        /// </summary>
        /// <remarks>
        /// The centralized approach should avoid multiple creation of the same quadrature rule.
        /// </remarks>
        XQuadFactoryHelper GetXQuadFactoryHelper(XQuadFactoryHelper.MomentFittingVariants variant, int HistoryIndex = 1)
        {
            var dict = m_QuadFactoryHelpersHistory[HistoryIndex];

            if (!dict.ContainsKey(variant))
            {
                dict[variant] = new XQuadFactoryHelper(
                    this.DataHistories.Select(hist => hist[HistoryIndex]).ToArray(),
                    variant);
            }

            return(dict[variant]);
        }
예제 #5
0
        public static void XDG_PolynomialRestAndPrlgTest(
            [Values(0, 1, 2, 3)] int p,
            [Values(0.0, 0.3)] double AggregationThreshold,
            [Values(0, 1)] int TrackerWidth)
        {
            XQuadFactoryHelper.MomentFittingVariants variant = XQuadFactoryHelper.MomentFittingVariants.OneStepGauss;

            var xt = new XDGTestSetup(p, AggregationThreshold, TrackerWidth, MultigridOperator.Mode.Eye, variant);


            // Basic Restriction & prolongation Test
            // -------------------------------------


            for (int iLevel = 0; iLevel < MgSeq.Length; iLevel++)
            {
                // create basis
                var XAggBasis = xt.XAggB[iLevel][0];

                // do restriction/prolongation
                double[] RestVec = new double[XAggBasis.LocalDim];
                XAggBasis.RestictFromFullGrid(xt.Xdg_uTest.CoordinateVector, RestVec);
                var Test = xt.Xdg_uTest.CloneAs();
                Test.Clear();
                XAggBasis.ProlongateToFullGrid(Test.CoordinateVector, RestVec);
                xt.agg.Extrapolate(Test.Mapping);

                // compare/test
                var ERR = xt.Xdg_uTest.CloneAs();
                ERR.Acc(-1.0, Test);
                double ERR_NORM = ERR.L2Norm();

                Console.WriteLine("Restriction/Prolongation err (p={0}, level={1}, width={2}, agg={3}): {4}",
                                  p, iLevel, TrackerWidth, AggregationThreshold, ERR_NORM);
                Assert.LessOrEqual(ERR_NORM, 1.0e-6);
            }
        }
예제 #6
0
        public static void XDG_ProlongationTest(
            [Values(0, 1, 2, 3)] int p,
            [Values(0.0, 0.3)] double AggregationThreshold,
            [Values(0, 1)] int TrackerWidth,
            [Values(MultigridOperator.Mode.Eye, MultigridOperator.Mode.IdMass)] MultigridOperator.Mode mode)
        {
            XQuadFactoryHelper.MomentFittingVariants variant = XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes;
            var xt = new XDGTestSetup(p, AggregationThreshold, TrackerWidth, MultigridOperator.Mode.Eye, variant
                                      //, ((Func<double[], double>)(X => X[0] + 0.75)).Vectorize()
                                      );
            int Jup = grid.Cells.NoOfLocalUpdatedCells;


            Random rnd  = new Random();
            int    Ltop = xt.XdgMultigridOp.Mapping.LocalLength; // Number of DOF's on top multigrid level.


            double[] RndVec   = Ltop.ForLoop(i => rnd.NextDouble());
            double[] NoJmpVec = new double[Ltop];

            for (int iLevel = 0; iLevel < MgSeq.Length - 1; iLevel++)
            {
                XDG_Recursive(0, iLevel, xt.XdgMultigridOp, RndVec, NoJmpVec); // restrict RndVec downt to level 'iLevel', and back up

                // right now, the XDG field defined by 'NoJmpVec' should be a member
                // of the aggregated XDG space on level 'iLevel';
                // so, there should be no inter-element jumps on the fine level, for each aggregated cell.
                // Let's test that!

                XDGField Test = new XDGField(xt.XB, "Test");
                xt.XdgMultigridOp.TransformSolFrom(Test.CoordinateVector, NoJmpVec);
                //xt.agg.Extrapolate(Test.Mapping);
                var aggGrd = MgSeq[iLevel];

                foreach (var spc in xt.LsTrk.SpeciesIdS)
                {
                    var Test_spc = Test.GetSpeciesShadowField(spc);
                    var SpcMask  = xt.LsTrk.Regions.GetSpeciesMask(spc);

                    BitArray AggSourceBitmask = xt.agg.GetAgglomerator(spc).AggInfo.SourceCells.GetBitMask();

                    double Err = 0;
                    for (int jagg = 0; jagg < aggGrd.iLogicalCells.NoOfLocalUpdatedCells; jagg++)
                    {
                        BitArray CompCellMask = new BitArray(Jup);
                        foreach (int jCell in aggGrd.iLogicalCells.AggregateCellToParts[jagg])
                        {
                            if (!AggSourceBitmask[jCell])
                            {
                                CompCellMask[jCell] = true;
                            }
                        }

                        SubGrid CompCellSubGrid = new SubGrid((new CellMask(grid, CompCellMask)).Intersect(SpcMask));

                        Err += JumpNorm(Test_spc, CompCellSubGrid.InnerEdgesMask).Pow2();
                    }


                    Console.WriteLine("prolongation jump test (level {0}, species {2}): {1}", iLevel, Err, xt.LsTrk.GetSpeciesName(spc));
                    Assert.LessOrEqual(Err, 1.0e-8);
                }
            }
        }
예제 #7
0
        public static void XDG_MatrixPolynomialRestAndPrlgTest(
            [Values(0, 1, 2, 3)] int p,
            [Values(0.0, 0.3)] double AggregationThreshold,
            [Values(0, 1)] int TrackerWidth)
        {
            XQuadFactoryHelper.MomentFittingVariants variant = XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes;
            var xt = new XDGTestSetup(p, AggregationThreshold, TrackerWidth, MultigridOperator.Mode.Eye, variant);


            // test matrix version of the restriction operator
            // -----------------------------------------------

            List <MultigridMapping> MultigridMaps = new List <MultigridMapping>();

            for (var mgop = xt.XdgMultigridOp; mgop != null; mgop = mgop.CoarserLevel)
            {
                MultigridMaps.Add(mgop.Mapping);
            }

            for (int iLevel = 0; iLevel < MgSeq.Length; iLevel++)
            {
                MultigridMapping mgMap = MultigridMaps[iLevel];
                var XAggBasis          = mgMap.AggBasis[0];

                // set the test field:
                XDGField Test = new XDGField(xt.XB, "Test");
                Random   rand = new Random();
                for (int i = 0; i < Test.CoordinateVector.Count; i++)
                {
                    Test.CoordinateVector[i] = rand.NextDouble();
                }
                xt.agg.ClearAgglomerated(Test.CoordinateVector, Test.Mapping);

                // do restriction/prolongation (Reference)
                double[] RestVecRef = new double[XAggBasis.LocalDim];
                XAggBasis.RestictFromFullGrid(Test.CoordinateVector, RestVecRef);

                // and now with the matrix:
                BlockMsrMatrix RestMtx = new BlockMsrMatrix(mgMap, mgMap.ProblemMapping);
                XAggBasis.GetRestrictionMatrix(RestMtx, mgMap, 0);
                double[] RestVec = new double[mgMap.LocalLength];
                RestMtx.SpMV(1.0, Test.CoordinateVector, 0.0, RestVec);

                double[] X1 = new double[xt.XdgMultigridOp.Mapping.LocalLength];
                XDGField X2 = new XDGField(Test.Basis);
                xt.XdgMultigridOp.TransformSolInto(Test.CoordinateVector, X1);
                xt.XdgMultigridOp.TransformSolFrom(X2.CoordinateVector, X1);
                //xt.agg.Extrapolate(X2.CoordinatesAsVector, X2.Mapping);
                var ERR2 = Test.CloneAs();
                ERR2.Acc(-1.0, X2);
                double ERR2Norm = ERR2.L2Norm();
                //Console.WriteLine("MultigridOperator TranformInto/FransformFrom mismatch: " + ERR2Norm);
                Assert.LessOrEqual(ERR2Norm, 1.0e-8);

                // compare
                double ERR  = 0.0;
                int    Nmax = XAggBasis.MaximalLength;
                for (int jAgg = 0; jAgg < mgMap.AggGrid.iLogicalCells.NoOfLocalUpdatedCells; jAgg++)
                {
                    int i0Ref = jAgg * Nmax;
                    int i0Tst = mgMap.LocalUniqueIndex(0, jAgg, 0);
                    int N     = mgMap.GetLength(jAgg);

                    for (int n = 0; n < N; n++)
                    {
                        double dist = RestVecRef[i0Ref + n] - RestVec[i0Tst + n];
                        ERR += dist.Pow2();
                    }
                }
                Console.WriteLine("Restriction matrix test (iLevel = {0}): {1}", iLevel, ERR);
                Assert.LessOrEqual(ERR, 1.0e-8);

                //
                double[] PrlgVecA = new double[XAggBasis.LocalDim];
                double[] PrlgVecB = new double[mgMap.LocalLength];
                for (int jAgg = 0; jAgg < mgMap.AggGrid.iLogicalCells.NoOfLocalUpdatedCells; jAgg++)
                {
                    int i0Ref = jAgg * Nmax;
                    int i0Tst = mgMap.LocalUniqueIndex(0, jAgg, 0);
                    int N     = mgMap.GetLength(jAgg);

                    for (int n = 0; n < N; n++)
                    {
                        double rndVal = rand.NextDouble();
                        PrlgVecA[i0Ref + n] = rndVal;
                        PrlgVecB[i0Tst + n] = rndVal;
                    }
                }

                XDGField QA = new XDGField(Test.Basis);
                XDGField QB = new XDGField(Test.Basis);

                XAggBasis.ProlongateToFullGrid(QA.CoordinateVector, PrlgVecA);
                var PrlgMtx = RestMtx.Transpose();
                PrlgMtx.SpMV(1.0, PrlgVecB, 0.0, QB.CoordinateVector);

                XDGField ERR5 = QA.CloneAs();
                ERR5.Acc(-1.0, QB);
                double ERR5_Norm = ERR5.L2Norm();
                Console.WriteLine("Prolongation matrix test (iLevel = {0}): {1}", iLevel, ERR5_Norm);
                Assert.LessOrEqual(ERR5_Norm, 1.0e-8);
            }
        }
예제 #8
0
            public XDGTestSetup(
                int p,
                double AggregationThreshold,
                int TrackerWidth,
                MultigridOperator.Mode mumo,
                XQuadFactoryHelper.MomentFittingVariants momentFittingVariant,
                ScalarFunction LevSetFunc = null)
            {
                // Level set, tracker and XDG basis
                // ================================

                if (LevSetFunc == null)
                {
                    LevSetFunc = ((_2D)((x, y) => 0.8 * 0.8 - x * x - y * y)).Vectorize();
                }
                LevSet = new LevelSet(new Basis(grid, 2), "LevelSet");
                LevSet.Clear();
                LevSet.ProjectField(LevSetFunc);
                LsTrk = new LevelSetTracker(grid, XQuadFactoryHelper.MomentFittingVariants.Classic, TrackerWidth, new string[] { "A", "B" }, LevSet);
                LsTrk.UpdateTracker();

                XB = new XDGBasis(LsTrk, p);

                XSpatialOperator Dummy = new XSpatialOperator(1, 0, 1, QuadOrderFunc.SumOfMaxDegrees(RoundUp: true), "C1", "u");

                //Dummy.EquationComponents["c1"].Add(new
                Dummy.Commit();

                //Tecplot.PlotFields(new DGField[] { LevSet }, "agglo", 0.0, 3);


                // operator
                // ========

                Debug.Assert(p <= 4);
                XDGBasis opXB = new XDGBasis(LsTrk, 4); // we want to have a very precise quad rule
                var      map  = new UnsetteledCoordinateMapping(opXB);

                int quadOrder = Dummy.QuadOrderFunction(map.BasisS.Select(bs => bs.Degree).ToArray(), new int[0], map.BasisS.Select(bs => bs.Degree).ToArray());

                //agg = new MultiphaseCellAgglomerator(new CutCellMetrics(momentFittingVariant, quadOrder, LsTrk, LsTrk.SpeciesIdS.ToArray()), AggregationThreshold, false);
                agg = LsTrk.GetAgglomerator(LsTrk.SpeciesIdS.ToArray(), quadOrder, __AgglomerationTreshold: AggregationThreshold);


                foreach (var S in LsTrk.SpeciesIdS)
                {
                    Console.WriteLine("Species {0}, no. of agglomerated cells {1} ",
                                      LsTrk.GetSpeciesName(S),
                                      agg.GetAgglomerator(S).AggInfo.SourceCells.Count());
                }

                // mass matrix factory
                // ===================

                // Basis maxB = map.BasisS.ElementAtMax(b => b.Degree);
                //MassFact = new MassMatrixFactory(maxB, agg);
                MassFact = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), quadOrder, 1).MassMatrixFactory;


                // Test field
                // ==========

                // set the test field: this is a polynomial function,
                // but different for each species; On this field, restriction followed by prolongation should be the identity
                this.Xdg_uTest = new XDGField(this.XB, "uTest");
                Dictionary <SpeciesId, double> dumia = new Dictionary <SpeciesId, double>();
                int i = 2;

                foreach (var Spc in LsTrk.SpeciesIdS)
                {
                    dumia.Add(Spc, i);
                    i -= 1;
                }
                SetTestValue(Xdg_uTest, dumia);


                // dummy operator matrix which fits polynomial degree p
                // ====================================================

                Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping);
                Xdg_opMtx.AccEyeSp(120.0);

                // XDG Aggregation BasiseS
                // =======================

                //XAggB = MgSeq.Select(agGrd => new XdgAggregationBasis[] { new XdgAggregationBasis(uTest.Basis, agGrd) }).ToArray();
                XAggB = new XdgAggregationBasis[MgSeq.Length][];
                var _XAggB = AggregationGridBasis.CreateSequence(MgSeq, Xdg_uTest.Mapping.BasisS);

                for (int iLevel = 0; iLevel < XAggB.Length; iLevel++)
                {
                    XAggB[iLevel] = new[] { (XdgAggregationBasis)(_XAggB[iLevel][0]) };
                    XAggB[iLevel][0].Update(agg);
                }

                // Multigrid Operator
                // ==================



                Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping);
                Xdg_opMtx.AccEyeSp(120.0);

                XdgMultigridOp = new MultigridOperator(XAggB, Xdg_uTest.Mapping,
                                                       Xdg_opMtx,
                                                       MassFact.GetMassMatrix(Xdg_uTest.Mapping, false),
                                                       new MultigridOperator.ChangeOfBasisConfig[][] {
                    new MultigridOperator.ChangeOfBasisConfig[] {
                        new MultigridOperator.ChangeOfBasisConfig()
                        {
                            VarIndex = new int[] { 0 }, mode = mumo, Degree = p
                        }
                    }
                });
            }
예제 #9
0
        public static void XDG_MatrixPolynomialRestAndPrlgTest_2(
            [Values(0, 1, 2, 3)] int p,
            [Values(0.0, 0.3)] double AggregationThreshold,
            [Values(0, 1)] int TrackerWidth,
            [Values(MultigridOperator.Mode.Eye, MultigridOperator.Mode.IdMass)] MultigridOperator.Mode mode)
        {
            if (AggregationThreshold < 0.1 && p >= 3 && mode == MultigridOperator.Mode.IdMass)
            {
                // this test combination is not supposed to work:
                // without agglomeration, for high p, the mass matrix may be indefinite in small cut-cells
                // => Cholesky decomposition on mass matrix fails, i.e. 'mode == IdMass' cannot succseed.
                return;
            }


            XQuadFactoryHelper.MomentFittingVariants variant = XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes;
            var xt = new XDGTestSetup(p, AggregationThreshold, TrackerWidth, mode, variant);


            // Restriction & prolongation together with orthonormalization
            // -----------------------------------------------------------


            for (var mgop = xt.MultigridOp; mgop != null; mgop = mgop.CoarserLevel)
            {
                var Itself = mgop.Mapping.FromOtherLevelMatrix(mgop.Mapping);
                Itself.AccEyeSp(-1.0);
                double Itslef_Norm = Itself.InfNorm();
                //Console.WriteLine("Level {0}, Restriction onto itself {1}", mgm.LevelIndex, Itslef_Norm);
                Assert.LessOrEqual(Itslef_Norm, 1.0e-8);
            }

            {
                // test change of basis on top level

                XDGField uTestRnd = new XDGField(xt.XB);
                Random   rnd      = new Random();
                for (int i = 0; i < uTestRnd.CoordinateVector.Count; i++)
                {
                    uTestRnd.CoordinateVector[i] = rnd.NextDouble();
                }
                xt.agg.ClearAgglomerated(uTestRnd.CoordinateVector, uTestRnd.Mapping);

                // perform change of basis on top level ...
                int      Ltop       = xt.MultigridOp.Mapping.LocalLength;
                double[] uTest_Fine = new double[Ltop];
                xt.MultigridOp.TransformSolInto(uTestRnd.CoordinateVector, uTest_Fine);

                // .. and back
                XDGField uError2 = uTestRnd.CloneAs();
                uError2.Clear();
                xt.MultigridOp.TransformSolFrom(uError2.CoordinateVector, uTest_Fine);

                // compare:
                uError2.Acc(-1.0, uTestRnd);
                double NORM_uError = uError2.L2Norm();

                // output
                Console.WriteLine("Top level change of basis error: {0}", NORM_uError);
                Assert.LessOrEqual(NORM_uError, 1.0e-8);
            }

            {
                // perform change of basis on top level
                int      Ltop       = xt.MultigridOp.Mapping.LocalLength;
                double[] uTest_Fine = new double[Ltop];
                xt.MultigridOp.TransformSolInto(xt.uTest.CoordinateVector, uTest_Fine);


                // check for each level of the multigrid operator...
                for (int iLevel = 0; iLevel < MgSeq.Count() - 1; iLevel++)
                {
                    double[] uTest_Prolonged = new double[Ltop];

                    XDG_Recursive(0, iLevel, xt.MultigridOp, uTest_Fine, uTest_Prolonged);

                    XDGField uError = xt.uTest.CloneAs();
                    uError.Clear();
                    xt.MultigridOp.TransformSolFrom(uError.CoordinateVector, uTest_Prolonged);
                    xt.agg.Extrapolate(uError.Mapping);

                    uError.Acc(-1.0, xt.uTest);
                    double NORM_uError = uError.L2Norm();

                    Console.WriteLine("Rest/Prlg error, level {0}: {1}", iLevel, NORM_uError);
                    Assert.LessOrEqual(NORM_uError, 1.0e-8);
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Instantiates those fields that are marked by an <see cref="InstantiateFromControlFileAttribute"/> - attribute;
        /// </summary>
        public static void CreateFieldsAuto(object _this, IGridData context,
                                            IDictionary <string, FieldOpts> FieldOptions, XQuadFactoryHelper.MomentFittingVariants cutCellQuadType,
                                            ICollection <DGField> IOFields, ICollection <DGField> RegisteredFields)
        {
            FieldInfo[] fields = _this.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Static);

            FieldInfo LevelSetTracker = null;

            List <FieldInfo> LevelSets   = new List <FieldInfo>();
            List <FieldInfo> OtherFields = new List <FieldInfo>();

            #region DetermineTypeOfFields
            // Determine the Type of the Fields
            foreach (FieldInfo f in fields)
            {
                object[] atts = f.GetCustomAttributes(typeof(InstantiateFromControlFileAttribute), true);

                if (atts.Length != 0)
                {
                    if (atts.Length != 1)
                    {
                        throw new ApplicationException("should not happen");
                    }

                    Type HistoryType, VectorType, ComponentType;
                    GetTypes(f, out HistoryType, out VectorType, out ComponentType);

                    if (typeof(LevelSet).IsAssignableFrom(ComponentType))
                    {
                        LevelSets.Add(f);
                    }
                    else
                    {
                        OtherFields.Add(f);
                    }
                }

                atts = f.GetCustomAttributes(typeof(LevelSetTrackerAttribute), true);

                if (atts.Length != 0)
                {
                    if (atts.Length != 1)
                    {
                        throw new ApplicationException("should not happen");
                    }

                    if (f.FieldType != typeof(LevelSetTracker))
                    {
                        throw new ApplicationException("stupid.");
                    }

                    if (LevelSetTracker != null)
                    {
                        throw new ApplicationException("only one level set tracker is allowed");
                    }
                    LevelSetTracker = f;
                }
            }
            #endregion

            #region CreateLevelSets
            // create Level Sets ..
            // =====================

            // must be initialized before the XDG fields ...

            FieldInfo[] LevelSetsSorted = new FieldInfo[LevelSets.Count];

            if (LevelSets.Count > 4)
            {
                throw new ApplicationException("at maximum, 4 different level sets are supported.");
            }

            if (LevelSets.Count > 1)
            {
                // more than 1 level set -> level set index is required.


                for (int i = 0; i < LevelSets.Count; i++)
                {
                    FieldInfo fi    = LevelSets[i];
                    object[]  atts2 = fi.GetCustomAttributes(typeof(LevelSetIndexAttribute), true);
                    if (atts2.Length > 1)
                    {
                        throw new ApplicationException("should not happen (AttributeUsage.AllowMultiple = false for 'LevelSetIndexAttribute')");
                    }
                    if (atts2.Length < 1)
                    {
                        throw new ApplicationException("missing 'LevelSetIndexAttribute' for level set '"
                                                       + fi.Name + "' in class '" + fi.ReflectedType.Name + "'; this contains " + LevelSets.Count
                                                       + " level sets, so level set indices in the range 0 (including) to " + LevelSets.Count
                                                       + " (excluding) are required.");
                    }

                    LevelSetIndexAttribute lsia = (LevelSetIndexAttribute)atts2[0];

                    if (lsia.m_idx < 0 || lsia.m_idx >= LevelSets.Count)
                    {
                        throw new ApplicationException("error with level set index for level set '"
                                                       + fi.Name + "': index is specified as " + lsia.m_idx + ", but allowed range is "
                                                       + "0 (including) to " + LevelSets.Count + " (excluding).");
                    }

                    if (LevelSetsSorted[lsia.m_idx] != null)
                    {
                        throw new ApplicationException("error with level set index " + lsia.m_idx + ": "
                                                       + " assigned for at least two level sets, i.e. for '" + fi.Name
                                                       + "' and for '" + LevelSetsSorted[lsia.m_idx].Name + "' -- each index is allowed only once.");
                    }
                }
            }
            else if (LevelSets.Count == 1)
            {
                LevelSetsSorted[0] = LevelSets[0];
            }


            LevelSet[] LevelSetsInstances = new LevelSet[LevelSets.Count];
            for (int i = 0; i < LevelSetsSorted.Length; i++)
            {
                InstantiateField(LevelSetsSorted[i], _this, IOFields, RegisteredFields, FieldOptions, context, null);

                object o = LevelSetsSorted[i].GetValue(_this);

                if (o is ScalarFieldHistory <LevelSet> )
                {
                    LevelSetsInstances[i] = ((ScalarFieldHistory <LevelSet>)LevelSetsSorted[i].GetValue(_this)).Current;
                }
                else
                {
                    LevelSetsInstances[i] = (LevelSet)LevelSetsSorted[i].GetValue(_this);
                }
            }

            #endregion

            #region CreareLevelSetTracker
            // create level set tracker
            // ========================


            LevelSetTracker lsTrk = null;

            foreach (DGField f in RegisteredFields)
            {
                if (f is XDGField)
                {
                    LevelSetTracker _lsTrk = ((XDGField)f).Basis.Tracker;

                    if (lsTrk == null)
                    {
                        lsTrk = _lsTrk;
                    }
                    else
                    {
                        if (!object.ReferenceEquals(lsTrk, _lsTrk))
                        {
                            throw new NotSupportedException();
                        }
                    }
                }
            }

            if (lsTrk == null)
            {
                if (LevelSets.Count > 0)
                {
                    if (LevelSetTracker == null)
                    {
                        throw new ApplicationException("missing Level Set Tracker");
                    }
                    LevelSetTrackerAttribute att = (LevelSetTrackerAttribute)(LevelSetTracker.GetCustomAttributes(typeof(LevelSetTrackerAttribute), true)[0]);


                    switch (LevelSetsSorted.Length)
                    {
                    case 1:
                        lsTrk = new LevelSetTracker((GridData)context, cutCellQuadType, att.m_NearCellWidth, (string[])(att.GetSpeciesTable(1)), LevelSetsInstances[0]);
                        break;

                    case 2:
                        lsTrk = new LevelSetTracker((GridData)context, cutCellQuadType, att.m_NearCellWidth, (string[, ])(att.GetSpeciesTable(2)), LevelSetsInstances[0], LevelSetsInstances[1]);
                        break;

                    case 3:
                        lsTrk = new LevelSetTracker((GridData)context, cutCellQuadType, att.m_NearCellWidth, (string[, , ])(att.GetSpeciesTable(3)), LevelSetsInstances[0], LevelSetsInstances[1], LevelSetsInstances[2]);
                        break;

                    case 4:
                        lsTrk = new LevelSetTracker((GridData)context, cutCellQuadType, att.m_NearCellWidth, (string[, , , ])(att.GetSpeciesTable(4)), LevelSetsInstances[0], LevelSetsInstances[1], LevelSetsInstances[2], LevelSetsInstances[3]);
                        break;
                    }

                    LevelSetTracker.SetValue(_this, lsTrk);
                }
            }

            #endregion


            // create other Fields, e.g. single phase, XDG, ...
            // ================================================

            foreach (FieldInfo f in OtherFields)
            {
                InstantiateField(f, _this, IOFields, RegisteredFields, FieldOptions, context, lsTrk);
            }
        }
예제 #11
0
        static public void AllUp([Values(0.0, 0.3)] double AggTresh,
#if DEBUG
                                 [Values(1)] int DGdegree,
                                 [Values(XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes)] XQuadFactoryHelper.MomentFittingVariants quadVariant,
                                 [Values(false)] bool DynamicBalance)