Example #1
0
    def __init__(self, code_params=None):
        """
        Instantiate the class
        
        Arguments:
        ----------
        code_params : dict
            Parameters controling the code generation
        """
        code_params = code_params or {}
        check_kwarg(code_params, "code_params", dict)
        
        params = DOLFINCodeGenerator.default_parameters()
        params.update(code_params)
        
        # Get a whole set of gotran code parameters and update with dolfin
        # specific options
        generation_params = parameters.generation.copy()
        generation_params.code.default_arguments = \
                            "st" if params.param_repr == "numerals" else "stp"
        generation_params.code.time.name = "time"

        generation_params.code.array.index_format = "[]"
        generation_params.code.array.index_offset = 0

        generation_params.code.parameters.representation = params.param_repr

        generation_params.code.states.representation = params.state_repr
        generation_params.code.states.array_name = "states"

        generation_params.code.body.array_name = "body"
        generation_params.code.body.representation = "named"
        
        # Init base class
        super(DOLFINCodeGenerator, self).__init__(ns="ufl")

        # Store attributes (over load default PythonCode parameters)
        self.params = generation_params
Example #2
0
    def function_code(self, comp, indent=0, default_arguments=None, \
                      include_signature=True):

        default_arguments = default_arguments or \
                            self.params.code.default_arguments

        check_arg(comp, CodeComponent)
        check_kwarg(default_arguments, "default_arguments", str)
        check_kwarg(indent, "indent", int)

        body_lines = self._init_arguments(comp, default_arguments)

        # Iterate over any body needed to define the dy
        for expr in comp.body_expressions:
            if isinstance(expr, Comment):
                body_lines.append("")
                body_lines.append("# " + str(expr))
            else:
                body_lines.append(self.to_code(expr.expr, expr.name))

        if comp.results:
            body_lines.append("")
            body_lines.append("# Return results")
            body_lines.append("return {0}".format(", ".join(\
                ("{0}[0]" if comp.shapes[result_name][0] == 1 \
                 else "dolfin.as_vector({0})").format(result_name) \
                 for result_name in comp.results)))

        if include_signature:

            # Add function prototype
            body_lines = self.wrap_body_with_function_prototype(\
                body_lines, comp.function_name, \
                self.args(default_arguments), \
                comp.description, self.decorators())

        return "\n".join(self.indent_and_split_lines(body_lines,
                                                     indent=indent))
Example #3
0
    def __init__(self,
                 ode,
                 field_states=None,
                 field_parameters=None,
                 monitored=None,
                 code_params=None):
        """
        A class for generating a C++ subclass of a goss::ODEParameterized
        
        Arguments:
        ----------
        ode : gotran.ODE
            The gotran ode
        field_states : list
            A list of state names, which should be treated as field states
        field_parameters : list
            A list of parameter names, which should be treated as field parameters
        monitored : list
            A list of names of intermediates of the ODE. Code for monitoring
            the intermediates will be generated.
        code_params : dict
            Parameters controling the code generation
        """

        field_states = field_states or []
        field_parameters = field_parameters or []
        monitored = monitored or []
        code_params = code_params or {}

        check_arg(ode, ODE)
        check_kwarg(field_states, "field_states", list, itemtypes=str)
        check_kwarg(field_parameters, "field_parameters", list, itemtypes=str)
        check_kwarg(monitored, "monitored", list, itemtypes=str)
        check_kwarg(code_params, "code_params", dict)

        state_strs = [state.name for state in ode.full_states]
        for state_str in field_states:
            if not state_str in state_strs:
                error("{0} is not a state in the {1} ODE".format(
                    state_str, ode))

        parameter_strs = [param.name for param in ode.parameters]
        for parameter_str in field_parameters:
            if not parameter_str in parameter_strs:
                error("{0} is not a parameter in the {1} ODE".format(\
                    parameter_str, ode))

        for expr_str in monitored:
            obj = ode.present_ode_objects.get(expr_str)
            if not isinstance(obj, Expression):
                error("{0} is not an expression in the {1} ODE".format(\
                    expr_str, ode))

        params = GossCodeGenerator.default_parameters()
        params.update(code_params)

        # Get a whole set of gotran code parameters and update with goss
        # specific options
        generation_params = parameters.generation.copy()
        generation_params.code.default_arguments = "st"
        generation_params.code.time.name = "time"

        generation_params.code.array.index_format = "[]"
        generation_params.code.array.index_offset = 0
        generation_params.code.array.flatten = True

        generation_params.code.parameters.representation = "named"

        generation_params.code.states.representation = params.state_repr
        generation_params.code.states.array_name = "states"

        generation_params.code.body.array_name = "body"
        generation_params.code.body.representation = params.body_repr
        generation_params.code.body.use_cse = params.use_cse
        generation_params.code.body.optimize_exprs = params.optimize_exprs
        generation_params.functions.jacobian.generate = params.generate_jacobian
        generation_params.functions.lu_factorization.generate = \
                                        params.generate_lu_factorization
        generation_params.functions.forward_backward_subst.generate = \
                                        params.generate_forward_backward_subst

        # Init base class
        super(GossCodeGenerator, self).__init__()

        # Store attributes
        self.params = generation_params
        self.file_form = _file_form.copy()
        self.class_form = _class_form.copy()
        name = ode.name

        self.name = name if name[0].isupper() else name[0].upper() + \
                    (name[1:] if len(name) > 1 else "")

        self.ode = ode
        self.field_states = field_states
        self.field_parameters = field_parameters
        self.monitored = monitored

        # Fill the forms with content
        self.file_form["MODELNAME"] = name.upper()
        self.class_form["ModelName"] = self.name
        self.class_form["num_states"] = ode.num_full_states
        self.class_form["num_parameters"] = ode.num_parameters
        self.class_form["num_field_states"] = len(field_states)
        self.class_form["num_field_parameters"] = len(field_parameters)
        self.class_form["num_monitored"] = len(monitored)
        self.class_form["monitored_evaluation_code"] = \
                    _no_monitored_snippet.format(ode.name.capitalize()) + "\n"
        self._code_generated = False