示例#1
0
        /// <summary>
        /// performs an integration over cells or edges in the composite rule provided to the constructor;
        /// </summary>
        public virtual void Execute()
        {
            using (var tr = new FuncTrace()) {
                // Init
                // ====

                // timers
                Stopwatch stpwSaveIntRes = new Stopwatch();
                stpwSaveIntRes.Reset();
                Stopwatch stpwQuad = new Stopwatch();
                stpwQuad.Reset();
                Stopwatch stpwEval = new Stopwatch();
                stpwEval.Reset();
                Stopwatch stpwAlloc = new Stopwatch();
                stpwAlloc.Reset();
                Stopwatch stpwNdSet = new Stopwatch();
                stpwNdSet.Reset();

                for (int i = CustomTimers.Length - 1; i >= 0; i--)
                {
                    CustomTimers[i].Reset();
                }

                // check input ...
                IGridData grd = gridData;

                // do quadrature
                // =============
                MultidimensionalArray lastQuadRuleNodes = null;
                int oldBulksize  = -1;
                int oldNoOfNodes = -1;
                int Bulkcnt      = 0;
                foreach (var chunkRulePair in m_compositeRule)
                {
                    Chunk chunk = chunkRulePair.Chunk;
                    m_CurrentRule = chunkRulePair.Rule;

                    //// init node set
                    stpwNdSet.Start();
                    if (!object.ReferenceEquals(m_CurrentRule.Nodes, lastQuadRuleNodes))
                    {
                        QuadNodesChanged(m_CurrentRule.Nodes);
                    }
                    stpwNdSet.Stop();

                    // define bulk size
                    int NoOfNodes = m_CurrentRule.Nodes.GetLength(0);
                    int ItemSize  = m_TotalNoOfIntegralsPerItem * NoOfNodes;
                    if (ItemSize <= 0)
                    {
                        continue;
                    }
                    int cdl = Quadrature_Bulksize.CHUNK_DATA_LIMIT;
                    if (ChunkDataLimitOverride > 0)
                    {
                        cdl = ChunkDataLimitOverride;
                    }
                    int MaxChunkLength = Quadrature_Bulksize.CHUNK_DATA_LIMIT / ItemSize;
                    if (MaxChunkLength < 1)
                    {
                        MaxChunkLength = 1;
                    }

                    //if (OberOasch && Bulkcnt == 0)
                    //    Console.WriteLine("Max Chunk length: " + MaxChunkLength);

                    int j           = chunk.i0;
                    int ChunkLength = MaxChunkLength;
                    int ChunkEnd    = chunk.i0 + chunk.Len;


                    while (j < ChunkEnd)
                    {
                        Bulkcnt++;

                        // limit bulksize
                        if ((j + ChunkLength) > ChunkEnd)
                        {
                            ChunkLength -= (j + ChunkLength - ChunkEnd);
                        }


                        // DEBUG check
#if DEBUG
                        CheckQuadratureChunk(j, ChunkLength, CurrentRuleRefElementIndex);
#endif

                        // reallocate buffers if bulksize was changed
                        stpwAlloc.Start();
                        if (ChunkLength != oldBulksize || m_CurrentRule.NoOfNodes != oldNoOfNodes)
                        {
                            AllocateBuffersInternal(ChunkLength, m_CurrentRule.Nodes);
                            AllocateBuffers(ChunkLength, m_CurrentRule.Nodes);
                            oldBulksize  = ChunkLength;
                            oldNoOfNodes = m_CurrentRule.NoOfNodes;
                        }
                        stpwAlloc.Stop();


                        if (this.m_ExEvaluate == null)
                        {
                            // evaluation of integrand
                            // =======================
                            stpwEval.Start();
                            m_EvalResults.Clear();
                            this.Evaluate(j, ChunkLength, this.CurrentRule, m_EvalResults);
                            stpwEval.Stop();

                            // quadrature
                            // ==========
                            stpwQuad.Start();
                            DoQuadrature(m_CurrentRule, j, ChunkLength);
                            stpwQuad.Stop();
                        }
                        else
                        {
                            Debug.Assert(this.m_Evaluate == null);

                            // evaluation of integrand
                            // =======================
                            stpwEval.Start();
                            this.m_ExEvaluate(j, ChunkLength, this.CurrentRule, m_QuadResults);
                            stpwEval.Stop();
                        }

                        // save results
                        // ============
                        stpwSaveIntRes.Start();
                        SaveIntegrationResults(j, ChunkLength, m_QuadResults);
                        stpwSaveIntRes.Stop();

                        // inc
                        j += ChunkLength;
                    }


                    lastQuadRuleNodes = m_CurrentRule.Nodes;
                }
                m_CurrentRule = null;

                //tr.Info("Quadrature performed in " + Bulkcnt + " chunk(s).");
                //Console.WriteLine("Quadrature performed in " + Bulkcnt + " chunk(s).");

                // finalize
                // ========

                {
                    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    //
                    // note that StopWatch.Elapsed.Ticks != StopWatch.ElapsedTicks
                    //
                    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                    var mcrEval = tr.LogDummyblock(stpwEval.Elapsed.Ticks, "integrand_evaluation");
                    tr.LogDummyblock(stpwQuad.Elapsed.Ticks, "quadrature");
                    tr.LogDummyblock(stpwSaveIntRes.Elapsed.Ticks, "saving_results");
                    tr.LogDummyblock(stpwNdSet.Elapsed.Ticks, "node_set_management");
                    tr.LogDummyblock(stpwAlloc.Elapsed.Ticks, "buffer_allocation");

                    Debug.Assert(m_CustomTimers.Length == m_CustomTimers_Names.Length);
                    Debug.Assert(m_CustomTimers.Length == m_CustomTimers_RootPointer.Length);
                    MethodCallRecord[] mcrS = new MethodCallRecord[CustomTimers.Length];

                    for (int iTimer = 0; iTimer < mcrS.Length; iTimer++)
                    {
                        int pt = m_CustomTimers_RootPointer[iTimer];
                        MethodCallRecord OwnerMcr = pt >= 0 ? mcrS[pt] : mcrEval;
                        mcrS[iTimer] = OwnerMcr.AddSubCall(CustomTimers_Names[iTimer], m_CustomTimers[iTimer].Elapsed.Ticks);
                    }
                }
            }
        }