def compute_integral_ir(itg_data, form_data, form_id, parameters): "Compute intermediate represention of integral." info("Computing quadrature representation") # Initialise representation ir = initialize_integral_ir("quadrature", itg_data, form_data, form_id) # Sort integrals into a dict with number of integral points as key sorted_integrals = _sort_integrals(itg_data.integrals, itg_data.metadata, form_data) # Tabulate quadrature points and basis function values in these points integrals_dict, psi_tables, quad_weights = \ _tabulate_basis(sorted_integrals, itg_data.domain_type, form_data) # Save tables for quadrature weights and points ir["quadrature_weights"] = quad_weights # Create dimensions of primary indices, needed to reset the argument 'A' # given to tabulate_tensor() by the assembler. ir["prim_idims"] = [create_element(ufl_element).space_dimension() for ufl_element in form_data.argument_elements] # Create and save the optisation parameters. ir["optimise_parameters"] = _parse_optimise_parameters(parameters) # Create transformer. if ir["optimise_parameters"]["optimisation"]: QuadratureTransformerClass = QuadratureTransformerOpt else: QuadratureTransformerClass = QuadratureTransformer transformer = QuadratureTransformerClass(psi_tables, quad_weights, form_data.geometric_dimension, form_data.topological_dimension, ir["entitytype"], form_data.function_replace_map, ir["optimise_parameters"]) # Transform integrals. ir["trans_integrals"] = _transform_integrals_by_type(ir, transformer, integrals_dict, itg_data.domain_type, form_data.cell) # Save tables populated by transformer ir["name_map"] = transformer.name_map ir["unique_tables"] = transformer.unique_tables # Basis values? # Save tables map, to extract table names for optimisation option -O. ir["psi_tables_map"] = transformer.psi_tables_map ir["additional_includes_set"] = transformer.additional_includes_set # Insert empty data which will be populated if optimization is turned on ir["geo_consts"] = {} return ir
def compute_integral_ir(itg_data, form_data, form_id, element_numbers, parameters): "Compute intermediate represention of integral." info("Computing tensor representation") # Extract monomial representation integrands = [itg.integrand() for itg in itg_data.integrals] monomial_form = extract_monomial_form(integrands, form_data.function_replace_map) # Transform monomial form to reference element transform_monomial_form(monomial_form) # Get some integral properties integral_type = itg_data.integral_type quadrature_degree = itg_data.metadata["quadrature_degree"] quadrature_rule = itg_data.metadata["quadrature_rule"] # Get some cell properties cell = itg_data.domain.ufl_cell() num_facets = cell.num_facets() # Helper to simplify code below compute_terms = lambda i, j: _compute_terms(monomial_form, i, j, integral_type, quadrature_degree, quadrature_rule, cell) # Compute representation of cell tensor if integral_type == "cell": # Compute sum of tensor representations terms = compute_terms(None, None) elif integral_type == "exterior_facet": # Compute sum of tensor representations for each facet terms = [compute_terms(i, None) for i in range(num_facets)] elif integral_type == "interior_facet": # Compute sum of tensor representations for each facet-facet pair terms = [[compute_terms(i, j) for j in range(num_facets)] for i in range(num_facets)] for i in range(num_facets): for j in range(num_facets): reorder_entries(terms[i][j]) else: error("Unhandled domain type: " + str(integral_type)) # Initialize representation and store terms ir = initialize_integral_ir("tensor", itg_data, form_data, form_id) ir["AK"] = terms return ir
def compute_integral_ir(itg_data, form_data, form_id, parameters): "Compute intermediate represention of integral." info("Computing quadrature representation") # Initialise representation ir = initialize_integral_ir("quadrature", itg_data, form_data, form_id) # Sort integrals into a dict with number of integral points as key sorted_integrals = _sort_integrals(itg_data.integrals, itg_data.metadata, form_data) # Tabulate quadrature points and basis function values in these points integrals_dict, psi_tables, quad_weights = \ _tabulate_basis(sorted_integrals, itg_data.domain_type, form_data) # Save tables for quadrature weights and points ir["quadrature_weights"] = quad_weights # Create dimensions of primary indices, needed to reset the argument 'A' # given to tabulate_tensor() by the assembler. ir["prim_idims"] = [ create_element(ufl_element).space_dimension() for ufl_element in form_data.argument_elements ] # Create and save the optisation parameters. ir["optimise_parameters"] = _parse_optimise_parameters(parameters) # Create transformer. if ir["optimise_parameters"]["optimisation"]: QuadratureTransformerClass = QuadratureTransformerOpt else: QuadratureTransformerClass = QuadratureTransformer transformer = QuadratureTransformerClass(psi_tables, quad_weights, form_data.geometric_dimension, form_data.topological_dimension, ir["entitytype"], form_data.function_replace_map, ir["optimise_parameters"]) # Transform integrals. ir["trans_integrals"] = _transform_integrals_by_type( ir, transformer, integrals_dict, itg_data.domain_type, form_data.cell) # Save tables populated by transformer ir["name_map"] = transformer.name_map ir["unique_tables"] = transformer.unique_tables # Basis values? # Save tables map, to extract table names for optimisation option -O. ir["psi_tables_map"] = transformer.psi_tables_map ir["additional_includes_set"] = transformer.additional_includes_set # Insert empty data which will be populated if optimization is turned on ir["geo_consts"] = {} return ir
def compute_integral_ir(itg_data, form_data, form_id, element_numbers, parameters): "Compute intermediate represention of integral." info("Computing tensor representation") # Extract monomial representation integrands = [itg.integrand() for itg in itg_data.integrals] monomial_form = extract_monomial_form(integrands, form_data.function_replace_map) # Transform monomial form to reference element transform_monomial_form(monomial_form) # Get some integral properties integral_type = itg_data.integral_type quadrature_degree = itg_data.metadata["quadrature_degree"] quadrature_rule = itg_data.metadata["quadrature_rule"] # Get some cell properties cell = itg_data.domain.cell() cellname = cell.cellname() facet_cellname = cell.facet_cellname() num_facets = cell.num_facets() # Helper to simplify code below compute_terms = lambda i, j: _compute_terms( monomial_form, i, j, integral_type, quadrature_degree, quadrature_rule, cellname, facet_cellname) # Compute representation of cell tensor if integral_type == "cell": # Compute sum of tensor representations terms = compute_terms(None, None) elif integral_type == "exterior_facet": # Compute sum of tensor representations for each facet terms = [compute_terms(i, None) for i in range(num_facets)] elif integral_type == "interior_facet": # Compute sum of tensor representations for each facet-facet pair terms = [[compute_terms(i, j) for j in range(num_facets)] for i in range(num_facets)] for i in range(num_facets): for j in range(num_facets): reorder_entries(terms[i][j]) else: error("Unhandled domain type: " + str(integral_type)) # Initialize representation and store terms ir = initialize_integral_ir("tensor", itg_data, form_data, form_id) ir["AK"] = terms return ir
def compute_integral_ir(itg_data, form_data, form_id, element_numbers, parameters): "Compute intermediate represention of integral." info("Computing uflacs representation") # Initialise representation ir = initialize_integral_ir("uflacs", itg_data, form_data, form_id) # Sort integrals into a dict with quadrature degree and rule as key sorted_integrals = sort_integrals(itg_data.integrals, itg_data.metadata["quadrature_degree"], itg_data.metadata["quadrature_rule"]) # TODO: Might want to create the uflacs ir first and then create the tables we need afterwards! # Tabulate quadrature points and basis function values in these points integrals_dict, psi_tables, quadrature_rules = \ tabulate_basis(sorted_integrals, form_data, itg_data) # Store element numbers, needed for classnames ir["element_numbers"] = element_numbers # Delegate to flacs to build its intermediate representation and add to ir uflacs_ir = compute_uflacs_integral_ir(psi_tables, ir["entitytype"], integrals_dict, form_data, parameters) # Store uflacs generated part separately ir["uflacs"] = uflacs_ir # Create and save the optisation parameters # TODO: Define uflacs specific optimization parameters instead #ir["optimise_parameters"] = parse_optimise_parameters(parameters) # Save tables for quadrature weights and points ir["quadrature_rules"] = quadrature_rules # Create dimensions of primary indices, needed to reset the argument 'A' # given to tabulate_tensor() by the assembler. ir["prim_idims"] = [ create_element(ufl_element).space_dimension() for ufl_element in form_data.argument_elements ] # Added for uflacs, not sure if this is the best way to get this: ir["coeff_idims"] = [ create_element(ufl_element).space_dimension() for ufl_element in form_data.coefficient_elements ] return ir
def compute_integral_ir(integral_data, form_data, form_id, element_numbers, classnames, parameters): "Compute intermediate represention of integral." info("Computing tsfc representation") # Initialise representation ir = initialize_integral_ir("tsfc", integral_data, form_data, form_id) # TSFC treats None and unset differently, so remove None values. parameters = {k: v for k, v in parameters.items() if v is not None} # Delay TSFC compilation ir["compile_integral"] = (integral_data, form_data, None, parameters) return ir
def compute_integral_ir(itg_data, form_data, form_id, element_numbers, parameters): "Compute intermediate represention of integral." info("Computing uflacs representation") # Initialise representation ir = initialize_integral_ir("uflacs", itg_data, form_data, form_id) # Sort integrals into a dict with quadrature degree and rule as key sorted_integrals = sort_integrals(itg_data.integrals, itg_data.metadata["quadrature_degree"], itg_data.metadata["quadrature_rule"]) # TODO: Might want to create the uflacs ir first and then create the tables we need afterwards! # Tabulate quadrature points and basis function values in these points integrals_dict, psi_tables, quadrature_rules = \ tabulate_basis(sorted_integrals, form_data, itg_data) # Store element numbers, needed for classnames ir["element_numbers"] = element_numbers # Delegate to flacs to build its intermediate representation and add to ir uflacs_ir = compute_uflacs_integral_ir(psi_tables, ir["entitytype"], integrals_dict, form_data, parameters) # Store uflacs generated part separately ir["uflacs"] = uflacs_ir # Create and save the optisation parameters # TODO: Define uflacs specific optimization parameters instead #ir["optimise_parameters"] = parse_optimise_parameters(parameters) # Save tables for quadrature weights and points ir["quadrature_rules"] = quadrature_rules # Create dimensions of primary indices, needed to reset the argument 'A' # given to tabulate_tensor() by the assembler. ir["prim_idims"] = [create_element(ufl_element).space_dimension() for ufl_element in form_data.argument_elements] # Added for uflacs, not sure if this is the best way to get this: ir["coeff_idims"] = [create_element(ufl_element).space_dimension() for ufl_element in form_data.coefficient_elements] return ir
def compute_integral_ir(itg_data, form_data, form_id, parameters): "Compute intermediate represention of integral." info("Computing uflacs representation") # Initialise representation ir = initialize_integral_ir("uflacs", itg_data, form_data, form_id) # Sort integrals into a dict with number of integral points as key sorted_integrals = _sort_integrals(itg_data.integrals, itg_data.metadata, form_data) # Tabulate quadrature points and basis function values in these points integrals_dict, psi_tables, quad_weights = \ _tabulate_basis(sorted_integrals, itg_data.domain_type, form_data) # Save tables for quadrature weights and points ir["quadrature_weights"] = quad_weights # Save tables for basis function values ir["psi_tables"] = psi_tables # Create dimensions of primary indices, needed to reset the argument 'A' # given to tabulate_tensor() by the assembler. ir["prim_idims"] = [ create_element(ufl_element).space_dimension() for ufl_element in form_data.argument_elements ] # Added for uflacs, not sure if this is the best way to get this: ir["coeff_idims"] = [ create_element(ufl_element).space_dimension() for ufl_element in form_data.coefficient_elements ] # Create and save the optisation parameters. ir["optimise_parameters"] = _parse_optimise_parameters(parameters) # Delegate to flacs to build its intermediate representation and add to ir import uflacs.backends.ffc uir = uflacs.backends.ffc.compute_tabulate_tensor_ir( ir, integrals_dict, form_data, parameters) ir.update(uir) return ir
def compute_integral_ir(itg_data, form_data, form_id, element_numbers, parameters): "Compute intermediate represention of integral." info("Computing quadrature representation") # Initialise representation ir = initialize_integral_ir("quadrature", itg_data, form_data, form_id) # Create and save the optisation parameters. ir["optimise_parameters"] = parse_optimise_parameters(parameters, itg_data) # Sort integrals into a dict with quadrature degree and rule as key sorted_integrals = sort_integrals(itg_data.integrals, itg_data.metadata["quadrature_degree"], itg_data.metadata["quadrature_rule"]) # Tabulate quadrature points and basis function values in these points integrals_dict, psi_tables, quadrature_rules = \ tabulate_basis(sorted_integrals, form_data, itg_data) # Save tables for quadrature weights and points ir["quadrature_weights"] = quadrature_rules # TODO: Rename this ir entry to quadrature_rules # Create dimensions of primary indices, needed to reset the argument 'A' # given to tabulate_tensor() by the assembler. ir["prim_idims"] = [ create_element(ufl_element).space_dimension() for ufl_element in form_data.argument_elements ] # Select transformer if ir["optimise_parameters"]["optimisation"] or parameters["pyop2-ir"]: QuadratureTransformerClass = QuadratureTransformerOpt else: QuadratureTransformerClass = QuadratureTransformer # Create transformer transformer = QuadratureTransformerClass( psi_tables, quadrature_rules, itg_data.domain.geometric_dimension(), itg_data.domain.topological_dimension(), ir["entitytype"], form_data.function_replace_map, ir["optimise_parameters"], parameters) # Transform integrals. cell = itg_data.domain.ufl_cell() ir["trans_integrals"] = _transform_integrals_by_type( ir, transformer, integrals_dict, itg_data.integral_type) # Save tables populated by transformer ir["name_map"] = transformer.name_map ir["unique_tables"] = transformer.unique_tables # Basis values? # Save tables map, to extract table names for optimisation option -O. ir["psi_tables_map"] = transformer.psi_tables_map ir["additional_includes_set"] = transformer.additional_includes_set # Insert empty data which will be populated if optimization is turned on ir["geo_consts"] = {} # Add local tensor entry dimensions ir["tensor_entry_size"] = tuple([1] * form_data.rank) # Add number of coefficients ir["num_coefficients"] = form_data.num_coefficients # Extract element data for psi_tables, needed for runtime quadrature. # This is used by integral type custom_integral. ir["element_data"] = _extract_element_data(transformer.element_map, element_numbers) return ir
def compute_integral_ir(itg_data, form_data, form_id, element_numbers, classnames, parameters): "Compute intermediate represention of integral." info("Computing uflacs representation") # Initialise representation ir = initialize_integral_ir("uflacs", itg_data, form_data, form_id) # Store element classnames ir["classnames"] = classnames # Get element space dimensions unique_elements = element_numbers.keys() ir["element_dimensions"] = { ufl_element: create_element(ufl_element).space_dimension() for ufl_element in unique_elements } # Create dimensions of primary indices, needed to reset the argument 'A' # given to tabulate_tensor() by the assembler. argument_dimensions = [ir["element_dimensions"][ufl_element] for ufl_element in form_data.argument_elements] # Compute shape of element tensor if ir["integral_type"] == "interior_facet": ir["tensor_shape"] = [2 * dim for dim in argument_dimensions] else: ir["tensor_shape"] = argument_dimensions integral_type = itg_data.integral_type cell = itg_data.domain.ufl_cell() if integral_type in custom_integral_types: # Set quadrature degree to twice the highest element degree, to get # enough points to identify basis functions via table computations max_element_degree = max([1] + [ufl_element.degree() for ufl_element in unique_elements]) rules = [("default", 2*max_element_degree)] quadrature_integral_type = "cell" else: # Collect which quadrature rules occur in integrals default_scheme = itg_data.metadata["quadrature_degree"] default_degree = itg_data.metadata["quadrature_rule"] rules = collect_quadrature_rules( itg_data.integrals, default_scheme, default_degree) quadrature_integral_type = integral_type # Compute actual points and weights quadrature_rules, quadrature_rule_sizes = compute_quadrature_rules( rules, quadrature_integral_type, cell) # Store quadrature rules in format { num_points: (points, weights) } ir["quadrature_rules"] = quadrature_rules # Store the fake num_points for analysis in custom integrals if integral_type in custom_integral_types: ir["fake_num_points"], = quadrature_rules.keys() # Group and accumulate integrals on the format { num_points: integral data } sorted_integrals = accumulate_integrals(itg_data, quadrature_rule_sizes) # Build coefficient numbering for UFC interface here, to avoid # renumbering in UFL and application of replace mapping if True: # Using the mapped coefficients, numbered by UFL coefficient_numbering = {} sorted_coefficients = sorted_by_count(form_data.function_replace_map.keys()) for i, f in enumerate(sorted_coefficients): g = form_data.function_replace_map[f] coefficient_numbering[g] = i assert i == g.count() # Replace coefficients so they all have proper element and domain for what's to come # TODO: We can avoid the replace call when proper Expression support is in place # and element/domain assignment is removed from compute_form_data. integrands = { num_points: replace(sorted_integrals[num_points].integrand(), form_data.function_replace_map) for num_points in sorted(sorted_integrals) } else: pass #coefficient_numbering = {} #coefficient_element = {} #coefficient_domain = {} #sorted_coefficients = sorted_by_count(form_data.function_replace_map.keys()) #for i, f in enumerate(sorted_coefficients): # g = form_data.function_replace_map[f] # coefficient_numbering[f] = i # coefficient_element[f] = g.ufl_element() # coefficient_domain[f] = g.ufl_domain() #integrands = { # num_points: sorted_integrals[num_points].integrand() # for num_points in sorted(sorted_integrals) # } # then pass coefficient_element and coefficient_domain to the uflacs ir as well # Build the more uflacs-specific intermediate representation uflacs_ir = build_uflacs_ir(itg_data.domain.ufl_cell(), itg_data.integral_type, ir["entitytype"], integrands, ir["tensor_shape"], coefficient_numbering, quadrature_rules, parameters) ir.update(uflacs_ir) return ir
def compute_integral_ir(itg_data, form_data, form_id, element_numbers, classnames, parameters): "Compute intermediate represention of integral." info("Computing quadrature representation") issue_deprecation_warning() set_float_formatting(parameters["precision"]) # Initialise representation ir = initialize_integral_ir("quadrature", itg_data, form_data, form_id) # Create and save the optisation parameters. ir["optimise_parameters"] = parse_optimise_parameters(parameters, itg_data) # Sort integrals into a dict with quadrature degree and rule as # key sorted_integrals = sort_integrals(itg_data.integrals, itg_data.metadata["quadrature_degree"], itg_data.metadata["quadrature_rule"]) # Tabulate quadrature points and basis function values in these # points integrals_dict, psi_tables, quadrature_rules = \ tabulate_basis(sorted_integrals, form_data, itg_data) # Save tables for quadrature weights and points ir["quadrature_rules"] = quadrature_rules # Create dimensions of primary indices, needed to reset the # argument 'A' given to tabulate_tensor() by the assembler. ir["prim_idims"] = [create_element(ufl_element).space_dimension() for ufl_element in form_data.argument_elements] # Select transformer if ir["optimise_parameters"]["optimisation"]: QuadratureTransformerClass = QuadratureTransformerOpt else: QuadratureTransformerClass = QuadratureTransformer # Create transformer transformer = QuadratureTransformerClass(psi_tables, quadrature_rules, itg_data.domain.geometric_dimension(), itg_data.domain.topological_dimension(), ir["entitytype"], form_data.function_replace_map, ir["optimise_parameters"]) # Transform integrals. cell = itg_data.domain.ufl_cell() ir["trans_integrals"] = _transform_integrals_by_type(ir, transformer, integrals_dict, itg_data.integral_type, cell) # Save tables populated by transformer ir["name_map"] = transformer.name_map ir["unique_tables"] = transformer.unique_tables # Basis values? # Save tables map, to extract table names for optimisation option # -O. ir["psi_tables_map"] = transformer.psi_tables_map ir["additional_includes_set"] = transformer.additional_includes_set # Insert empty data which will be populated if optimization is # turned on ir["geo_consts"] = {} # Extract element data for psi_tables, needed for runtime # quadrature. This is used by integral type custom_integral. ir["element_data"] = _extract_element_data(transformer.element_map, classnames) return ir
def compute_integral_ir(itg_data, form_data, form_id, parameters): "Compute intermediate represention of integral." info("Computing tensor representation") # Extract monomial representation monomial_form = extract_monomial_form(itg_data.integrals, form_data.function_replace_map) # Transform monomial form to reference element transform_monomial_form(monomial_form) # Get some cell properties cell = form_data.cell cellname = cell.cellname() facet_cellname = cell.facet_cellname() num_facets = cellname_to_num_entities[cellname][-2] # Initialize representation ir = initialize_integral_ir("tensor", itg_data, form_data, form_id) ir["rank"] = form_data.rank # Compute representation of cell tensor quadrature_degree = itg_data.metadata["quadrature_degree"] quadrature_rule = itg_data.metadata["quadrature_rule"] if itg_data.domain_type == "cell": # Compute sum of tensor representations ir["AK"] = _compute_terms(monomial_form, None, None, itg_data.domain_type, quadrature_degree, quadrature_rule, cellname, facet_cellname) elif itg_data.domain_type == "exterior_facet": # Compute sum of tensor representations for each facet terms = [None for i in range(num_facets)] for i in range(num_facets): terms[i] = _compute_terms(monomial_form, i, None, itg_data.domain_type, quadrature_degree, quadrature_rule, cellname, facet_cellname) ir["AK"] = terms elif itg_data.domain_type == "interior_facet": # Compute sum of tensor representations for each facet-facet pair terms = [[None for j in range(num_facets)] for i in range(num_facets)] for i in range(num_facets): for j in range(num_facets): terms[i][j] = _compute_terms(monomial_form, i, j, itg_data.domain_type, quadrature_degree, quadrature_rule, cellname, facet_cellname) reorder_entries(terms[i][j]) ir["AK"] = terms else: error("Unhandled domain type: " + str(itg_data.domain_type)) return ir