示例#1
0
        public void ComputeStronglyConnectedComponents_LongLine_HaveCorrectLength()
        {
            var g   = new DependencyGraph <int>(i => i == 5 ? new[] { 12, 4 } : i <= 0 ? ArrayTools.Empty <int>() : new[] { i - 1 });
            var a   = new TarjanStronglyConnectedComponentsAlgorithm <DependencyGraph <int>, int, DependencyGraph <int> .Edge>(g);
            var scc = a.ComputeStronglyConnectedComponents(100);

            Assert.That(scc.Length, Is.EqualTo(94));
            Assert.That(scc[5].Length, Is.EqualTo(8));
            var scc2 = a.ComputeStronglyConnectedComponents(105);

            Assert.That(scc2.Length, Is.EqualTo(5));
        }
示例#2
0
        public void Init(MultigridOperator op)
        {
            using (new FuncTrace()) {
                if (m_MgOp != null)
                {
                    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    // someone is trying to re-use this solver: see if the settings permit that
                    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                    if (op.LevelIndex != m_MgOp.LevelIndex)
                    {
                        throw new ArgumentException("Re-use on different level not possible.");
                    }
                    if (!this.MtxFull._RowPartitioning.EqualsPartition(op.OperatorMatrix._RowPartitioning))
                    {
                        throw new ArgumentException("Matrix has changed, unable to re-use");
                    }
                    if (!this.MtxFull._ColPartitioning.EqualsPartition(op.OperatorMatrix._ColPartitioning))
                    {
                        throw new ArgumentException("Matrix has changed, unable to re-use");
                    }
#if DEBUG
                    if (!object.ReferenceEquals(this.MtxFull, op.OperatorMatrix))
                    {
                        BlockMsrMatrix Check = this.MtxFull.CloneAs();
                        Check.Acc(-1.0, op.OperatorMatrix);
                        if (Check.InfNorm() != 0.0)
                        {
                            throw new ArgumentException("Matrix has changed, unable to re-use");
                        }
                    }
#endif
                    if (this.m_BlockingStrategy.GetNoOfBlocks(op) != this.blockSolvers.Count())
                    {
                        throw new ArgumentException("Blocking, unable to re-use");
                    }


                    return;
                }

                var Mop   = op.OperatorMatrix;
                var MgMap = op.Mapping;
                this.m_MgOp = op;
                int myMpiRank = MgMap.MpiRank;
                int myMpisize = MgMap.MpiSize;

                if (!Mop.RowPartitioning.EqualsPartition(MgMap.Partitioning))
                {
                    throw new ArgumentException("Row partitioning mismatch.");
                }
                if (!Mop.ColPartition.EqualsPartition(MgMap.Partitioning))
                {
                    throw new ArgumentException("Column partitioning mismatch.");
                }

                var ag = MgMap.AggGrid;

                int JComp  = ag.iLogicalCells.NoOfLocalUpdatedCells;
                int JGhost = ag.iLogicalCells.NoOfExternalCells;

#if DEBUG
                ilPSP.Connectors.Matlab.BatchmodeConnector matlab;
                if (m_MatlabParalellizationCheck)
                {
                    matlab = new ilPSP.Connectors.Matlab.BatchmodeConnector();
                }
                else
                {
                    matlab = null;
                }
#endif

                //Mop.Clear();
                //for(int i = Mop.RowPartitioning.i0; i < Mop.RowPartitioning.iE; i++) {
                //    Mop[i, i] = i + 1;
                //}


                // get cell blocks
                // ===============

                var _Blocks         = this.m_BlockingStrategy.GetBlocking(op);
                int NoOfSchwzBlocks = _Blocks.Count();

                // test cell blocks
                // ================
#if DEBUG
                {
                    // ensure that each cell is used exactly once, among all blocks
                    bool[] test = new bool[ag.iLogicalCells.NoOfLocalUpdatedCells];
                    foreach (var bi in _Blocks)
                    {
                        foreach (int j in bi)
                        {
                            Debug.Assert(test[j] == false);
                            test[j] = true;
                        }
                        ;
                    }
                    for (int i = 0; i < test.Length; i++)
                    {
                        Debug.Assert(test[i] == true);
                    }
                }
#endif

                // extend blocks according to desired overlap
                // ==========================================
                {
                    BitArray marker = new BitArray(JComp + JGhost);

                    if (Overlap < 0)
                    {
                        throw new ArgumentException();
                    }
                    if (Overlap > 0)
                    {
                        if (Overlap > 1 && Mop.RowPartitioning.MpiSize > 1)
                        {
                            throw new NotSupportedException("In MPI parallel runs, the maximum supported overlap for the Schwarz preconditioner is 1.");
                        }

                        foreach (List <int> bi in _Blocks) // loop over blocks...
                        {
                            marker.SetAll(false);          // marks all cells which are members of the block
                            foreach (int jcomp in bi)
                            {
                                marker[jcomp] = true;
                            }

                            // determine overlap regions
                            for (int k = 0; k < Overlap; k++)
                            {
                                int Jblock = bi.Count;
                                for (int j = 0; j < Jblock; j++)
                                {
                                    int   jCell  = bi[j];
                                    int[] Neighs = ag.iLogicalCells.CellNeighbours[jCell];
                                    foreach (int jNeigh in Neighs)
                                    {
                                        if (marker[jNeigh] == false)
                                        {
                                            // neighbor cell is not already a member of the block
                                            // => add it.
                                            bi.Add(jNeigh);
                                            marker[jNeigh] = true;
                                        }
                                    }
                                }
                            }

                            bi.Sort();
                        }
                    }

                    BlockCells = _Blocks.Select(list => list.ToArray()).ToArray();
                }


                // convert cell blocks to DOF blocks
                // =================================

                List <int>[] BlkIdx_gI_lR;                  //  for each Schwarz block, (global) indices in the local range
                List <int>[] BlkIdx_gI_eR;                  //  for each Schwarz block, (global) indices of external rows and columns
                List <int>[] TempRowIdx_gI;                 // for each Schwarz block, (global) indices into the temporary matrix
                List <int>[] BlkIdx_lI_eR;                  //  for each Schwarz block, (local)  indices of external rows and columns
                List <int>[] LocalBlocks_i0, LocalBlocks_N; // blocking of the Schwarz-Blocks.

                // for matrix 'ExternalRowsTemp': which rows of 'Mop' are required locally
                List <int> ExternalRowsIndices, ExternalRows_BlockI0, ExternalRows_BlockN;
                {
                    int Jup = MgMap.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;
                    int Jgh = MgMap.AggGrid.iLogicalCells.NoOfExternalCells;

                    int LocalizedBlockCounter = 0;

                    BlkIdx_gI_lR   = NoOfSchwzBlocks.ForLoop(iPart => new List <int>(BlockCells[iPart].Length * MgMap.MaximalLength));
                    BlkIdx_gI_eR   = NoOfSchwzBlocks.ForLoop(iPart => new List <int>());
                    LocalBlocks_i0 = NoOfSchwzBlocks.ForLoop(iPart => new List <int>());
                    LocalBlocks_N  = NoOfSchwzBlocks.ForLoop(iPart => new List <int>());

                    TempRowIdx_gI = NoOfSchwzBlocks.ForLoop(iPart => new List <int>());
                    BlkIdx_lI_eR  = NoOfSchwzBlocks.ForLoop(iPart => new List <int>());


                    ExternalRowsIndices  = new List <int>();
                    ExternalRows_BlockI0 = new List <int>();
                    ExternalRows_BlockN  = new List <int>();

                    for (int iPart = 0; iPart < NoOfSchwzBlocks; iPart++)   // loop over parts...
                    {
                        int[] bc    = BlockCells[iPart];
                        var   biI   = BlkIdx_gI_lR[iPart];
                        var   biE   = BlkIdx_gI_eR[iPart];
                        var   l1    = TempRowIdx_gI[iPart];
                        var   l2    = BlkIdx_lI_eR[iPart];
                        var   LBBi0 = LocalBlocks_i0[iPart];
                        var   LBBN  = LocalBlocks_N[iPart];


                        int Jblock         = bc.Length;
                        int anotherCounter = 0;

                        for (int jblk = 0; jblk < Jblock; jblk++)   // loop over cells in blocks...
                        {
                            int j = bc[jblk];
                            int N = MgMap.GetLength(j);

                            if (j < Jup)
                            {
                                // locally updated cell
                                int i0 = MgMap.GlobalUniqueIndex(0, j, 0);

                                for (int n = 0; n < N; n++)
                                {
                                    biI.Add(i0 + n);
                                }
                            }
                            else
                            {
                                // external cell
                                int i0E = MgMap.GlobalUniqueIndex(0, j, 0); //
                                int i0L = MgMap.LocalUniqueIndex(0, j, 0);  //
                                ExternalRows_BlockI0.Add(LocalizedBlockCounter);
                                ExternalRows_BlockN.Add(N);
                                //LEBi0.Add(LocalizedBlockCounter);
                                //LEBn.Add(N);
                                for (int n = 0; n < N; n++)
                                {
                                    biE.Add(i0E + n);
                                    ExternalRowsIndices.Add(i0E + n);
                                    l1.Add(LocalizedBlockCounter + n);
                                    l2.Add(i0L + n);
                                    Debug.Assert(Mop._RowPartitioning.FindProcess(i0E + n) != myMpiRank);
                                }

                                LocalizedBlockCounter += N;
                            }

                            LBBi0.Add(anotherCounter);
                            LBBN.Add(N);

                            anotherCounter += N;
                        }
                    }

                    //this.BlockIndices = _LocallyStoredBlockIndices.Select(bi => bi.ToArray()).ToArray();
                }


                // get rows for blocks that use external cells
                // ===========================================

#if DEBUG
                {
                    if (Overlap == 0)
                    {
                        Debug.Assert(ExternalRowsIndices.Count == 0);
                        Debug.Assert(ExternalRows_BlockI0.Count == 0);
                        Debug.Assert(ExternalRows_BlockN.Count == 0);
                    }

                    foreach (var bi in BlkIdx_gI_lR)
                    {
                        foreach (int idx in bi)
                        {
                            Debug.Assert(idx >= m_MgOp.Mapping.i0);
                            Debug.Assert(idx < m_MgOp.Mapping.iE);
                        }
                    }

                    foreach (var ei in BlkIdx_gI_eR)
                    {
                        foreach (int idx in ei)
                        {
                            Debug.Assert(idx < m_MgOp.Mapping.i0 || idx >= m_MgOp.Mapping.iE);
                        }
                    }


                    int LL   = m_MgOp.Mapping.LocalLength;
                    int jMax = m_MgOp.Mapping.AggGrid.iLogicalCells.NoOfCells - 1;
                    int LE   = m_MgOp.Mapping.LocalUniqueIndex(0, jMax, 0) + m_MgOp.Mapping.GetLength(jMax);


                    foreach (var ci in BlkIdx_lI_eR)
                    {
                        foreach (int idx in ci)
                        {
                            Debug.Assert(idx >= LL);
                            Debug.Assert(idx < LE);
                        }
                    }

                    if (m_MatlabParalellizationCheck)
                    {
                        int globalBlockCounter = 0;
                        for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++)
                        {
                            int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter);
                            if (rankCounter == myMpiRank)
                            {
                                Debug.Assert(rank_NoBlks == NoOfSchwzBlocks);
                            }

                            for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++)
                            {
                                double[] vec;
                                if (rankCounter == myMpiRank)
                                {
                                    vec = ArrayTools.Cat(BlkIdx_gI_lR[iBlock], BlkIdx_gI_eR[iBlock]).Select(ii => ((double)(ii + 1))).ToArray();
                                }
                                else
                                {
                                    vec = new double[0];
                                }

                                matlab.PutVector(vec, string.Format("BlockIdx{0}", globalBlockCounter));

                                globalBlockCounter++;
                                csMPI.Raw.Barrier(csMPI.Raw._COMM.WORLD);
                            }
                        }
                    }
                }
#endif


                BlockMsrMatrix ExternalRowsTemp;
                if (myMpisize > 1 && Overlap > 0)
                {
                    //int NoOfLocalRows = _ExternalBlockIndices.Sum(L => L.Count);

                    BlockPartitioning PermRow = new BlockPartitioning(ExternalRowsIndices.Count, ExternalRows_BlockI0, ExternalRows_BlockN, Mop.MPI_Comm, i0isLocal: true);

                    // Remark: we use a permutation matrix for MPI-exchange of rows

                    BlockMsrMatrix Perm = new BlockMsrMatrix(PermRow, Mop._RowPartitioning);
                    for (int iRow = 0; iRow < ExternalRowsIndices.Count; iRow++)
                    {
                        Debug.Assert(Mop._RowPartitioning.IsInLocalRange(ExternalRowsIndices[iRow]) == false);
                        Perm[iRow + PermRow.i0, ExternalRowsIndices[iRow]] = 1;
                    }

                    ExternalRowsTemp = BlockMsrMatrix.Multiply(Perm, Mop);

#if DEBUG
                    if (m_MatlabParalellizationCheck)
                    {
                        matlab.PutSparseMatrix(Perm, "Perm");
                        matlab.PutSparseMatrix(ExternalRowsTemp, "ExternalRowsTemp");
                    }
#endif
                }
                else
                {
                    ExternalRowsTemp = null;
                }

                ExternalRowsIndices  = null;
                ExternalRows_BlockI0 = null;
                ExternalRows_BlockN  = null;



                // create solvers
                // ==============


                {
                    blockSolvers = new ISparseSolver[NoOfSchwzBlocks];

#if DEBUG
                    List <BlockMsrMatrix> Blocks = new List <BlockMsrMatrix>();
#endif
                    for (int iPart = 0; iPart < NoOfSchwzBlocks; iPart++)
                    {
                        var bi = BlkIdx_gI_lR[iPart];

                        int Bsz;
                        if (MgMap.MinimalLength == MgMap.MaximalLength)
                        {
                            Bsz = MgMap.MaximalLength;
                        }
                        else
                        {
                            Bsz = 1;
                        }

                        var l1 = TempRowIdx_gI[iPart];

                        //if (M.RowPartitioning.MpiSize > 1) {
                        //    int i0Proc = M.RowPartitioning.i0;
                        //    bi = bi.CloneAs();
                        //    for (int i = 0; i < bi.Length; i++) {
                        //        bi[i] += i0Proc;
                        //    }
                        //}

                        BlockPartitioning localBlocking = new BlockPartitioning(bi.Count + l1.Count, LocalBlocks_i0[iPart], LocalBlocks_N[iPart], csMPI.Raw._COMM.SELF);

                        if (l1.Count > 0)
                        {
                            // convert the indices into 'ExternalRowsTemp' to global indices
                            int l1L    = l1.Count;
                            int offset = ExternalRowsTemp._RowPartitioning.i0;
                            for (int i = 0; i < l1L; i++)
                            {
                                l1[i] += offset;
                            }
                        }

                        BlockMsrMatrix Block = new BlockMsrMatrix(localBlocking, localBlocking);// bi.Length, bi.Length, Bsz, Bsz);
                        Mop.WriteSubMatrixTo(Block, bi, default(int[]), bi, default(int[]));
                        if (l1.Count > 0)
                        {
                            int   offset   = bi.Count;
                            int[] targRows = l1.Count.ForLoop(i => i + offset);

                            var   biE         = BlkIdx_gI_eR[iPart];
                            int[] extTargCols = biE.Count.ForLoop(i => i + offset);

                            Mop.AccSubMatrixTo(1.0, Block, bi, default(int[]), new int[0], default(int[]), biE, extTargCols);
                            ExternalRowsTemp.AccSubMatrixTo(1.0, Block, l1, targRows, bi, default(int[]), biE, extTargCols);
                        }
#if DEBUG
                        if (m_MatlabParalellizationCheck)
                        {
                            Blocks.Add(Block);
                        }
#endif
                        blockSolvers[iPart] = new PARDISOSolver()
                        {
                            CacheFactorization = true,
                            UseDoublePrecision = false
                        };
                        //blockSolvers[iPart] = new FullDirectSolver();
                        //blockSolvers[iPart] = new ilPSP.LinSolvers.MUMPS.MUMPSSolver();
                        blockSolvers[iPart].DefineMatrix(Block);
                    }

#if DEBUG
                    if (m_MatlabParalellizationCheck)
                    {
                        int globalBlockCounter = 0;
                        for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++)
                        {
                            int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter);
                            for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++)
                            {
                                BlockMsrMatrix Block;
                                if (rankCounter == myMpiRank)
                                {
                                    Block = Blocks[iBlock];
                                }
                                else
                                {
                                    Block = null;
                                }

                                matlab.PutSparseMatrix(Block, string.Format("Block{0}", globalBlockCounter));

                                globalBlockCounter++;
                                csMPI.Raw.Barrier(csMPI.Raw._COMM.WORLD);
                            }
                        }
                    }
#endif
                }

                // Record required indices
                // =======================
                {
                    this.BlockIndices_Local    = new int[NoOfSchwzBlocks][];
                    this.BlockIndices_External = new int[NoOfSchwzBlocks][];
                    int LocalI0     = MgMap.i0;
                    int LocalLength = MgMap.LocalLength;

                    for (int iBlock = 0; iBlock < NoOfSchwzBlocks; iBlock++)
                    {
                        var   _bi = BlkIdx_gI_lR[iBlock];
                        int   L   = _bi.Count;
                        int[] bil = new int[L];
                        this.BlockIndices_Local[iBlock] = bil;

                        for (int l = 0; l < L; l++)
                        {
                            bil[l] = _bi[l] - LocalI0;
                            Debug.Assert(bil[l] >= 0);
                            Debug.Assert(bil[l] < MgMap.LocalLength);
                        }

                        var _biE = BlkIdx_lI_eR[iBlock];
                        if (_biE.Count > 0)
                        {
                            this.BlockIndices_External[iBlock] = _biE.ToArray();
                        }
                    }
                }


                this.MtxFull = Mop;

                if (CoarseSolver != null)
                {
                    CoarseSolver.Init(op.CoarserLevel);
                }

                // Debug & Test-Code
                // =================
