예제 #1
0
 def deprecated_signature(self, function_replace_map=None):
     if self._signature is None:
         from ufl.algorithms.signature import compute_form_signature
         self._signature = compute_form_signature(self,
                                                  function_replace_map)
     assert self._signature
     return self._signature
예제 #2
0
    def _store(self, obj, form, bcs):
        form_sig = compute_form_signature(form)

        if self.invalid_count[form_sig] > parameters["assembly_cache"]["max_misses"]:
            if self.invalid_count[form_sig] == \
               parameters["assembly_cache"]["max_misses"] + 1:
                debug("form %s missed too many times, excluding from cache." % form)

        else:
            cache_entry = _CacheEntry(obj, form, bcs)
            self.cache[form_sig] = cache_entry
            self.evict()
예제 #3
0
    def _lookup(self, form, bcs):
        form_sig = compute_form_signature(form)
        cache_entry = self.cache.get(form_sig, None)

        retval = None
        if cache_entry is not None:
            if not cache_entry.is_valid(form, bcs):
                self.invalid_count[form_sig] += 1
                del self.cache[form_sig]
                return None
            else:
                self.invalid_count[form_sig] = 0

            retval = cache_entry.get_object()
            self._hits += 1
            self._hits_size += retval.nbytes

        return retval
예제 #4
0
def preprocess(form,
               object_names=None,
               common_cell=None,
               element_mapping=None):
    """
    Preprocess raw input form to obtain form metadata, including a
    modified (preprocessed) form more easily manipulated by form
    compilers. The original form is left untouched. Currently, the
    following transformations are made to the preprocessed form:

      expand_compounds    (side effect of calling expand_derivatives)
      expand_derivatives
      renumber arguments and coefficients and apply evt. element mapping
    """
    tic = Timer('preprocess')  # TODO: Reposition tic calls after refactoring.

    # Check that we get a form
    ufl_assert(isinstance(form, Form), "Expecting Form.")
    original_form = form

    # Object names is empty if not given
    object_names = object_names or {}

    # Element mapping is empty if not given
    element_mapping = element_mapping or {}

    # Create empty form data
    form_data = FormData()

    # Store copies of preprocess input data, for future validation if called again...
    form_data._input_object_names = dict(object_names)
    form_data._input_element_mapping = dict(element_mapping)
    #form_data._input_common_cell = no need to store this

    # Store name of form if given, otherwise empty string
    # such that automatic names can be assigned externally
    form_data.name = object_names.get(id(form), "")

    # Extract common cell
    common_cell = extract_common_cell(form, common_cell)

    # TODO: Split out expand_compounds from expand_derivatives
    # Expand derivatives
    tic('expand_derivatives')
    form = expand_derivatives(form, common_cell.geometric_dimension())  # EXPR

    # Propagate restrictions of interior facet integrals to the terminal nodes
    form = propagate_restrictions(form)  # INTEGRAL, EXPR

    # --- BEGIN DOMAIN SPLITTING AND JOINING
    # Store domain metadata per domain type
    form_data.domain_data = extract_domain_data(form)

    # Split up integrals and group by domain type and domain id,
    # adding integrands with same domain and compiler data
    sub_integral_data = integral_dict_to_sub_integral_data(
        form.integral_groups())
    # TODO: Replace integral_data with this through ufl and ffc?
    if 0: print_sub_integral_data(sub_integral_data)

    # Reconstruct form from these integrals in a more canonical representation
    form = reconstruct_form_from_sub_integral_data(sub_integral_data,
                                                   form_data.domain_data)

    # Represent in the way ffc expects TODO: Change ffc? Fine for now.
    form_data.integral_data = convert_sub_integral_data_to_integral_data(
        sub_integral_data)
    # --- END DOMAIN SPLITTING AND JOINING

    # --- BEGIN FUNCTION ANALYSIS
    # --- BEGIN SPLIT EXPR JOIN
    # Replace arguments and coefficients with new renumbered objects
    tic('extract_arguments_and_coefficients')
    original_arguments, original_coefficients = \
        extract_arguments_and_coefficients(form)

    tic('build_element_mapping')
    element_mapping = build_element_mapping(element_mapping, common_cell,
                                            original_arguments,
                                            original_coefficients)

    tic('build_argument_replace_map')  # TODO: Remove renumbered ones?
    replace_map, renumbered_arguments, renumbered_coefficients = \
        build_argument_replace_map(original_arguments,
                                   original_coefficients,
                                   element_mapping)

    # Note: This is the earliest point signature can be computed

    # Build mapping to original arguments and coefficients, which is
    # useful if the original arguments have data attached to them
    inv_replace_map = dict((w, v) for (v, w) in replace_map.iteritems())
    original_arguments = [inv_replace_map[v] for v in renumbered_arguments]
    original_coefficients = [
        inv_replace_map[w] for w in renumbered_coefficients
    ]

    # TODO: Build mapping from object to position instead? But we need mapped elements as well anyway.
    #argument_positions = { v: i }
    #coefficient_positions = { w: i }

    # Store data extracted by preprocessing
    form_data.original_arguments = original_arguments
    form_data.original_coefficients = original_coefficients
    # --- END SPLIT INTEGRAL JOIN

    # Mappings from elements and functions (coefficients and arguments)
    # that reside in form to objects with canonical numbering as well as
    # completed cells and elements
    # TODO: Create additional function mappings per integral,
    #       to have different counts? Depends on future UFC design.
    form_data.element_replace_map = element_mapping
    form_data.function_replace_map = replace_map

    # Store some useful dimensions
    form_data.rank = len(form_data.original_arguments)
    form_data.num_coefficients = len(form_data.original_coefficients)

    # Store argument names
    form_data.argument_names = \
        [object_names.get(id(form_data.original_arguments[i]), "v%d" % i)
         for i in range(form_data.rank)]

    # Store coefficient names
    form_data.coefficient_names = \
        [object_names.get(id(form_data.original_coefficients[i]), "w%d" % i)
         for i in range(form_data.num_coefficients)]
    # --- END FUNCTION ANALYSIS

    # --- BEGIN SIGNATURE COMPUTATION
    # TODO: Compute signatures of each INTEGRAL and EXPR as well, perhaps compute it hierarchially from integral_data?
    # Store signature of form
    tic('signature')
    # TODO: Remove signature() from Form, not safe to cache with a replacement map
    #form_data.signature = form.signature(form_data.function_replace_map)
    form_data.signature = compute_form_signature(
        form, form_data.function_replace_map)
    # --- END SIGNATURE COMPUTATION

    # --- BEGIN CONSISTENCY CHECKS
    # Check that we don't have a mixed linear/bilinear form or anything like that
    ufl_assert(
        len(compute_form_arities(form)) == 1,
        "All terms in form must have same rank.")
    # --- END CONSISTENCY CHECKS

    # --- BEGIN ELEMENT DATA
    # Store elements, sub elements and element map
    tic('extract_elements')
    form_data.argument_elements = tuple(f.element()
                                        for f in renumbered_arguments)
    form_data.coefficient_elements = tuple(f.element()
                                           for f in renumbered_coefficients)
    form_data.elements = form_data.argument_elements + form_data.coefficient_elements
    form_data.unique_elements = unique_tuple(form_data.elements)
    form_data.sub_elements = extract_sub_elements(form_data.elements)
    form_data.unique_sub_elements = unique_tuple(form_data.sub_elements)
    # --- END ELEMENT DATA

    # --- BEGIN DOMAIN DATA
    # Store element domains (NB! This is likely to change!)
    # TODO: DOMAINS: What is a sensible way to store domains for a form?
    form_data.domains = tuple(
        sorted(set(element.domain() for element in form_data.unique_elements)))

    # Store toplevel domains (NB! This is likely to change!)
    # TODO: DOMAINS: What is a sensible way to store domains for a form?
    form_data.top_domains = tuple(
        sorted(set(domain.top_domain() for domain in form_data.domains)))

    # Store common cell
    form_data.cell = common_cell

    # Store data related to cell
    form_data.geometric_dimension = form_data.cell.geometric_dimension()
    form_data.topological_dimension = form_data.cell.topological_dimension()

    # Store number of domains for integral types
    form_data.num_sub_domains = extract_num_sub_domains(form)
    # --- END DOMAIN DATA

    # A coarse profiling implementation TODO: Add counting of nodes, Add memory usage
    tic.end()
    if preprocess.enable_profiling:
        print tic

    # Store preprocessed form and return
    form_data.preprocessed_form = form
    form_data.preprocessed_form._is_preprocessed = True

    # Attach signatures to original and preprocessed forms TODO: Avoid this?
    ufl_assert(form_data.preprocessed_form._signature is None, "")
    form_data.preprocessed_form._signature = form_data.signature
    ufl_assert(original_form._signature is None, "")
    original_form._signature = form_data.signature

    return form_data
