Exemple #1
0
def mark(indicator,
         refineTolerance,
         coarsenTolerance=0,
         minLevel=0,
         maxLevel=None,
         gridView=None):
    if ufl and (isinstance(indicator, list) or isinstance(indicator, tuple)):
        indicator = ufl.as_vector(indicator)
    if ufl and isinstance(indicator, ufl.core.expr.Expr):  #
        if gridView is None:
            _, coeff_ = extract_arguments_and_coefficients(indicator)
            gridView = [c.grid for c in coeff_ if hasattr(c, "grid")]
            gridView += [c.gridView for c in coeff_ if hasattr(c, "gridView")]
            if len(gridView) == 0:
                raise ValueError(
                    "if a ufl expression is passed as indicator then the 'gridView' must also be provided"
                )
            gridView = gridView[0]
        indicator = expression2GF(gridView, indicator, 0)
    if gridView is None:
        gridView = indicator.gridView
    try:
        if not gridView.canAdapt:
            raise AttributeError(
                "indicator function must be over grid view that supports adaptation"
            )
    except AttributeError:
        raise AttributeError(
            "indicator function must be over grid view that supports adaptation"
        )
    if maxLevel == None:
        maxLevel = -1
    return gridView.mark(indicator, refineTolerance, coarsenTolerance,
                         minLevel, maxLevel)
Exemple #2
0
    def _analyze_form_arguments(self):
        "Analyze which Argument and Coefficient objects can be found in the form."
        from ufl.algorithms.analysis import extract_arguments_and_coefficients
        arguments, coefficients = extract_arguments_and_coefficients(self)

        # Define canonical numbering of arguments and coefficients
        self._arguments = tuple(
            sorted(set(arguments), key=lambda x: x.number()))
        self._coefficients = tuple(
            sorted(set(coefficients), key=lambda x: x.count()))
        self._coefficient_numbering = dict(
            (c, i) for i, c in enumerate(self._coefficients))
Exemple #3
0
    def _analyze_form_arguments(self):
        "Analyze which Argument and Coefficient objects can be found in the form."
        from ufl.algorithms.analysis import extract_arguments_and_coefficients
        arguments, coefficients = extract_arguments_and_coefficients(self)

        # Define canonical numbering of arguments and coefficients
        self._arguments = tuple(sorted(set(arguments),
                                       key=lambda x: x.number()))
        self._coefficients = tuple(sorted(set(coefficients),
                                          key=lambda x: x.count()))
        self._coefficient_numbering = dict((c, i) for i,
                                           c in enumerate(self._coefficients))
Exemple #4
0
def generateMethodBody(cppType, expr, returnResult, default, predefined):
    if expr is not None and not expr == [None]:
        try:
            dimR = expr.ufl_shape[0]
        except:
            if isinstance(expr,list) or isinstance(expr,tuple):
                expr = as_vector(expr)
            else:
                expr = as_vector([expr])
            dimR = expr.ufl_shape[0]

        _, coeff = extract_arguments_and_coefficients(expr)
        coeff = {c : c.toVectorCoefficient()[0] for c in coeff if len(c.ufl_shape) == 0 and not c.is_cellwise_constant()}
        expr = replace(expr, coeff)

        t = ExprTensor(expr.ufl_shape) # , exprTensorApply(lambda u: u, expr.ufl_shape, expr))
        expression = [expr[i] for i in t.keys()]
        u = extract_arguments_and_coefficients(expr)[0]
        if u != []:
            u = u[0]
            du = Grad(u)
            d2u = Grad(du)
            arg_u = Variable("const RangeType &", "u")
            arg_du = Variable("const JacobianRangeType &", "du")
            arg_d2u = Variable("const HessianRangeType &", "d2u")
            predefined.update( {u: arg_u, du: arg_du, d2u: arg_d2u} )
        code, results = generateCode(predefined, expression, tempVars=False)
        result = Variable(cppType, 'result')
        if cppType == 'double':
            code = code + [assign(result, results[0])]
        else:
            code = code + [assign(result[i], r) for i, r in zip(t.keys(), results)]
        if returnResult:
            code = [Declaration(result)] + code + [return_(result)]
    else:
        result = Variable(cppType, 'result')
        code = [assign(result, construct(cppType,default) )]
        if returnResult:
            code = [Declaration(result)] + code + [return_(result)]
    return code