#if DEBUG
                if (m_MatlabParalellizationCheck)
                {
                    Console.WriteLine("Matlab dir: " + matlab.WorkingDirectory);

                    matlab.PutSparseMatrix(Mop, "Full");
                    int GlobalNoOfBlocks = NoOfSchwzBlocks.MPISum();



                    for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++)
                    {
                        matlab.Cmd("BlockErr({0} + 1, 1) = norm( Block{0} - Full( BlockIdx{0}, BlockIdx{0} ), inf );", iGlbBlock);
                    }

                    Random   rnd     = new Random(myMpiRank);
                    double[] testRHS = new double[MgMap.LocalLength];
                    for (int i = 0; i < testRHS.Length; i++)
                    {
                        testRHS[i] = rnd.NextDouble();
                    }
                    matlab.PutVector(testRHS, "testRHS");

                    MPIexchange <double[]> ResExchange = new MPIexchange <double[]>(MgMap, testRHS);
                    ResExchange.TransceiveStartImReturn();
                    ResExchange.TransceiveFinish(0.0);

                    int offset = MgMap.LocalLength;

                    int g = 0;
                    for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++)
                    {
                        int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter);
                        for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++)
                        {
                            double[] SubVec;
                            if (rankCounter == myMpiRank)
                            {
                                int LL = this.BlockIndices_Local[iBlock].Length;
                                int LE;
                                if (this.BlockIndices_External[iBlock] != null)
                                {
                                    LE = this.BlockIndices_External[iBlock].Length;
                                }
                                else
                                {
                                    LE = 0;
                                }
                                int L = LL + LE;

                                SubVec = new double[L];
                                for (int i = 0; i < LL; i++)
                                {
                                    SubVec[i] = testRHS[this.BlockIndices_Local[iBlock][i]];
                                }
                                if (LE > 0)
                                {
                                    for (int i = 0; i < LE; i++)
                                    {
                                        SubVec[i + LL] = ResExchange.Vector_Ext[this.BlockIndices_External[iBlock][i] - offset];
                                    }
                                }
                            }
                            else
                            {
                                SubVec = new double[0];
                            }

                            matlab.PutVector(SubVec, "SubVec" + g);

                            g++;
                        }
                    }

                    for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++)
                    {
                        matlab.Cmd("RhsErr({0} + 1, 1) = norm( SubVec{0} - testRHS( BlockIdx{0} ), inf );", iGlbBlock);
                    }

                    double[] testX = new double[testRHS.Length];
                    MPIexchangeInverse <double[]> XExchange = new MPIexchangeInverse <double[]>(MgMap, testX);

                    g = 0;
                    for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++)
                    {
                        int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter);
                        for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++)
                        {
                            if (rankCounter == myMpiRank)
                            {
                                int LL = this.BlockIndices_Local[iBlock].Length;
                                int LE;
                                if (this.BlockIndices_External[iBlock] != null)
                                {
                                    LE = this.BlockIndices_External[iBlock].Length;
                                }
                                else
                                {
                                    LE = 0;
                                }
                                int L = LL + LE;


                                for (int i = 0; i < LL; i++)
                                {
                                    testX[this.BlockIndices_Local[iBlock][i]] += (g + 1);
                                }
                                if (LE > 0)
                                {
                                    for (int i = 0; i < LE; i++)
                                    {
                                        XExchange.Vector_Ext[this.BlockIndices_External[iBlock][i] - offset] += (g + 1);
                                    }
                                }
                            }
                            else
                            {
                                //nop
                            }

                            g++;
                        }
                    }
                    XExchange.TransceiveStartImReturn();
                    XExchange.TransceiveFinish(1.0);

                    matlab.Cmd("testXref = zeros({0},1);", MgMap.TotalLength);
                    for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++)
                    {
                        matlab.Cmd("testXref(BlockIdx{0},1) = testXref(BlockIdx{0},1) + ({0} + 1);", iGlbBlock);
                    }

                    matlab.PutVector(testX, "testX");
                    matlab.Cmd("testXErr = norm(testX - testXref, inf);");

                    MultidimensionalArray BlockErr = MultidimensionalArray.Create(GlobalNoOfBlocks, 1);
                    MultidimensionalArray RhsErr   = MultidimensionalArray.Create(GlobalNoOfBlocks, 1);
                    MultidimensionalArray testXErr = MultidimensionalArray.Create(1, 1);

                    matlab.GetMatrix(BlockErr, "BlockErr");
                    matlab.GetMatrix(RhsErr, "RhsErr");
                    matlab.GetMatrix(testXErr, "testXErr");

                    matlab.Execute();

                    for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++)
                    {
                        Console.WriteLine("Block #{0} Error (external? ) " + BlockErr[iGlbBlock, 0], iGlbBlock);
                        Console.WriteLine("RHS #{0} Error " + RhsErr[iGlbBlock, 0], iGlbBlock);
                        Debug.Assert(BlockErr[iGlbBlock, 0] == 0);
                        Debug.Assert(RhsErr[iGlbBlock, 0] == 0);
                    }

                    Console.WriteLine("X Error " + testXErr[0, 0]);
                    Debug.Assert(testXErr[0, 0] == 0.0);

                    matlab.Dispose();
                }
#endif
            }
        }
示例#3
0
    object Wavefunction(float xmin, float xmax, int num_points, int num_elevel, float[] PE)
    {
        float HBAR = 6.62606957E-34f;
        float NM2M = 1E-9f;
        float EV2J = 1.6E-19f;
        float mass = 9.10938291E-31f;
        float C    = (-HBAR * HBAR / (2 * mass)) / (NM2M * NM2M * EV2J);

        float[] xx     = numeric.linspace(xmin, xmax, num_points - 2);
        float   dx     = (xmax - xmin) / (num_points);
        int     factor = (int)Mathf.Round(C / (dx * dx));

        int[] a = new int[1] {
            num_points - 2
        };

        float[][] melement = numeric.rep(a, -2 * factor);
        float[][] K        = numeric.diag(melement[0]);

        for (int i = 0; i < num_points - 3; i++)
        {
            K[i][i + 1] = factor;
            K[i + 1][i] = factor;
        }         //kinetic energy matrix
                  //float[][] P = new float[][];

        float[] P1 = ArrayTools.SubArray(PE, 1, num_points - 1);

        int   shift      = 0;
        float min_pe     = Mathf.Min(P1);
        bool  shift_flag = false;

        //The min PE val is a lowerbound on the eigenvalues(Gershgorin).
        //If too close to negative values shift eigenvalues to guarentee positivity.
        if (min_pe < numeric.epsilon)
        {
            shift      = (int)Mathf.Round(Mathf.Abs(min_pe) + 1);
            shift_flag = true;
        }
        float[][] P = numeric.diag(P1);

        float[][] H = new float[K.Length][];
        for (int i = 0; i < K.Length; i++)
        {
            H[i] = new float[K[i].Length];
            for (int j = 0; j < K[i].Length; j++)
            {
                H[i][j] = K[i][j] + P[i][j];
            }
        }


        if (shift_flag)
        {
            float[][] element = numeric.rep(a, shift);
            float[][] Hadd    = numeric.diag(element[0]);
            for (int i = 0; i < H.Length; i++)
            {
                for (int j = 0; j < H[0].Length; j++)
                {
                    H[i][j] = Hadd[i][j] + H[i][j];
                }
            }
        }
        object[] eigen = (object[])numeric.svd(H);

        float[][] U = numeric.transpose((float[][])eigen[0]);
        float[]   S = (float[])eigen[1];
        if (shift_flag)
        {
            for (int i = 0; i < S.Length; i++)
            {
                S[i] = S[i] - shift;
            }
        }

        float[][] psi_array = new float[num_points - 2][];


        for (int i = 0; i < num_points - 2; i++)
        {
            float[] psi = U[i];
            ArrayTools.Push(psi, 0);
            ArrayTools.PushLast(psi, 0);

            float area = trapz(dx, prob(psi));
            for (int j = 0; j < psi.Length; j++)
            {
                psi[j] = psi[j] / Mathf.Sqrt(area);
            }

            psi_array[i] = psi;
        }

        //Collect the desired number of energy levels.
        float[][] wave_eqs = new float[num_elevel][];
        float[]   eng_lvls = new float[num_elevel];
        for (int i = 0; i < num_elevel; i++)
        {
            wave_eqs[i] = psi_array[num_points - 3 - i];
            eng_lvls[i] = S[num_points - 3 - i];
        }
        object[] obj = new object[2];
        obj[0] = eng_lvls;
        obj[1] = wave_eqs;
        return(obj);
    }
示例#4
0
        public void ApplyToVector <I>(IList <I> input, IList <I[]> output, IPartitioning outputPartitioning)
        {
            using (new FuncTrace()) {
                Debug.Assert(DestGlobalId.Length == MappingIndex.Length);
                Debug.Assert(OldGlobalId.Length == MappingIndex.Length);
                int oldJ = DestGlobalId.Length;

                if (input.Count != oldJ)
                {
                    throw new ArgumentException("Mismatch between input vector length and current data length.");
                }
                if (output.Count != outputPartitioning.LocalLength)
                {
                    throw new ArgumentException("Length mismatch of output list and output partition.");
                }

                int j0Dest = outputPartitioning.i0;

                // keys: processors which should receive data from this processor
                Dictionary <int, ApplyToVector_Helper <I> > AllSendData = new Dictionary <int, ApplyToVector_Helper <I> >();

                for (int j = 0; j < oldJ; j++)
                {
                    I data_j = input[j];

                    foreach (int jDest in TargetIdx[j])
                    {
                        if (outputPartitioning.IsInLocalRange(jDest))
                        {
                            I[] destCollection = output[jDest - j0Dest];
                            ArrayTools.AddToArray(data_j, ref destCollection);
                            output[jDest - j0Dest] = destCollection;
                        }
                        else
                        {
                            int targProc = outputPartitioning.FindProcess(jDest);

                            ApplyToVector_Helper <I> dataTargPrc;
                            if (!AllSendData.TryGetValue(targProc, out dataTargPrc))
                            {
                                dataTargPrc = new ApplyToVector_Helper <I>();
                                AllSendData.Add(targProc, dataTargPrc);
                            }

                            dataTargPrc.TargetIndices.Add(jDest);
                            dataTargPrc.Items.Add(data_j);
                        }
                    }
                }

                var AllRcvData = SerialisationMessenger.ExchangeData(AllSendData, outputPartitioning.MPI_Comm);

                foreach (var kv in AllRcvData)
                {
                    int rcvProc = kv.Key;
                    j0Dest = outputPartitioning.GetI0Offest(rcvProc);

                    var TIdxs = kv.Value.TargetIndices;
                    var TVals = kv.Value.Items;
                    Debug.Assert(TIdxs.Count == TVals.Count);
                    int L = TIdxs.Count;

                    for (int l = 0; l < L; l++)
                    {
                        int idx = TIdxs[l] - j0Dest;
                        Debug.Assert(outputPartitioning.IsInLocalRange(idx));

                        I[] destCollection = output[idx];
                        ArrayTools.AddToArray(TVals[idx], ref destCollection);
                        output[idx] = destCollection;
                    }
                }
            }
        }
示例#5
0
        static public IBM_Control IBMCylinderFlow(string _DbPath = null, int k = 2, bool only_channel = true, bool pardiso = true, int no_p = 1, int no_it = 1, bool load_Grid = false, string _GridGuid = null)
        {
            // int cells_x, int cells_yz
            IBM_Control  C         = new IBM_Control();
            bool         xPeriodic = false;
            int          i         = 2;
            const double BaseSize  = 1.0;

            // basic database options
            // ======================

            //C.DbPath = _DbPath;

            C.DbPath   = @"\\dc1\userspace\stange\HiWi_database\PerformanceTests";
            C.savetodb = true;

            bool   restart            = false;
            string restartSession     = "67a29dcc-ade9-4704-b198-b3380e774f5a";
            string restartGrid        = "42e1ede0-40fc-4267-9d48-94c0397ac9a5";
            bool   startFromGivenGrid = true;
            string startGrid          = "42e1ede0-40fc-4267-9d48-94c0397ac9a5";

            switch (i)
            {
            case 1:
                C.MeshFactor = 1.258;     // was 1.33
                break;

            case 2:
                C.MeshFactor = 3.0;     //1.77; //0.92;
                break;

            case 3:
                C.MeshFactor = 0.7;     // was 07
                break;

            default:

                throw new ApplicationException();
            }

            if (pardiso)
            {
                if (only_channel)
                {
                    C.SessionName = "2DChannel_Pardiso_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it;
                }
                else
                {
                    C.SessionName = "Cylinder_Pardiso_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it;
                }
            }
            else
            {
                if (only_channel)
                {
                    C.SessionName = "2DChannel_Mumps_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it;
                }
                else
                {
                    C.SessionName = "Cylinder_Mumps_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it;
                }
            }
            C.saveperiod = 1;
            //C.SessionName = "Sphere_k" + k + "_h" + h+"Re100";


            C.Tags.Add("Pardiso " + pardiso);
            C.Tags.Add("only channel " + only_channel);
            C.Tags.Add("k " + k);
            C.Tags.Add("no_p" + no_p);
            C.Tags.Add("run " + no_it);
            C.Tags.Add("MeshFactor " + C.MeshFactor);

            C.ProjectName = "FixedCylinderRe100_k" + i + "_CellAgglo02_penalty4_newMesh2";

            C.ProjectDescription = "Cylinder";

            // DG degrees
            // ==========

            C.FieldOptions.Add("VelocityX", new FieldOpts()
            {
                Degree   = k,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("VelocityY", new FieldOpts()
            {
                Degree   = k,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            //Console.WriteLine("Achtung: equal order!!!!");
            C.FieldOptions.Add("Pressure", new FieldOpts()
            {
                Degree = k - 1,

                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("PhiDG", new FieldOpts()
            {
                Degree   = 2,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Phi", new FieldOpts()
            {
                Degree   = 2,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });

            // restart options
            // ===============
            if (restart)
            {
                C.RestartInfo = new Tuple <Guid, TimestepNumber>(new Guid(restartSession), -1);
                C.GridGuid    = new Guid(restartGrid);
            }
            //grid and boundary conditions
            // ============================

            // Initial Values
            // ==============

            double radius = 0.5;

            C.PhysicalParameters.rho_A = 1.0;
            C.PhysicalParameters.mu_A  = 1.0 / 100.0;

            if (!restart)
            {
                if (!startFromGivenGrid)
                {
                    C.GridFunc = delegate
                    {
                        var _xNodes1 = Grid1D.TanhSpacing(-2.0, -1.0, Convert.ToInt32(10.0 * C.MeshFactor), 0.5, false); //10
                        _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1));
                        var _xNodes2 = GenericBlas.Linspace(-1.0, 2.0, Convert.ToInt32(35.0 * C.MeshFactor));            //35
                        _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1));
                        var _xNodes3 = Grid1D.TanhSpacing(2.0, 20.0, Convert.ToInt32(60.0 * C.MeshFactor), 1.5, true);   //60

                        var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3);


                        var _yNodes1 = Grid1D.TanhSpacing(-2.0, -1.0, Convert.ToInt32(7.0 * C.MeshFactor), 0.9, false); //7
                        _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1));
                        var _yNodes2 = GenericBlas.Linspace(-1.0, 1.0, Convert.ToInt32(25.0 * C.MeshFactor));           //25
                        _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1));
                        var _yNodes3 = Grid1D.TanhSpacing(1.0, 2.1, Convert.ToInt32(7.0 * C.MeshFactor), 1.1, true);    //7
                        var yNodes   = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3);



                        //double[] xNodes = GenericBlas.Linspace(0 * BaseSize, 22 * BaseSize, 25);
                        //double[] yNodes = GenericBlas.Linspace(0 * BaseSize, 4.1 * BaseSize, 25);
                        var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic);
                        grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper");
                        grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower");
                        if (!xPeriodic)
                        {
                            grd.EdgeTagNames.Add(3, "Velocity_Inlet_left");
                            grd.EdgeTagNames.Add(4, "Pressure_Outlet_right");
                        }

                        grd.DefineEdgeTags(delegate(double[] X)
                        {
                            byte et = 0;
                            if (Math.Abs(X[1] - (-2.0 * BaseSize)) <= 1.0e-8)
                            {
                                et = 1;
                            }
                            if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8)
                            {
                                et = 2;
                            }
                            if (!xPeriodic && Math.Abs(X[0] - (-2.0 * BaseSize)) <= 1.0e-8)
                            {
                                et = 3;
                            }
                            if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8)
                            {
                                et = 4;
                            }


                            Debug.Assert(et != 0);
                            return(et);
                        });

                        Console.WriteLine("Cells:    {0}", grd.NumberOfCells);

                        return(grd);
                    };
                }
                else
                {
                    C.GridGuid = new Guid(startGrid);
                }
                if (only_channel)
                {
                    C.InitialValues_Evaluators.Add("Phi", X => - 1);
                }
                else
                {
                    C.InitialValues_Evaluators.Add("Phi", X => - (X[0]).Pow2() + -(X[1]).Pow2() + radius.Pow2());
                }


                //C.InitialValues.Add("Phi", X => -1);

                C.InitialValues_Evaluators.Add("VelocityX", X => 4.0 * 1.5 * (X[1] + 2.0) * (4.1 - (X[1] + 2.0)) / (4.1 * 4.1));
            }

            //C.GridFunc = delegate {

            //    // Box1
            //    var box1_p1 = new double[2] { -2, -2 };
            //    var box1_p2 = new double[2] { 20, 2.1 };
            //    var box1 = new GridBox(box1_p1, box1_p2, 46, 20); //k1: 70,25 ; k2: 46,20 ; k3: 35,15

            //    // Box2
            //    var box2_p1 = new double[2] { -2, -2 };
            //    var box2_p2 = new double[2] { 3, 2.1 };
            //    var box2 = new GridBox(box2_p1, box2_p2, 26, 40); //k1: 40,50 ; k2: 26,40; k3: 20, 30

            //    // Box3
            //    var box3_p1 = new double[2] { -2, -1 };
            //    var box3_p2 = new double[2] { 1, 1 };
            //    var box3 = new GridBox(box3_p1, box3_p2, 32, 38); //k1: 48,58  ; k2: 32,38; k3: 24, 30

            //    // Box4
            //    var box4_p1 = new double[2] { -0.7, -0.72 };
            //    var box4_p2 = new double[2] { 0.7, 0.7 };
            //    var box4 = new GridBox(box4_p1, box4_p2, 30, 56); //k1: 44,84  ; k2: 30,56; k3: 22, 42

            //    var grd = Grid2D.HangingNodes2D(box1, box2, box3,box4);

            //    grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper");
            //    grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower");
            //    if (!xPeriodic) {
            //        grd.EdgeTagNames.Add(3, "Velocity_Inlet_left");
            //        grd.EdgeTagNames.Add(4, "Pressure_Outlet_right");
            //    }

            //    grd.DefineEdgeTags(delegate (double[] X) {
            //        byte et = 0;
            //        if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8)
            //            et = 1;
            //        if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8)
            //            et = 2;
            //        if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8)
            //            et = 3;
            //        if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8)
            //            et = 4;


            //        Debug.Assert(et != 0);
            //        return et;
            //    });

            //    Console.WriteLine("Cells:    {0}", grd.NumberOfCells);

            //    return grd;
            //};

            C.AddBoundaryCondition("Velocity_Inlet_upper", "VelocityX", X => 0.0);
            C.AddBoundaryCondition("Velocity_Inlet_lower", "VelocityX", X => 0.0); //-(4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1))
            if (!xPeriodic)
            {
                C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX", X => (4.0 * 1.5 * (X[1] + 2.0) * (4.1 - (X[1] + 2.0)) / (4.1 * 4.1)));
                //C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX#A", X => 1);
            }
            C.AddBoundaryCondition("Pressure_Outlet_right");



            //C.InitialValues.Add("Phi", X => phi(X, 0));

            //C.InitialValues.Add("Phi", X => ((X[0] / (radius * BaseSize)) - mPx) * (X[0] / (radius * BaseSize)) - mPx) + ((X[1]) / (radius * BaseSize)) - 2.)Pow2() - radius.Pow2()));  // quadratic form
            //    );


            //C.InitialValues.Add("VelocityX", delegate (double[] X)
            //{
            //    double x = X[0];
            //    double y = X[1];

            //    double R = Math.Sqrt((x + 1).Pow2() + y.Pow2());

            //    double xVel = 0;

            //    if (R < 0.75)
            //    {
            //        xVel = 1;
            //    }
            //    return xVel;
            //});

            //C.InitialValues.Add("VelocityY", delegate (double[] X) {
            //    double x = X[0];
            //    double y = X[1];

            //    double R = Math.Sqrt((x + 1).Pow2() + (y).Pow2());

            //    double yVel = 0;

            //    if (R < 0.75) {
            //        yVel = 1;
            //    }
            //    return yVel;
            //});

            // For restart
            //C.RestartInfo = new Tuple<Guid, TimestepNumber>(new Guid("8f5cfed9-31c7-4be8-aa56-e92e5348e08b"), 95);
            //C.GridGuid = new Guid("71ffc0c4-66aa-4762-b07e-45385f34b03f");

            // Physical Parameters
            // ===================


            C.PhysicalParameters.IncludeConvection = true;


            // misc. solver options
            // ====================

            C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2;
            C.AdvancedDiscretizationOptions.PenaltySafety = 4;
            C.LevelSetSmoothing = false;
            //C.option_solver = "direct";
            C.MaxKrylovDim             = 20;
            C.MaxSolverIterations      = 50;
            C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite;
            //C.NoOfMultigridLevels = 0;

            if (pardiso)
            {
                C.whichSolver = DirectSolver._whichSolver.PARDISO;
            }
            else
            {
                C.whichSolver = DirectSolver._whichSolver.MUMPS;
            }
            // Timestepping
            // ============

            C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2;
            double dt = 0.1;

            C.dtMax         = dt;
            C.dtMin         = dt;
            C.Endtime       = 70;
            C.NoOfTimesteps = 10;

            // haben fertig...
            // ===============
            return(C);
        }