예제 #5
0
def preprocess(form, object_names=None, common_cell=None, element_mapping=None):
    """
    Preprocess raw input form to obtain form metadata, including a
    modified (preprocessed) form more easily manipulated by form
    compilers. The original form is left untouched. Currently, the
    following transformations are made to the preprocessed form:

      expand_compounds    (side effect of calling expand_derivatives)
      expand_derivatives
      renumber arguments and coefficients and apply evt. element mapping
    """
    tic = Timer('preprocess') # TODO: Reposition tic calls after refactoring.

    # Check that we get a form
    ufl_assert(isinstance(form, Form), "Expecting Form.")
    original_form = form

    # Object names is empty if not given
    object_names = object_names or {}

    # Element mapping is empty if not given
    element_mapping = element_mapping or {}

    # Create empty form data
    form_data = FormData()

    # Store copies of preprocess input data, for future validation if called again...
    form_data._input_object_names = dict(object_names)
    form_data._input_element_mapping = dict(element_mapping)
    #form_data._input_common_cell = no need to store this

    # Store name of form if given, otherwise empty string
    # such that automatic names can be assigned externally
    form_data.name = object_names.get(id(form), "")

    # Extract common cell
    common_cell = extract_common_cell(form, common_cell)

    # TODO: Split out expand_compounds from expand_derivatives
    # Expand derivatives
    tic('expand_derivatives')
    form = expand_derivatives(form, common_cell.geometric_dimension()) # EXPR

    # Propagate restrictions of interior facet integrals to the terminal nodes
    form = propagate_restrictions(form) # INTEGRAL, EXPR

    # --- BEGIN DOMAIN SPLITTING AND JOINING
    # Store domain metadata per domain type
    form_data.domain_data = extract_domain_data(form)

    # Split up integrals and group by domain type and domain id,
    # adding integrands with same domain and compiler data
    sub_integral_data = integral_dict_to_sub_integral_data(form.integral_groups())
    # TODO: Replace integral_data with this through ufl and ffc?
    if 0: print_sub_integral_data(sub_integral_data)

    # Reconstruct form from these integrals in a more canonical representation
    form = reconstruct_form_from_sub_integral_data(sub_integral_data, form_data.domain_data)

    # Represent in the way ffc expects TODO: Change ffc? Fine for now.
    form_data.integral_data = convert_sub_integral_data_to_integral_data(sub_integral_data)
    # --- END DOMAIN SPLITTING AND JOINING


    # --- BEGIN FUNCTION ANALYSIS
    # --- BEGIN SPLIT EXPR JOIN
    # Replace arguments and coefficients with new renumbered objects
    tic('extract_arguments_and_coefficients')
    original_arguments, original_coefficients = \
        extract_arguments_and_coefficients(form)

    tic('build_element_mapping')
    element_mapping = build_element_mapping(element_mapping,
                                            common_cell,
                                            original_arguments,
                                            original_coefficients)

    tic('build_argument_replace_map') # TODO: Remove renumbered ones?
    replace_map, renumbered_arguments, renumbered_coefficients = \
        build_argument_replace_map(original_arguments,
                                   original_coefficients,
                                   element_mapping)

    # Note: This is the earliest point signature can be computed

    # Build mapping to original arguments and coefficients, which is
    # useful if the original arguments have data attached to them
    inv_replace_map = dict((w,v) for (v,w) in replace_map.iteritems())
    original_arguments = [inv_replace_map[v] for v in renumbered_arguments]
    original_coefficients = [inv_replace_map[w] for w in renumbered_coefficients]

    # TODO: Build mapping from object to position instead? But we need mapped elements as well anyway.
    #argument_positions = { v: i }
    #coefficient_positions = { w: i }

    # Store data extracted by preprocessing
    form_data.original_arguments      = original_arguments
    form_data.original_coefficients   = original_coefficients
    # --- END SPLIT INTEGRAL JOIN

    # Mappings from elements and functions (coefficients and arguments)
    # that reside in form to objects with canonical numbering as well as
    # completed cells and elements
    # TODO: Create additional function mappings per integral,
    #       to have different counts? Depends on future UFC design.
    form_data.element_replace_map = element_mapping
    form_data.function_replace_map = replace_map

    # Store some useful dimensions
    form_data.rank = len(form_data.original_arguments)
    form_data.num_coefficients = len(form_data.original_coefficients)

    # Store argument names
    form_data.argument_names = \
        [object_names.get(id(form_data.original_arguments[i]), "v%d" % i)
         for i in range(form_data.rank)]

    # Store coefficient names
    form_data.coefficient_names = \
        [object_names.get(id(form_data.original_coefficients[i]), "w%d" % i)
         for i in range(form_data.num_coefficients)]
    # --- END FUNCTION ANALYSIS


    # --- BEGIN SIGNATURE COMPUTATION
    # TODO: Compute signatures of each INTEGRAL and EXPR as well, perhaps compute it hierarchially from integral_data?
    # Store signature of form
    tic('signature')
    # TODO: Remove signature() from Form, not safe to cache with a replacement map
    #form_data.signature = form.signature(form_data.function_replace_map)
    form_data.signature = compute_form_signature(form, form_data.function_replace_map)
    # --- END SIGNATURE COMPUTATION


    # --- BEGIN CONSISTENCY CHECKS
    # Check that we don't have a mixed linear/bilinear form or anything like that
    ufl_assert(len(compute_form_arities(form)) == 1, "All terms in form must have same rank.")
    # --- END CONSISTENCY CHECKS


    # --- BEGIN ELEMENT DATA
    # Store elements, sub elements and element map
    tic('extract_elements')
    form_data.argument_elements    = tuple(f.element() for f in renumbered_arguments)
    form_data.coefficient_elements = tuple(f.element() for f in renumbered_coefficients)
    form_data.elements             = form_data.argument_elements + form_data.coefficient_elements
    form_data.unique_elements      = unique_tuple(form_data.elements)
    form_data.sub_elements         = extract_sub_elements(form_data.elements)
    form_data.unique_sub_elements  = unique_tuple(form_data.sub_elements)
    # --- END ELEMENT DATA


    # --- BEGIN DOMAIN DATA
    # Store element domains (NB! This is likely to change!)
    # TODO: DOMAINS: What is a sensible way to store domains for a form?
    form_data.domains = tuple(sorted(set(element.domain()
                                         for element in form_data.unique_elements)))

    # Store toplevel domains (NB! This is likely to change!)
    # TODO: DOMAINS: What is a sensible way to store domains for a form?
    form_data.top_domains = tuple(sorted(set(domain.top_domain()
                                             for domain in form_data.domains)))

    # Store common cell
    form_data.cell = common_cell

    # Store data related to cell
    form_data.geometric_dimension = form_data.cell.geometric_dimension()
    form_data.topological_dimension = form_data.cell.topological_dimension()

    # Store number of domains for integral types
    form_data.num_sub_domains = extract_num_sub_domains(form)
    # --- END DOMAIN DATA


    # A coarse profiling implementation TODO: Add counting of nodes, Add memory usage
    tic.end()
    if preprocess.enable_profiling:
        print tic

    # Store preprocessed form and return
    form_data.preprocessed_form = form
    form_data.preprocessed_form._is_preprocessed = True

    # Attach signatures to original and preprocessed forms TODO: Avoid this?
    ufl_assert(form_data.preprocessed_form._signature is None, "")
    form_data.preprocessed_form._signature = form_data.signature
    ufl_assert(original_form._signature is None, "")
    original_form._signature = form_data.signature

    return form_data
예제 #6
0
파일: form.py 프로젝트: strekalloff/mpm
 def _compute_signature(self):
     from ufl.algorithms.signature import compute_form_signature
     self._signature = compute_form_signature(self,
                                              self._compute_renumbering())
예제 #7
0
파일: form.py 프로젝트: FEniCS/ufl
 def _compute_signature(self):
     from ufl.algorithms.signature import compute_form_signature
     self._signature = compute_form_signature(self,
                                              self._compute_renumbering())
예제 #8
0
 def deprecated_signature(self, function_replace_map=None):
     if self._signature is None:
         from ufl.algorithms.signature import compute_form_signature
         self._signature = compute_form_signature(self, function_replace_map)
     assert self._signature
     return self._signature