/// <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); } } } }