示例#6
0
        public static void DragCurve(Curve curve)
        /// Backup curve to return the removed nodes when dragging cursor returned to curve field
        {
            if (UI.current.layout)
            {
                return;
            }
            if (UI.current.optimizeElements && !UI.current.IsInWindow())
            {
                return;
            }

            //moving
            bool isDragging = false;
            bool isReleased = false;
            int  dragNum    = -1;

            Curve.Node[] originalPoints = null;

            for (int i = 0; i < curve.points.Length; i++)
            {
                bool    newDragging = false; bool newReleased = false;
                Vector2 newPos = DragPoint(curve, i, ref newDragging, ref newReleased);

                if (newDragging)
                {
                    originalPoints = new Curve.Node[curve.points.Length];                     //curve.GetPositions();
                    for (int p = 0; p < originalPoints.Length; p++)
                    {
                        originalPoints[p] = new Curve.Node(curve.points[p]);
                    }

                    curve.points[i].pos = newPos;
                }

                if (newDragging || newReleased)
                {
                    dragNum = i;
                }

                isDragging = isDragging || newDragging;
                isReleased = isReleased || newReleased;
            }

            //adding
            if (ClickedNearCurve(curve))
            {
                Vector2 addPos   = ToCurve(UI.current.mousePos);
                int     addedNum = AddPoint(curve, addPos);

                //starting drag
                DragPoint(curve, addedNum, ref isDragging, ref isReleased);                   //just to start drag
            }

            //removing
            if (isDragging)
            {
                //calc if node should be removed
                bool isRemoved = false;
                if (dragNum != 0 && dragNum != curve.points.Length - 1)             //ignoring first and last
                {
                    Vector2 pos = ToCell(curve.points[dragNum].pos);
                    if (!Cell.current.InternalRect.Extended(10).Contains(pos))
                    {
                        isRemoved = true;
                    }
                }

                //removing
                if (isRemoved)
                {
                    UI.current.MarkChanged(completeUndo: true);
                    ArrayTools.RemoveAt(ref curve.points, dragNum);
                }

                //clamping if cursor is too close to the field to remove
                else
                {
                    ClampPoint(curve, dragNum);
                }
            }

            //if returned dragging to field
            else if (DragDrop.obj != null && DragDrop.obj.GetType() == typeof((Curve, Curve.Node, int)))
            {
                (Curve curve, Curve.Node node, int num)dragObj = ((Curve, Curve.Node, int))DragDrop.obj;
                if (dragObj.curve == curve && !curve.points.Contains(dragObj.node))
                {
                    DragDrop.TryDrag(dragObj, UI.current.mousePos);
                    //to make it repaint

                    if (Cell.current.InternalRect.Extended(10).Contains(UI.current.mousePos))
                    {
                        ArrayTools.Insert(ref curve.points, dragObj.num, dragObj.node);
                        dragObj.node.pos = ToCurve(UI.current.mousePos);
                        ClampPoint(dragObj.curve, dragObj.num);                         //this will place it between prev and next points
                    }

                    DragDrop.TryRelease(dragObj, UI.current.mousePos);
                    //otherwise it will not be released forever
                }
            }

            if (Cell.current.valChanged)
            {
                curve.Refresh();
            }
        }
示例#7
0
        void UpdateAgglom(bool ReplaceTop)
        {
            if (m_RequiredTimeLevels == 0)
            {
                m_Versions.Clear();
            }


            if (m_RequiredTimeLevels == 0 && ReplaceTop == true)
            {
                throw new NotSupportedException();
            }
            if (!ReplaceTop)
            {
                m_RequiredTimeLevels++;
                m_Versions.Add(m_LsTrk.Regions.Version);
            }
            else
            {
                m_Versions[m_Versions.Count - 1] = m_LsTrk.Regions.Version;
            }
            Debug.Assert(m_RequiredTimeLevels == m_Versions.Count);

            for (int i = 0; i < m_Versions.Count; i++)
            {
                if (m_Versions[m_Versions.Count - 1 - i] != m_LsTrk.RegionsHistory[1 - i].Version)
                {
                    throw new ApplicationException("Internal Error, level-set-tracker history stack messed up."); // cheap test, also affordable in release
                }
            }


            double[] oldAggTrsh;
            if (m_RequiredTimeLevels > 1)
            {
                oldAggTrsh = new double[m_RequiredTimeLevels - 1];
                ArrayTools.SetAll(oldAggTrsh, this.Config_AgglomerationThreshold);
            }
            else
            {
                oldAggTrsh = null;
            }
            Debug.Assert(m_LsTrk.PopulatedHistoryLength >= m_RequiredTimeLevels - 1);

//#if DEBUG
//            if(m_RequiredTimeLevels > 1) {
//                Debug.Assert(m_OldSources != null);
//            } else {
//                m_OldSources = null;
//                m_OldVolumes = null;
//            }
//#endif
            m_CurrentAgglomeration = m_LsTrk.GetAgglomerator(Config_SpeciesToCompute, Config_CutCellQuadratureOrder,
                                                             this.Config_AgglomerationThreshold,
                                                             AgglomerateNewborn: oldAggTrsh != null, AgglomerateDecased: (oldAggTrsh != null), ExceptionOnFailedAgglomeration: true,
                                                             oldTs__AgglomerationTreshold: oldAggTrsh);
//#if DEBUG
//            int[][] NewSources = new int[Config_SpeciesToCompute.Length][];
//            {
//                for(int iSpc = 0; iSpc < NewSources.Length; iSpc++) {
//                    var Spc = Config_SpeciesToCompute[iSpc];
//                    NewSources[iSpc] = m_CurrentAgglomeration.GetAgglomerator(Spc).AggInfo.SourceCells.ItemEnum.ToArray();
//                }
//            }
//            double[][][] NewVolumes = new double[m_RequiredTimeLevels][][];
//            for(int iTs = 0; iTs < m_RequiredTimeLevels; iTs++) {
//                NewVolumes[iTs] = new double[Config_SpeciesToCompute.Length][];
//                for(int iSpc = 0; iSpc < NewSources.Length; iSpc++) {
//                    var Spc = Config_SpeciesToCompute[iSpc];
//                    NewVolumes[iTs][iSpc] = m_LsTrk.GetXDGSpaceMetrics(Config_SpeciesToCompute, Config_CutCellQuadratureOrder, 1 - iTs).CutCellMetrics.CutCellVolumes[Spc].To1DArray();
//                }
//            }


//            if(m_RequiredTimeLevels > 1) {
//                for(int iSpc = 0; iSpc < NewSources.Length; iSpc++) {
//                    var Spc = Config_SpeciesToCompute[iSpc];
//                    int[] _OldSources_spc = m_OldSources[iSpc];
//                    int[] _NewSources_spc = NewSources[iSpc];
//                    Debug.Assert(_OldSources_spc.IsSubsetOf(_NewSources_spc));
//                }
//            }
//            m_OldSources = NewSources;
//            m_OldVolumes = NewVolumes;
//#endif

            //foreach (var spId in m_CurrentAgglomeration.SpeciesList) {
            //    string SpName = m_LsTrk.GetSpeciesName(spId);
            //    int NoOfAgg = m_CurrentAgglomeration.GetAgglomerator(spId).AggInfo.AgglomerationPairs.Length;
            //    Console.WriteLine("Species {0}, time {2}, number of agglomerations: {1}", SpName, NoOfAgg, m_RequiredTimeLevels);
            //}
        }
示例#8
0
        /// <summary>
        /// Calculated topology of the grid, i.e creating the boundarySubgrids
        /// for each sub-grid
        /// </summary>
        protected void GetBoundaryTopology()
        {
            // NumOfSgrd - 1, because largest grid (id=0) don't need a boundary cells
            BoundaryTopology = new int[CurrentClustering.NumberOfClusters - 1, gridData.iLogicalCells.NoOfLocalUpdatedCells];
            ArrayTools.SetAll(BoundaryTopology, -1);
            BoundarySgrds = new SubGrid[CurrentClustering.NumberOfClusters - 1];
            jSub2jCell    = new int[CurrentClustering.NumberOfClusters - 1][];
            int[][]    LocalCells2SubgridIndex = new int[CurrentClustering.NumberOfClusters][];
            BitArray[] SgrdWithGhostCells      = new BitArray[CurrentClustering.NumberOfClusters];
            // prepare the calculation and  save temporarily all array which involve MPI communication
            for (int id = 0; id < CurrentClustering.NumberOfClusters; id++)
            {
                LocalCells2SubgridIndex[id] = CurrentClustering.Clusters[id].LocalCellIndex2SubgridIndex;
                SgrdWithGhostCells[id]      = CurrentClustering.Clusters[id].VolumeMask.GetBitMaskWithExternal();
            }

            for (int id = 1; id < CurrentClustering.NumberOfClusters; id++)
            {
                SubGrid  sgrd = CurrentClustering.Clusters[id];
                BitArray BoBA = new BitArray(gridData.iLogicalCells.NoOfLocalUpdatedCells);

                //BitArray SgrdWithGhostCell = sgrd.VolumeMask.GetBitMaskWithExternal();
                //int[] LocalCellIndex2SubgridIndex = sgrd.LocalCellIndex2SubgridIndex;

                foreach (BoSSS.Foundation.Grid.Chunk chunk in sgrd.BoundaryEdgesMask)
                {
                    foreach (int edge in chunk.Elements)
                    {
                        int cell1 = gridData.iLogicalEdges.CellIndices[edge, 0];
                        int cell2 = gridData.iLogicalEdges.CellIndices[edge, 1];

                        if (cell2 >= gridData.iLogicalCells.NoOfLocalUpdatedCells)   //special case: cell2 is "ghost-cell" at MPI border
                        {
                            if (SgrdWithGhostCells[id][cell2])
                            {
                                int gridId = GetClusterIDOf(cell1, ABevolver);
                                if (gridId != -1)   // cell is not in void area of IBM
                                {
                                    BoundaryTopology[id - 1, cell1] = gridId;
                                    BoBA[cell1] = true;
                                }
                            }
                        }
                        else if (cell1 >= 0 && cell2 >= 0 && LocalCells2SubgridIndex[id][cell1] >= 0 && LocalCells2SubgridIndex[id][cell2] < 0)
                        {
                            //BoT[id - 1, cell2] = getSgrdIdOf(cell2, LocalCells2SubgridIndex);
                            //BoBA[cell2] = true;
                            int gridId = GetClusterIDOf(cell2, ABevolver);
                            if (gridId != -1)   // cell is not in void area of IBM
                            {
                                BoundaryTopology[id - 1, cell2] = gridId;
                                BoBA[cell2] = true;
                            }
                        }
                        else if (cell1 >= 0 && cell2 >= 0 && LocalCells2SubgridIndex[id][cell2] >= 0 && LocalCells2SubgridIndex[id][cell1] < 0)
                        {
                            //BoT[id - 1, cell1] = getSgrdIdOf(cell1, LocalCells2SubgridIndex);
                            //BoBA[cell1] = true;
                            int gridId = GetClusterIDOf(cell1, ABevolver);
                            if (gridId != -1)   // cell is not in void area of IBM
                            {
                                BoundaryTopology[id - 1, cell1] = gridId;
                                BoBA[cell1] = true;
                            }
                        }
                    }
                }
                //Creating the Boundary sub-grid
                BoundarySgrds[id - 1] = new SubGrid(new CellMask(gridData, BoBA));
                jSub2jCell[id - 1]    = BoundarySgrds[id - 1].SubgridIndex2LocalCellIndex;
            }

            // Debugging the boundary topology with MPI
            //int ii = 0;
            //SgrdField.Clear();
            //foreach (SubGrid Sgrd in BoSgrd) {
            //    foreach (BoSSS.Foundation.Grid.Chunk chunk in Sgrd.VolumeMask) {
            //        foreach (int cell in chunk.Elements) {
            //            SgrdField.SetMeanValue(cell, ii + 1);
            //        }
            //    }
            //    ii++;
            //}
        }
示例#9
0
        /// <summary>
        ///
        /// </summary>
        public void AssembleMatrix_Timestepper <T>(
            int CutCellQuadOrder,
            BlockMsrMatrix OpMatrix, double[] OpAffine,
            Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales,
            IEnumerable <T> CurrentState,
            VectorField <SinglePhaseField> SurfaceForce,
            VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature,
            UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
            double time, IEnumerable <T> CoupledCurrentState = null, IEnumerable <T> CoupledParams = null) where T : DGField
        {
            if (ColMapping.BasisS.Count != this.Op.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.Op.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            // check:
            var Tracker = this.LsTrk;
            int D       = Tracker.GridDat.SpatialDimension;

            if (CurrentState != null && CurrentState.Count() != (D + 1))
            {
                throw new ArgumentException();
            }
            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }
            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }



            LevelSet Phi = (LevelSet)(Tracker.LevelSets[0]);

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();

            IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea;


            // advanced settings for the navier slip boundary condition
            // ========================================================

            CellMask SlipArea;

            switch (this.dntParams.GNBC_Localization)
            {
            case NavierSlip_Localization.Bulk: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask;
                break;
            }

            case NavierSlip_Localization.ContactLine: {
                SlipArea = null;
                break;
            }

            case NavierSlip_Localization.Nearband: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth));
                break;
            }

            case NavierSlip_Localization.Prescribed: {
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentException();
            }


            MultidimensionalArray SlipLengths;

            SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs();
            SlipLengths.Clear();
            //SlipLengths.AccConstant(-1.0);

            if (SlipArea != null)
            {
                foreach (Chunk cnk in SlipArea)
                {
                    for (int i = cnk.i0; i < cnk.JE; i++)
                    {
                        switch (this.dntParams.GNBC_SlipLength)
                        {
                        case NavierSlip_SlipLength.hmin_DG: {
                            int degU = ColMapping.BasisS.ToArray()[0].Degree;
                            SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1);
                            break;
                        }

                        case NavierSlip_SlipLength.hmin_Grid: {
                            SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i];
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_SlipLength: {
                            SlipLengths[i] = this.physParams.sliplength;
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_Beta: {
                            SlipLengths[i] = -1.0;
                            break;
                        }
                        }
                    }
                }
            }



            // parameter assembly
            // ==================

            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;

            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }

            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(Tracker, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }

            // Temperature gradient for evaporation
            VectorField <DGField> GradTemp = new VectorField <DGField>(D, new XDGBasis(LsTrk, 0), XDGField.Factory);

            if (CoupledCurrentState != null)
            {
                DGField Temp = CoupledCurrentState.ToArray()[0];
                GradTemp = new VectorField <DGField>(D, Temp.Basis, "GradTemp", XDGField.Factory);
                XNSEUtils.ComputeGradientForParam(Temp, GradTemp, this.LsTrk);
            }

            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]),
                Normals,
                ((evaporation) ? GradTemp.ToArray() : new SinglePhaseField[D]),
                ((evaporation) ? CoupledCurrentState.ToArray <DGField>() : new SinglePhaseField[1]),
                ((evaporation) ? CoupledParams.ToArray <DGField>() : new SinglePhaseField[1]));  //((evaporation) ? GradTemp.ToArray() : new SinglePhaseField[D]));

            // linearization velocity:
            if (this.U0meanrequired)
            {
                VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }
            }



            // assemble the matrix & affine vector
            // ===================================

            // compute matrix
            if (OpMatrix != null)
            {
                //Op.ComputeMatrixEx(Tracker,
                //    ColMapping, Params, RowMapping,
                //    OpMatrix, OpAffine, false, time, true,
                //    AgglomeratedCellLengthScales,
                //    InterfaceLengths, SlipLengths,
                //    SpcToCompute);

                XSpatialOperator.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                    if (evaporation)
                    {
                        BitArray EvapMicroRegion = new BitArray(this.LsTrk.GridDat.Cells.Count);;  // this.LsTrk.GridDat.GetBoundaryCells().GetBitMask();
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion);
                    }
                }

                if (Op.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                mtxBuilder.time = time;

                mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);

#if DEBUG
                // remark: remove this piece in a few months from now on (09may18) if no problems occur
                {
                    BlockMsrMatrix checkOpMatrix = new BlockMsrMatrix(RowMapping, ColMapping);
                    double[]       checkAffine   = new double[OpAffine.Length];

                    Op.ComputeMatrixEx(Tracker,
                                       ColMapping, Params, RowMapping,
                                       OpMatrix, OpAffine, false, time, true,
                                       AgglomeratedCellLengthScales,
                                       InterfaceLengths, SlipLengths,
                                       SpcToCompute);


                    double[] checkResult = checkAffine.CloneAs();
                    var      currentVec  = new CoordinateVector(CurrentState.ToArray());
                    checkOpMatrix.SpMV(1.0, new CoordinateVector(CurrentState.ToArray()), 1.0, checkResult);

                    double L2_dist = GenericBlas.L2DistPow2(checkResult, OpAffine).MPISum().Sqrt();
                    double RefNorm = (new double[] { checkResult.L2NormPow2(), OpAffine.L2NormPow2(), currentVec.L2NormPow2() }).MPISum().Max().Sqrt();

                    Assert.LessOrEqual(L2_dist, RefNorm * 1.0e-6);
                    Debug.Assert(L2_dist < RefNorm * 1.0e-6);
                }
#endif
            }
            else
            {
                XSpatialOperator.XEvaluatorNonlin eval = Op.GetEvaluatorEx(Tracker,
                                                                           CurrentState.ToArray(), Params, RowMapping,
                                                                           SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                    if (evaporation)
                    {
                        BitArray EvapMicroRegion = new BitArray(this.LsTrk.GridDat.Cells.Count);
                        eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion);
                    }
                }

                if (Op.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);
            }


            // check
            // =====

            /*
             * {
             *  DGField[] testDomainFieldS = ColMapping.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray();
             *  CoordinateVector test = new CoordinateVector(testDomainFieldS);
             *
             *  DGField[] errFieldS = ColMapping.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray();
             *  CoordinateVector Err = new CoordinateVector(errFieldS);
             *
             *  var eval = Op.GetEvaluatorEx(LsTrk,
             *      testDomainFieldS, Params, RowMapping);
             *
             *  foreach (var s in this.LsTrk.SpeciesIdS)
             *      eval.SpeciesOperatorCoefficients[s].CellLengthScales = AgglomeratedCellLengthScales[s];
             *
             *  eval.time = time;
             *  int L = test.Count;
             *  Random r = new Random();
             *  for(int i = 0; i < L; i++) {
             *      test[i] = r.NextDouble();
             *  }
             *
             *
             *
             *  double[] R1 = new double[L];
             *  double[] R2 = new double[L];
             *  eval.Evaluate(1.0, 1.0, R1);
             *
             *  R2.AccV(1.0, OpAffine);
             *  OpMatrix.SpMV(1.0, test, 1.0, R2);
             *
             *  Err.AccV(+1.0, R1);
             *  Err.AccV(-1.0, R2);
             *
             *  double ErrDist = GenericBlas.L2DistPow2(R1, R2).MPISum().Sqrt();
             *
             *  double Ref = test.L2NormPow2().MPISum().Sqrt();
             *
             *  Debug.Assert(ErrDist <= Ref*1.0e-5, "Mismatch between explicit evaluation of XDG operator and matrix.");
             * }
             */
        }
