\( \usepackage{euler} % must be loaded before fontspec for the whole doc (below); this must be kept for pngmath, however \usepackage{hyperref} \usepackage{amsmath} \usepackage{amsbsy} %\usepackage{mathabx} \usepackage{underscore} \usepackage[all]{xy} % Metadata of the pdf output \hypersetup{pdftitle={Yade Documentation}} \hypersetup{pdfauthor={Smilauer, V., et al.}} \hypersetup{pdfkeywords={Discrete element method, granular materials, contact law, hydromechanical coupling}} % symbols \renewcommand{\mat}{\boldsymbol} \renewcommand{\vec}{\boldsymbol} \renewcommand{\tens}{\boldsymbol} %normalized and locfram here \def\normalized#1{\widehat{#1}} \def\locframe#1{\widetilde{#1}} % timestep \def\Dt{\Delta t} \def\Dtcr{\Dt_{\rm cr}} % algorithm complexity \def\bigO#1{{\mathcal{O}(#1)}} % variants for greek symbols \let\epsilon\varepsilon \let\theta\vartheta \let\phi\varphi % shorthands \let\sig\sigma \let\eps\epsilon % variables at different points of time \def\prev#1{#1^-} \def\pprev#1{#1^\ominus} \def\curr#1{#1^{\circ}} \def\nnext#1{#1^\oplus} \def\next#1{#1^+} % shorthands for geometry \def\currn{\curr{\vec{n}}} \def\currC{\curr{\vec{C}}} \def\uT{\vec{u}_T} \def\curruT{\curr{\vec{u}}_T} \def\prevuT{\prev{\vec{u}}_T} \def\currn{\curr{\vec{n}}} \def\prevn{\prev{\vec{n}}} % motion \def\pprevvel{\pprev{\dot{\vec{u}}}} \def\nnextvel{\nnext{\dot{\vec{u}}}} \def\curraccel{\curr{\ddot{\vec{u}}}} \def\prevpos{\prev{\vec{u}}} \def\currpos{\curr{\vec{u}}} \def\nextpos{\next{\vec{u}}} \def\curraaccel{\curr{\dot{\vec{\omega}}}} \def\pprevangvel{\pprev{\vec{\omega}}} \def\nnextangvel{\nnext{\vec{\omega}}} \def\loccurr#1{\curr{\locframe{#1}}} \def\numCPU{n_{\rm cpu}} \DeclareMathOperator{\Align}{Align} \DeclareMathOperator{\sign}{sgn} % sorting algorithms \def\isleq#1{\currelem{#1}\ar@/^/[ll]^{\leq}} \def\isnleq#1{\currelem{#1}\ar@/^/[ll]^{\not\leq}} \def\currelem#1{\fbox{$#1$}} \def\sortSep{||} \def\sortInv{\hbox{\phantom{||}}} \def\sortlines#1{\xymatrix@=3pt{#1}} \def\crossBound{||\mkern-18mu<} \)

# Source code for yade.timing

    # encoding: utf-8
    # 2008 © Václav Šmilauer <eudoxos@arcig.cz>
    """Functions for accessing timing information stored in engines and functors.

    See :ref:`timing` section of the programmer's manual for some examples (https://yade-dem.org/doc/prog.html#timing).

    """

    from yade.wrapper import *

    def _resetEngine(e):
       if e.timingDeltas:
          e.timingDeltas.reset()
       if isinstance(e, Functor):
          return
       if isinstance(e, Dispatcher):
          for f in e.functors:
             _resetEngine(f)
       elif isinstance(e, ParallelEngine):
          for s in e.slaves:
             _resetEngine(s)
       e.execTime, e.execCount = 0, 0

    def reset():
       "Zero all timing data."
       for e in O.engines:
          _resetEngine(e)

    _statCols = {'label': 40, 'count': 20, 'time': 20, 'relTime': 20}
    _maxLev = 3

    def runtime():
       '''
       Return total running time (same as last line in the output of stats()) in nanoseconds
       '''
       return sum([e.execTime for e in O.engines])

    def _formatLine(label, time, count, totalTime, level):
       sp, negSp = ' ' * level * 2, ' ' * (_maxLev - level) * 2
       raw = []
       raw.append(label)
       raw.append(str(count) if count >= 0 else '')
       raw.append((str(time / 1000) + u'us') if time >= 0 else '')
       raw.append(('%6.2f%%' % (time * 100. / totalTime)) if totalTime > 0 else '')
       return u' '.join(
               [
                       (sp + raw[0]).ljust(_statCols['label']),
                       (raw[1] + negSp).rjust(_statCols['count']),
                       (raw[2] + negSp).rjust(_statCols['time']),
                       (raw[3] + negSp).rjust(_statCols['relTime']),
               ]
       )

    def _delta_stats(deltas, totalTime, level):
       ret = 0
       deltaTime = sum([d[1] for d in deltas.data])
       for d in deltas.data:
          print(_formatLine(d[0], d[1], d[2], totalTime, level))
          ret += 1
       if len(deltas.data) > 1:
          print(_formatLine('TOTAL', deltaTime, sum(d[2] for d in deltas.data), totalTime, level))
          ret += 1
       return ret

    def _engines_stats(engines, totalTime, level):
       lines = 0
       hereLines = 0
       for e in engines:
          if not isinstance(e, Functor):
             print(_formatLine(u'"' + e.label + '"' if e.label else e.__class__.__name__, e.execTime, e.execCount, totalTime, level))
             lines += 1
             hereLines += 1
          if e.timingDeltas:
             if isinstance(e, Functor):
                print(
                        _formatLine(
                                e.__class__.__name__, sum(d[1] for d in e.timingDeltas.data), sum(d[2] for d in e.timingDeltas.data), totalTime,
                                level
                        )
                )
                lines += 1
                hereLines += 1
                execTime = sum([d[1] for d in e.timingDeltas.data])
             else:
                execTime = e.execTime
             lines += _delta_stats(e.timingDeltas, execTime, level + 1)
          if isinstance(e, Dispatcher):
             lines += _engines_stats(e.functors, e.execTime, level + 1)
          if isinstance(e, InteractionLoop):
             lines += _engines_stats(e.geomDispatcher.functors, e.execTime, level + 1)
             lines += _engines_stats(e.physDispatcher.functors, e.execTime, level + 1)
             lines += _engines_stats(e.lawDispatcher.functors, e.execTime, level + 1)
          elif isinstance(e, ParallelEngine):
             for slave in e.slaves:
                print("\\")
                if not isinstance(slave, list):
                   lines += _engines_stats([slave], e.execTime, level + 1)
                else:
                   for el in slave:
                      _engines_stats([el], e.execTime, level + 1)
             print("/")
       if hereLines > 1 and not isinstance(e, Functor):
          print(_formatLine('TOTAL', totalTime, -1, totalTime, level))
          lines += 1
       return lines

    def stats():
       """Print summary table of timing information from engines and functors. Absolute times as well as percentages are given. Sample output:

       .. code-block:: none

          Name                                                    Count                 Time            Rel. time
          -------------------------------------------------------------------------------------------------------
          ForceResetter                                       102               2150us                0.02%
          "collider"                                            5              64200us                0.60%
          InteractionLoop                                     102           10571887us               98.49%
          "combEngine"                                        102               8362us                0.08%
          "newton"                                            102              73166us                0.68%
          "cpmStateUpdater"                                     1               9605us                0.09%
          PyRunner                                              1                136us                0.00%
          "plotDataCollector"                                   1                291us                0.00%
          TOTAL                                                             10733564us              100.00%

       sample output (compiled with -DENABLE_PROFILING=1 option):

       .. code-block:: none

          Name                                                    Count                 Time            Rel. time
          -------------------------------------------------------------------------------------------------------
          ForceResetter                                       102               2150us                0.02%
          "collider"                                            5              64200us                0.60%
          InteractionLoop                                     102           10571887us               98.49%
            Ig2_Sphere_Sphere_ScGeom                        1222186            1723168us               16.30%
              Ig2_Sphere_Sphere_ScGeom                        1222186            1723168us              100.00%
            Ig2_Facet_Sphere_ScGeom                             753               1157us                0.01%
              Ig2_Facet_Sphere_ScGeom                             753               1157us              100.00%
            Ip2_CpmMat_CpmMat_CpmPhys                         11712              26015us                0.25%
              end of Ip2_CpmPhys                                11712              26015us              100.00%
            Ip2_FrictMat_CpmMat_FrictPhys                         0                  0us                0.00%
            Law2_ScGeom_CpmPhys_Cpm                         3583872            4819289us               45.59%
              GO A                                            1194624            1423738us               29.54%
              GO B                                            1194624            1801250us               37.38%
              rest                                            1194624            1594300us               33.08%
              TOTAL                                           3583872            4819289us              100.00%
            Law2_ScGeom_FrictPhys_CundallStrack                   0                  0us                0.00%
          "combEngine"                                        102               8362us                0.08%
          "newton"                                            102              73166us                0.68%
          "cpmStateUpdater"                                     1               9605us                0.09%
          PyRunner                                              1                136us                0.00%
          "plotDataCollector"                                   1                291us                0.00%
          TOTAL                                                             10733564us              100.00%

       """

       print(
               'Name'.ljust(_statCols['label']) + ' ' + 'Count'.rjust(_statCols['count']) + ' ' + 'Time'.rjust(_statCols['time']) + ' ' +
               'Rel. time'.rjust(_statCols['relTime'])
       )
       print('-' * (sum([_statCols[k] for k in _statCols]) + len(_statCols) - 1))
       _engines_stats(O.engines, sum([e.execTime for e in O.engines]), 0)
       print()