Beispiel #1
0
 /// <summary>
 /// ctor.
 /// </summary>
 internal XQuadSchemeHelper(XDGSpaceMetrics __XDGSpaceMetrics)
 {
     MPICollectiveWatchDog.Watch();
     this.XDGSpaceMetrics = __XDGSpaceMetrics;
     ConstructorCommon();
 }
Beispiel #2
0
        static internal void ComputeMassMatrixBlocks(
            IEnumerable <SpeciesId> _SpeciesIds,
            out Dictionary <SpeciesId, MassMatrixBlockContainer> Result,
            Basis b,
            XDGSpaceMetrics homie)
        {
            using (var tracer = new FuncTrace()) {
                if (b is XDGBasis)
                {
                    throw new ArgumentException();
                }
                var ctx = homie.GridDat;

                Result = new Dictionary <SpeciesId, MassMatrixBlockContainer>();
                var schemeHelper = homie.XQuadSchemeHelper;
                int Nnx          = b.Length;

                int quadorder = homie.CutCellQuadOrder;


                // define domains and allocate memory
                // ==================================


                foreach (var Species in _SpeciesIds)   // loop over species...

                // interation dom
                {
                    var _IntegrationDomain = homie.LevelSetRegions.GetSpeciesMask(Species).Intersect(homie.LevelSetRegions.GetCutCellMask());

                    // domain for mass-matrix blocks (include agglomeration targets)
                    var _BlockDomain = _IntegrationDomain; //.Union(Agg.GetAgglomerator(Species).AggInfo.AllAffectedCells);

                    // alloc mem for blocks
                    var _MassMatrixBlocksSpc = MultidimensionalArray.Create(_BlockDomain.NoOfItemsLocally, Nnx, Nnx);

                    // Subgrid index to cell index
                    int[] _jSub2jCell = _BlockDomain.ItemEnum.ToArray();

                    // cell to subgrid index
                    //Dictionary<int, int> _jCell2jSub;
                    //if (Agg.GetAgglomerator(Species).AggInfo.AgglomerationPairs.Length > 0) {
                    //    _jCell2jSub = new Dictionary<int, int>();
                    //    for (int i = 0; i < _jSub2jCell.Length; i++) {
                    //        _jCell2jSub.Add(_jSub2jCell[i], i);
                    //    }
                    //} else {
                    //    _jCell2jSub = null;
                    //}

                    Result.Add(Species, new MassMatrixBlockContainer()
                    {
                        IntegrationDomain = _IntegrationDomain,
                        MassMatrixBlocks  = _MassMatrixBlocksSpc,
                        //jCell2jSub = _jCell2jSub,
                        jSub2jCell = _jSub2jCell
                    });
                }

                // compute blocks
                // ==============

                foreach (var Species in _SpeciesIds)
                {
                    // get quad scheme
                    CellQuadratureScheme scheme = schemeHelper.GetVolumeQuadScheme(Species, IntegrationDomain: Result[Species].IntegrationDomain);

                    // result storage
                    var MassMatrixBlocksSpc = Result[Species].MassMatrixBlocks;

                    tracer.Info("mass matrix quad order: " + quadorder);

                    // compute the products of the basis functions:
                    int      BlockCnt     = -1;
                    int[]    BlockCell    = Result[Species].jSub2jCell;
                    CellMask speciesCells = homie.LevelSetRegions.GetSpeciesMask(Species);
                    CellQuadrature.GetQuadrature(
                        new int[] { Nnx, Nnx },
                        ctx,
                        scheme.Compile(ctx, quadorder),
                        delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                        // Del_Evaluate
                        // ~~~~~~~~~~~~~
                        var BasisVal = b.CellEval(QR.Nodes, i0, Length);
                        EvalResult.Multiply(1.0, BasisVal, BasisVal, 0.0, "ikmn", "ikm", "ikn");
                    },
                        delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                        // Del_SaveIntegrationResults
                        // ~~~~~~~~~~~~~~~~~~~~~~~~~~

                        for (int i = 0; i < Length; i++)
                        {
                            int jCell = i0 + i;
                            BlockCnt++;

                            // insert ID block in agglomeration target cells (if necessary):
                            // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                            var Block = MassMatrixBlocksSpc.ExtractSubArrayShallow(BlockCnt, -1, -1);
                            while (BlockCell[BlockCnt] < jCell)
                            {
                                // agglomeration source/target cell that is not cut
                                // mass matrix is identity (full) or zero (void)
                                Block.Clear();
                                if (speciesCells.Contains(BlockCell[BlockCnt]))
                                {
                                    // cell is full
                                    for (int nn = 0; nn < Nnx; nn++)
                                    {
                                        Block[nn, nn] = 1.0;
                                    }
                                }
                                BlockCnt++;
                                Block = MassMatrixBlocksSpc.ExtractSubArrayShallow(BlockCnt, -1, -1);
                            }

                            // store computed block
                            // - - - - - - - - - - -
                            Debug.Assert(BlockCell[BlockCnt] == jCell);
                            MassMatrixBlocksSpc.ExtractSubArrayShallow(BlockCnt, -1, -1)
                            .Set(ResultsOfIntegration.ExtractSubArrayShallow(i, -1, -1));
#if DEBUG
                            for (int n = 0; n < Nnx; n++)
                            {
                                for (int m = 0; m < Nnx; m++)
                                {
                                    Debug.Assert(Block[n, m] == Block[m, n]);
                                }
                            }
#endif
                        }
                    }).Execute();
                    // ------------------------------------ quadrature end.

                    BlockCnt++;
                    while (BlockCnt < MassMatrixBlocksSpc.GetLength(0))
                    {
                        // agglomeration source/target cell that is not cut
                        // mass matrix is identity (full) or zero (void)
                        var Block = MassMatrixBlocksSpc.ExtractSubArrayShallow(BlockCnt, -1, -1);
                        Block.Clear();
                        if (speciesCells.Contains(BlockCell[BlockCnt]))
                        {
                            // cell is full
                            for (int nn = 0; nn < Nnx; nn++)
                            {
                                Block[nn, nn] = 1.0;
                            }
                        }
                        BlockCnt++;
                    }


                    /*
                     * // test mass matrix for positive definiteness
                     * {
                     *  int JSUB = MassMatrixBlocksSpc.GetLength(0);
                     *  SubGrid Idom = null;
                     *
                     *  int failCount = 0;
                     *  var PosDefiniteTest = new FullMatrix(Nnx, Nnx);
                     *
                     *  for (int jsub = 0; jsub < JSUB; jsub++) {
                     *      PosDefiniteTest.Clear();
                     *      PosDefiniteTest.Acc(MassMatrixBlocksSpc.ExtractSubArrayShallow(jsub, -1, -1), 1.0);
                     *
                     *      try {
                     *          PosDefiniteTest.Clear();
                     *          PosDefiniteTest.Acc(MassMatrixBlocksSpc.ExtractSubArrayShallow(jsub, -1, -1), 1.0);
                     *          PosDefiniteTest.InvertSymmetrical();
                     *
                     *          //PosDefiniteTest.Clear();
                     *          //PosDefiniteTest.AccEye(1.0);
                     *          //PosDefiniteTest.Acc(MassMatrixBlocksSpc.ExtractSubArrayShallow(jsub, -1, -1), -1.0);
                     *          //PosDefiniteTest.InvertSymmetrical();
                     *      } catch (ArithmeticException ae) {
                     *          if (Idom == null)
                     *              Idom = new SubGrid(scheme.Domain);
                     *
                     *          int jCell = Idom.SubgridIndex2LocalCellIndex[jsub];
                     *          long Gid = Tracker.GridDat.Cells.GetCell(jCell).GlobalID;
                     *
                     *
                     *          double volFrac = Tracker.GetSpeciesVolume(jCell, Species)/ctx.Cells.GetCellVolume(jCell);
                     *
                     *          var errString = string.Format("Indefinite mass matrix in cell: globalId = {0}, local index = {1}, species {2}; \n   cell volume fraction: {3};\n   [{4}]", Gid, jCell, Tracker.GetSpeciesName(Species), volFrac, ae.Message);
                     *          tracer.Logger.Error(errString);
                     *          //Console.WriteLine(errString);
                     *          failCount++;
                     *      }
                     *  }
                     *
                     *  if (failCount > 0) {
                     *      var errString = string.Format("Indefinite mass matrix in {0} of {1} cut cells", failCount, JSUB);
                     *      tracer.Logger.Error(errString);
                     *      Console.WriteLine(errString);
                     *  } else {
                     *      Console.WriteLine("No indefinite mass matrix blocks");
                     *  }
                     *
                     * }
                     * // */

                    // backup before agglomeration (required if we wanna treat e.g. velocity in DG and pressure in XDG)
                    //MultidimensionalArray[] massMatrixBlocksB4Agglom = new MultidimensionalArray[Result[Species].jSub2jCell.Length];
                    //Result[Species].MassMatrixBlocks_B4Agglom = massMatrixBlocksB4Agglom;
                    //var _jCell2jSub = Result[Species].jCell2jSub;
                    //int J = ctx.Cells.NoOfLocalUpdatedCells;
                    //foreach (var pair in Agg.GetAgglomerator(Species).AggInfo.AgglomerationPairs) {

                    //    foreach (int jCell in new int[] { pair.jCellSource, pair.jCellTarget }) { // create a backup of source and target cell
                    //        if (jCell >= J)
                    //            continue;

                    //        int jSub = _jCell2jSub[jCell];

                    //        if (massMatrixBlocksB4Agglom[jSub] == null) {
                    //            massMatrixBlocksB4Agglom[jSub] = MassMatrixBlocksSpc.ExtractSubArrayShallow(jSub, -1, -1).CloneAs();
                    //        }
                    //    }
                    //}

                    // agglomeration
                    //Agg.GetAgglomerator(Species).ManipulateMassMatrixBlocks(MassMatrixBlocksSpc, b, Result[Species].jSub2jCell, Result[Species].jCell2jSub);
                    //throw new NotImplementedException("todo");
                }
            }
        }
Beispiel #3
0
 /// <summary>
 /// ctor.
 /// </summary>
 internal CutCellMetrics(XDGSpaceMetrics owner)
 {
     XDGSpaceMetrics = owner;
     ComputeNonAgglomeratedMetrics();
 }
Beispiel #4
0
 /// <summary>
 /// ctor.
 /// </summary>
 public MassMatrixFactory(XDGSpaceMetrics __XDGSpaceMetrics)
 {
     XDGSpaceMetrics = __XDGSpaceMetrics;
     this.MaxBasis   = new Basis(XDGSpaceMetrics.GridDat, XDGSpaceMetrics.CutCellQuadOrder / 2);
 }