示例#10
0
		private void DrawGraph ()
		{
			bool isMini = IsMini;

			//background
			float gridColor = !StylesCache.isPro ? 0.45f : 0.12f;
			float gridBackgroundColor = !StylesCache.isPro ? 0.5f : 0.15f;

			#if MM_DEBUG
				if (!graph.debugGraphBackground)
				{
					gridColor = graph.debugGraphBackColor;
					gridBackgroundColor = graph.debugGraphBackColor;
				}
			#endif

			Draw.StaticGrid(
				displayRect: new Rect(0, 0, Screen.width, Screen.height-toolbarSize),
				cellSize:32,
				color:new Color(gridColor,gridColor,gridColor), 
				background:new Color(gridBackgroundColor,gridBackgroundColor,gridBackgroundColor),
				fadeWithZoom:true);

			#if MM_DEBUG
				if (graph.drawInSceneView)
				{
					using (Cell.Full)
						DrawSceneView();
				}
			#endif

			//drawing groups
			foreach (Group group in graph.groups)
				using (Cell.Custom(group.guiPos.x, group.guiPos.y, group.guiSize.x, group.guiSize.y))
				{
					GroupDraw.DragGroup(group, graph.generators);
					GroupDraw.DrawGroup(group, isMini:isMini);
				}


			//dragging nodes
			foreach (Generator gen in graph.generators)
				GeneratorDraw.DragGenerator(gen, selected);


			//drawing links
			//using (Timer.Start("Links"))
			if (!UI.current.layout)
			{
				List<(IInlet<object> inlet, IOutlet<object> outlet)> linksToRemove = null;
				foreach (var kvp in graph.links)
				{
					IInlet<object> inlet = kvp.Key;
					IOutlet<object> outlet = kvp.Value;

					Cell outletCell = UI.current.cellObjs.GetCell(outlet, "Outlet");
					Cell inletCell = UI.current.cellObjs.GetCell(inlet, "Inlet");

					if (outletCell == null || inletCell == null)
					{
						Debug.LogError("Could not find a cell for inlet/outlet. Removing link");
						if (linksToRemove == null) linksToRemove = new List<(IInlet<object> inlet, IOutlet<object> outlet)>();
						linksToRemove.Add((inlet,outlet));
						continue;
					}

					GeneratorDraw.DrawLink(
						GeneratorDraw.StartCellLinkpos(outletCell),
						GeneratorDraw.EndCellLinkpos(inletCell), 
						GeneratorDraw.GetLinkColor(inlet),
						width:!isMini ? 4f : 6f );
				}

				if (linksToRemove != null)
					foreach ((IInlet<object> inlet, IOutlet<object> outlet) in linksToRemove)
					{
						graph.UnlinkInlet(inlet);
						graph.UnlinkOutlet(outlet);
					}
			}

			//removing null generators (for test purpose)
			for (int n=graph.generators.Length-1; n>=0; n--)
			{
				if (graph.generators[n] == null)
					ArrayTools.RemoveAt(ref graph.generators, n);
			}

			//drawing generators
			//using (Timer.Start("Generators"))
			float nodeWidth = !isMini ? GeneratorDraw.nodeWidth : GeneratorDraw.miniWidth;
			foreach (Generator gen in graph.generators)
				using (Cell.Custom(gen.guiPosition.x, gen.guiPosition.y, nodeWidth, 0))
					GeneratorDraw.DrawGeneratorOrPortal(gen, graph, isMini:isMini, selected.Contains(gen));


			//de-selecting nodes (after dragging and drawing since using drag obj)
			if (!UI.current.layout)
			{
				GeneratorDraw.SelectGenerators(selected, shiftForSingleSelect:!isMini);
				GeneratorDraw.DeselectGenerators(selected); //and deselected always without shift
			}
				
			//add/remove button
			//using (Timer.Start("AddRemove"))
			using (Cell.Full)
				DragDrawAddRemove();

			//right click menu (should have access to cellObjs)
			if (!UI.current.layout  &&  Event.current.type == EventType.MouseDown  &&  Event.current.button == 1)
				RightClick.DrawRightClickItems(graphUI, graphUI.mousePos, graph);

			//create menu on space
			if (!UI.current.layout  &&  Event.current.type == EventType.KeyDown  &&  Event.current.keyCode == KeyCode.Space  && !Event.current.shift)
				CreateRightClick.DrawCreateItems(graphUI.mousePos, graph);

			//delete selected generators
			if (selected!=null  &&  selected.Count!=0  &&  Event.current.type==EventType.KeyDown  &&  Event.current.keyCode==KeyCode.Delete)
				GraphEditorActions.RemoveGenerators(graph, selected);
		}
示例#11
0
        public ExtensionVelocityBDFMover(LevelSetTracker LSTrk,
                                         SinglePhaseField LevelSet,
                                         VectorField <SinglePhaseField> LevelSetGradient,
                                         VectorField <DGField> Velocity,
                                         EllipticExtVelAlgoControl Control,
                                         IncompressibleBoundaryCondMap bcMap,
                                         int BDForder,
                                         VectorField <SinglePhaseField> VectorExtension,
                                         double[] Density = null,
                                         bool AssumeDivergenceFreeVelocity = false, SubGrid subGrid = null)
        {
            this.GridDat          = LSTrk.GridDat;
            D                     = GridDat.SpatialDimension;
            this.LevelSetGradient = LevelSetGradient;
            this.LSTrk            = LSTrk;
            this.LevelSet         = LevelSet;

            this.Velocity = Velocity;
            this.OldRHS   = LevelSet.CloneAs();
            this.AdvectionSpatialOperator = CreateAdvectionSpatialOperator(bcMap);

            this.subGrid   = subGrid;
            this.nearfield = subGrid != null;

            Basis NonXVelocityBasis;

            if (Velocity == null)
            {
                throw new ArgumentException("Velocity Field not initialized!");
            }

            // Initialize Extension Velocity Algorithm
            double        PenaltyBase = Control.PenaltyMultiplierInterface * ((double)((LevelSet.Basis.Degree + 1) * (LevelSet.Basis.Degree + D))) / ((double)D);
            ILevelSetForm InterfaceFlux;



            //VectorExtension = new VectorField<SinglePhaseField>(D, Velocity[0].Basis, "ExtVel", SinglePhaseField.Factory);
            if (Velocity[0].GetType() == typeof(SinglePhaseField))
            {
                NonXVelocityBasis = ((SinglePhaseField)Velocity[0]).Basis;
                InterfaceFlux     = new SingleComponentInterfaceForm(PenaltyBase, LSTrk);
            }
            else if (Velocity[0].GetType() == typeof(XDGField))
            {
                NonXVelocityBasis = ((XDGField)Velocity[0]).Basis.NonX_Basis;
                InterfaceFlux     = new DensityWeightedExtVel(PenaltyBase, LSTrk, Density);
            }
            else
            {
                throw new ArgumentException("VelocityField must be either a SinglePhaseField or a XDGField!");
            };
            //VectorExtension = new VectorField<SinglePhaseField>(D, NonXVelocityBasis, "ExtVel", SinglePhaseField.Factory);
            this.VectorExtension = VectorExtension;



            VelocityExtender = new Extender[D];
            for (int d = 0; d < D; d++)
            {
                VelocityExtender[d] = new Extender(VectorExtension[d], LSTrk, InterfaceFlux, new List <DGField> {
                    Velocity[d]
                }, LevelSetGradient, Control);
                VelocityExtender[d].ConstructExtension(new List <DGField> {
                    Velocity[d]
                }, Control.subGridRestriction);
            }
#if DEBUG
            VectorExtension.CheckForNanOrInf();
#endif

            // Initialize Advection Algorithm
            divU = new SinglePhaseField(NonXVelocityBasis);
            divU.Identification = "Divergence";
            divU.Clear();
            divU.Divergence(1.0, VectorExtension);
            MeanVelocity = new VectorField <SinglePhaseField>(D.ForLoop(d => new SinglePhaseField(new Basis(GridDat, 0), VariableNames.Velocity0MeanVector(D)[d])));
            MeanVelocity.Clear();
            MeanVelocity.AccLaidBack(1.0, VectorExtension);
            myBDFTimestepper = new BDFTimestepper(AdvectionSpatialOperator, new List <DGField>()
            {
                LevelSet
            }, ArrayTools.Cat(VectorExtension, this.MeanVelocity, this.divU), BDForder, Control.solverFactory, false, subGrid);
        }
            /// <summary>
            /// computes the injector for multigrid level 1
            /// </summary>
            /// <seealso cref="BuildInjector_Lv2andup"/>
            private static MultidimensionalArray[] BuildInjector_Lv1(
                Basis maxDgBasis, int Np,
                MultidimensionalArray InjectorsBase, bool[] InjectorsBaseReady,
                int Jagg, int[][] Ag2Pt, int[][] C2F)
            {
                using (new FuncTrace()) {
                    MultidimensionalArray ortho = MultidimensionalArray.Create(Np, Np);

                    MultidimensionalArray[] Injectors_iLevel = new MultidimensionalArray[Jagg];

#if DEBUG
                    {
                        int Jbase = InjectorsBase.GetLength(0);
                        if (InjectorsBase.GetLength(1) != InjectorsBase.GetLength(2))
                        {
                            throw new ArgumentException();
                        }
                        int N     = InjectorsBase.GetLength(1);
                        var check = MultidimensionalArray.Create(N, N);
                        for (int j = 0; j < Jbase; j++)
                        {
                            check.Clear();
                            check.AccEye(1.0);
                            check.Acc(-1.0, InjectorsBase.ExtractSubArrayShallow(j, -1, -1));

                            if (check.InfNorm() != 0.0)
                            {
                                throw new ArgumentException();
                            }
                        }
                    }
#endif
                    var iLPar = maxDgBasis.GridDat.iLogicalCells; // cells of *parent* grid

                    for (int j = 0; j < Jagg; j++)                // loop over aggregate cells
                    {
                        Debug.Assert(ArrayTools.ListEquals(Ag2Pt[j], C2F[j]));

                        int[] compCell = Ag2Pt[j];
                        int   I        = compCell.Length;


                        int    iRoot   = -1;
                        double maxSize = -1.0;
                        for (int i = 0; i < I; i++)
                        {
                            double sz = iLPar.GetCellVolume(compCell[i]);
                            if (sz <= 0.0)
                            {
                                throw new ArithmeticException("found cell with non-positive volume.");
                            }
                            if (sz > maxSize)
                            {
                                iRoot   = i;
                                maxSize = sz;
                            }
                        }

                        //var gdat = ((maxDgBasis.GridDat) as Classic.GridData);
                        //double[] Sizes = compCell.Select(jPart => gdat.iLogicalCells.GetCellVolume(jPart)).ToArray();


                        Injectors_iLevel[j] = MultidimensionalArray.Create(I, Np, Np);
                        if (I > 1)
                        {
                            // compute extrapolation
                            int[,] CellPairs = new int[I - 1, 2];

                            int cnt = 0;
                            for (int i = 0; i < I; i++)
                            {
                                if (i != iRoot)
                                {
                                    CellPairs[cnt, 0] = compCell[iRoot];
                                    CellPairs[cnt, 1] = compCell[i];
                                    Debug.Assert(CellPairs[cnt, 0] != CellPairs[cnt, 1]);
                                    cnt++;
                                }
                            }

                            //cnt = 0;
                            //for (int i = 0; i < I - 1; i++) {
                            //    CellPairs[cnt, 0] = compCell[0];
                            //    CellPairs[cnt, 1] = compCell[i + 1];
                            //    cnt++;
                            //}


                            var ExpolMtx = MultidimensionalArray.Create(I, Np, Np);
                            maxDgBasis.GetExtrapolationMatrices(CellPairs, ExpolMtx.ExtractSubArrayShallow(new int[] { 1, 0, 0 }, new int[] { I - 1, Np - 1, Np - 1 }));
                            for (int i = 0; i < iRoot; i++)
                            {
                                var M2 = ExpolMtx.ExtractSubArrayShallow(i, -1, -1);
                                var M1 = ExpolMtx.ExtractSubArrayShallow(i + 1, -1, -1);
                                M2.Set(M1);
                            }
                            for (int n = 0; n < Np; n++)
                            {
                                for (int m = 0; m < Np; m++)
                                {
                                    ExpolMtx[iRoot, n, m] = n == m ? 1.0 : 0.0;
                                }
                            }

                            // Compute intermediate mass matrix
                            var MMtemp = MultidimensionalArray.Create(Np, Np);
                            MMtemp.Multiply(1.0, ExpolMtx, ExpolMtx, 0.0, "nm", "iln", "ilm");

                            // orthonormalize
                            //try {
                            MMtemp.SymmetricLDLInversion(ortho, null);     // ortho is output, will be overwritten

                            //} catch (ArithmeticException ae) {
                            //    PlotScheisse(gdat.Grid, compCell);
                            //}
                            Injectors_iLevel[j].Multiply(1.0, ExpolMtx, ortho, 0.0, "inm", "ink", "km");
                        }
                        else
                        {
                            Injectors_iLevel[j].ExtractSubArrayShallow(0, -1, -1).AccEye(1.0);
                        }

                        // base level injector
                        var injBase = InjectorsBase.ExtractSubArrayShallow(compCell[0], -1, -1);
                        injBase.Set(Injectors_iLevel[j].ExtractSubArrayShallow(0, -1, -1));
                        Debug.Assert(InjectorsBaseReady[compCell[0]]);

                        for (int i = 1; i < I; i++)
                        {
                            InjectorsBaseReady[compCell[i]] = false;
                        }
                    }

                    return(Injectors_iLevel);
                }
            }
            public void Init(int ReqDegree)
            {
                if (ReqDegree < 0)
                {
                    throw new ArgumentOutOfRangeException();
                }
                if (ReqDegree <= MaxSupportedDegree)
                {
                    return;
                }

                var   aGdat      = m_owner.AncestorGrid;
                Basis maxDGbasis = new Basis(aGdat, ReqDegree);
                int   Np         = maxDGbasis.Length;
                int   Jbase      = aGdat.Cells.NoOfLocalUpdatedCells;

                int Jagg = m_owner.iLogicalCells.NoOfLocalUpdatedCells;

                int[][] Ag2Pt = m_owner.iLogicalCells.AggregateCellToParts;
                int[][] C2F   = m_owner.jCellCoarse2jCellFine;

                if (m_owner.ParentGrid is AggregationGridData)
                {
                    var     agParrent  = m_owner.ParentGrid as AggregationGridData;
                    int[][] Ag2Pt_Fine = agParrent.iLogicalCells.AggregateCellToParts;

                    agParrent.m_ChefBasis.Init(MaxSupportedDegree);

                    if (ReqDegree == agParrent.m_ChefBasis.MaxSupportedDegree)
                    {
                        this.InjectorsBase = agParrent.m_ChefBasis.InjectorsBase.CloneAs();
                    }
                    else
                    {
                        this.InjectorsBase = agParrent.m_ChefBasis.InjectorsBase.ExtractSubArrayShallow(new int[] { 0, 0, 0 }, new int[] { Jbase - 1, Np - 1, Np - 1 }).CloneAs();
                    }
                    this.InjectorsBaseReady = agParrent.m_ChefBasis.InjectorsBaseReady.CloneAs();

                    this.Injectors = BuildInjector_Lv2andup(maxDGbasis, Np, this.InjectorsBase, this.InjectorsBaseReady, Jagg, Ag2Pt_Fine, C2F);
                }
                else if (m_owner.ParentGrid is Classic.GridData)
                {
                    // this is level 0

                    var agParrent = m_owner.ParentGrid as Classic.GridData;
                    this.InjectorsBase      = MultidimensionalArray.Create(Jbase, Np, Np);
                    this.InjectorsBaseReady = new bool[Jbase];
                    ArrayTools.SetAll(this.InjectorsBaseReady, true);

                    for (int j = 0; j < Jbase; j++)
                    {
                        this.InjectorsBase.ExtractSubArrayShallow(j, -1, -1).AccEye(1.0);
                    }

                    if (IsCloneOfAncestor())
                    {
                        //this.Injectors = BuildInjector_Lv1(maxDGbasis, Np, this.InjectorsBase, this.InjectorsBaseReady, Jagg, Ag2Pt, C2F);
                        // nop
                    }
                    else
                    {
                        this.Injectors = BuildInjector_Lv1(maxDGbasis, Np, this.InjectorsBase, this.InjectorsBaseReady, Jagg, Ag2Pt, C2F);
                        //this.Injectors = BuildInjector_Lv2andup(maxDGbasis, Np, this.InjectorsBase, this.InjectorsBaseReady, Jagg, Ag2Pt_Fine, C2F);
                    }
                }
                else
                {
                    throw new NotSupportedException("dont know what to do");
                }

                MaxSupportedDegree = ReqDegree;
            }
示例#14
0
        public void GetOutDegree_LongLine_IsCorrect()
        {
            var g = new DependencyGraph <int>(i => i == 5 ? new[] { 12, 4 } : i <= 0 ? ArrayTools.Empty <int>() : new[] { i - 1 });

            Assert.That(g.GetOutDegree(5), Is.EqualTo(2));
        }
示例#15
0
            /// <summary>
            /// Updates all columns related to convergence plots
            /// </summary>
            public void Update()
            {
                // Get all sessions which are successfully terminated
                // ==================================================
                var SuccSessions = owner.Sessions.Where(sess => sess.SuccessfulTermination == true).ToArray();

                // Group the sessions according to polynomial degree
                // =================================================
                System.Func <int[], int[], bool> eqFunc = (A, B) => ArrayTools.AreEqual(A, B);
                var comp          = eqFunc.ToEqualityComparer();
                var SessionGroups = SuccSessions.GroupBy(GetDGDegreeKey, comp).ToArray();


                // Spatial convergence for each session group
                // ==========================================

                // intermediate result storage
                // 1st key: Field name
                // 2nd key: session name
                // value: error norm
                var Errors = new Dictionary <string, Dictionary <Guid, double> >();


                foreach (IEnumerable <ISessionInfo> spatialSeries in SessionGroups)
                {
                    if (spatialSeries.Count() <= 1)
                    {
                        continue;
                    }

                    ITimestepInfo[] tsiS = spatialSeries.Select(sess => sess.Timesteps.Last()).ToArray();

                    // find DG field identifications which are present in _all_ timesteps
                    var commonFieldIds = new HashSet <string>();
                    foreach (var fi in tsiS[0].FieldInitializers)
                    {
                        string id = fi.Identification;

                        bool containedInOthers = true;
                        foreach (var tsi in tsiS.Skip(1))
                        {
                            if (tsi.FieldInitializers.Where(fii => fii.Identification == id).Count() <= 0)
                            {
                                containedInOthers = false;
                            }
                        }

                        if (containedInOthers)
                        {
                            commonFieldIds.Add(id);
                        }
                    }

                    string[] fieldIds = commonFieldIds.ToArray();

                    // compute L2-errors
                    DGFieldComparison.ComputeErrors(fieldIds, tsiS, out double[] hS, out var DOFs, out var ERRs, out var tsiIdS);


                    // record errors
                    foreach (var id in fieldIds)
                    {
                        Dictionary <Guid, double> err_id;
                        if (!Errors.TryGetValue(id, out err_id))
                        {
                            err_id = new Dictionary <Guid, double>();
                            Errors.Add(id, err_id);
                        }

                        for (int iGrd = 0; iGrd < hS.Length; iGrd++)
                        {
                            ITimestepInfo tsi  = tsiS.Single(t => t.ID == tsiIdS[iGrd]);
                            ISessionInfo  sess = tsi.Session;

                            err_id.Add(sess.ID, ERRs[id][iGrd]);
                        }
                    }
                }



                // Set L2 error columns in session table
                // =====================================
                foreach (string fieldName in Errors.Keys)
                {
                    string colName = "L2Error_" + fieldName;

                    if (owner.AdditionalSessionTableColums.ContainsKey(colName))
                    {
                        owner.AdditionalSessionTableColums.Remove(colName);
                    }

                    var ErrorsCol = Errors[fieldName];

                    owner.AdditionalSessionTableColums.Add(colName, delegate(ISessionInfo s) {
                        object ret = 0.0;

                        if (ErrorsCol.ContainsKey(s.ID))
                        {
                            ret = ErrorsCol[s.ID];
                        }

                        return(ret);
                    });
                }
            }