Exemple #5
0
    def __init__(self, interpolator, *functions, **kwargs):
        super().__init__()

        self.expr = interpolator.expr
        self.arguments, self.coefficients = extract_arguments_and_coefficients(self.expr)

        if isinstance(interpolator.V, firedrake.Function):
            self.V = interpolator.V.function_space()
        else:
            self.V = interpolator.V

        for coefficient in self.coefficients:
            self.add_dependency(coefficient, no_duplicates=True)

        for function in functions:
            self.add_dependency(function, no_duplicates=True)
Exemple #6
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
Exemple #7
0
def preprocess_expression(expr,
                          object_names=None,
                          common_cell=None,
                          element_mapping=None):
    """
    Preprocess raw input expression to obtain expression metadata,
    including a modified (preprocessed) expression more easily
    manipulated by expression compilers. The original expression
    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_expression')

    # Check that we get an expression
    ufl_assert(isinstance(expr, Expr), "Expecting Expr.")

    # 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 expression data
    expr_data = ExprData()

    # Store original expression
    expr_data.original_expr = expr

    # Store name of expr if given, otherwise empty string
    # such that automatic names can be assigned externally
    expr_data.name = object_names.get(id(expr),
                                      "")  # TODO: Or default to 'expr'?

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

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

    # Renumber indices
    #expr = renumber_indices(expr) # TODO: No longer needed?

    # Replace arguments and coefficients with new renumbered objects
    tic('extract_arguments_and_coefficients')
    original_arguments, original_coefficients = \
        extract_arguments_and_coefficients(expr)

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

    tic('build_argument_replace_map')
    replace_map, renumbered_arguments, renumbered_coefficients = \
        build_argument_replace_map(original_arguments,
                                   original_coefficients,
                                   element_mapping)
    expr = replace(expr, replace_map)

    # 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
    ]

    # Store data extracted by preprocessing
    expr_data.arguments = renumbered_arguments  # TODO: Needed?
    expr_data.coefficients = renumbered_coefficients  # TODO: Needed?
    expr_data.original_arguments = original_arguments
    expr_data.original_coefficients = original_coefficients
    expr_data.renumbered_arguments = renumbered_arguments
    expr_data.renumbered_coefficients = renumbered_coefficients

    tic('replace')
    # Mappings from elements and functions (coefficients and arguments)
    # that reside in expr to objects with canonical numbering as well as
    # completed cells and elements
    expr_data.element_replace_map = element_mapping
    expr_data.function_replace_map = replace_map

    # Store signature of form
    tic('signature')
    expr_data.signature = compute_expression_signature(
        expr, expr_data.function_replace_map)

    # Store elements, sub elements and element map
    tic('extract_elements')
    expr_data.elements = tuple(
        f.element()
        for f in chain(renumbered_arguments, renumbered_coefficients))
    expr_data.unique_elements = unique_tuple(expr_data.elements)
    expr_data.sub_elements = extract_sub_elements(expr_data.elements)
    expr_data.unique_sub_elements = unique_tuple(expr_data.sub_elements)

    # Store element domains (NB! This is likely to change!)
    # FIXME: DOMAINS: What is a sensible way to store domains for a expr?
    expr_data.domains = tuple(
        sorted(set(element.domain() for element in expr_data.unique_elements)))

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

    # Store common cell
    expr_data.cell = common_cell

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

    # Store some useful dimensions
    expr_data.rank = len(expr_data.arguments)  # TODO: Is this useful for expr?
    expr_data.num_coefficients = len(expr_data.coefficients)

    # Store argument names # TODO: Is this useful for expr?
    expr_data.argument_names = \
        [object_names.get(id(expr_data.original_arguments[i]), "v%d" % i)
         for i in range(expr_data.rank)]

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

    # Store preprocessed expression
    expr_data.preprocessed_expr = expr

    tic.end()

    # A coarse profiling implementation
    # TODO: Add counting of nodes
    # TODO: Add memory usage
    if preprocess_expression.enable_profiling:
        print tic

    return expr_data
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
def preprocess_expression(expr, object_names=None, common_cell=None, element_mapping=None):
    """
    Preprocess raw input expression to obtain expression metadata,
    including a modified (preprocessed) expression more easily
    manipulated by expression compilers. The original expression
    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_expression')

    # Check that we get an expression
    ufl_assert(isinstance(expr, Expr), "Expecting Expr.")

    # 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 expression data
    expr_data = ExprData()

    # Store original expression
    expr_data.original_expr = expr

    # Store name of expr if given, otherwise empty string
    # such that automatic names can be assigned externally
    expr_data.name = object_names.get(id(expr), "") # TODO: Or default to 'expr'?

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

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

    # Renumber indices
    #expr = renumber_indices(expr) # TODO: No longer needed?

    # Replace arguments and coefficients with new renumbered objects
    tic('extract_arguments_and_coefficients')
    original_arguments, original_coefficients = \
        extract_arguments_and_coefficients(expr)

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

    tic('build_argument_replace_map')
    replace_map, renumbered_arguments, renumbered_coefficients = \
        build_argument_replace_map(original_arguments,
                                   original_coefficients,
                                   element_mapping)
    expr = replace(expr, replace_map)

    # 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]

    # Store data extracted by preprocessing
    expr_data.arguments               = renumbered_arguments    # TODO: Needed?
    expr_data.coefficients            = renumbered_coefficients # TODO: Needed?
    expr_data.original_arguments      = original_arguments
    expr_data.original_coefficients   = original_coefficients
    expr_data.renumbered_arguments    = renumbered_arguments
    expr_data.renumbered_coefficients = renumbered_coefficients

    tic('replace')
    # Mappings from elements and functions (coefficients and arguments)
    # that reside in expr to objects with canonical numbering as well as
    # completed cells and elements
    expr_data.element_replace_map = element_mapping
    expr_data.function_replace_map = replace_map

    # Store signature of form
    tic('signature')
    expr_data.signature = compute_expression_signature(expr, expr_data.function_replace_map)

    # Store elements, sub elements and element map
    tic('extract_elements')
    expr_data.elements            = tuple(f.element() for f in
                                          chain(renumbered_arguments,
                                                renumbered_coefficients))
    expr_data.unique_elements     = unique_tuple(expr_data.elements)
    expr_data.sub_elements        = extract_sub_elements(expr_data.elements)
    expr_data.unique_sub_elements = unique_tuple(expr_data.sub_elements)

    # Store element domains (NB! This is likely to change!)
    # FIXME: DOMAINS: What is a sensible way to store domains for a expr?
    expr_data.domains = tuple(sorted(set(element.domain()
                                         for element in expr_data.unique_elements)))

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

    # Store common cell
    expr_data.cell = common_cell

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

    # Store some useful dimensions
    expr_data.rank = len(expr_data.arguments) # TODO: Is this useful for expr?
    expr_data.num_coefficients = len(expr_data.coefficients)

    # Store argument names # TODO: Is this useful for expr?
    expr_data.argument_names = \
        [object_names.get(id(expr_data.original_arguments[i]), "v%d" % i)
         for i in range(expr_data.rank)]

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

    # Store preprocessed expression
    expr_data.preprocessed_expr = expr

    tic.end()

    # A coarse profiling implementation
    # TODO: Add counting of nodes
    # TODO: Add memory usage
    if preprocess_expression.enable_profiling:
        print tic

    return expr_data
