Exemplo n.º 1
0
    def create_evaluables(self):
        variables = self.dpb.create_variables().as_dict()

        possible_mat_names = get_expression_arg_names(self.obj_fun_term)
        materials = self.dpb.create_materials(possible_mat_names).as_dict()

        aux = self.dpb.create_evaluable(self.obj_fun_term,
                                        try_equations=False,
                                        var_dict=variables,
                                        **materials)
        self.of_equations, self.of_variables = aux

        possible_mat_names = get_expression_arg_names(self.sens_terms)
        materials = self.apb.create_materials(possible_mat_names).as_dict()

        aux = self.apb.create_evaluable(self.sens_terms,
                                        try_equations=False,
                                        var_dict=variables,
                                        **materials)
        self.ofg_equations, self.ofg_variables = aux
Exemplo n.º 2
0
    def create_evaluable(self, expression, try_equations=True, auto_init=False,
                         preserve_caches=False, copy_materials=True,
                         integrals=None,
                         ebcs=None, epbcs=None, lcbcs=None,
                         ts=None, functions=None,
                         mode='eval', var_dict=None, extra_args=None,
                         verbose=True, **kwargs):
        """
        Create evaluable object (equations and corresponding variables)
        from the `expression` string. Convenience function calling
        :func:`create_evaluable()
        <sfepy.fem.evaluate.create_evaluable()>` with defaults provided
        by the ProblemDefinition instance `self`.

        The evaluable can be repeatedly evaluated by calling
        :func:`eval_equations() <sfepy.fem.evaluate.eval_equations()>`,
        e.g. for different values of variables.

        Parameters
        ----------
        expression : str
            The expression to evaluate.
        try_equations : bool
            Try to get variables from `self.equations`. If this fails,
            variables can either be provided in `var_dict`, as keyword
            arguments, or are created automatically according to the
            expression.
        auto_init : bool
            Set values of all variables to all zeros.
        preserve_caches : bool
            If True, do not invalidate evaluate caches of variables.
        copy_materials : bool
            Work with a copy of `self.equations.materials` instead of
            reusing them. Safe but can be slow.
        integrals : Integrals instance, optional
            The integrals to be used. Automatically created as needed if
            not given.
        ebcs : Conditions instance, optional
            The essential (Dirichlet) boundary conditions for 'weak'
            mode. If not given, `self.ebcs` are used.
        epbcs : Conditions instance, optional
            The periodic boundary conditions for 'weak'
            mode. If not given, `self.epbcs` are used.
        lcbcs : Conditions instance, optional
            The linear combination boundary conditions for 'weak'
            mode. If not given, `self.lcbcs` are used.
        ts : TimeStepper instance, optional
            The time stepper. If not given, `self.ts` is used.
        functions : Functions instance, optional
            The user functions for boundary conditions, materials
            etc. If not given, `self.functions` are used.
        mode : one of 'eval', 'el_avg', 'qp', 'weak'
            The evaluation mode - 'weak' means the finite element
            assembling, 'qp' requests the values in quadrature points,
            'el_avg' element averages and 'eval' means integration over
            each term region.
        var_dict : dict, optional
            The variables (dictionary of (variable name) : (Variable
            instance)) to be used in the expression. Use this if the
            name of a variable conflicts with one of the parameters of
            this method.
        extra_args : dict, optional
            Extra arguments to be passed to terms in the expression.
        verbose : bool
            If False, reduce verbosity.
        **kwargs : keyword arguments
            Additional variables can be passed as keyword arguments, see
            `var_dict`.

        Returns
        -------
        equations : Equations instance
            The equations that can be evaluated.
        variables : Variables instance
            The corresponding variables. Set their values and use
            :func:`eval_equations() <sfepy.fem.evaluate.eval_equations()>`.

        Examples
        --------
        `problem` is ProblemDefinition instance.

        >>> out = problem.create_evaluable('dq_state_in_volume_qp.i1.Omega(u)')
        >>> equations, variables = out

        `vec` is a vector of coefficients compatible with the field
        of 'u' - let's use all ones.

        >>> vec = nm.ones((variables['u'].n_dof,), dtype=nm.float64)
        >>> variables['u'].data_from_any(vec)
        >>> vec_qp = eval_equations(equations, variables, mode='qp')

        Try another vector:

        >>> vec = 3 * nm.ones((variables['u'].n_dof,), dtype=nm.float64)
        >>> variables['u'].data_from_any(vec)
        >>> vec_qp = eval_equations(equations, variables, mode='qp')
        """
        from sfepy.fem.equations import get_expression_arg_names

        variables = get_default(var_dict, {})

        if try_equations and self.equations is not None:
            # Make a copy, so that possible variable caches are preserved.
            for key, var in self.equations.variables.as_dict().iteritems():
                if key in variables:
                    continue
                var = var.copy(name=key)
                if not preserve_caches:
                    var.clear_evaluate_cache()
                variables[key] = var

        elif var_dict is None:
            possible_var_names = get_expression_arg_names(expression)
            variables = self.create_variables(possible_var_names)

        materials = self.get_materials()
        if materials is not None:
            if copy_materials:
                materials = materials.semideep_copy()

            else:
                materials = Materials(objs=materials._objs)

        else:
            possible_mat_names = get_expression_arg_names(expression)
            materials = self.create_materials(possible_mat_names)

        _kwargs = copy(kwargs)
        for key, val in kwargs.iteritems():
            if isinstance(val, Variable):
                if val.name != key:
                    msg = 'inconsistent variable name! (%s == %s)' \
                          % (val.name, key)
                    raise ValueError(msg)
                variables[val.name] = val
                _kwargs.pop(key)

            elif isinstance(val, Material):
                if val.name != key:
                    msg = 'inconsistent material name! (%s == %s)' \
                          % (val.name, key)
                    raise ValueError(msg)
                materials[val.name] = val
                _kwargs.pop(key)

        kwargs = _kwargs

        ebcs = get_default(ebcs, self.ebcs)
        epbcs = get_default(epbcs, self.epbcs)
        lcbcs = get_default(lcbcs, self.lcbcs)
        ts = get_default(ts, self.get_timestepper())
        functions = get_default(functions, self.functions)
        integrals = get_default(integrals, self.get_integrals())

        out = create_evaluable(expression, self.fields, materials,
                               variables.itervalues(), integrals,
                               ebcs=ebcs, epbcs=epbcs, lcbcs=lcbcs,
                               ts=ts, functions=functions,
                               auto_init=auto_init,
                               mode=mode, extra_args=extra_args, verbose=verbose,
                               kwargs=kwargs)

        if copy_materials:
            equations = out[0]
            equations.time_update_materials(self.ts, self, verbose=verbose)

        return out