示例#16
0
        public OperatorFactory(
            OperatorConfiguration config,
            LevelSetTracker _LsTrk,
            int _HMFdegree,
            int degU,
            IncompressibleMultiphaseBoundaryCondMap BcMap,
            bool _movingmesh,
            bool _evaporation,
            bool _staticInt)
        {
            // variable names
            // ==============
            D          = _LsTrk.GridDat.SpatialDimension;
            this.LsTrk = _LsTrk;
            //this.momentFittingVariant = momentFittingVariant;
            this.HMFDegree           = _HMFdegree;
            this.dntParams           = config.dntParams.CloneAs();
            this.physParams          = config.physParams.CloneAs();
            this.UseExtendedVelocity = config.UseXDG4Velocity;
            this.movingmesh          = _movingmesh;
            this.evaporation         = _evaporation;

            // test input
            // ==========
            {
                if (config.DomBlocks.GetLength(0) != 2 || config.CodBlocks.GetLength(0) != 2)
                {
                    throw new ArgumentException();
                }
                if (config.physParams.mu_A == 0.0 && config.physParams.mu_B == 0.0)
                {
                    muIs0 = true;
                }
                else
                {
                    if (config.physParams.mu_A <= 0)
                    {
                        throw new ArgumentException();
                    }
                    if (config.physParams.mu_B <= 0)
                    {
                        throw new ArgumentException();
                    }
                }

                if (config.physParams.rho_A <= 0)
                {
                    throw new ArgumentException();
                }
                if (config.physParams.rho_B <= 0)
                {
                    throw new ArgumentException();
                }

                if (_LsTrk.SpeciesNames.Count != 2)
                {
                    throw new ArgumentException();
                }
                if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B")))
                {
                    throw new ArgumentException();
                }
            }


            // full operator:
            CodName = ((new string[] { "momX", "momY", "momZ" }).GetSubVector(0, D)).Cat("div");
            Params  = ArrayTools.Cat(
                VariableNames.Velocity0Vector(D),
                VariableNames.Velocity0MeanVector(D),
                "Curvature",
                (new string[] { "surfForceX", "surfForceY", "surfForceZ" }).GetSubVector(0, D),
                (new string[] { "NX", "NY", "NZ" }).GetSubVector(0, D),
                (new string[] { "GradTempX", "GradTempY", "GradTempZ" }.GetSubVector(0, D)),
                VariableNames.Temperature,
                "DisjoiningPressure");
            DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure);

            // selected part:
            if (config.CodBlocks[0])
            {
                CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, D));
            }
            if (config.CodBlocks[1])
            {
                CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D, 1));
            }

            if (config.DomBlocks[0])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, D));
            }
            if (config.DomBlocks[1])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D, 1));
            }

            muA   = config.physParams.mu_A;
            muB   = config.physParams.mu_B;
            rhoA  = config.physParams.rho_A;
            rhoB  = config.physParams.rho_B;
            sigma = config.physParams.Sigma;

            MatInt = !evaporation;

            double kA    = 0.0;
            double kB    = 0.0;
            double hVapA = 0.0;
            double hVapB = 0.0;

            double Tsat  = 0.0;
            double R_int = 0.0;
            double p_c   = 0.0;

            if (evaporation)
            {
                kA    = config.thermParams.k_A;
                kB    = config.thermParams.k_B;
                hVapA = config.thermParams.hVap_A;
                hVapB = config.thermParams.hVap_B;

                Tsat = config.thermParams.T_sat;
                p_c  = config.thermParams.pc;
                //double T_intMin = 0.0;
                double f = config.thermParams.fc;
                double R = config.thermParams.Rc;
                //double pc = config.thermParams.pc;

                if (config.thermParams.hVap_A > 0 && config.thermParams.hVap_B < 0)
                {
                    R_int = ((2.0 - f) / (2 * f)) * Tsat * Math.Sqrt(2 * Math.PI * R * Tsat) / (rhoB * hVapA.Pow2());
                    //T_intMin = Tsat * (1 + (pc / (rhoA * hVapA.Pow2())));
                }
                else if (config.thermParams.hVap_A < 0 && config.thermParams.hVap_B > 0)
                {
                    R_int = ((2.0 - f) / (2 * f)) * Tsat * Math.Sqrt(2 * Math.PI * R * Tsat) / (rhoA * hVapB.Pow2());
                    //T_intMin = Tsat * (1 + (pc / (rhoB * hVapB.Pow2())));
                }
                this.CurvatureRequired = true;
            }



            //if (!MatInt)
            //    throw new NotSupportedException("Non-Material interface is NOT tested!");

            // create Operator
            // ===============
            m_OP = new XSpatialOperator(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree);

            // build the operator
            // ==================
            {
                // Momentum equation
                // =================

                if (config.physParams.IncludeConvection && config.Transport)
                {
                    for (int d = 0; d < D; d++)
                    {
                        var comps = m_OP.EquationComponents[CodName[d]];

                        // convective part:
                        // variante 1:

                        double LFFA = config.dntParams.LFFA;
                        double LFFB = config.dntParams.LFFB;


                        var conv = new Operator.Convection.ConvectionInBulk_LLF(D, BcMap, d, rhoA, rhoB, LFFA, LFFB, LsTrk);
                        comps.Add(conv);                                                                                                                                 // Bulk component

                        comps.Add(new Operator.Convection.ConvectionAtLevelSet_LLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, config.physParams.Material, BcMap, movingmesh)); // LevelSet component
                        //comps.Add(new Operator.Convection.ConvectionAtLevelSet_weightedLLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, BcMap, movingmesh));       // LevelSet component

                        if (evaporation)
                        {
                            //comps.Add(new Operator.Convection.ConvectionAtLevelSet_Divergence(d, D, LsTrk, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti, kA, kB, hVapA, R_int, Tsat, sigma, p_c));
                            //comps.Add(new Operator.Convection.ConvectionAtLevelSet_nonMaterialLLF(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c));
                            //comps.Add(new Operator.Convection.ConvectionAtLevelSet_nonMaterial(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c));
                        }

                        // variante 3:
                        //var convA = new LocalConvection(D, d, rhoA, rhoB, this.config.varMode, LsTrk);
                        //XOP.OnIntegratingBulk += convA.SetParameter;
                        //comps.Add(convA);
                        //////var convB = new LocalConvection2(D, d, rhoA, rhoB, varMode, LsTrk); // macht Bum-Bum!
                        ////XOP.OnIntegratingBulk += convB.SetParameter;
                        ////comps.Add(convB);
                    }

                    this.U0meanrequired = true;
                }

                // pressure gradient
                // =================

                if (config.PressureGradient)
                {
                    for (int d = 0; d < D; d++)
                    {
                        var comps = m_OP.EquationComponents[CodName[d]];


                        var pres = new Operator.Pressure.PressureInBulk(d, BcMap);
                        comps.Add(pres);

                        //if (!MatInt)
                        //    throw new NotSupportedException("New Style pressure coupling does not support non-material interface.");
                        var presLs = new Operator.Pressure.PressureFormAtLevelSet(d, D, LsTrk); //, dntParams.UseWeightedAverages, muA, muB);
                        comps.Add(presLs);

                        //if (evaporation) {
                        //    var presLSGen = new Operator.Pressure.GeneralizedPressureFormAtLevelSet(d, D, LsTrk, config.thermParams.p_sat, hVapA);
                        //    comps.Add(presLSGen);
                        //}
                    }
                }

                // viscous operator
                // ================

                if (config.Viscous && !muIs0)
                {
                    for (int d = 0; d < D; d++)
                    {
                        var comps = m_OP.EquationComponents[CodName[d]];
                        // viscous part:
                        //double _D = D;
                        //double penalty_mul = dntParams.PenaltySafety;
                        //double _p = degU;
                        //double penalty_base = (_p + 1) * (_p + _D) / _D;
                        //double penalty = penalty_base * penalty_mul;
                        double penalty = dntParams.PenaltySafety;
                        switch (dntParams.ViscosityMode)
                        {
                        case ViscosityMode.Standard: {
                            // Bulk operator:
                            var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm(
                                dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                                BcMap, d, D, muA, muB);         // , _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B);

                            comps.Add(Visc);

                            if (dntParams.UseGhostPenalties)
                            {
                                var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB);
                                m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty);
                            }
                            // Level-Set operator:
                            comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, true));

                            break;
                        }

                        case ViscosityMode.TransposeTermMissing: {
                            // Bulk operator:
                            var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm(
                                dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                                BcMap, d, D, muA, muB);
                            comps.Add(Visc);

                            if (dntParams.UseGhostPenalties)
                            {
                                var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB);
                                m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty);
                            }
                            // Level-Set operator:
                            comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, false));

                            break;
                        }

                        case ViscosityMode.ExplicitTransformation: {
                            // Bulk operator
                            var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm(
                                dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                                BcMap, d, D, muA, muB);
                            comps.Add(Visc);
                            if (dntParams.UseGhostPenalties)
                            {
                                var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB);
                                m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty);
                            }

                            //Level-Set operator:
                            //comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Explicit(d, D, LsTrk, penalty, muA, muB));
                            throw new NotSupportedException("Beim refact rausgeflogen, braucht eh kein Mensch. fk, 08jan16.");

                            //break;
                        }

                        case ViscosityMode.FullySymmetric: {
                            // Bulk operator
                            var Visc1 = new Operator.Viscosity.ViscosityInBulk_GradUTerm(
                                dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                                BcMap, d, D, muA, muB, _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B);
                            var Visc2 = new Operator.Viscosity.ViscosityInBulk_GradUtranspTerm(
                                dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                                BcMap, d, D, muA, muB, _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B);
                            //var Visc3 = new Operator.Viscosity.ViscosityInBulk_divTerm(dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB);


                            comps.Add(Visc1);
                            comps.Add(Visc2);
                            //comps.Add(Visc3);

                            if (dntParams.UseGhostPenalties)
                            {
                                var Visc1Penalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(
                                    penalty, 0.0,
                                    BcMap, d, D, muA, muB);
                                var Visc2Penalty = new Operator.Viscosity.ViscosityInBulk_GradUtranspTerm(
                                    penalty, 0.0,
                                    BcMap, d, D, muA, muB);
                                //var Visc3Penalty = new Operator.Viscosity.ViscosityInBulk_divTerm(
                                //    penalty, 0.0,
                                //    BcMap, d, D, muA, muB);
                                //m_OP.OnIntegratingBulk += Visc3Penalty.SetParameter;
                                m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(Visc1Penalty);
                                m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(Visc2Penalty);
                                //m_OP.AndresHint.EquationComponents[CodName[d]].Add(Visc3Penalty);
                            }

                            // Level-Set operator
                            comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, _staticInt, dntParams.UseWeightedAverages));

                            if (this.evaporation)
                            {
                                comps.Add(new Operator.Viscosity.GeneralizedViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c));
                            }

                            break;
                        }

                        default:
                            throw new NotImplementedException();
                        }
                    }
                }

                // Continuum equation
                // ==================

                if (config.continuity)
                {
                    for (int d = 0; d < D; d++)
                    {
                        var src = new Operator.Continuity.DivergenceInBulk_Volume(d, D, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti);
                        var flx = new Operator.Continuity.DivergenceInBulk_Edge(d, BcMap, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti);
                        m_OP.EquationComponents["div"].Add(flx);
                        m_OP.EquationComponents["div"].Add(src);
                    }

                    var divPen = new Operator.Continuity.DivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, MatInt, config.dntParams.ContiSign, config.dntParams.RescaleConti, _staticInt); //, dntParams.UseWeightedAverages, muA, muB);
                    m_OP.EquationComponents["div"].Add(divPen);

                    if (evaporation)
                    {
                        var divPenGen = new Operator.Continuity.GeneralizedDivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti, kA, kB, hVapA, R_int, Tsat, sigma, p_c);
                        m_OP.EquationComponents["div"].Add(divPenGen);
                    }

                    //// pressure stabilization
                    //if (this.config.PressureStab) {
                    //    Console.WriteLine("Pressure Stabilization active.");
                    //var pStabi = new PressureStabilization(0.0001, 0.0001);
                    //    m_OP.OnIntegratingBulk += pStabi.SetParameter;
                    //    m_OP.EquationComponents["div"].Add(pStabi);
                    ////var pStabiLS = new PressureStabilizationAtLevelSet(D, LsTrk, rhoA, muA, rhoB, muB, sigma, this.config.varMode, MatInt);
                    //    //XOP.EquationComponents["div"].Add(pStabiLS);
                    //} else {
                    //    Console.WriteLine("Pressure Stabilization INACTIVE.");
                    //}
                }

                // surface tension
                // ===============

                if (config.PressureGradient && config.physParams.Sigma != 0.0)
                {
                    // isotropic part of the surface stress tensor
                    if (config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux ||
                        config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Local ||
                        config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            if (config.dntParams.SST_isotropicMode != SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine)
                            {
                                IEquationComponent G = new SurfaceTension_LaplaceBeltrami_Surface(d, config.physParams.Sigma * 0.5);
                                IEquationComponent H = new SurfaceTension_LaplaceBeltrami_BndLine(d, config.physParams.Sigma * 0.5, config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux);
                                m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(G);
                                m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(H);
                            }
                            else
                            {
                                //G = new SurfaceTension_LaplaceBeltrami2_Surface(d, config.physParams.Sigma * 0.5);
                                //H = new SurfaceTension_LaplaceBeltrami2_BndLine(d, config.physParams.Sigma * 0.5, config.physParams.Theta_e, config.physParams.betaL);
                                IEquationComponent isoSurfT = new IsotropicSurfaceTension_LaplaceBeltrami(d, D, config.physParams.Sigma * 0.5, BcMap.EdgeTag2Type, BcMap, config.physParams.theta_e, config.physParams.betaL, _staticInt);
                                m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(isoSurfT);
                            }
                        }

                        this.NormalsRequired = true;
                    }
                    else if (config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Projected ||
                             config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_ClosestPoint ||
                             config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_LaplaceBeltramiMean ||
                             config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Fourier)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            m_OP.EquationComponents[CodName[d]].Add(new CurvatureBasedSurfaceTension(d, D, LsTrk, config.physParams.Sigma));
                        }

                        this.CurvatureRequired = true;

                        /*
                         * Console.WriteLine("REM: hack in Operator factory");
                         * for(int d = 0; d < D; d++) {
                         *  //var G = new SurfaceTension_LaplaceBeltrami_Surface(d, config.physParams.Sigma * 0.5);
                         *  var H = new SurfaceTension_LaplaceBeltrami_BndLine(d, config.physParams.Sigma * 0.5, config.dntParams.surfTensionMode == SurfaceTensionMode.LaplaceBeltrami_Flux);
                         *
                         *  //m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(G);
                         *  m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(H);
                         * }
                         *
                         * this.NormalsRequired = true;
                         */
                    }
                    else
                    {
                        throw new NotImplementedException("Not implemented.");
                    }


                    // dynamic part
                    if (config.dntParams.SurfStressTensor != SurfaceSressTensor.Isotropic)
                    {
                        double muI  = config.physParams.mu_I;
                        double lamI = config.physParams.lambda_I;

                        double penalty_base = (degU + 1) * (degU + D) / D;
                        double penalty      = penalty_base * dntParams.PenaltySafety;

                        // surface shear viscosity
                        if (config.dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceRateOfDeformation ||
                            config.dntParams.SurfStressTensor == SurfaceSressTensor.SemiImplicit ||
                            config.dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven)
                        {
                            for (int d = 0; d < D; d++)
                            {
                                var surfDeformRate = new BoussinesqScriven_SurfaceDeformationRate_GradU(d, muI * 0.5, penalty);
                                m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfDeformRate);
                                //m_OP.OnIntegratingSurfaceElement += surfDeformRate.SetParameter;

                                if (config.dntParams.SurfStressTensor != SurfaceSressTensor.SemiImplicit)
                                {
                                    var surfDeformRateT = new BoussinesqScriven_SurfaceDeformationRate_GradUTranspose(d, muI * 0.5, penalty);
                                    m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfDeformRateT);
                                    //m_OP.OnIntegratingSurfaceElement += surfDeformRateT.SetParameter;
                                }
                            }
                        }
                        // surface dilatational viscosity
                        if (config.dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceVelocityDivergence ||
                            config.dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven)
                        {
                            for (int d = 0; d < D; d++)
                            {
                                var surfVelocDiv = new BoussinesqScriven_SurfaceVelocityDivergence(d, muI * 0.5, lamI * 0.5, penalty, BcMap.EdgeTag2Type);
                                m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfVelocDiv);
                                //m_OP.OnIntegratingSurfaceElement += surfVelocDiv.SetParameter;
                            }
                        }
                    }


                    // stabilization
                    if (config.dntParams.UseLevelSetStabilization)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            m_OP.EquationComponents[CodName[d]].Add(new LevelSetStabilization(d, D, LsTrk));
                        }
                    }
                }


                // surface force term
                // ==================


                if (config.PressureGradient && config.physParams.useArtificialSurfaceForce)
                {
                    for (int d = 0; d < D; d++)
                    {
                        m_OP.EquationComponents[CodName[d]].Add(new SurfaceTension_ArfForceSrc(d, D, LsTrk));
                    }
                }


                // evaporation (mass flux)
                // =======================

                if (evaporation)
                {
                    for (int d = 0; d < D; d++)
                    {
                        m_OP.EquationComponents[CodName[d]].Add(new Operator.DynamicInterfaceConditions.MassFluxAtInterface(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c));
                    }
                }
            }

            // Finalize
            // ========

            m_OP.Commit();
        }