Exemple #10
0
    def __init__(self, name, uflExpr, virtualize, dimRange=None, predefined=None):
        self.className = name
        self.targs = ['class GridPart']
        if dimRange is not None:
            self.bindable = True
            self.dimRange = dimRange
            self.bindableBase = 'Dune::Fem::BindableGridFunctionWithSpace<GridPart,Dune::Dim<'+str(self.dimRange)+'>>'
            self.bases = ['public '+self.bindableBase]
            self.includeFiles = ['dune/fem/function/localfunction/bindable.hh']
        else:
            self.bindable = False
            self.bases = []
            self.includeFiles = []
        self.includeFiles += ['dune/fem/common/intersectionside.hh']
        self.gridPartType = TypeAlias("GridPartType", "GridPart")
        self.ctor_args = []
        self.ctor_init = []
        self.skeleton = None
        self.init = None
        self.vars = None

        uflExpr = [e for e in uflExpr if e is not None]
        coefficients = set()
        for expr in uflExpr:
            try:
                coefficients |= set(expr.coefficients())
            except:
                _, cc = extract_arguments_and_coefficients(expr)
                coefficients |= set(cc)
        extracedAll = False
        while not extracedAll:
            extracedAll = True
            for c in coefficients:
                try:
                    predef = c.predefined
                except AttributeError:
                    continue
                for expr in predef.values():
                    _, cc = extract_arguments_and_coefficients(expr)
                    cc = set(cc)
                    if not cc.issubset(coefficients):
                       coefficients |= cc
                       extracedAll = False
                if not extracedAll:
                    break

        self.constantList = sorted((c for c in coefficients if c.is_cellwise_constant()), key=lambda c: c.count())
        self.coefficientList = sorted((c for c in coefficients if not c.is_cellwise_constant()), key=lambda c: c.count())

        constants=[fieldVectorType(c,useScalar=True) for c in self.constantList]
        coefficients=(fieldVectorType(c) for c in self.coefficientList)
        constantNames=[getattr(c, 'name', None) for c in self.constantList]
        constantShapes=[getattr(c, 'ufl_shape', None) for c in self.constantList]
        coefficientNames=[getattr(c, 'name', None) for c in self.coefficientList]
        parameterNames=[getattr(c, 'parameter', None) for c in self.constantList]

        if not len(set(constantNames)) == len(constantNames):
            raise AttributeError("two constants have the same name which will lead to failure during code generation:"+','.join(c for c in constantNames))

        # this part modifies duplicate names in coefficient - slow version
        # can be improved
        coefficientNames_ = coefficientNames
        coefficientNames = []
        for c in coefficientNames_:
            if c is not None:
                while c in coefficientNames:
                    c = c+"A"
            coefficientNames.append(c)

        self._constants = [] if constants is None else list(constants)
        self._coefficients = [] if coefficients is None else list(coefficients)

        self._constantShapes = [None,] * len(self._constants) if constantShapes is None else list(constantShapes)
        self._constantNames  = [None,] * len(self._constants) if constantNames is None else list(constantNames)
        self._constantNames  = ['constant' + str(i) if n is None else n for i, n in enumerate(self._constantNames)]
        if len(self._constantNames) != len(self._constants):
            raise ValueError("Length of constantNames must match length of constants")
        invalidConstants = [n for n in self._constantNames if n is not None and re.match('^[a-zA-Z_][a-zA-Z0-9_]*$', n) is None]
        if invalidConstants:
            raise ValueError('Constant names are not valid C++ identifiers:' + ', '.join(invalidConstants) + '.')
        self._constantValues = [ None if not hasattr(c,"value") else c.value for c in self.constantList ]

        self._coefficientNames = [None,] * len(self._coefficients) if coefficientNames is None else list(coefficientNames)
        self._coefficientNames = ['coefficient' + str(i) if n is None else n for i, n in enumerate(self._coefficientNames)]
        if len(self._coefficientNames) != len(self._coefficients):
            raise ValueError("Length of coefficientNames must match length of coefficients")
        invalidCoefficients = [n for n in self._coefficientNames if n is not None and re.match('^[a-zA-Z_][a-zA-Z0-9_]*$', n) is None]
        if invalidCoefficients:
            raise ValueError('Coefficient names are not valid C++ identifiers:' + ', '.join(invalidCoefficients) + '.')

        self._parameterNames = [None,] * len(self._constants) if parameterNames is None else list(parameterNames)
        if len(self._parameterNames) != len(self._constants):
            raise ValueError("Length of parameterNames must match length of constants")
        self._derivatives = [('RangeType', 'evaluate'), ('JacobianRangeType', 'jacobian'), ('HessianRangeType', 'hessian')]
        if self._coefficients:
            if virtualize:
                self.coefficientCppTypes = \
                    ['Dune::FemPy::VirtualizedGridFunction< ' +\
                     gridPartType(c) + ', ' + fieldVectorType(c) + ' >' \
                        if not c.cppTypeName.startswith("Dune::Python::SimpleGridFunction") \
                        else c.cppTypeName \
                    for c in self.coefficientList]
                # VirtualizedGF need GridParts but they have to be the same for all coefficients
                # Do we want this to work in some way? Then we can add
                # includes here - but '.bind(entity)' will fail.
                # for c in self.coefficientList:
                #     self.includeFiles += c.grid.cppIncludes
            else:
                self.coefficientCppTypes = [c.cppTypeName for c in self.coefficientList]
        else:
            self.coefficientCppTypes = []

        # need to replace possible grid functions in values of predefined
        # import pdb; pdb.set_trace()
        self.predefined = {} if predefined is None else predefined
        for idx, coefficient in enumerate(self.coefficientList):
            try:
                self.predefined.update( coefficient.predefined )
            except AttributeError:
                pass
        for idx, coefficient in enumerate(self.coefficientList):
            for derivative in self.coefficient(idx, 'x', side=None):
                for k,v in self.predefined.items():
                    if coefficient == v:
                        self.predefined[k] = derivative
                coefficient = Grad(coefficient)
