Source code for sfepy.fem.integrals

import numpy as nm

from sfepy.base.base import OneTypeList, Container, Struct, basestr
from quadratures import QuadraturePoints

[docs]class Integrals(Container): """ Container for instances of :class:`Integral`. """ @staticmethod
[docs] def from_conf(conf): objs = OneTypeList(Integral) for desc in conf.itervalues(): if hasattr(desc, 'vals'): aux = Integral(desc.name, kind=desc.kind, coors=desc.vals, weights=desc.weights) else: aux = Integral(desc.name, kind=desc.kind, order=desc.order) objs.append(aux) obj = Integrals(objs) return obj
[docs] def get(self, name, kind='v'): """ Return existing or new integral. Parameters ---------- name : str The name can either be a non-negative integer, a string representation of a non-negative integer (the integral order) or 'a' (automatic order) or a string beginning with 'i' (existing custom integral name). """ if name == 'a': raise NotImplementedError elif isinstance(name, basestr) and (name[0] == 'i'): try: obj = self[name] except IndexError: raise ValueError('integral %s is not defined!' % name) else: try: order = int(name) except: raise ValueError('unsupported integral reference! (%s)' % name) name = '__%s_o%d' % (kind, order) if self.has_key(name): obj = self[name] else: # Create new integral, and add it to self. obj = Integral(name, kind, order=order) self.append(obj) return obj
[docs]class Integral(Struct): """ Wrapper class around quadratures. """ def __init__(self, name, kind='v', order=1, coors=None, weights=None): self.name = name self.kind = kind self.qps = {} if coors is None: self.mode = 'builtin' else: self.mode = 'custom' self.coors = coors self.weights = weights self.order = 0 if order in ('auto', 'custom', 'a', 'c'): self.order = -1 else: self.order = int(order)
[docs] def get_key(self): """ Get the key string corresponding to the integral kind and order, that can be used to distinguish various cached data evaluated using the integral. """ return '__%s_o%d' % (self.kind, self.order)
[docs] def get_qp(self, geometry): """ Get quadrature point coordinates and corresponding weights for given geometry. For built-in quadratures, the integration order is given by `self.order`. Parameters ---------- geometry : str The geometry key describing the integration domain, see the keys of `sfepy.fem.quadratures.quadrature_tables`. Returns ------- coors : array The coordinates of quadrature points. weights: array The quadrature weights. """ if geometry in self.qps: qp = self.qps[geometry] else: if self.mode == 'builtin': qp = QuadraturePoints.from_table(geometry, self.order) else: qp = QuadraturePoints(None, coors=self.coors, weights=self.weights) self.qps[geometry] = qp return qp.coors, qp.weights
[docs] def integrate(self, function, order=1, geometry='1_2'): """ Integrate numerically a given scalar function. Parameters ---------- function : callable(coors) The function of space coordinates to integrate. order : int, optional The integration order. For tensor product geometries, this is the 1D (line) order. geometry : str The geometry key describing the integration domain. Default is `'1_2'`, i.e. a line integral in [0, 1]. For other values see the keys of `sfepy.fem.quadratures.quadrature_tables`. Returns ------- val : float The value of the integral. """ qp = QuadraturePoints.from_table(geometry, order) fvals = function(qp.coors) val = nm.sum(fvals * qp.weights) return val