示例#17
0
        public static IBM_Control[] IBMCylinderFlow(string _DbPath = null, int k = 2, bool xPeriodic = false, double VelXBase = 0.0)
        {
            List <IBM_Control> R = new List <IBM_Control>();

            foreach (int i in new int[] { 3 })
            {
                IBM_Control C = new IBM_Control();

                C.Paramstudy_CaseIdentification = new Tuple <string, object>[] {
                    new Tuple <string, object>("k", i),
                };

                k = i;

                const double BaseSize = 1.0;

                // basic database options
                // ======================

                C.DbPath      = @"\\fdyprime\userspace\krause\BoSSS_DBs\Paper_CellAgglo01_Penalty4";
                C.savetodb    = false;
                C.ProjectName = "FixedCylinderRe100_k" + i + "_CellAgglo02_penalty4_newMesh2";

                switch (i)
                {
                case 1:
                    C.MeshFactor = 1.33; // was 1.33
                    break;

                case 2:
                    C.MeshFactor = 0.92;
                    break;

                case 3:
                    C.MeshFactor = 0.7; // was 07
                    break;

                default:

                    throw new ApplicationException();
                }

                C.ProjectDescription = "Cylinder";
                C.Tags.Add("with immersed boundary method");

                // DG degrees
                // ==========

                C.FieldOptions.Add("VelocityX", new FieldOpts()
                {
                    Degree   = k,
                    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
                });
                C.FieldOptions.Add("VelocityY", new FieldOpts()
                {
                    Degree   = k,
                    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
                });
                //Console.WriteLine("Achtung: equal order!!!!");
                C.FieldOptions.Add("Pressure", new FieldOpts()
                {
                    Degree = k - 1,

                    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
                });
                C.FieldOptions.Add("PhiDG", new FieldOpts()
                {
                    Degree   = 2,
                    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
                });
                C.FieldOptions.Add("Phi", new FieldOpts()
                {
                    Degree   = 2,
                    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
                });

                //grid and boundary conditions
                // ============================

                C.GridFunc = delegate {
                    var _xNodes1 = Grid1D.TanhSpacing(-2, -1, Convert.ToInt32(10 * C.MeshFactor), 0.5, false); //10
                    _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1));
                    var _xNodes2 = GenericBlas.Linspace(-1, 2, Convert.ToInt32(35 * C.MeshFactor));            //35
                    _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1));
                    var _xNodes3 = Grid1D.TanhSpacing(2, 20, Convert.ToInt32(60 * C.MeshFactor), 1.5, true);   //60

                    var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3);


                    var _yNodes1 = Grid1D.TanhSpacing(-2, -1, Convert.ToInt32(7 * C.MeshFactor), 0.9, false); //7
                    _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1));
                    var _yNodes2 = GenericBlas.Linspace(-1, 1, Convert.ToInt32(25 * C.MeshFactor));           //25
                    _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1));
                    var _yNodes3 = Grid1D.TanhSpacing(1, 2.1, Convert.ToInt32(7 * C.MeshFactor), 1.1, true);  //7
                    var yNodes   = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3);



                    //double[] xNodes = GenericBlas.Linspace(0 * BaseSize, 22 * BaseSize, 25);
                    //double[] yNodes = GenericBlas.Linspace(0 * BaseSize, 4.1 * BaseSize, 25);
                    var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic);
                    grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper");
                    grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower");
                    if (!xPeriodic)
                    {
                        grd.EdgeTagNames.Add(3, "Velocity_Inlet_left");
                        grd.EdgeTagNames.Add(4, "Pressure_Outlet_right");
                    }

                    grd.DefineEdgeTags(delegate(double[] X) {
                        byte et = 0;
                        if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8)
                        {
                            et = 1;
                        }
                        if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8)
                        {
                            et = 2;
                        }
                        if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8)
                        {
                            et = 3;
                        }
                        if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8)
                        {
                            et = 4;
                        }


                        Debug.Assert(et != 0);
                        return(et);
                    });

                    Console.WriteLine("Cells:    {0}", grd.NumberOfCells);

                    return(grd);
                };

                //C.GridFunc = delegate {

                //    // Box1
                //    var box1_p1 = new double[2] { -2, -2 };
                //    var box1_p2 = new double[2] { 20, 2.1 };
                //    var box1 = new GridBox(box1_p1, box1_p2, 46, 20); //k1: 70,25 ; k2: 46,20 ; k3: 35,15

                //    // Box2
                //    var box2_p1 = new double[2] { -2, -2 };
                //    var box2_p2 = new double[2] { 3, 2.1 };
                //    var box2 = new GridBox(box2_p1, box2_p2, 26, 40); //k1: 40,50 ; k2: 26,40; k3: 20, 30

                //    // Box3
                //    var box3_p1 = new double[2] { -2, -1 };
                //    var box3_p2 = new double[2] { 1, 1 };
                //    var box3 = new GridBox(box3_p1, box3_p2, 32, 38); //k1: 48,58  ; k2: 32,38; k3: 24, 30

                //    // Box4
                //    var box4_p1 = new double[2] { -0.7, -0.72 };
                //    var box4_p2 = new double[2] { 0.7, 0.7 };
                //    var box4 = new GridBox(box4_p1, box4_p2, 30, 56); //k1: 44,84  ; k2: 30,56; k3: 22, 42

                //    var grd = Grid2D.HangingNodes2D(box1, box2, box3,box4);

                //    grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper");
                //    grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower");
                //    if (!xPeriodic) {
                //        grd.EdgeTagNames.Add(3, "Velocity_Inlet_left");
                //        grd.EdgeTagNames.Add(4, "Pressure_Outlet_right");
                //    }

                //    grd.DefineEdgeTags(delegate (double[] X) {
                //        byte et = 0;
                //        if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8)
                //            et = 1;
                //        if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8)
                //            et = 2;
                //        if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8)
                //            et = 3;
                //        if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8)
                //            et = 4;


                //        Debug.Assert(et != 0);
                //        return et;
                //    });

                //    Console.WriteLine("Cells:    {0}", grd.NumberOfCells);

                //    return grd;
                //};

                C.AddBoundaryCondition("Velocity_Inlet_upper", "VelocityX", X => 0);
                C.AddBoundaryCondition("Velocity_Inlet_lower", "VelocityX", X => 0); //-(4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1))
                if (!xPeriodic)
                {
                    C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX", X => (4 * 1.5 * (X[1] + 2) * (4.1 - (X[1] + 2)) / (4.1 * 4.1)));
                    //C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX#A", X => 1);
                }
                C.AddBoundaryCondition("Pressure_Outlet_right");


                // Initial Values
                // ==============

                double radius = 0.5;
                C.PhysicalParameters.rho_A = 1;
                C.PhysicalParameters.mu_A  = 1.0 / 20;

                //C.InitialValues.Add("Phi", X => phi(X, 0));

                //C.InitialValues.Add("Phi", X => ((X[0] / (radius * BaseSize)) - mPx) * (X[0] / (radius * BaseSize)) - mPx) + ((X[1]) / (radius * BaseSize)) - 2.)Pow2() - radius.Pow2()));  // quadratic form
                //    );
                C.InitialValues_Evaluators.Add("Phi", X => - (X[0]).Pow2() + -(X[1]).Pow2() + radius.Pow2());
                //C.InitialValues.Add("Phi", X => -1);

                C.InitialValues_Evaluators.Add("VelocityX", X => 4 * 1.5 * (X[1] + 2) * (4.1 - (X[1] + 2)) / (4.1 * 4.1));
                //C.InitialValues.Add("VelocityX", delegate (double[] X)
                //{
                //    double x = X[0];
                //    double y = X[1];

                //    double R = Math.Sqrt((x + 1).Pow2() + y.Pow2());

                //    double xVel = 0;

                //    if (R < 0.75)
                //    {
                //        xVel = 1;
                //    }
                //    return xVel;
                //});

                //C.InitialValues.Add("VelocityY", delegate (double[] X) {
                //    double x = X[0];
                //    double y = X[1];

                //    double R = Math.Sqrt((x + 1).Pow2() + (y).Pow2());

                //    double yVel = 0;

                //    if (R < 0.75) {
                //        yVel = 1;
                //    }
                //    return yVel;
                //});

                // For restart
                //C.RestartInfo = new Tuple<Guid, TimestepNumber>(new Guid("8f5cfed9-31c7-4be8-aa56-e92e5348e08b"), 95);
                //C.GridGuid = new Guid("71ffc0c4-66aa-4762-b07e-45385f34b03f");

                // Physical Parameters
                // ===================


                C.PhysicalParameters.IncludeConvection = true;


                // misc. solver options
                // ====================

                C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2;

                C.LevelSetSmoothing = false;
                //C.option_solver = "direct";
                C.MaxKrylovDim             = 20;
                C.MaxSolverIterations      = 50;
                C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite;
                C.NoOfMultigridLevels      = 0;

                // Timestepping
                // ============

                C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.ImplicitEuler;
                double dt = 0.05;
                C.dtMax         = dt;
                C.dtMin         = dt;
                C.Endtime       = 70;
                C.NoOfTimesteps = 1000000;

                // haben fertig...
                // ===============

                R.Add(C);
            }

            return(R.ToArray());
        }
示例#18
0
        /// <summary>
        /// ctor.
        /// </summary>
        public NECQuadratureVolume(IGridData context,
                                   SpatialOperator DiffOp,
                                   IList <DGField> _DomainFields,
                                   IList <DGField> _ParameterFields,
                                   UnsetteledCoordinateMapping CodomainMapping,
                                   ICompositeQuadRule <QuadRule> domNrule)
            : base(context, DiffOp, _DomainFields, _ParameterFields, CodomainMapping)
        {
            // -----------------
            // quadrature object
            // -----------------

            m_Quad = CellQuadrature.GetQuadrature2(new int[] { CodomainMapping.NoOfCoordinatesPerCell }, context, domNrule,
                                                   this.EvaluateEx,
                                                   this.SaveIntegrationResults,
                                                   this.AllocateBuffers);

            int Gamma = _DomainFields.Count;

            // ------------------------
            // sort equation components
            // ------------------------

            m_NonlinSources = EquationComponentArgMapping <INonlinearSource> .GetArgMapping(DiffOp, true);

            m_NonlinFormV = EquationComponentArgMapping <INonlinVolumeForm_V> .GetArgMapping(DiffOp, true,
                                                                                             eq => ((eq.VolTerms & (TermActivationFlags.V | TermActivationFlags.UxV | TermActivationFlags.GradUxV)) != 0),
                                                                                             eq => (eq is IVolumeForm ? new NonlinVolumeFormVectorizer((IVolumeForm)eq) : null));

            m_NonlinFormGradV = EquationComponentArgMapping <INonlinVolumeForm_GradV> .GetArgMapping(DiffOp, true,
                                                                                                     eq => ((eq.VolTerms & (TermActivationFlags.UxGradV | TermActivationFlags.GradV | TermActivationFlags.GradUxGradV)) != 0),
                                                                                                     eq => (eq is IVolumeForm ? new NonlinVolumeFormVectorizer((IVolumeForm)eq) : null));

            Debug.Assert(base.m_DomainFields.Length >= Gamma);
            m_ValueRequired    = new bool[base.m_DomainFields.Length];
            m_GradientRequired = new bool[Gamma];

            // base.m_DomainFields may also contain parameter fields:
            for (int i = Gamma; i < base.m_DomainFields.Length; i++)
            {
                m_ValueRequired[i] = true;
            }

            this.m_NonlinFormV.DetermineReqFields(m_GradientRequired,
                                                  comp => ((comp.VolTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0));
            this.m_NonlinFormGradV.DetermineReqFields(m_GradientRequired,
                                                      comp => ((comp.VolTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0));
            this.m_NonlinFormV.DetermineReqFields(m_ValueRequired,
                                                  comp => ((comp.VolTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0));
            this.m_NonlinFormGradV.DetermineReqFields(m_ValueRequired,
                                                      comp => ((comp.VolTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0));
            this.m_NonlinSources.DetermineReqFields(m_ValueRequired, comp => true);
            base.m_NonlinFluxes.DetermineReqFields(m_ValueRequired, comp => true);
            base.m_NonlinFluxesEx.DetermineReqFields(m_ValueRequired, comp => true);

            // ---------
            // profiling
            // ---------

            var _CustomTimers       = new Stopwatch[] { new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch() };
            var _CustomTimers_Names = new string[] { "Flux-Eval", "Basis-Eval", "Field-Eval", "Loops", "ParametersAndNormals", "Flux-Trafo" };

            Flux_Eval                       = _CustomTimers[0];
            Flux_Trafo                      = _CustomTimers[5];
            Field_Eval                      = _CustomTimers[2];
            Basis_Eval                      = _CustomTimers[1];
            Loops                           = _CustomTimers[3];
            ParametersAndNormals            = _CustomTimers[4];
            m_Quad.CustomTimers             = m_Quad.CustomTimers.Cat(_CustomTimers);
            m_Quad.CustomTimers_Names       = m_Quad.CustomTimers_Names.Cat(_CustomTimers_Names);
            m_Quad.CustomTimers_RootPointer = new int[_CustomTimers_Names.Length];
            ArrayTools.SetAll(m_Quad.CustomTimers_RootPointer, -1);

            this.m_NonlinSources_watch   = this.m_NonlinSources.InitStopWatches(0, m_Quad);
            this.m_NonlinFormV_watch     = this.m_NonlinFormV.InitStopWatches(0, m_Quad);
            this.m_NonlinFormGradV_watch = this.m_NonlinFormGradV.InitStopWatches(0, m_Quad);
            base.m_NonlinFluxesWatches   = base.m_NonlinFluxes.InitStopWatches(0, m_Quad);
            base.m_NonlinFluxesExWatches = base.m_NonlinFluxesEx.InitStopWatches(0, m_Quad);

            // ---------------------
            // alloc multidim arrays
            // ---------------------

            m_FluxValues    = new MultidimensionalArray[m_CodomainBasisS.Length];
            m_FluxValuesTrf = new MultidimensionalArray[m_CodomainBasisS.Length];
            for (int i = 0; i < m_FluxValues.Length; i++)
            {
                if (m_NonlinFluxes[i].m_AllComponentsOfMyType.Length > 0 || m_NonlinFluxesEx[i].m_AllComponentsOfMyType.Length > 0 || m_NonlinFormGradV[i].m_AllComponentsOfMyType.Length > 0)
                {
                    m_FluxValues[i]    = new MultidimensionalArray(3);
                    m_FluxValuesTrf[i] = new MultidimensionalArray(3);

                    Basis GradBasis = base.m_CodomainBasisS[i];
                    if (m_MaxCodBasis_Gradient == null || m_MaxCodBasis_Gradient.Degree < GradBasis.Degree)
                    {
                        m_MaxCodBasis_Gradient = GradBasis;
                    }
                }
            }

            m_SourceValues = new MultidimensionalArray[m_CodomainBasisS.Length];
            for (int i = 0; i < m_SourceValues.Length; i++)
            {
                if (m_NonlinSources[i].m_AllComponentsOfMyType.Length > 0 || m_NonlinFormV[i].m_AllComponentsOfMyType.Length > 0)
                {
                    m_SourceValues[i] = new MultidimensionalArray(2);

                    Basis ValBasis = base.m_CodomainBasisS[i];
                    if (m_MaxCodBasis == null || m_MaxCodBasis.Degree < ValBasis.Degree)
                    {
                        m_MaxCodBasis = ValBasis;
                    }
                }
            }


            m_FieldValues    = new MultidimensionalArray[m_DomainFields.Length];
            m_FieldGradients = new MultidimensionalArray[Gamma];
            for (int i = 0; i < m_DomainFields.Length; i++)
            {
                if (m_ValueRequired[i])
                {
                    m_FieldValues[i] = new MultidimensionalArray(2);
                }
                if (i < Gamma && m_GradientRequired[i])
                {
                    m_FieldGradients[i] = new MultidimensionalArray(3);
                }
            }


            m_TestFuncWeighted     = new MultidimensionalArray(2);
            m_TestFuncGradWeighted = new MultidimensionalArray(3);
        }
示例#19
0
        static void InfoRecursive(object obj, int RecursionDepth, int MaxRecursionDepth)
        {
            if (obj == null)
            {
                Console.WriteLine("Null");
                return;
            }

            if (RecursionDepth > MaxRecursionDepth)
            {
                Console.WriteLine(" ... no further recursion - max recursion depth reached.");
                return;
            }

            Type objT = obj.GetType();

            if ((objT.IsPrimitive || objT.IsEnum || objT == typeof(string)))
            {
                Console.WriteLine(obj.ToString() + " (" + objT.Name + ")");
                return;
            }

            if (objT.IsSubclassOf(typeof(System.Delegate)))
            {
                // unable to log delegates
                Console.WriteLine("Delegate");
                return;
            }

            void WriteSpaces()
            {
                //Console.WriteLine();
                for (int i = 0; i < RecursionDepth; i++)
                {
                    Console.Write(" ");
                }
            }

            if (obj is System.Collections.IEnumerable)
            {
                System.Collections.IEnumerable objEnu = (System.Collections.IEnumerable)obj;
                int cnt = 0;
                foreach (var objE in objEnu)
                {
                    WriteSpaces();
                    Console.Write("[{0}]: ", cnt);
                    cnt++;
                    InfoRecursive(objE, RecursionDepth + 1, MaxRecursionDepth);
                }
                return;
            }

            BindingFlags biFlags = BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty;

            MemberInfo[] PIs = objT.GetProperties(biFlags);
            MemberInfo[] FIs = objT.GetFields(biFlags);

            foreach (MemberInfo mi in ArrayTools.Cat(PIs, FIs))
            {
                WriteSpaces();
                Console.Write(mi.Name + ": ");

                object Val;
                if (mi is PropertyInfo)
                {
                    PropertyInfo pi = ((PropertyInfo)mi);
                    if (!pi.CanRead)
                    {
                        Console.WriteLine("cannot read.");
                        continue;
                    }
                    if (pi.GetIndexParameters() != null && pi.GetIndexParameters().Length > 0)
                    {
                        // no support for indexed properties.
                        Console.WriteLine("indexed property - not supported.");
                        continue;
                    }

                    //pi.GetIndexParameters
                    try {
                        Val = pi.GetValue(obj, biFlags, null, null, null);
                    } catch (TargetInvocationException tie) {
                        Console.WriteLine(tie.GetType().Name + ": " + tie.Message);
                        continue;
                    }
                }
                else if (mi is FieldInfo)
                {
                    Val = ((FieldInfo)mi).GetValue(obj);
                }
                else
                {
                    Console.WriteLine("unsupported member type: " + mi.GetType().FullName + ".");
                    continue;
                }

                InfoRecursive(Val, RecursionDepth + 1, MaxRecursionDepth);
            }
        }
示例#20
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="OpMatrix"></param>
        /// <param name="OpAffine"></param>
        /// <param name="RowMapping"></param>
        /// <param name="ColMapping"></param>
        /// <param name="CurrentState"></param>
        /// <param name="AgglomeratedCellLengthScales"></param>
        /// <param name="time"></param>
        /// <param name="CutCellQuadOrder"></param>
        /// <param name="SurfaceForce"></param>
        /// <param name="LevelSetGradient"></param>
        /// <param name="ExternalyProvidedCurvature"></param>
        public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine,
                                       UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
                                       IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time,
                                       int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce,
                                       VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature) where T : DGField
        {
            // checks:
            if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            int D = this.LsTrk.GridDat.SpatialDimension;

            if (CurrentState != null && CurrentState.Count() != (D + 1))
            {
                throw new ArgumentException();
            }

            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }

            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }



            // advanced settings for the navier slip boundary condition
            // ========================================================

            CellMask SlipArea;

            switch (this.dntParams.GNBC_Localization)
            {
            case NavierSlip_Localization.Bulk: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask;
                break;
            }

            case NavierSlip_Localization.ContactLine: {
                SlipArea = null;
                break;
            }

            case NavierSlip_Localization.Nearband: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth));
                break;
            }

            case NavierSlip_Localization.Prescribed: {
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentException();
            }


            MultidimensionalArray SlipLengths;

            SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs();
            SlipLengths.Clear();
            //SlipLengths.AccConstant(-1.0);
            if (SlipArea != null)
            {
                foreach (Chunk cnk in SlipArea)
                {
                    for (int i = cnk.i0; i < cnk.JE; i++)
                    {
                        switch (this.dntParams.GNBC_SlipLength)
                        {
                        case NavierSlip_SlipLength.hmin_DG: {
                            int degU = ColMapping.BasisS.ToArray()[0].Degree;
                            SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1);
                            break;
                        }

                        case NavierSlip_SlipLength.hmin_Grid: {
                            SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i];
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_SlipLength: {
                            SlipLengths[i] = this.physParams.sliplength;
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_Beta: {
                            SlipLengths[i] = -1.0;
                            break;
                        }
                        }
                    }
                }
            }


            // parameter assembly
            // ==================

            LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]);

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();

            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;

            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }

            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(this.LsTrk, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }

            // Temperature gradient for evaporation
            //VectorField<DGField> GradTemp = new VectorField<DGField>(D, new XDGBasis(LsTrk, 0), XDGField.Factory);
            //if (CoupledCurrentState != null) {
            //    DGField Temp = CoupledCurrentState.ToArray()[0];
            //    GradTemp = new VectorField<DGField>(D, Temp.Basis, "GradTemp", XDGField.Factory);
            //    XNSEUtils.ComputeGradientForParam(Temp, GradTemp, this.LsTrk);
            //}

            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                Normals,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]));

            // linearization velocity:
            if (this.U0meanrequired)
            {
                VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }
            }



            // assemble the matrix & affine vector
            // ===================================

            IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea;

            // compute matrix
            if (OpMatrix != null)
            {
                XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                mtxBuilder.time = time;

                mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);
            }
            else
            {
                XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk,
                                                                                      CurrentState.ToArray(), Params, RowMapping,
                                                                                      SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);
            }
        }