Exemple #11
0
def load(grid, form, *args, renumbering=None, tempVars=True,
        virtualize=True, modelPatch=[None,None],
        includes=None):

    if not isinstance(modelPatch,list) and not isinstance(modelPatch,tuple):
        modelPatch = [modelPatch,None]

    if isinstance(form, Equation):
        form = form.lhs - form.rhs

    if isinstance(form, Integrands):
        integrands = form
    else:
        if len(form.arguments()) < 2:
            raise ValueError("Integrands model requires form with at least two arguments.")

        phi_, u_ = form.arguments()

        if phi_.ufl_function_space().scalar:
            phi = TestFunction(phi_.ufl_function_space().toVectorSpace())
            form = replace(form,{phi_:phi[0]})
        else:
            phi = phi_
        if u_.ufl_function_space().scalar:
            u = TrialFunction(u_.ufl_function_space().toVectorSpace())
            form = replace(form,{u_:u[0]})
        else:
            u = u_

        if not isinstance(form, Form):
            raise ValueError("ufl.Form or ufl.Equation expected.")

        _, coeff_ = extract_arguments_and_coefficients(form)
        coeff_ = set(coeff_)

        # added for dirichlet treatment same as conservationlaw model
        dirichletBCs = [arg for arg in args if isinstance(arg, DirichletBC)]
        # remove the dirichletBCs
        arg = [arg for arg in args if not isinstance(arg, DirichletBC)]
        for dBC in dirichletBCs:
            _, coeff__ = extract_arguments_and_coefficients(dBC.ufl_value)
            coeff_ |= set(coeff__)
        coeff = {c : c.toVectorCoefficient()[0] for c in coeff_ if len(c.ufl_shape) == 0 and not c.is_cellwise_constant()}

        form = replace(form,coeff)
        uflExpr = [form]
        for dBC in dirichletBCs:
            arg.append(dBC.replace(coeff))
            uflExpr += [dBC.ufl_value] # arg[-1].ufl_value]

        if modelPatch[1] is not None:
            uflExpr += modelPatch[1]

        derivatives = gatherDerivatives(form, [phi, u])

        derivatives_phi = derivatives[0]
        derivatives_u = derivatives[1]

        integrands = Integrands(u,
                                (d.ufl_shape for d in derivatives_u), (d.ufl_shape for d in derivatives_phi),
                                uflExpr,virtualize)

    if modelPatch[0] is not None:
        modelPatch[0](integrands)

    # set up the source class
    source = Source(integrands, grid, includes, form, *args,
             tempVars=tempVars,virtualize=virtualize)

    # ufl coefficient and constants only have numbers which depend on the
    # order in whch they were generated - we need to keep track of how
    # these numbers are translated into the tuple numbering in the
    # generated C++ code
    if isinstance(form, Form):
        coefficients = set(integrands.coefficientList+integrands.constantList)
        numCoefficients = len(coefficients)
        if renumbering is None:
            renumbering = dict()
            renumbering.update((c, i) for i, c in enumerate(sorted((c for c in coefficients if not c.is_cellwise_constant()), key=lambda c: c.count())))
            renumbering.update((c, i) for i, c in enumerate(c for c in coefficients if c.is_cellwise_constant()))
        coefficientNames = integrands._coefficientNames # ['coefficient' + str(i) if n is None else n for i, n in enumerate(getattr(c, 'name', None) for c in coefficients if not c.is_cellwise_constant())]
    else:
        coefficientNames = form.coefficientNames

    # call code generator
    from dune.generator import builder
    module = builder.load(source.name(), source, "Integrands")

    assert hasattr(module,"Integrands"),\
          "GridViews of coefficients need to be compatible with the grid view of the ufl model"

    rangeValueTuple, domainValueTuple = source.valueTuples()
    setattr(module.Integrands, "_domainValueType", domainValueTuple)
    setattr(module.Integrands, "_rangeValueType", rangeValueTuple)
    # redirect the __init__ method to take care of setting coefficient and renumbering
    class Model(module.Integrands):
        def __init__(self, *args, **kwargs):
            self.base = module.Integrands
            init(self,integrands,*args,**kwargs)
            for c in integrands.constantList:
                c.registerModel(self)

    setattr(Model, '_coefficientNames', {n: i for i, n in enumerate(coefficientNames)})
    if renumbering is not None:
        setattr(Model, '_renumbering', renumbering)
        Model._setConstant = module.Integrands.__dict__['setConstant']
        setattr(Model, 'setConstant', setConstant)

    return Model
