diff --git a/python/dune/perftool/compile.py b/python/dune/perftool/compile.py index 1df3417f0b26d35202ad9f8cb1e653833d91bafe..9726396aa250cac3fe49ed3845bf833cf261877b 100644 --- a/python/dune/perftool/compile.py +++ b/python/dune/perftool/compile.py @@ -79,4 +79,9 @@ def compile_form(): if get_option("operator_file"): from dune.perftool.pdelab.localoperator import generate_localoperator - generate_localoperator(form, get_option("operator_file")) + kernels = generate_localoperator(form) + + # TODO insert sophisticated analysis/feedback loops here + + from dune.perftool.pdelab.localoperator import generate_localoperator_file + generate_localoperator_file(kernels) diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py index eb3543448fe5d2aad2d39d19b2aad808a3ef8a74..6f36a57da7880b521d1ae17b69b309e3dc8e3e01 100644 --- a/python/dune/perftool/pdelab/localoperator.py +++ b/python/dune/perftool/pdelab/localoperator.py @@ -129,7 +129,7 @@ def cgen_class_from_cache(name, tag, members=[]): return Class(name, base_classes=base_classes, members=members) -def generate_localoperator(form, operatorfile): +def generate_localoperator(form): # For the moment, I do assume that there is but one integral of each type. This might differ # if you use different quadrature orders for different terms. assert len(form.integrals()) == len(set(i.integral_type() for i in form.integrals())) @@ -138,14 +138,22 @@ def generate_localoperator(form, operatorfile): from dune.perftool.generation import delete_cache delete_cache() + # Manage includes and base classes that we always need + operator_include('dune/pdelab/gridfunctionspace/gridfunctionspaceutilities.hh') + operator_include('dune/pdelab/localoperator/idefault.hh') + operator_include('dune/pdelab/localoperator/flags.hh') + operator_include('dune/pdelab/localoperator/pattern.hh') + operator_include('dune/geometry/quadraturerules.hh') + + public_base_class('Dune::PDELab::LocalOperatorDefaultFlags') + # Have a data structure collect the generated kernels - operator_methods = [] + operator_kernels = {} # Generate the necessary residual methods for integral in form.integrals(): kernel = generate_term(integrand=integral.integrand(), measure=integral.integral_type()) - signature = measure_specific_details(integral.integral_type())["residual_signature"] - operator_methods.append(AssemblyMethod(signature, kernel)) + operator_kernels[(integral.integral_type(), 'residual')] = kernel # Generate the necessary jacobian methods from dune.perftool.options import get_option @@ -158,19 +166,20 @@ def generate_localoperator(form, operatorfile): for integral in jacform.integrals(): kernel = generate_term(integrand=integral.integrand(), measure=integral.integral_type()) - signature = measure_specific_details(integral.integral_type())["jacobian_signature"] - operator_methods.append(AssemblyMethod(signature, kernel)) + operator_kernels[(integral.integral_type(), 'jacobian')] = kernel # TODO: JacobianApply for matrix-free computations. - # Manage includes and base classes that we always need - operator_include('dune/pdelab/gridfunctionspace/gridfunctionspaceutilities.hh') - operator_include('dune/pdelab/localoperator/idefault.hh') - operator_include('dune/pdelab/localoperator/flags.hh') - operator_include('dune/pdelab/localoperator/pattern.hh') - operator_include('dune/geometry/quadraturerules.hh') + # Return the set of generated kernels + return operator_kernels - public_base_class('Dune::PDELab::LocalOperatorDefaultFlags') +def generate_localoperator_file(kernels): + operator_methods = [] + + # Make generables from the given kernels + for method, kernel in kernels.items(): + signature = measure_specific_details(method[0])["{}_signature".format(method[1])] + operator_methods.append(AssemblyMethod(signature, kernel)) # Write the file! from dune.perftool.file import generate_file