示例#21
0
        private void BuildNeighborship(int[][] AggregationCells)
        {
            IGridData pGrid      = ParentGrid;
            int       j0Coarse   = CellPartitioning.i0;
            int       JlocCoarse = CellPartitioning.LocalLength;
            int       JElocFine  = pGrid.iLogicalCells.Count;
            int       JlocFine   = pGrid.iLogicalCells.NoOfLocalUpdatedCells;

            // compute fine-to-coarse mapping
            // ==============================

            int[] Fine2CoarseGlobal = new int[JElocFine]; // index: local cell index on fine grid; maps to _global_ cell index on coarse grid.
            {
                ArrayTools.SetAll(Fine2CoarseGlobal, -111);
                for (int jCellCoarse = 0; jCellCoarse < JlocCoarse; jCellCoarse++)
                {
                    foreach (int jCellFine in AggregationCells[jCellCoarse])
                    {
                        if (jCellFine < 0 || jCellFine >= JlocFine)
                        {
                            throw new ArgumentOutOfRangeException();
                        }
                        Fine2CoarseGlobal[jCellFine] = jCellCoarse + j0Coarse;
                    }
                }


                Fine2CoarseGlobal.MPIExchange <int[], int>(pGrid);
            }

            // define external coarse cells
            // ============================
            int JElocCoarse;
            {
                HashSet <long> tmpCoarseExternal = new HashSet <long>();
                for (int jF = JlocFine; jF < JElocFine; jF++)
                {
                    tmpCoarseExternal.Add(Fine2CoarseGlobal[jF]);
                }

                long[] ExtGlbIdx = tmpCoarseExternal.ToArray();
                Array.Sort(ExtGlbIdx); // since the send lists are ascending, the external cells also should be ascending;
                //                        since the MPI rank only increases with the global cell index, this sort-operation also guarantees
                //                        that the external cells are sorted according to MPI rank.
                m_Parallel.GlobalIndicesExternalCells = ExtGlbIdx;
                JElocCoarse = JlocCoarse + ExtGlbIdx.Length;

                // global-to-local index mapping:
                Dictionary <long, int> GlobalIdx2Local = new Dictionary <long, int>();
                for (int jC = JlocCoarse; jC < JElocCoarse; jC++)
                {
                    GlobalIdx2Local.Add(ExtGlbIdx[jC - JlocCoarse], jC);
                }
                m_Parallel.Global2LocalIdx = GlobalIdx2Local;
            }

            // fine-to-coarse, coarse-to-fine mapping in local indices
            // ========================================================
            {
                // fine-to-coarse
                this.jCellFine2jCellCoarse = new int[JElocFine];
                var F2C = jCellFine2jCellCoarse;

                for (int jF = 0; jF < JElocFine; jF++)   // loop over fine cells...
                {
                    int jCoarse;
                    if (jF < JlocFine)
                    {
                        jCoarse = Fine2CoarseGlobal[jF] - j0Coarse;
                        Debug.Assert(jCoarse >= 0);
                        Debug.Assert(jCoarse < JlocCoarse);
                    }
                    else
                    {
                        jCoarse = m_Parallel.Global2LocalIdx[Fine2CoarseGlobal[jF]];
                        Debug.Assert(jCoarse >= JlocCoarse);
                        Debug.Assert(jCoarse < JElocCoarse);
                    }

                    F2C[jF] = jCoarse;
                }

                // coarse-to-fine mapping
                this.jCellCoarse2jCellFine = new int[JElocCoarse][];
                var C2F    = jCellCoarse2jCellFine;
                var tmpC2F = new List <int> [JElocCoarse];
                for (int jC = 0; jC < JElocCoarse; jC++)
                {
                    tmpC2F[jC] = new List <int>();
                }
                for (int jFine = 0; jFine < JElocFine; jFine++)
                {
                    int jCoarse = F2C[jFine];
                    Debug.Assert(!tmpC2F[jCoarse].Contains(jFine));
                    tmpC2F[jCoarse].Add(jFine);
                }
                for (int jC = 0; jC < JElocCoarse; jC++)
                {
                    C2F[jC] = tmpC2F[jC].ToArray();
                }
            }

            // define neighborship
            // ===================
            {
                int[][] FineClNeigh = pGrid.iLogicalCells.CellNeighbours;

                HashSet <int>[]        tmpClNeig = new HashSet <int> [JlocCoarse];
                Dictionary <long, int> ExtCells_GlobalIdx2Local = m_Parallel.Global2LocalIdx;


                for (int jCellCoarse = 0; jCellCoarse < JlocCoarse; jCellCoarse++)   // loop over all coarse grid cells...
                {
                    foreach (int jCellFine in AggregationCells[jCellCoarse])
                    {
                        int[] FineNeighs = FineClNeigh[jCellFine];
                        foreach (int jCellFineNeigh in FineNeighs)                        // loop over all neighbor cells in the fine grid...
                        {
                            int jCellCoarseNeighGlob = Fine2CoarseGlobal[jCellFineNeigh]; // map index of fine grid neighbor to coarse cell index

                            // convert global cell index to local
                            int jCellCoarseNeighLoc;
                            if (jCellCoarseNeighGlob >= j0Coarse && jCellCoarseNeighGlob <= (j0Coarse + JlocCoarse))
                            {
                                // Neighbor is a locally updated cell
                                jCellCoarseNeighLoc = jCellCoarseNeighGlob - j0Coarse;
                            }
                            else
                            {
                                // Neighbor is an external cell

                                jCellCoarseNeighLoc = ExtCells_GlobalIdx2Local[jCellCoarseNeighGlob];
                            }

                            // add neighbor cell
                            if (jCellCoarse != jCellCoarseNeighLoc)
                            {
                                if (tmpClNeig[jCellCoarse] == null)
                                {
                                    tmpClNeig[jCellCoarse] = new HashSet <int>();
                                }
                                tmpClNeig[jCellCoarse].Add(jCellCoarseNeighLoc);
                            }
                        }
                    }
                }

                m_LogicalCellData.CellNeighbours = new int[JlocCoarse][];
                var CN = m_LogicalCellData.CellNeighbours;
                for (int jCellCoarse = 0; jCellCoarse < JlocCoarse; jCellCoarse++)
                {
                    var hs = tmpClNeig[jCellCoarse];
                    Debug.Assert(hs == null || hs.Contains(jCellCoarse) == false);
                    if (hs != null)
                    {
                        int[] xx = new int[hs.Count];
                        CN[jCellCoarse] = xx;
                        int i = 0;
                        foreach (int x in hs)
                        {
                            xx[i] = x;
                            i++;
                        }
                    }
                    else
                    {
                        CN[jCellCoarse] = new int[0];
                    }
                    Debug.Assert(CN[jCellCoarse].Contains(jCellCoarse) == false);
                }
            }

            // MPI send lists
            // ==============
            int mpiSize = CellPartitioning.MpiSize;
            {
                m_Parallel.ProcessesToSendTo      = ParentGrid.iParallel.ProcessesToSendTo.CloneAs();
                m_Parallel.ProcessesToReceiveFrom = ParentGrid.iParallel.ProcessesToReceiveFrom.CloneAs();

                int[] F2C = this.jCellFine2jCellCoarse;

                m_Parallel.SendCommLists = new int[mpiSize][];
                var tmpSendList = new HashSet <int>();
                for (int rnk = 0; rnk < mpiSize; rnk++)
                {
                    int[] ParrentSendList = ParentGrid.iParallel.SendCommLists[rnk];
                    if (ParrentSendList != null && ParrentSendList.Length > 0)
                    {
                        tmpSendList.Clear();

                        foreach (int jFine in ParrentSendList)
                        {
                            Debug.Assert(jFine >= 0);
                            Debug.Assert(jFine < ParentGrid.iLogicalCells.NoOfLocalUpdatedCells);

                            int jCoarse = F2C[jFine];
                            Debug.Assert(jCoarse >= 0);
                            Debug.Assert(jCoarse < this.iLogicalCells.NoOfLocalUpdatedCells);

                            tmpSendList.Add(jCoarse);
                        }

                        m_Parallel.SendCommLists[rnk] = tmpSendList.ToArray();
                        Array.Sort(m_Parallel.SendCommLists[rnk]);
                    }
                }
            }

            // MPI receive lists
            // =================
            {
                //ParentGrid.iParallel.ProcessesToReceiveFrom
                var GlobalIdx = this.m_Parallel.GlobalIndicesExternalCells;

                this.m_Parallel.RcvCommListsNoOfItems   = new int[mpiSize];
                this.m_Parallel.RcvCommListsInsertIndex = new int[mpiSize];
                int[] NoOfItems = this.m_Parallel.RcvCommListsNoOfItems;
                int[] InsertIdx = this.m_Parallel.RcvCommListsInsertIndex;
                ArrayTools.SetAll(InsertIdx, -1);

#if DEBUG
                HashSet <int> ProcCheck = new HashSet <int>();
#endif

                for (int jC = JlocCoarse; jC < JElocCoarse; jC++)
                {
                    int jGlob = (int)GlobalIdx[jC - JlocCoarse];
                    int iProc = this.CellPartitioning.FindProcess(jGlob);
#if DEBUG
                    ProcCheck.Add(iProc);
#endif
                    if (InsertIdx[iProc] < 0)
                    {
                        InsertIdx[iProc] = jC;
                    }
                    else
                    {
                        Debug.Assert(jC > InsertIdx[iProc]);
                    }
                    NoOfItems[iProc]++;
                }

#if DEBUG
                Debug.Assert(this.iParallel.ProcessesToReceiveFrom.SetEquals(ProcCheck));
#endif
            }

            // MPI check
            // =========
#if DEBUG
            {
                int[] TestData = new int[JElocCoarse];
                for (int jC = 0; jC < JlocCoarse; jC++)
                {
                    int GlobalIdx;
                    GlobalIdx    = jC + j0Coarse;
                    TestData[jC] = GlobalIdx;
                }

                TestData.MPIExchange <int[], int>(this);

                for (int jC = 0; jC < JElocCoarse; jC++)
                {
                    int GlobalIdx;
                    if (jC < JlocCoarse)
                    {
                        GlobalIdx = jC + j0Coarse;
                    }
                    else
                    {
                        GlobalIdx = (int)(m_Parallel.GlobalIndicesExternalCells[jC - JlocCoarse]);
                    }

                    Debug.Assert(TestData[jC] == GlobalIdx);
                }
            }
#endif
        }
示例#22
0
        /// <summary>
        /// ctor for the operator factory, where the equation compnents are set
        /// </summary>
        /// <param name="config"></param>
        /// <param name="_LsTrk"></param>
        /// <param name="_HMFdegree"></param>
        /// <param name="BcMap"></param>
        /// <param name="degU"></param>
        public XNSE_OperatorFactory(IXNSE_Configuration config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, int degU)
        {
            this.LsTrk = _LsTrk;
            this.D     = _LsTrk.GridDat.SpatialDimension;

            this.HMFDegree = _HMFdegree;

            this.physParams = config.getPhysParams;
            this.dntParams  = config.getDntParams;


            // test input
            // ==========
            {
                if (config.getDomBlocks.GetLength(0) != 2 || config.getCodBlocks.GetLength(0) != 2)
                {
                    throw new ArgumentException();
                }

                if ((config.getPhysParams.mu_A <= 0) && (config.getPhysParams.mu_B <= 0))
                {
                    config.isViscous = false;
                }
                else
                {
                    if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0))
                    {
                        throw new ArgumentException();
                    }
                }

                if ((config.getPhysParams.rho_A <= 0) || (config.getPhysParams.rho_B <= 0))
                {
                    throw new ArgumentException();
                }

                if (_LsTrk.SpeciesNames.Count != 2)
                {
                    throw new ArgumentException();
                }
                if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B")))
                {
                    throw new ArgumentException();
                }
            }

            // full operator:
            // ==============
            CodName = ArrayTools.Cat(EquationNames.MomentumEquations(D), EquationNames.ContinuityEquation);
            Params  = ArrayTools.Cat(
                VariableNames.Velocity0Vector(D),
                VariableNames.Velocity0MeanVector(D),
                VariableNames.NormalVector(D),
                VariableNames.Curvature,
                VariableNames.SurfaceForceVector(D)
                );
            DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure);

            // selected part:
            if (config.getCodBlocks[0])
            {
                CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, D));
            }
            if (config.getCodBlocks[1])
            {
                CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D, 1));
            }

            if (config.getDomBlocks[0])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, D));
            }
            if (config.getDomBlocks[1])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D, 1));
            }


            // create Operator
            // ===============
            m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesIdS.ToArray());

            // add components
            // ==============

            // species bulk components
            for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++)
            {
                // Navier Stokes equations
                XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired);

                // continuity equation
                if (config.isContinuity)
                {
                    XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap);
                }
            }

            // interface components
            XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, D, BcMap, LsTrk);                                                          // surface stress tensor
            XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force

            if (config.isContinuity)
            {
                XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, D, LsTrk);       // continuity equation
            }
            m_XOp.Commit();
        }
示例#23
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="TargetMappingIndex"></param>
        /// <param name="outputPartitioning">
        /// Partitioning of the new grid, resp the return array.
        /// </param>
        /// <returns>
        /// - 1st index: cell index in new grid, correlates with <paramref name="outputPartitioning"/>.
        /// - 2nd index: enumeration over cells (in the old grid) which are combined in the new grid.
        ///   For cells with refinement, always one entry, for cells which are coarsened a greater number of entries.
        ///   If null, the cell is not changed.
        /// - content: Subdivision leaf index, correlates with 2nd index of <see cref="KrefS_SubdivLeaves"/>, can be used as an input to <see cref="GetSubdivBasisTransform(int, int, int)"/>.
        /// </returns>
        public int[][] GetTargetMappingIndex(IPartitioning outputPartitioning)
        {
            using (new FuncTrace()) {
                Debug.Assert(DestGlobalId.Length == MappingIndex.Length);
                Debug.Assert(OldGlobalId.Length == MappingIndex.Length);
                int oldJ = DestGlobalId.Length;

                // Caching
                // =======

                if (m_TargetMappingIndex != null)
                {
                    // caching
                    if (m_TargetMappingIndex.Length != outputPartitioning.LocalLength)
                    {
                        throw new ArgumentException("Length mismatch of output list and output partition.");
                    }

                    return(m_TargetMappingIndex);
                }

                // local evaluation, prepare communication
                // =======================================

                m_TargetMappingIndex = new int[outputPartitioning.LocalLength][];

                int j0Dest = outputPartitioning.i0;

                // keys: processors which should receive data from this processor
                Dictionary <int, GetTargetMapping_Helper> AllSendData = new Dictionary <int, GetTargetMapping_Helper>();

                for (int j = 0; j < oldJ; j++)
                {
                    int[] MappingIndex_j = MappingIndex[j];
                    if (MappingIndex_j != null)
                    {
                        Debug.Assert(TargetIdx[j].Length == MappingIndex_j.Length);
                        int L = MappingIndex_j.Length;

                        for (int l = 0; l < L; l++)
                        {
                            int jDest  = TargetIdx[j][l];
                            int MapIdx = MappingIndex_j[l];

                            if (outputPartitioning.IsInLocalRange(jDest))
                            {
                                int[] destCollection = m_TargetMappingIndex[jDest - j0Dest];
                                ArrayTools.AddToArray(MapIdx, ref destCollection);
                                m_TargetMappingIndex[jDest - j0Dest] = destCollection;
                            }
                            else
                            {
                                int targProc = outputPartitioning.FindProcess(jDest);

                                GetTargetMapping_Helper dataTargPrc;
                                if (!AllSendData.TryGetValue(targProc, out dataTargPrc))
                                {
                                    dataTargPrc = new GetTargetMapping_Helper();
                                    AllSendData.Add(targProc, dataTargPrc);
                                }

                                dataTargPrc.TargetIndices.Add(jDest);
                                dataTargPrc.Items.Add(MapIdx);
                            }
                        }
                    }
                    else
                    {
                        Debug.Assert(TargetIdx[j].Length == 1);
                    }
                }

                // communication
                // =============

                var AllRcvData = SerialisationMessenger.ExchangeData(AllSendData, outputPartitioning.MPI_Comm);

                foreach (var kv in AllRcvData)
                {
                    int rcvProc = kv.Key;
                    j0Dest = outputPartitioning.GetI0Offest(rcvProc);

                    var TIdxs = kv.Value.TargetIndices;
                    var TVals = kv.Value.Items;
                    Debug.Assert(TIdxs.Count == TVals.Count);
                    int L = TIdxs.Count;

                    for (int l = 0; l < L; l++)
                    {
                        int idx = TIdxs[l] - j0Dest;
                        Debug.Assert(outputPartitioning.IsInLocalRange(idx));

                        int[] destCollection = m_TargetMappingIndex[idx];
                        ArrayTools.AddToArray(TVals[idx], ref destCollection);
                        m_TargetMappingIndex[idx] = destCollection;
                    }
                }

                // return
                // ======

                return(m_TargetMappingIndex);
            }
        }
