def _setup(self): """A setup method to initialize all the local assembly kernels generated by TSFC and creates templated function calls conforming to the Eigen-C++ template library standard. This function also collects any information regarding orientations and extra include directories. """ transformer = Transformer() include_dirs = [] templated_subkernels = [] assembly_calls = OrderedDict([(it, []) for it in self.supported_integral_types]) subdomain_calls = OrderedDict([(sd, []) for sd in self.supported_subdomain_types]) coords = None oriented = False needs_cell_sizes = False # Maps integral type to subdomain key subdomain_map = {"exterior_facet": "subdomains_exterior_facet", "exterior_facet_vert": "subdomains_exterior_facet", "interior_facet": "subdomains_interior_facet", "interior_facet_vert": "subdomains_interior_facet"} for cxt_kernel in self.context_kernels: local_coefficients = cxt_kernel.coefficients it_type = cxt_kernel.original_integral_type exp = cxt_kernel.tensor if it_type not in self.supported_integral_types: raise ValueError("Integral type '%s' not recognized" % it_type) # Explicit checking of coordinates coordinates = cxt_kernel.tensor.ufl_domain().coordinates if coords is not None: assert coordinates == coords, "Mismatching coordinates!" else: coords = coordinates for split_kernel in cxt_kernel.tsfc_kernels: indices = split_kernel.indices kinfo = split_kernel.kinfo kint_type = kinfo.integral_type needs_cell_sizes = needs_cell_sizes or kinfo.needs_cell_sizes args = [c for i in kinfo.coefficient_map for c in self.coefficient(local_coefficients[i])] if kinfo.oriented: args.insert(0, self.cell_orientations_sym) if kint_type in ["interior_facet", "exterior_facet", "interior_facet_vert", "exterior_facet_vert"]: args.append(ast.FlatBlock("&%s" % self.it_sym)) if kinfo.needs_cell_sizes: args.append(self.cell_size_sym) # Assembly calls within the macro kernel tensor = eigen_tensor(exp, self.temps[exp], indices) call = ast.FunCall(kinfo.kernel.name, tensor, self.coord_sym, *args) # Subdomains only implemented for exterior facet integrals if kinfo.subdomain_id != "otherwise": if kint_type not in subdomain_map: msg = "Subdomains for integral type '%s' not implemented" % kint_type raise NotImplementedError(msg) sd_id = kinfo.subdomain_id sd_key = subdomain_map[kint_type] subdomain_calls[sd_key].append((sd_id, call)) else: assembly_calls[it_type].append(call) # Subkernels for local assembly (Eigen templated functions) from coffee.base import Node assert isinstance(kinfo.kernel._code, Node) kast = transformer.visit(kinfo.kernel._code) templated_subkernels.append(kast) include_dirs.extend(kinfo.kernel._include_dirs) oriented = oriented or kinfo.oriented # Add subdomain call to assembly dict assembly_calls.update(subdomain_calls) self.assembly_calls = assembly_calls self.templated_subkernels = templated_subkernels self.include_dirs = list(set(include_dirs)) self.oriented = oriented self.needs_cell_sizes = needs_cell_sizes
def _setup(self): """A setup method to initialize all the local assembly kernels generated by TSFC and creates templated function calls conforming to the Eigen-C++ template library standard. This function also collects any information regarding orientations and extra include directories. """ transformer = Transformer() include_dirs = [] templated_subkernels = [] assembly_calls = OrderedDict([(it, []) for it in self.supported_integral_types]) coords = None oriented = False for cxt_kernel in self.context_kernels: local_coefficients = cxt_kernel.coefficients it_type = cxt_kernel.original_integral_type exp = cxt_kernel.tensor if it_type not in self.supported_integral_types: raise ValueError("Integral type '%s' not recognized" % it_type) # Explicit checking of coordinates coordinates = cxt_kernel.tensor.ufl_domain().coordinates if coords is not None: assert coordinates == coords, "Mismatching coordinates!" else: coords = coordinates for split_kernel in cxt_kernel.tsfc_kernels: indices = split_kernel.indices kinfo = split_kernel.kinfo # TODO: Implement subdomains for Slate tensors if kinfo.subdomain_id != "otherwise": raise NotImplementedError("Subdomains not implemented.") args = [ c for i in kinfo.coefficient_map for c in self.coefficient(local_coefficients[i]) ] if kinfo.oriented: args.insert(0, self.cell_orientations_sym) if kinfo.integral_type in [ "interior_facet", "exterior_facet", "interior_facet_vert", "exterior_facet_vert" ]: args.append(ast.FlatBlock("&%s" % self.it_sym)) # Assembly calls within the macro kernel tensor = eigen_tensor(exp, self.temps[exp], indices) call = ast.FunCall(kinfo.kernel.name, tensor, self.coord_sym, *args) assembly_calls[it_type].append(call) # Subkernels for local assembly (Eigen templated functions) kast = transformer.visit(kinfo.kernel._ast) templated_subkernels.append(kast) include_dirs.extend(kinfo.kernel._include_dirs) oriented = oriented or kinfo.oriented self.assembly_calls = assembly_calls self.templated_subkernels = templated_subkernels self.include_dirs = list(set(include_dirs)) self.oriented = oriented