+
Skip to content

Slow (hierarchical) basis calculation on highly refined meshes #677

Open
@MartinEssink

Description

@MartinEssink

When a mesh or refined in a small region around some feature, the calculation of the hierarchical basis slows down considerably with the increase of the refinement. After about ~10 refinement iterations the increase in time is exponential, while the increase in ndof is typically more linear or quadratic. This issue seems to stem from the way a hierarchical basis is constructed that involved the calculation of all basis functions on each level of the mesh, most of which are not required. For higher refinement levels it might therefore be beneficial to have an option to only calculate the basis functions that are actually needed, or to calculate them on-the-fly. Such an approach would most likely slightly degrade the performance at low refinement levels, thus having it as an option would be great.

To illustrate the problem I am facing I have made a simple script to benchmark the performance at different levels. This code starts with a 2x2 mesh, which is subsequently refined continuously in the corner. An overview of the ndof and time to calculate the basis is plotted below, clearly showing the exponential increase in time.
Refinement_benchmark

from nutils import mesh, function, solver, util, export, cli, testing
from nutils.expression_v2 import Namespace
import numpy
import treelog 
import time
import matplotlib.pyplot as plt

def main():
    domain, geom = mesh.unitsquare(2, 'square')
    x, y = geom
    plt.figure()

    with treelog.iter.fraction('level', range(24)) as lrange:
        for irefine in lrange:
            if irefine:
                refdom = domain.refined
                ns.refbasis = refdom.basis('th-std', degree=3)
                indicator = refdom.integral('refbasis_n (x_0 x_0 + x_1 x_1)' @ ns, degree=3*2).eval()
                supp = ns.refbasis.get_support(indicator == numpy.min(indicator))
                domain = domain.refined_by(refdom.transforms[supp])

            ns = Namespace()
            ns.x = geom
            t = time.time()
            nrun=1
            for i in range(nrun):
                ns.basis = domain.basis('th-std', degree=3)
            btime = (time.time() - t)/nrun
            treelog.user('Level', irefine, 'ndof', len(ns.basis) , 'time', btime)
            plt.semilogy(irefine,btime,'r.')
            plt.semilogy(irefine,len(ns.basis),'b.')

    plt.xlabel('Refinement step')
    plt.ylabel('(blue) ndof; (red) basis time [s]')
    plt.tight_layout(pad=.1)
    plt.savefig("Refinement_benchmark.png", dpi=300)
    plt.savefig("Refinement_benchmark.pdf", dpi=300)
    plt.show()
            
if __name__ == '__main__':
    cli.run(main)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载