Exemplo n.º 3
0
    def check_custom_sensitivity(self, term_desc, idsg, delta,
                                 dp_var_data, state_ap):
        pb = self.apb

        domain = pb.domain

        possible_mat_names = get_expression_arg_names(term_desc)
        materials = self.dpb.create_materials(possible_mat_names).as_dict()

        variables = self.ofg_equations.variables
        aux = self.dpb.create_evaluable(term_desc,
                                        try_equations=False,
                                        var_dict=variables,
                                        verbose=False,
                                        **materials)
        check0_equations, check0_variables = aux

        aux = self.dpb.create_evaluable(term_desc,
                                        try_equations=False,
                                        var_dict=variables,
                                        verbose=False,
                                        **materials)
        check1_equations, check1_variables = aux

        var_data = state_ap.get_parts()
        var_data.update(dp_var_data)

        check0_equations.set_data(var_data, ignore_unknown=True)
        check1_equations.set_data(var_data, ignore_unknown=True)

        dim = self.sp_boxes.dim
        n_mesh_nod = domain.shape.n_nod

        a_grad = []
        d_grad = []

        coors0 = domain.mesh.coors

        for nu in self.generate_mesh_velocity( (n_mesh_nod, dim), [idsg] ):
            check1_variables['Nu'].set_data(nu.ravel())

            aux = eval_equations(check1_equations, check1_variables,
                                 term_mode=1)
            a_grad.append( aux )

            coorsp = coors0 + delta * nu
            pb.set_mesh_coors( coorsp, update_fields=True )
            valp = eval_equations(check0_equations, check0_variables,
                                  term_mode=0)

            coorsm = coors0 - delta * nu
            pb.set_mesh_coors( coorsm, update_fields=True )
            valm = eval_equations(check0_equations, check0_variables,
                                  term_mode=0)

            d_grad.append( 0.5 * (valp - valm) / delta )

        pb.set_mesh_coors( coors0, update_fields=True )

        a_grad = nm.array( a_grad, nm.float64 )
        d_grad = nm.array( d_grad, nm.float64 )

        output( term_desc + ':' )
        output( '       a: %.8e' % a_grad )
        output( '       d: %.8e' % d_grad )
        output( '-> ratio:', a_grad / d_grad )
        pause()