Exemple #12
0
def compileUFL(form, patch, *args, **kwargs):
    if isinstance(form, Equation):
        form = form.lhs - form.rhs
    if not isinstance(form, Form):
        raise Exception("ufl.Form expected.")
    if len(form.arguments()) < 2:
        raise Exception("ConservationLaw model requires form with at least two arguments.")

    phi_, u_ = form.arguments()

    if phi_.ufl_function_space().scalar:
        phi = TestFunction(phi_.ufl_function_space().toVectorSpace())
        form = replace(form,{phi_:phi[0]})
    else:
        phi = phi_
    if u_.ufl_function_space().scalar:
        u = TrialFunction(u_.ufl_function_space().toVectorSpace())
        form = replace(form,{u_:u[0]})
    else:
        u = u_
    _, coeff_ = extract_arguments_and_coefficients(form)
    coeff_ = set(coeff_)

    # added for dirichlet treatment same as conservationlaw model
    dirichletBCs = [arg for arg in args if isinstance(arg, DirichletBC)]
    # remove the dirichletBCs
    arg = [arg for arg in args if not isinstance(arg, DirichletBC)]
    for dBC in dirichletBCs:
        _, coeff__ = extract_arguments_and_coefficients(dBC.ufl_value)
        coeff_ |= set(coeff__)
    if patch is not None:
        for a in patch:
            try:
                _, coeff__ = extract_arguments_and_coefficients(a)
                coeff_ |= set(coeff__)
            except:
                pass # a might be a float/int and not a ufl expression

    coeff = {c : c.toVectorCoefficient()[0] for c in coeff_ if len(c.ufl_shape) == 0 and not c.is_cellwise_constant()}
    form = replace(form,coeff)
    for bc in dirichletBCs:
        bc.ufl_value = replace(bc.ufl_value, coeff)
    if patch is not None:
        patch = [a if not isinstance(a, Expr) else replace(a,coeff) for a in patch]

    phi = form.arguments()[0]
    dimRange = phi.ufl_shape[0]

    u = form.arguments()[1]
    du = Grad(u)
    d2u = Grad(du)
    ubar = Coefficient(u.ufl_function_space())
    dubar = Grad(ubar)
    d2ubar = Grad(dubar)
    dimDomain = u.ufl_shape[0]

    x = SpatialCoordinate(form.ufl_cell())

    try:
        field = u.ufl_function_space().field
    except AttributeError:
        field = "double"

    # if exact solution is passed in subtract a(u,.) from the form
    if "exact" in kwargs:
        b = replace(form, {u: as_vector(kwargs["exact"])} )
        form = form - b

    dform = apply_derivatives(derivative(action(form, ubar), ubar, u))

    source, flux, boundarySource = splitUFLForm(form)
    linSource, linFlux, linBoundarySource = splitUFLForm(dform)
    fluxDivergence, _, _ = splitUFLForm(inner(source.as_ufl() - div(flux.as_ufl()), phi) * dx(0))

    # split linNVSource off linSource
    # linSources = splitUFL2(u, du, d2u, linSource)
    # linNVSource = linSources[2]
    # linSource = linSources[0] + linSources[1]

    if patch is not None:
        model = ConservationLawModel(dimDomain, dimRange, u, modelSignature(form,*patch,*args))
    else:
        model = ConservationLawModel(dimDomain, dimRange, u, modelSignature(form,None,*args))
    model._replaceCoeff = coeff

    model.hasNeumanBoundary = not boundarySource.is_zero()

    #expandform = expand_indices(expand_derivatives(expand_compounds(equation.lhs)))
    #if expandform == adjoint(expandform):
    #    model.symmetric = 'true'
    model.field = field

    dirichletBCs = [arg for arg in args if isinstance(arg, DirichletBC)]
    # deprecated
    # if "dirichlet" in kwargs:
    #     dirichletBCs += [DirichletBC(u.ufl_function_space(), as_vector(value), bndId) for bndId, value in kwargs["dirichlet"].items()]

    uflCoefficients = set(form.coefficients())
    for bc in dirichletBCs:
        _, c = extract_arguments_and_coefficients(bc.ufl_value)
        uflCoefficients |= set(c)
    if patch is not None:
        for a in patch:
            if isinstance(a, Expr):
                _, c = extract_arguments_and_coefficients(a)
                uflCoefficients |= set(c)

    constants = dict()
    coefficients = dict()

    for coefficient in uflCoefficients:
        try:
            name = getattr(coefficient, "name")
        except AttributeError:
            name = str(coefficient)
        if coefficient.is_cellwise_constant():
            try:
                parameter = getattr(coefficient, "parameter")
            except AttributeError:
                parameter = None
            if len(coefficient.ufl_shape) == 0:
                constants[coefficient] = model.addConstant('double', name=name, parameter=parameter)
            elif len(coefficient.ufl_shape) == 1:
                constants[coefficient] = model.addConstant('Dune::FieldVector< double, ' + str(coefficient.ufl_shape[0]) + ' >', name=name, parameter=parameter)
            else:
                Exception('Currently, only scalars and vectors are supported as constants')
        else:
            shape = coefficient.ufl_shape[0]
            try:
                coefficients[coefficient] = model.addCoefficient(
                        shape,
                        coefficient.cppTypeName,
                        name=name,
                        field=coefficient.ufl_function_space().field)
            except AttributeError:
                coefficients[coefficient] = model.addCoefficient(
                        shape,
                        coefficient.cppTypeName,
                        name=name)

    model.coefficients = coefficients
    model.constants = constants

    tempVars = kwargs.get("tempVars", True)

    predefined = {u: model.arg_u, du: model.arg_du, d2u: model.arg_d2u}
    predefined[x] = UnformattedExpression('auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + model.arg_x.name + ' ) )')
    model.predefineCoefficients(predefined,'x')
    model.source = generateCode(predefined, source, tempVars=tempVars)
    model.flux = generateCode(predefined, flux, tempVars=tempVars)
    predefined.update({ubar: model.arg_ubar, dubar: model.arg_dubar, d2ubar: model.arg_d2ubar})
    model.linSource = generateCode(predefined, linSource, tempVars=tempVars)
    model.linFlux = generateCode(predefined, linFlux, tempVars=tempVars)

    # model.linNVSource = generateCode({u: arg, du: darg, d2u: d2arg, ubar: argbar, dubar: dargbar, d2ubar: d2argbar}, linNVSource, model.coefficients, tempVars)

    predefined = {u: model.arg_u}
    predefined[x] = UnformattedExpression('auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + model.arg_x.name + ' ) )')
    model.predefineCoefficients(predefined,'x')
    model.alpha = generateCode(predefined, boundarySource, tempVars=tempVars)
    predefined.update({ubar: model.arg_ubar})
    model.linAlpha = generateCode(predefined, linBoundarySource, tempVars=tempVars)

    predefined = {u: model.arg_u, du: model.arg_du, d2u: model.arg_d2u}
    predefined[x] = UnformattedExpression('auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + model.arg_x.name + ' ) )')
    model.predefineCoefficients(predefined,'x')
    model.fluxDivergence = generateCode(predefined, fluxDivergence, tempVars=tempVars)

    if dirichletBCs:
        model.hasDirichletBoundary = True

        predefined = {}
        predefined[x] = UnformattedExpression('auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + model.arg_x.name + ' ) )')
        model.predefineCoefficients(predefined,'x')

        maxId = 0
        codeDomains = []
        bySubDomain = dict()
        neuman = []
        for bc in dirichletBCs:
            if bc.subDomain in bySubDomain:
                raise Exception('Multiply defined Dirichlet boundary for subdomain ' + str(bc.subDomain))
            if not isinstance(bc.functionSpace, (FunctionSpace, FiniteElementBase)):
                raise Exception('Function space must either be a ufl.FunctionSpace or a ufl.FiniteElement')
            if isinstance(bc.functionSpace, FunctionSpace) and (bc.functionSpace != u.ufl_function_space()):
                raise Exception('Space of trial function and dirichlet boundary function must be the same - note that boundary conditions on subspaces are not available, yet')
            if isinstance(bc.functionSpace, FiniteElementBase) and (bc.functionSpace != u.ufl_element()):
                raise Exception('Cannot handle boundary conditions on subspaces, yet')

            if isinstance(bc.value, list):
                neuman = [i for i, x in enumerate(bc.value) if x == None]
            else:
                neuman = []

            value = ExprTensor(u.ufl_shape)
            for key in value.keys():
                value[key] = Indexed(bc.ufl_value, MultiIndex(tuple(FixedIndex(k) for k in key)))
            if isinstance(bc.subDomain,int):
                bySubDomain[bc.subDomain] = value,neuman
                maxId = max(maxId, bc.subDomain)
            else:
                domain = ExprTensor(())
                for key in domain.keys():
                    domain[key] = Indexed(bc.subDomain, MultiIndex(tuple(FixedIndex(k) for k in key)))
                codeDomains.append( (value,neuman,domain) )
        defaultCode = []
        defaultCode.append(Declaration(Variable('int', 'domainId')))
        defaultCode.append(Declaration(Variable('auto', 'tmp0'),
            initializer=UnformattedExpression('auto','intersection.geometry().center()')))
        for i,v in enumerate(codeDomains):
            block = Block()
            defaultCode.append(
                    generateDirichletDomainCode(predefined, v[2], tempVars=tempVars))
            defaultCode.append('if (domainId)')
            block = UnformattedBlock()
            block.append('std::fill( dirichletComponent.begin(), dirichletComponent.end(), ' + str(maxId+i+1) + ' );')
            if len(v[1])>0:
                [block.append('dirichletComponent[' + str(c) + '] = 0;') for c in v[1]]
            block.append('return true;')
            defaultCode.append(block)
        defaultCode.append(return_(False))

        bndId = Variable('const int', 'bndId')
        getBndId = UnformattedExpression('int', 'BoundaryIdProviderType::boundaryId( ' + model.arg_i.name + ' )')
        switch = SwitchStatement(bndId, default=defaultCode)
        for i,v in bySubDomain.items():
            code = []
            if len(v[1])>0:
                [code.append('dirichletComponent[' + str(c) + '] = 0;') for c in v[1]]
            code.append(return_(True))
            switch.append(i, code)
        model.isDirichletIntersection = [Declaration(bndId, initializer=getBndId),
                                         UnformattedBlock('std::fill( dirichletComponent.begin(), dirichletComponent.end(), ' + bndId.name + ' );'),
                                         switch
                                        ]

        switch = SwitchStatement(model.arg_bndId, default=assign(model.arg_r, construct("RRangeType", 0)))
        for i, v in bySubDomain.items():
            switch.append(i, generateDirichletCode(predefined, v[0], tempVars=tempVars))
        for i,v in enumerate(codeDomains):
            switch.append(i+maxId+1, generateDirichletCode(predefined, v[0], tempVars=tempVars))
        model.dirichlet = [switch]

    return model