def __repr__(self): r = "Integral(%s, %s, %s, %s, %s, %s)" % (repr(self._integrand), repr(self._integral_type), repr(self._ufl_domain), repr(self._subdomain_id), repr(self._metadata), repr(self._subdomain_data)) return as_native_str(r)
def __repr__(self): "Compute repr string of form. This can be huge for complicated forms." # Warning used for making sure we don't use this in the general pipeline: # warning("Calling repr on form is potentially expensive and should be avoided except during debugging.") # Not caching this because it can be huge itgs = ", ".join(repr(itg) for itg in self.integrals()) r = "Form([" + itgs + "])" return as_native_str(r)
def __init__(self, *elements): self._elements = elements cell = elements[0].cell() if not all(e.cell() == cell for e in elements[1:]): error("Cell mismatch for sub elements of enriched element.") if isinstance(elements[0].degree(), int): degrees = {e.degree() for e in elements} - {None} degree = max(degrees) if degrees else None else: degree = tuple(map(max, zip(*[e.degree() for e in elements]))) # We can allow the scheme not to be defined, but all defined # should be equal quad_schemes = [e.quadrature_scheme() for e in elements] quad_schemes = [qs for qs in quad_schemes if qs is not None] quad_scheme = quad_schemes[0] if quad_schemes else None if not all(qs == quad_scheme for qs in quad_schemes): error("Quadrature scheme mismatch.") value_shape = elements[0].value_shape() if not all(e.value_shape() == value_shape for e in elements[1:]): error("Element value shape mismatch.") reference_value_shape = elements[0].reference_value_shape() if not all(e.reference_value_shape() == reference_value_shape for e in elements[1:]): error("Element reference value shape mismatch.") # mapping = elements[0].mapping() # FIXME: This fails for a mixed subelement here. # if not all(e.mapping() == mapping for e in elements[1:]): # error("Element mapping mismatch.") # Get name of subclass: EnrichedElement or NodalEnrichedElement class_name = as_native_str(self.__class__.__name__) # Initialize element data FiniteElementBase.__init__(self, class_name, cell, degree, quad_scheme, value_shape, reference_value_shape) # Cache repr string self._repr = as_native_str("%s(%s)" % (class_name, ", ".join(repr(e) for e in self._elements)))
def __init__(self, element): self._element = element self._repr = as_native_str("BrokenElement(%s)" % repr(element)) family = "BrokenElement" cell = element.cell() degree = element.degree() quad_scheme = element.quadrature_scheme() value_shape = element.value_shape() reference_value_shape = element.reference_value_shape() FiniteElementBase.__init__(self, family, cell, degree, quad_scheme, value_shape, reference_value_shape)
def __repr__(self): # For standard cells, return name of builtin cell object if # possible. This reduces the size of the repr strings for # domains, elements, etc. as well gdim = self.geometric_dimension() tdim = self.topological_dimension() name = self.cellname() if gdim == tdim and name in cellname2dim: r = name else: r = "Cell(%s, %s)" % (repr(name), repr(gdim)) return as_native_str(r)
def attach_ufl_id(cls): """Equip class with ``.ufl_id()`` and handle bookkeeping. Usage: 1. Apply to class:: @attach_ufl_id class MyClass(object): 2. If ``__slots__`` is defined, include ``_ufl_id`` attribute:: __slots__ = ("_ufl_id",) 3. Add keyword argument to constructor:: def __init__(self, *args, ufl_id=None): 4. Call ``self._init_ufl_id`` with ``ufl_id`` and assign to ``._ufl_id`` attribute:: self._ufl_id = self._init_ufl_id(ufl_id) Result: ``MyClass().ufl_id()`` returns unique value for each constructed object. """ def _get_ufl_id(self): "Return the ufl_id of this object." return self._ufl_id def _init_ufl_id(cls): "Initialize new ufl_id for the object under construction." # Bind cls with closure here def init_ufl_id(self, ufl_id): if ufl_id is None: ufl_id = cls._ufl_global_id cls._ufl_global_id = max(ufl_id, cls._ufl_global_id) + 1 return ufl_id return init_ufl_id # Modify class: if hasattr(cls, "__slots__"): assert as_native_str("_ufl_id") in cls.__slots__ cls._ufl_global_id = 0 cls.ufl_id = _get_ufl_id cls._init_ufl_id = _init_ufl_id(cls) return cls
def __init__(self, element): self._element = element self._repr = as_native_str("HDivElement(%s)" % repr(element)) family = "TensorProductElement" cell = element.cell() degree = element.degree() quad_scheme = element.quadrature_scheme() value_shape = (element.cell().geometric_dimension(),) reference_value_shape = (element.cell().topological_dimension(),) # Skipping TensorProductElement constructor! Bad code smell, refactor to avoid this non-inheritance somehow. FiniteElementBase.__init__(self, family, cell, degree, quad_scheme, value_shape, reference_value_shape)
def __init__(self, element, restriction_domain): if not isinstance(element, FiniteElementBase): error("Expecting a finite element instance.") if restriction_domain not in valid_restriction_domains: error("Expecting one of the strings %s." % (valid_restriction_domains,)) FiniteElementBase.__init__(self, "RestrictedElement", element.cell(), element.degree(), element.quadrature_scheme(), element.value_shape(), element.reference_value_shape()) self._element = element self._restriction_domain = restriction_domain self._repr = as_native_str("RestrictedElement(%s, %s)" % ( repr(self._element), repr(self._restriction_domain)))
def __init__(self, function_space, count=None): FormArgument.__init__(self) counted_init(self, count, Coefficient) if isinstance(function_space, FiniteElementBase): # For legacy support for .ufl files using cells, we map # the cell to The Default Mesh element = function_space domain = default_domain(element.cell()) function_space = FunctionSpace(domain, element) elif not isinstance(function_space, AbstractFunctionSpace): error("Expecting a FunctionSpace or FiniteElement.") self._ufl_function_space = function_space self._ufl_shape = function_space.ufl_element().value_shape() self._repr = as_native_str("Coefficient(%s, %s)" % ( repr(self._ufl_function_space), repr(self._count)))
def __repr__(self): "Return a repr string for this Measure." global integral_type_to_measure_name args = [] args.append(repr(self._integral_type)) if self._subdomain_id is not None: args.append("subdomain_id=%s" % repr(self._subdomain_id)) if self._domain is not None: args.append("domain=%s" % repr(self._domain)) if self._metadata: # Stored as EmptyDict if None args.append("metadata=%s" % repr(self._metadata)) if self._subdomain_data is not None: args.append("subdomain_data=%s" % repr(self._subdomain_data)) r = "%s(%s)" % (type(self).__name__, ', '.join(args)) return as_native_str(r)
def run_command(command, verbose): "Run command and collect errors in log file." global _command_timings t1 = time.time() try: output = as_native_str(subprocess.check_output(command, shell=True)) t2 = time.time() _command_timings.append((command, t2 - t1)) if verbose: print(output) return True except subprocess.CalledProcessError as e: t2 = time.time() _command_timings.append((command, t2 - t1)) if e.output: log_error(e.output) print(e.output) return False
def __init__(self, function_space, number, part=None): FormArgument.__init__(self) if isinstance(function_space, FiniteElementBase): # For legacy support for .ufl files using cells, we map the cell to # the default Mesh element = function_space domain = default_domain(element.cell()) function_space = FunctionSpace(domain, element) elif not isinstance(function_space, AbstractFunctionSpace): error("Expecting a FunctionSpace or FiniteElement.") self._ufl_function_space = function_space self._ufl_shape = function_space.ufl_element().value_shape() if not isinstance(number, numbers.Integral): error("Expecting an int for number, not %s" % (number,)) if part is not None and not isinstance(part, numbers.Integral): error("Expecting None or an int for part, not %s" % (part,)) self._number = number self._part = part self._repr = as_native_str("Argument(%s, %s, %s)" % ( repr(self._ufl_function_space), repr(self._number), repr(self._part)))
def __repr__(self): r = "SobolevSpace(%s, %s)" % (repr(self.name), repr( list(self.parents))) return as_native_str(r)
def __repr__(self): r = "TensorProductMesh(%s, %s)" % (repr(self._ufl_meshes), repr(self._ufl_id)) return as_native_str(r)
def __repr__(self): r = "%s(%s)" % (self._ufl_class_.__name__, repr(self._domain)) return as_native_str(r)
def __repr__(self): r = "MultiIndex(%s)" % repr(self._indices) return as_native_str(r)
def __repr__(self): r = "Mesh(%s, %s)" % (repr(self._ufl_coordinate_element), repr(self._ufl_id)) return as_native_str(r)
def __init__(self, family, cell=None, degree=None, form_degree=None, quad_scheme=None, variant=None): """Create finite element. *Arguments* family (string) The finite element family cell The geometric cell degree (int) The polynomial degree (optional) form_degree (int) The form degree (FEEC notation, used when field is viewed as k-form) quad_scheme The quadrature scheme (optional) variant Hint for the local basis function variant (optional) """ # Note: Unfortunately, dolfin sometimes passes None for # cell. Until this is fixed, allow it: if cell is not None: cell = as_cell(cell) family, short_name, degree, value_shape, reference_value_shape, sobolev_space, mapping = canonical_element_description(family, cell, degree, form_degree) # TODO: Move these to base? Might be better to instead # simplify base though. self._sobolev_space = sobolev_space self._mapping = mapping self._short_name = short_name self._variant = variant # Finite elements on quadrilaterals and hexahedrons have an IrreducibleInt as degree if cell is not None: if cell.cellname() in ["quadrilateral", "hexahedron"]: from ufl.algorithms.estimate_degrees import IrreducibleInt degree = IrreducibleInt(degree) # Type check variant if variant is not None and not isinstance(variant, str): raise ValueError("Illegal variant: must be string or None") # Initialize element data FiniteElementBase.__init__(self, family, cell, degree, quad_scheme, value_shape, reference_value_shape) # Cache repr string qs = self.quadrature_scheme() if qs is None: quad_str = "" else: quad_str = ", quad_scheme=%s" % repr(qs) v = self.variant() if v is None: var_str = "" else: var_str = ", variant=%s" % repr(v) self._repr = as_native_str("FiniteElement(%s, %s, %s%s%s)" % ( repr(self.family()), repr(self.cell()), repr(self.degree()), quad_str, var_str)) assert '"' not in self._repr
def __repr__(self): r = "Label(%d)" % self._count return as_native_str(r)
def __repr__(self): r = "%s(%s)" % (type(self).__name__, repr(self._value)) return as_native_str(r)
def __repr__(self): r = "Identity(%d)" % self._dim return as_native_str(r)
def __repr__(self): r = "ExprList(*%s)" % repr(self.ufl_operands) return as_native_str(r)
def __repr__(self): r = "Zero(%s, %s, %s)" % ( repr(self.ufl_shape), repr(self.ufl_free_indices), repr(self.ufl_index_dimensions)) return as_native_str(r)
def __repr__(self): r = "Index(%d)" % self._count return as_native_str(r)
def __repr__(self): r = "Integral(%s, %s, %s, %s, %s, %s)" % ( repr(self._integrand), repr(self._integral_type), repr(self._ufl_domain), repr(self._subdomain_id), repr(self._metadata), repr(self._subdomain_data)) return as_native_str(r)
def __repr__(self): r = "PermutationSymbol(%d)" % self._dim return as_native_str(r)
def __repr__(self): tdim = self.topological_dimension() r = "MeshView(%s, %s, %s)" % (repr( self._ufl_mesh), repr(tdim), repr(self._ufl_id)) return as_native_str(r)
def __init__(self, family, cell=None, degree=None, form_degree=None, quad_scheme=None, variant=None): """Create finite element. *Arguments* family (string) The finite element family cell The geometric cell degree (int) The polynomial degree (optional) form_degree (int) The form degree (FEEC notation, used when field is viewed as k-form) quad_scheme The quadrature scheme (optional) variant Hint for the local basis function variant (optional) """ # Note: Unfortunately, dolfin sometimes passes None for # cell. Until this is fixed, allow it: if cell is not None: cell = as_cell(cell) family, short_name, degree, value_shape, reference_value_shape, sobolev_space, mapping = canonical_element_description( family, cell, degree, form_degree) # TODO: Move these to base? Might be better to instead # simplify base though. self._sobolev_space = sobolev_space self._mapping = mapping self._short_name = short_name self._variant = variant # Finite elements on quadrilaterals and hexahedrons have an IrreducibleInt as degree if cell is not None: if cell.cellname() in ["quadrilateral", "hexahedron"]: from ufl.algorithms.estimate_degrees import IrreducibleInt degree = IrreducibleInt(degree) # Type check variant if variant is not None and not isinstance(variant, str): raise ValueError("Illegal variant: must be string or None") # Initialize element data FiniteElementBase.__init__(self, family, cell, degree, quad_scheme, value_shape, reference_value_shape) # Cache repr string qs = self.quadrature_scheme() if qs is None: quad_str = "" else: quad_str = ", quad_scheme=%s" % repr(qs) v = self.variant() if v is None: var_str = "" else: var_str = ", variant=%s" % repr(v) self._repr = as_native_str("FiniteElement(%s, %s, %s%s%s)" % (repr(self.family()), repr(self.cell()), repr(self.degree()), quad_str, var_str)) assert '"' not in self._repr
def main(args): "Run all regression tests." # Check command-line arguments TODO: Use argparse only_auto = "--only-auto" in args use_auto = "--skip-auto" not in args use_uflacs = "--skip-uflacs" not in args use_quad = "--skip-quad" not in args use_tsfc = "--use-tsfc" in args use_ext_quad = "--ext-quad" in args use_ext_uflacs = "--ext-uflacs" in args skip_download = "--skip-download" in args skip_run = "--skip-run" in args skip_code_diff = "--skip-code-diff" in args skip_validate = "--skip-validate" in args bench = "--bench" in args debug = "--debug" in args verbose = ("--verbose" in args) or debug # debug implies verbose permissive = "--permissive" in args or bench tolerant = "--tolerant" in args print_timing = "--print-timing" in args show_help = "--help" in args flags = ( "--only-auto", "--skip-auto", "--skip-uflacs", "--skip-quad", "--use-tsfc", "--ext-quad", "--skip-download", "--skip-run", "--skip-code-diff", "--skip-validate", "--bench", "--debug", "--verbose", "--permissive", "--tolerant", "--print-timing", "--help", ) args = [arg for arg in args if arg not in flags] # Hack: add back --verbose for ffc.main to see if verbose: args = args + ["--verbose"] if show_help: info("Valid arguments:\n" + "\n".join(flags)) return 0 if bench or not skip_validate: skip_run = False if bench: skip_code_diff = True skip_validate = True if use_ext_quad or use_ext_uflacs: skip_code_diff = True # Extract .ufl names from args only_forms = set([arg for arg in args if arg.endswith(".ufl")]) args = [arg for arg in args if arg not in only_forms] # Download reference data if skip_download: info_blue("Skipping reference data download") else: try: cmd = "./scripts/download" output = as_native_str(subprocess.check_output(cmd, shell=True)) print(output) info_green("Download reference data ok") except subprocess.CalledProcessError as e: print(e.output) info_red("Download reference data failed") if tolerant: global output_tolerance output_tolerance = 1e-3 # Clean out old output directory output_directory = "output" clean_output(output_directory) os.chdir(output_directory) # Adjust which test cases (combinations of compile arguments) to run here test_cases = [] if only_auto: test_cases += ["-r auto"] else: if use_auto: test_cases += ["-r auto"] if use_uflacs: test_cases += ["-r uflacs -O0", "-r uflacs -O"] if use_quad: test_cases += ["-r quadrature -O0", "-r quadrature -O"] import warnings from ffc.quadrature.deprecation import QuadratureRepresentationDeprecationWarning warnings.simplefilter("once", QuadratureRepresentationDeprecationWarning) if use_tsfc: test_cases += ["-r tsfc -O0", "-r tsfc -O"] # Silence good-performance messages by COFFEE import coffee coffee.set_log_level(coffee.logger.PERF_WARN) if use_ext_quad: test_cases += ext_quad if use_ext_uflacs: test_cases += ext_uflacs test_case_timings = {} fails = OrderedDict() for argument in test_cases: test_case_timings[argument] = time.time() fails[argument] = OrderedDict() begin("Running regression tests with %s" % argument) # Clear and enter output sub-directory sub_directory = "_".join(argument.split(" ")).replace("-", "") clean_output(sub_directory) os.chdir(sub_directory) # Workarounds for feature lack in representation if "quadrature" in argument and not only_forms: skip_forms = known_quad_failures info_blue("Skipping forms known to fail with quadrature:\n" + "\n".join(sorted(skip_forms))) elif "uflacs" in argument and not only_forms: skip_forms = known_uflacs_failures info_blue("Skipping forms known to fail with uflacs:\n" + "\n".join(sorted(skip_forms))) elif "tsfc" in argument and not only_forms: skip_forms = known_tsfc_failures info_blue("Skipping forms known to fail with tsfc:\n" + "\n".join(sorted(skip_forms))) else: skip_forms = set() # Generate test cases generate_test_cases(bench, only_forms, skip_forms) # Generate code failures = generate_code(args + argument.split(), only_forms, skip_forms, debug) if failures: fails[argument]["generate_code"] = failures # Location of reference directories reference_directory = os.path.abspath("../../ffc-reference-data/") code_reference_dir = os.path.join(reference_directory, sub_directory) # Note: We use the r_auto references for all test cases. This # ensures that we continously test that the codes generated by # all different representations are equivalent. output_reference_dir = os.path.join(reference_directory, "r_auto") # Validate code by comparing to code generated with this set # of compiler parameters if skip_code_diff: info_blue("Skipping code diff validation") else: failures = validate_code(code_reference_dir) if failures: fails[argument]["validate_code"] = failures # Build and run programs and validate output to common # reference if skip_run: info_blue("Skipping program execution") else: failures = build_programs(bench, permissive, debug, verbose) if failures: fails[argument]["build_programs"] = failures failures = run_programs(bench, debug, verbose) if failures: fails[argument]["run_programs"] = failures # Validate output to common reference results if skip_validate: info_blue("Skipping program output validation") else: failures = validate_programs(output_reference_dir) if failures: fails[argument]["validate_programs"] = failures # Go back up os.chdir(os.path.pardir) end() test_case_timings[argument] = time.time() - test_case_timings[argument] # Go back up os.chdir(os.path.pardir) # Print results if print_timing: info_green("Timing of all commands executed:") timings = '\n'.join("%10.2e s %s" % (t, name) for (name, t) in _command_timings) info_blue(timings) for argument in test_cases: info_blue("Total time for %s: %.1f s" % (argument, test_case_timings[argument])) num_failures = sum(len(failures_phase) for failures_args in fails.values() for failures_phase in failures_args.values()) if num_failures == 0: info_green("Regression tests OK") return 0 else: info_red("Regression tests failed") info_red("") info_red("Long summary:") for argument in test_cases: if not fails[argument]: info_green(" No failures with args '%s'" % argument) else: info_red(" Failures with args '%s':" % argument) for phase, failures in fails[argument].items(): info_red(" %d failures in %s:" % (len(failures), phase)) for f in failures: info_red(" %s" % (f,)) info_red("") info_red("Short summary:") phase_fails = defaultdict(int) for argument in test_cases: if not fails[argument]: info_green(" No failures with args '%s'" % argument) else: info_red(" Number of failures with args '%s':" % argument) for phase, failures in fails[argument].items(): info_red(" %d failures in %s." % (len(failures), phase)) phase_fails[phase] += len(failures) info_red("") info_red("Total failures for all args:") for phase, count in phase_fails.items(): info_red(" %s: %d failed" % (phase, count)) info_red("") info_red("Error messages stored in %s" % logfile) return 1
def __repr__(self): r = "MixedFunctionSpace(*%s)" % repr(self._ufl_function_spaces) return as_native_str(r)
def __repr__(self): r = "TensorProductFunctionSpace(*%s)" % repr(self._ufl_function_spaces) return as_native_str(r)
def __repr__(self): r = "FixedIndex(%d)" % self._value return as_native_str(r)
def __repr__(self): tdim = self.topological_dimension() r = "MeshView(%s, %s, %s)" % (repr(self._ufl_mesh), repr(tdim), repr(self._ufl_id)) return as_native_str(r)
def __repr__(self): "Default repr string construction for operators." # This should work for most cases r = "%s(%s)" % (self._ufl_class_.__name__, ", ".join( repr(op) for op in self.ufl_operands)) return as_native_str(r)
def __repr__(self): "Default repr string construction for operators." # This should work for most cases r = "%s(%s)" % (self._ufl_class_.__name__, ", ".join(repr(op) for op in self.ufl_operands)) return as_native_str(r)
def __repr__(self): r = "SobolevSpace(%s, %s)" % (repr(self.name), repr(list( self.parents))) return as_native_str(r)
def __repr__(self): r = "Equation(%s, %s)" % (repr(self.lhs), repr(self.rhs)) return as_native_str(r)
def __repr__(self): r = "Mesh(%s, %s)" % (repr( self._ufl_coordinate_element), repr(self._ufl_id)) return as_native_str(r)
def __repr__(self): r = "FunctionSpace(%s, %s)" % (repr(self._ufl_domain), repr(self._ufl_element)) return as_native_str(r)