示例#24
0
        /// <summary>
        /// Computes a mapping from the new, cell local DG coordinate index to the previous/old DG coordinate index, or vice-versa.
        /// </summary>
        /// <param name="jCell">
        /// Local cell index.
        /// </param>
        /// <param name="New2Old">
        /// If true, a mapping from new species index to previous/old species index is returned,
        /// if false the other way around.
        /// </param>
        /// <param name="LsTrk">
        /// </param>
        /// <param name="Map">
        /// DG coordinate mapping.
        /// </param>
        /// <returns>
        /// Null, if there is no change in species ordering in cell <paramref name="jCell"/>
        /// from the previous level-set tracker state to the actual.
        ///
        /// Otherwise, if <paramref name="New2Old"/> is true, an array of the same length
        /// as the number of degrees-of-freedom currently in cell <paramref name="jCell"/>.
        ///  - index: current DOF index in cell <paramref name="jCell"/>.
        ///  - content: index of this DOF with respect to the previous level-set-tracker state.
        /// If <paramref name="New2Old"/> false, the other way around.
        /// </returns>
        public static int[] MappingUpdate(LevelSetTracker LsTrk, int jCell, UnsetteledCoordinateMapping Map, bool New2Old)
        {
            int[] SpeciesMap = SpeciesUpdate(LsTrk, jCell, New2Old);
            if (SpeciesMap == null)
            {
                return(null);
            }

            int NoVar = Map.NoOfVariables;

            XDGBasis[] XBasiseS = new XDGBasis[NoVar];
            Basis[]    BasiseS  = new Basis[NoVar];
            int[]      Ns       = new int[NoVar];

            for (int iVar = 0; iVar < NoVar; iVar++)
            {
                Basis b = Map.BasisS[iVar];
                XBasiseS[iVar] = b as XDGBasis;
                if (XBasiseS[iVar] != null)
                {
                    BasiseS[iVar] = XBasiseS[iVar].NonX_Basis;
                }
                else
                {
                    BasiseS[iVar] = b;
                }
                Ns[iVar] = BasiseS[iVar].Length;
            }

            //List<int> oldIdx = new List<int>();
            //List<int> newIdx = new List<int>();
            int[] IdxMap = new int[Map.MaxTotalNoOfCoordinatesPerCell];
            ArrayTools.SetAll(IdxMap, int.MinValue);

            bool AnyRelocation = false;

            int i0 = Map.LocalUniqueCoordinateIndex(0, jCell, 0);

            for (int iVar = 0; iVar < NoVar; iVar++)
            {
                int i0Var  = Map.LocalUniqueCoordinateIndex(iVar, jCell, 0);
                int N      = Ns[iVar];
                int offset = i0Var - i0;

                if (XBasiseS[iVar] != null)
                {
                    // XDG-field

                    for (int i = 0; i < SpeciesMap.Length; i++)
                    {
                        int ii = SpeciesMap[i];
                        for (int n = 0; n < N; n++)
                        {
                            int idxS = offset + n + i * N;
                            int idxT = ii >= 0 ? offset + n + ii * N : int.MinValue;
                            Debug.Assert(IdxMap[idxS] < 0);
                            IdxMap[idxS] = idxT;

                            AnyRelocation |= (idxS != idxT);
                        }
                    }
                }
                else
                {
                    // single-phase-field
                    for (int n = 0; n < N; n++)
                    {
                        int idx = offset + n;
                        //oldIdx.Add(idx);
                        //newIdx.Add(idx);
                        Debug.Assert(IdxMap[idx] < 0);
                        IdxMap[idx] = idx;
                    }
                }
            }

            return(IdxMap);
            //if (AnyRelocation)
            //    return IdxMap;
            //else
            //    return null;
        }
示例#25
0
 /// <summary>
 /// Usual plotting
 /// </summary>
 protected override void PlotCurrentState(double physTime, TimestepNumber timestepNo, int superSampling = 0)
 {
     Tecplot.PlotFields(
         ArrayTools.Cat <DGField>(f1Gradient_Analytical, f1Gradient_Numerical, f1, GridData.BoundaryMark(), Laplace_f1_Numerical, Laplace_f2_Numerical),
         "derivatives", 0.0, superSampling);
 }
示例#26
0
        /// <summary>
        /// One Iteration of the ReInitialization
        /// Operators must be built first
        /// </summary>
        /// <param name="ChangeRate">
        /// L2-Norm of the Change-Rate in the level set in this reinit step
        /// </param>
        /// <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>
        /// <returns></returns>
        public void ReInitSingleStep(out double ChangeRate, SubGrid Restriction = null, bool IncludingInterface = true)
        {
            if (!IncludingInterface)
            {
                throw new NotImplementedException("Untested, not yet functional!");
            }

            using (new FuncTrace()) {
                /// Init Residuals
                Residual.Clear();
                Residual.Acc(1.0, Phi);
                OldPhi.Clear();
                OldPhi.Acc(1.0, Phi);
                NewPhi.Clear();
                NewPhi.Acc(1.0, Phi);

                CellMask RestrictionMask = Restriction == null ? null : Restriction.VolumeMask;


                //if (Control.Upwinding && UpdateDirection && IterationCounter % 10 == 0) {

                if (false && Control.Upwinding && UpdateDirection)
                {
                    //if (Control.Upwinding && UpdateDirection) {
                    UpdateBulkMatrix(Restriction);
                }

                UpdateDirection = false;
                // RHS part
                RHSField.CoordinateVector.Clear();
                //Operator_RHS.Evaluate(NewPhi.Mapping, RHSField.Mapping);
                Operator_RHS.Evaluate(double.NaN, IncludingInterface ? Restriction : null, IncludingInterface ? SubGridBoundaryModes.BoundaryEdge : SubGridBoundaryModes.InnerEdge, ArrayTools.Cat(new DGField[] { Phi }, parameterFields, new DGField[] { RHSField }));
#if DEBUG
                RHSField.CheckForNanOrInf();
#endif
                // solve
                // =====
                double[] RHS = OpAffine.CloneAs();
                RHS.ScaleV(-1.0);
                RHS.AccV(1.0, RHSField.CoordinateVector);


                SolverResult Result;
                if (Restriction != null)
                {
                    SubRHS.Clear();
                    SubSolution.Clear();

                    SubRHS.AccV(1.0, RHS, default(int[]), SubVecIdx);
                    SubSolution.AccV(1.0, NewPhi.CoordinateVector, default(int[]), SubVecIdx);

                    Result = slv.Solve(SubSolution, SubRHS);

                    NewPhi.Clear(RestrictionMask);
                    NewPhi.CoordinateVector.AccV(1.0, SubSolution, SubVecIdx, default(int[]));
                }
                else
                {
                    Result = slv.Solve(NewPhi.CoordinateVector, RHS);
                }
#if Debug
                OpMatrix.SpMV(-1.0, NewPhi.CoordinateVector, 1.0, RHS);
                Console.WriteLine("LinearSolver: {0} Iterations, Converged={1}, Residual = {2} ", Result.NoOfIterations, Result.Converged, RHS.L2Norm());
#endif



                // Apply underrelaxation

                Phi.Clear(RestrictionMask);
                Phi.Acc(1 - underrelaxation, OldPhi, RestrictionMask);
                Phi.Acc(underrelaxation, NewPhi, RestrictionMask);
                Residual.Acc(-1.0, Phi, RestrictionMask);
                ChangeRate = Residual.L2Norm(RestrictionMask);


                //Calculate
                LevelSetGradient.Clear();
                LevelSetGradient.Gradient(1.0, Phi, RestrictionMask);
                //LevelSetGradient.GradientByFlux(1.0, Phi);
                MeanLevelSetGradient.Clear();
                MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient, RestrictionMask);

                if (Control.Upwinding)
                {
                    //RestrictionMask.GetBitMask();
                    for (int i = 0; i < MeanLevelSetGradient.CoordinateVector.Length; i++)
                    {
                        NewDirection[i] = Math.Sign(MeanLevelSetGradient.CoordinateVector[i]);
                        //NewDirection[i] = MeanLevelSetGradient.CoordinateVector[i];
                        OldDirection[i] -= NewDirection[i];
                    }

                    double MaxDiff = OldDirection.L2Norm();
                    //if (MaxDiff > 1E-20 && IterationCounter % 10 == 0 ) {
                    //if (MaxDiff > 1E-20) {
                    //    Console.WriteLine("Direction Values differ by {0}", MaxDiff);
                    if (MaxDiff > 0.2)
                    {
                        //UpdateDirection = true;
                        //Console.WriteLine("Direction Values differ by {0} => Updating ReInit-Matrix", MaxDiff);
                    }
                    ;
                    //}

                    //Console.WriteLine("HACK!!! Updating Upwind Matrix everytime!");
                    //UpdateDirection = true;

                    // Reset Value
                    OldDirection.Clear();
                    OldDirection.AccV(1.0, NewDirection);
                }
            }
        }
示例#27
0
        public static IBM_Control IBMCylinderFlow(string _DbPath = null, int k = 2, bool xPeriodic = false, double VelXBase = 0.0)
        {
            IBM_Control C = new IBM_Control();

            const double BaseSize = 1.0;

            // basic database options
            // ====================

            C.savetodb           = false;
            C.ProjectDescription = "Cylinder";
            C.Tags.Add("with immersed boundary method");

            // DG degrees
            // ==========

            C.FieldOptions.Add("VelocityX", new FieldOpts()
            {
                Degree   = k,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("VelocityY", new FieldOpts()
            {
                Degree   = k,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Pressure", new FieldOpts()
            {
                Degree   = k - 1,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("PhiDG", new FieldOpts()
            {
                Degree   = 2,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Phi", new FieldOpts()
            {
                Degree   = 2,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });

            // grid and boundary conditions
            // ============================

            C.GridFunc = delegate {
                var _xNodes1 = Grid1D.TanhSpacing(0, 1, 5, 1, false);
                _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1));
                var _xNodes2 = GenericBlas.Linspace(1, 5.5, 35);
                _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1));
                var _xNodes3 = Grid1D.TanhSpacing(5.5, 22, 20, 1.3, true);

                var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3);


                var _yNodes1 = Grid1D.TanhSpacing(0, 1, 5, 1.2, false);
                _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1));
                var _yNodes2 = GenericBlas.Linspace(1, 3, 20);
                _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1));
                var _yNodes3 = Grid1D.TanhSpacing(3, 4.1, 5, 1.2, true);

                var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3);

                var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic);
                grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper");
                grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower");
                if (!xPeriodic)
                {
                    grd.EdgeTagNames.Add(3, "Velocity_Inlet_left");
                    grd.EdgeTagNames.Add(4, "Pressure_Outlet_right");
                }

                grd.DefineEdgeTags(delegate(double[] X) {
                    byte et = 0;
                    if (Math.Abs(X[1] - (0 * BaseSize)) <= 1.0e-8)
                    {
                        et = 1;
                    }
                    if (Math.Abs(X[1] + (-4.1 * BaseSize)) <= 1.0e-8)
                    {
                        et = 2;
                    }
                    if (!xPeriodic && Math.Abs(X[0] - (0 * BaseSize)) <= 1.0e-8)
                    {
                        et = 3;
                    }
                    if (!xPeriodic && Math.Abs(X[0] + (-22 * BaseSize)) <= 1.0e-8)
                    {
                        et = 4;
                    }


                    Debug.Assert(et != 0);
                    return(et);
                });

                return(grd);
            };

            C.AddBoundaryCondition("Velocity_Inlet_upper", "VelocityX", X => 0);
            C.AddBoundaryCondition("Velocity_Inlet_lower", "VelocityX", X => 0);
            if (!xPeriodic)
            {
                C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX", X => (4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1)));
            }
            C.AddBoundaryCondition("Pressure_Outlet_right");

            // Initial Values
            // ==============

            C.particleRadius = 0.5;

            C.InitialValues_Evaluators.Add("Phi", X => - (X[0] - 2).Pow2() + -(X[1] - 2).Pow2() + C.particleRadius.Pow2());


            C.InitialValues_Evaluators.Add("VelocityX", X => 0);


            // Physical Parameters
            // ===================

            C.PhysicalParameters.mu_A  = 0.05;
            C.PhysicalParameters.rho_A = 1;

            C.PhysicalParameters.IncludeConvection = true;
            C.PhysicalParameters.Material          = true;

            // misc. solver options
            // ====================

            C.AdvancedDiscretizationOptions.PenaltySafety = 1;
            C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.1;
            C.LevelSetSmoothing        = false;
            C.MaxKrylovDim             = 20;
            C.MaxSolverIterations      = 100;
            C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite;
            C.NoOfMultigridLevels      = 1;

            // Timestepping
            // ============

            C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2;
            double dt = 1E20;

            C.dtFixed       = dt;
            C.dtMax         = dt;
            C.dtMin         = dt;
            C.Endtime       = 200;
            C.NoOfTimesteps = 1;

            // haben fertig...
            // ===============

            return(C);
        }
示例#28
0
        /// <summary>
        /// Based on the Ideas by
        /// C. Basting and D. Kuzmin,
        /// “A minimization-based finite element formulation for interface-preserving level set reinitialization”,
        /// Computing, vol. 95, no. 1, pp. 13–25, Dec. 2012.
        /// Create Spatial Operators and build the corresponding Matrices
        /// For the Left-Hand Side of the ReInitProblem
        /// RHS is computed on the fly in <see cref="ReInitSingleStep"/>
        /// The Bulk component is constant unless the grid changes, thus it is computed in <see cref="BuildOperators(CellQuadratureScheme)"/>.
        /// The Interface component changes with its motion.
        /// This component is calculated in <see cref="UpdateOperators(CellQuadratureScheme)"/>.
        /// </summary>
        /// <param name="LSTrck"></param>
        /// <param name="Control">various parameters <paramref name="EllipticReinitControl"/></param>
        /// <param name="HMFOrder">order of tghe interface quadrature</param>
        public EllipticReInit(LevelSetTracker LSTrck, EllipticReInitAlgoControl Control, SinglePhaseField LevelSetForReInit = null)
        {
            this.Control         = Control;
            this.LevelSetTracker = LSTrck;
            if (LevelSetForReInit == null)
            {
                Phi = LevelSetTracker.LevelSets[0] as SinglePhaseField;
            }
            else
            {
                Phi = LevelSetForReInit;
            }
            this.underrelaxation = Control.underrelaxation;

            Residual = new SinglePhaseField(Phi.Basis);
            OldPhi   = new SinglePhaseField(Phi.Basis);
            NewPhi   = new SinglePhaseField(Phi.Basis);
            foreach (SinglePhaseField f in new List <SinglePhaseField> {
                Residual, OldPhi, NewPhi
            })
            {
                f.Clear();
                f.Acc(1.0, Phi);
            }


            this.D = LevelSetTracker.GridDat.SpatialDimension;

            this.ConvergenceCriterion = Control.ConvergenceCriterion;
            this.MaxIteration         = Control.MaxIt;

            double PenaltyBase = ((double)((Phi.Basis.Degree + 1) * (Phi.Basis.Degree + D))) / ((double)D);


            // Choose Forms according to Upwinding or Central Fluxes
            string[] paramNames;
            int      noOfParamFields;

            IEquationComponent BulkForm;
            RHSForm            myRHSForm;

            LevelSetGradient     = new VectorField <SinglePhaseField>(D, Phi.Basis, "LevelSetGradient", SinglePhaseField.Factory);
            MeanLevelSetGradient = new VectorField <SinglePhaseField>(D, new Basis(Phi.GridDat, 0), "MeanLevelSetGradient", SinglePhaseField.Factory);

            if (Control.Upwinding)
            {
                paramNames      = new string[] { "OldLevelSet", "MeanLevelSetGradient[0]", "MeanLevelSetGradient[1]" };
                noOfParamFields = D;
                LevelSetGradient.Clear();
                LevelSetGradient.Gradient(1.0, Phi);
                //LevelSetGradient.GradientByFlux(1.0, Phi);
                MeanLevelSetGradient.Clear();
                MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient);

                parameterFields = ArrayTools.Cat(new SinglePhaseField[] { OldPhi }, MeanLevelSetGradient.ToArray());
                //throw new NotImplementedException("ToDO");
                BulkForm  = new EllipticReInitUpwindForm_Laplace(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck);
                myRHSForm = new EllipticReInitUpwindForm_RHS(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck);

                OldDirection = new double[MeanLevelSetGradient.CoordinateVector.ToArray().Length];
                for (int i = 0; i < MeanLevelSetGradient.CoordinateVector.Length; i++)
                {
                    OldDirection[i] = Math.Sign(MeanLevelSetGradient.CoordinateVector[i]);
                }
                NewDirection = OldDirection.CloneAs();
            }
            else
            {
                paramNames      = new string[] { };
                noOfParamFields = 0;
                parameterFields = new SinglePhaseField[] { };
                BulkForm        = new CentralDifferencesLHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck.GridDat.Cells.cj);
                myRHSForm       = new CentralDifferencesRHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck);
            }


            // SIP for the bulk Phase
            //this.Operator_bulk = new SpatialOperator(1, noOfParamFields, 1, QuadOrderFunc.SumOfMaxDegrees(1, RoundUp: false), variableNames);
            this.Operator_bulk = BulkForm.Operator();



            // Zero at the Interface
            // Calculate Quadrature Order
            Func <int[], int[], int[], int> InterfaceQuadOrder;

            InterfaceQuadOrder = QuadOrderFunc.FixedOrder(Phi.Basis.Degree * 2 + 2);

            // Generate Interface Operator
            this.Operator_interface = (new EllipticReInitInterfaceForm(Control.PenaltyMultiplierInterface * PenaltyBase, LSTrck)).XOperator(new[] { "A" }, InterfaceQuadOrder);

            // Nonlinear Part on the RHS
            // switch for the potential functions
            switch (Control.Potential)
            {
            case ReInitPotential.BastingDoubleWell: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWell(d, b));
                break;
            };

            case ReInitPotential.BastingSingleWell: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWell(d, b));
                break;
            };

            case ReInitPotential.SingleWellNear: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellNear(d, b));
                break;
            };

            case ReInitPotential.P4DoubleWell: {
                Console.WriteLine("Warning - This Option for Elliptic ReInit does not work well");
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWellAlternative(d, b));
                break;
            };

            case ReInitPotential.SingleWellOnCutDoubleWellElse: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellOnCutDoubleWellElse(d, b));
                break;
            }
            }
            Operator_RHS = myRHSForm.Operator(QuadOrderFunc.SumOfMaxDegrees(2, RoundUp: true));


            // The result of the nonlinear part on the rhs is projected on a single-phase field
            RHSField = new SinglePhaseField(Phi.Basis, "RHS");

            OpMatrix = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping);
            OpAffine = new double[OpMatrix.RowPartitioning.LocalLength];

            // Matrix and RHS for the Bulk component
            OpMatrix_bulk = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping);
            OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength];

            // Matrix and RHS for the Interface Penalty
            OpMatrix_interface = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping);
            OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength];

            // Init Parameter Fields
            OldPhi.Clear();
            OldPhi.Acc(1.0, Phi);

            // Compute Matrices
            UpdateBulkMatrix();
        }
示例#29
0
    void psiCalcDisplay()
    {
        float[][] psi_set;
        float[]   charges, charges_x, charges_y;
        object[]  solution;

//		vertical_steps=100;
        //number of eigen energies
        xmin = -3.78f;
        xmax = 4.1f;
        xss  = numeric.linspace(-1.0f, 1.0f, num_points);


        charges = new float[2] {
            10, -15
        };
        charges_x = new float[2] {
            -0.5f, 0.5f
        };
        charges_y = new float[2] {
            0.1f, 0.1f
        };
        dx = (xmax - xmin) / (num_points);

        solution   = (object[])Wavefunction(xmin, xmax, num_points, num_elevel, pe_profile);
        energy_set = (float[])solution[0];
        ArrayTools.Update(energy_set, x => x + yOffset2);
        psi_set = (float[][])solution[1];


        psi_valuesInit = psi_set[E];
        lineRenderer.SetVertexCount(psi_valuesInit.Length);
//		Debug.Log(psi_valuesInit.Length);
        float a = (E + 1.0f) / num_elevel;

//		Debug.Log(a);
        vertical_steps = Mathf.FloorToInt(50.0f / a);
        psiAnim        = psiMotionArray(psi_valuesInit, vertical_steps);
        probM          = prob(psi_valuesInit);
        cumprob        = new float[probM.Length];
        cumprob[0]     = probM[0];
        float sumprob = 0;

        for (int i = 0; i < probM.Length; i++)
        {
            sumprob = sumprob + probM[i];
        }

        for (int i = 1; i < probM.Length; i++)
        {
            cumprob[i] = cumprob[i - 1] + probM[i];
        }
        for (int i = 0; i < cumprob.Length; i++)
        {
            cumprob[i] = cumprob[i] / sumprob;
        }
        EnergyLevels.ePlotsignal = true;
        this.i = 0;
        GameObject.Find("Wire").GetComponent <WireColor>().probSignal = true;
//		Debug.Log(psiAnim.Length);
    }
 public Expression ToExpression(Func <object, Expression> fallbackConverter)
 {
     return(New(GetType().GetConstructors()[0], ArrayTools.Empty <Expression>()));
 }