Exemplo n.º 4
0
    def create_evaluable(self,
                         expression,
                         try_equations=True,
                         auto_init=False,
                         preserve_caches=False,
                         copy_materials=True,
                         integrals=None,
                         ebcs=None,
                         epbcs=None,
                         lcbcs=None,
                         ts=None,
                         functions=None,
                         mode='eval',
                         var_dict=None,
                         strip_variables=True,
                         extra_args=None,
                         verbose=True,
                         **kwargs):
        """
        Create evaluable object (equations and corresponding variables)
        from the `expression` string. Convenience function calling
        :func:`create_evaluable()
        <sfepy.fem.evaluate.create_evaluable()>` with defaults provided
        by the ProblemDefinition instance `self`.

        The evaluable can be repeatedly evaluated by calling
        :func:`eval_equations() <sfepy.fem.evaluate.eval_equations()>`,
        e.g. for different values of variables.

        Parameters
        ----------
        expression : str
            The expression to evaluate.
        try_equations : bool
            Try to get variables from `self.equations`. If this fails,
            variables can either be provided in `var_dict`, as keyword
            arguments, or are created automatically according to the
            expression.
        auto_init : bool
            Set values of all variables to all zeros.
        preserve_caches : bool
            If True, do not invalidate evaluate caches of variables.
        copy_materials : bool
            Work with a copy of `self.equations.materials` instead of
            reusing them. Safe but can be slow.
        integrals : Integrals instance, optional
            The integrals to be used. Automatically created as needed if
            not given.
        ebcs : Conditions instance, optional
            The essential (Dirichlet) boundary conditions for 'weak'
            mode. If not given, `self.ebcs` are used.
        epbcs : Conditions instance, optional
            The periodic boundary conditions for 'weak'
            mode. If not given, `self.epbcs` are used.
        lcbcs : Conditions instance, optional
            The linear combination boundary conditions for 'weak'
            mode. If not given, `self.lcbcs` are used.
        ts : TimeStepper instance, optional
            The time stepper. If not given, `self.ts` is used.
        functions : Functions instance, optional
            The user functions for boundary conditions, materials
            etc. If not given, `self.functions` are used.
        mode : one of 'eval', 'el_avg', 'qp', 'weak'
            The evaluation mode - 'weak' means the finite element
            assembling, 'qp' requests the values in quadrature points,
            'el_avg' element averages and 'eval' means integration over
            each term region.
        var_dict : dict, optional
            The variables (dictionary of (variable name) : (Variable instance))
            to be used in the expression. Use this if the name of a variable
            conflicts with one of the parameters of this method.
        strip_variables : bool
            If False, the variables in `var_dict` or `kwargs` not present in
            the expression are added to the actual variables as a context.
        extra_args : dict, optional
            Extra arguments to be passed to terms in the expression.
        verbose : bool
            If False, reduce verbosity.
        **kwargs : keyword arguments
            Additional variables can be passed as keyword arguments, see
            `var_dict`.

        Returns
        -------
        equations : Equations instance
            The equations that can be evaluated.
        variables : Variables instance
            The corresponding variables. Set their values and use
            :func:`eval_equations() <sfepy.fem.evaluate.eval_equations()>`.

        Examples
        --------
        `problem` is ProblemDefinition instance.

        >>> out = problem.create_evaluable('dq_state_in_volume_qp.i1.Omega(u)')
        >>> equations, variables = out

        `vec` is a vector of coefficients compatible with the field
        of 'u' - let's use all ones.

        >>> vec = nm.ones((variables['u'].n_dof,), dtype=nm.float64)
        >>> variables['u'].set_data(vec)
        >>> vec_qp = eval_equations(equations, variables, mode='qp')

        Try another vector:

        >>> vec = 3 * nm.ones((variables['u'].n_dof,), dtype=nm.float64)
        >>> variables['u'].set_data(vec)
        >>> vec_qp = eval_equations(equations, variables, mode='qp')
        """
        from sfepy.fem.equations import get_expression_arg_names

        variables = get_default(var_dict, {})
        var_context = get_default(var_dict, {})

        if try_equations and self.equations is not None:
            # Make a copy, so that possible variable caches are preserved.
            for key, var in self.equations.variables.as_dict().iteritems():
                if key in variables:
                    continue
                var = var.copy(name=key)
                if not preserve_caches:
                    var.clear_evaluate_cache()
                variables[key] = var

        elif var_dict is None:
            possible_var_names = get_expression_arg_names(expression)
            variables = self.create_variables(possible_var_names)

        materials = self.get_materials()
        if materials is not None:
            if copy_materials:
                materials = materials.semideep_copy()

            else:
                materials = Materials(objs=materials._objs)

        else:
            possible_mat_names = get_expression_arg_names(expression)
            materials = self.create_materials(possible_mat_names)

        _kwargs = copy(kwargs)
        for key, val in kwargs.iteritems():
            if isinstance(val, Variable):
                if val.name != key:
                    msg = 'inconsistent variable name! (%s == %s)' \
                          % (val.name, key)
                    raise ValueError(msg)
                var_context[val.name] = variables[val.name] = val
                _kwargs.pop(key)

            elif isinstance(val, Material):
                if val.name != key:
                    msg = 'inconsistent material name! (%s == %s)' \
                          % (val.name, key)
                    raise ValueError(msg)
                materials[val.name] = val
                _kwargs.pop(key)

        kwargs = _kwargs

        ebcs = get_default(ebcs, self.ebcs)
        epbcs = get_default(epbcs, self.epbcs)
        lcbcs = get_default(lcbcs, self.lcbcs)
        ts = get_default(ts, self.get_timestepper())
        functions = get_default(functions, self.functions)
        integrals = get_default(integrals, self.get_integrals())

        out = create_evaluable(expression,
                               self.fields,
                               materials,
                               variables.itervalues(),
                               integrals,
                               ebcs=ebcs,
                               epbcs=epbcs,
                               lcbcs=lcbcs,
                               ts=ts,
                               functions=functions,
                               auto_init=auto_init,
                               mode=mode,
                               extra_args=extra_args,
                               verbose=verbose,
                               kwargs=kwargs)

        if not strip_variables:
            variables = out[1]
            variables.extend([
                var for var in var_context.itervalues() if var not in variables
            ])

        equations = out[0]
        mode = 'update' if not copy_materials else 'normal'
        equations.time_update_materials(self.ts,
                                        mode=mode,
                                        problem=self,
                                        verbose=verbose)

        return out