Source code for viennagrid.algorithms

#-*- coding: utf-8 -*-

import viennagrid

_SUPPORTED_NORMS = ('1', '2', 'inf')

[docs]def inner_prod(point1, point2): """ Compute the inner product of two vectors (represented by points). :param point1: First point :type point1: :class:`viennagrid.Point` :param point2: Second point :type point2: :class:`viennagrid.Point` :returns: float --- the result of the inner product :raises: TypeError """ try: point1 = point1._point except AttributeError: raise TypeError('paramater at position 1 is not a valid point') try: point2 = point2._point except AttributeError: raise TypeError('paramater at position 1 is not a valid point') # Try to get method 'inner_prod' from 'point1'. If it doesn't have the method, # it means it's not a cartesian point. Thus, convert to cartesian coordinates # and get the method. If it still doesn't have the method, raise an exception. try: inner_prod_fn = point1.__getattribute__('inner_prod') except AttributeError: casted_pnt1 = point1.to_cartesian() try: inner_prod_fn = casted_pnt1.__getattribute__('inner_prod') except AttributeError: raise TypeError('point1 has no method named inner_prod') else: casted_pnt1 = point1 # If point types are equal, simply calculate the inner product. If they're not # equal, try to convert 'point2' to the type of 'point1'. If types are still # different, it means that both points are of incompatible types # (i.e. incompatible dimensions). if casted_pnt1.__class__ is point2.__class__: return inner_prod_fun(point2) else: casted_pnt2 = point2.to_cartesian() if casted_pnt1.__class__ is casted_pnt2.__class__: return inner_prod_fun(casted_pnt2) else: raise TypeError('incompatible point types')
[docs]def cross_prod(point1, point2): """ Compute the cross product of two vectors (represented by points). :param point1: First point :type point1: :class:`viennagrid.Point` :param point2: Second point :type point2: :class:`viennagrid.Point` :returns: :class:`viennagrid.Point` --- the result of the cross product :raises: TypeError """ try: point1 = point1._point except AttributeError: raise TypeError('paramater at position 1 is not a valid point') try: point2 = point2._point except AttributeError: raise TypeError('paramater at position 1 is not a valid point') # Try to get method 'cross_prod' from 'point1'. If it doesn't have the method, # it means it's not a cartesian point. Thus, convert to cartesian coordinates # and get the method. If it still doesn't have the method, raise an exception. try: cross_prod_fn = point1.__getattribute__('cross_prod') except AttributeError: casted_pnt1 = point1.to_cartesian() try: cross_prod_fn = casted_pnt1.__getattribute__('cross_prod') except AttributeError: raise TypeError('point1 has no method named cross_prod') else: casted_pnt1 = point1 # If point types are equal, simply calculate the cross product. If they're not # equal, try to convert 'point2' to the type of 'point1'. If types are still # different, it means that both points are of incompatible types # (i.e. incompatible dimensions). if casted_pnt1.__class__ is point2.__class__: return viennagrid.Point(cross_prod_fn(point2)) else: casted_pnt2 = point2.to_cartesian() if casted_pnt1.__class__ is casted_pnt2.__class__: return viennagrid.Point(cross_prod_fn(casted_pnt2)) else: raise TypeError('incompatible point types')
[docs]def norm(point, norm_type=2): """ Compute the norm of a vector (represented by a point). :param point: Point :type point: :class:`viennagrid.Point` :param norm_type: Norm to calculate (at this time only 1, 2 and 'inf' are supported). :type norm_type: int or str :returns: float --- the norm of the vector :raises: ValueError, TypeError """ try: point = point._point except AttributeError: raise TypeError('paramater at position 1 is not a valid point') norm_type = str(norm_type) if norm_type in _SUPPORTED_NORMS: norm_fn = viennagrid.wrapper.__getattribute__('norm_%(norm_type)s' % locals()) return norm_fn(point) else: raise ValueError('unsupported norm type: %(norm_type)s')
[docs]def apply_voronoi(dom): """ Compute Voronoi information of the given domain. :param dom: Domain :type dom: :class:`viennagrid.Domain` :raises: TypeError """ try: dom = dom._domain except AttributeError: raise TypeError('parameter at position 1 is not a valid domain') viennagrid.wrapper.apply_voronoi(dom)
[docs]def centroid(cell): """ Compute the centroid of the given cell. :param cell: Cell whose centroid should be computed :type cell: :class:`viennagrid.Cell` :returns: :class:`viennagrid.Point` --- the centroid of the cell :raises: TypeError """ try: cell = cell._cell except AttributeError: raise TypeError('parameter at position 1 is not a valid cell') point = viennagrid.wrapper.centroid(cell) return viennagrid.Point(*point.coords, coord_sytem=point.coord_system)
[docs]def cell_refine(dom, seg, predicate): """ Refine all cells of the given domain and segmentation which match a given predicate. :param dom: Domain to refine :type dom: :class:`viennagrid.Domain` :param seg: Segmentation of the domain to refine :type seg: :class:`viennagrid.Segmentation` :param predicate: Function that tells whether a cell should be refined or not :type predicate: function object that accepts a cell as parameter and returns a boolean :returns: A two-element tuple containing the output domain and segmentation after the refinement. :raises: TypeError """ try: config = dom.config dom = dom._domain except AttributeError: raise TypeError('parameter at position 1 is not a valid domain') try: seg = seg._segmentation except AttributeError: raise TypeError('parameter at position 2 is not a valid domain') refined_result = viennagrid.wrapper.cell_refine(dom, seg, predicate) refined_domain = viennagrid.Domain(config) refined_domain._domain = refined_result[0] refined_segmentation = viennagrid.Segmentation(refined_domain) refined_segmentation._segmentation = refined_result[1] return (refined_domain, refined_segmentation)
[docs]def circumcenter(cell): """ Compute the circumcenter of the given cell. :param cell: Cell whose circumcenter should be computed :type cell: :class:`viennagrid.Cell` :returns: :class:`viennagrid.Point` --- the circumcenter of the cell :raises: TypeError """ try: cell = cell._cell except AttributeError: raise TypeError('parameter at position 1 is not a valid cell') point = viennagrid.wrapper.circumcenter(cell) return viennagrid.Point(*point.coords, coord_system=point.coord_system)
[docs]def is_boundary(domseg, boundary_elem): """ Check if the given element is a boundary element of the given domain or segment. :param domseg: Domain or segment :type domseg: :class:`viennagrid.Domain` or :class:`viennagrid.Segment` :param boundary_elem: Element of which to check if its a boundary element of the given domain or segment. The element can be a facet, and edge or a vertex. :type boundary_elem: :class:`viennagrid.Facet`, :class:`viennagrid.Edge` or :class:`viennagrid.Vertex` :returns: bool --- True if the given element is a boundary element of the given domain or segment; False otherwise. :raises: TypeError """ try: if isinstance(domseg, viennagrid.Domain): domseg = domseg._domain elif isinstance(domseg, viennagrid.Segment): domseg = domseg._segment except AttributeError: raise TypeError('parameter at position 1 is not a valid domain or segment') try: if isinstance(boundary_elem, viennagrid.Facet): boundary_elem = boundary_elem._facet elif isinstance(boundary_elem, viennagrid.Edge): boundary_elem = boundary_elem._edge elif isinstance(boundary_elem, viennagrid.Vertex): boundary_elem = boundary_elem._vertex except AttributeError: raise TypeError('parameter at position 2 is not a valid boundary element') return viennagrid.wrapper.is_boundary(domseg, boundary_elem)
[docs]def is_interface(seg0, seg1, interface_elem): """ Check if the given element is an interface element of the two given segments. :param seg0: First segment :type seg0: :class:`viennagrid.Segment` :param seg1: Second segment :type seg1: :class:`viennagrid.Segment` :param interface_elem: Element of which to check if its an interface element of the given segments. The element can be a facet, and edge or a vertex. :type interface_elem: :class:`viennagrid.Facet`, :class:`viennagrid.Edge` or :class:`viennagrid.Vertex` :returns: bool --- True if the given element is an interface element of the given segments; False otherwise. :raises: TypeError """ try: seg0 = seg0._segment except AttributeError: raise TypeError('parameter at position 1 is not a valid segment') try: seg1 = seg1._segment except AttributeError: raise TypeError('parameter at position 2 is not a valid segment') try: if isinstance(interface_elem, viennagrid.Facet): interface_elem = interface_elem._facet elif isinstance(interface_elem, viennagrid.Edge): interface_elem = interface_elem._edge elif isinstance(interface_elem, viennagrid.Vertex): interface_elem = interface_elem._vertex except AttributeError: raise TypeError('parameter at position 3 is not a valid interface element') return viennagrid.wrapper.is_interface(seg0, seg1, interface_elem)
[docs]def refine(dom, seg, predicate): """ Refine all edges of the given domain and segmentation which match a given predicate. :param dom: Domain to refine :type dom: :class:`viennagrid.Domain` :param seg: Segmentation of the domain to refine :type seg: :class:`viennagrid.Segmentation` :param predicate: Function that tells whether an edge should be refined or not :type predicate: function object that accepts an edge as parameter and returns a boolean :returns: A two-element tuple containing the output domain and segmentation after the refinement. :raises: TypeError """ try: config = dom.config dom = dom._domain except AttributeError: raise TypeError('parameter at position 1 is not a valid domain') try: seg = seg._segmentation except AttributeError: raise TypeError('parameter at position 2 is not a valid domain') refined_result = viennagrid.wrapper.refine(dom, seg, predicate) refined_domain = viennagrid.Domain(config) refined_domain._domain = refined_result[0] refined_segmentation = viennagrid.Segmentation(refined_domain) refined_segmentation._segmentation = refined_result[1] return (refined_domain, refined_segmentation)
[docs]def refine_uniformly(dom, seg): """ Refine all edges of the given domain and segmentation. :param dom: Domain to refine :type dom: :class:`viennagrid.Domain` :param seg: Segmentation of the domain to refine :type seg: :class:`viennagrid.Segmentation` :returns: A two-element tuple containing the output domain and segmentation after the refinement. :raises: TypeError """ try: config = dom.config dom = dom._domain except AttributeError: raise TypeError('parameter at position 1 is not a valid domain') try: seg = seg._segmentation except AttributeError: raise TypeError('parameter at position 2 is not a valid domain') refined_result = viennagrid.wrapper.refine_uniformly(dom, seg) refined_domain = viennagrid.Domain(config) refined_domain._domain = refined_result[0] refined_segmentation = viennagrid.Segmentation(refined_domain) refined_segmentation._segmentation = refined_result[1] return (refined_domain, refined_segmentation)
[docs]def surface(elem): """ Calculate the surface of the given element. :param elem: Element whose surface should be calculated. :type elem: :class:`viennagrid.Cell`, :class:`viennagrid.Domain` or :class:`viennagrid.Segment` :returns: float --- the surface of the cell, domain or segment :raises: TypeError """ try: if isinstance(elem, viennagrid.Cell): elem = elem._cell elif isinstance(elem, viennagrid.Domain): elem = elem._domain elif isinstance(elem, viennagrid.Segment): elem = elem._segment except AttributeError: raise TypeError('parameter at position 1 is not a valid element') return viennagrid.wrapper.surface(elem)
[docs]def volume(elem): """ Calculate the volume of the given element. :param elem: Element whose volume should be calculated. :type elem: :class:`viennagrid.Cell`, :class:`viennagrid.Domain` or :class:`viennagrid.Segment` :returns: float --- the volume of the cell, domain or segment :raises: TypeError """ try: if isinstance(elem, viennagrid.Cell): elem = elem._cell elif isinstance(elem, viennagrid.Domain): elem = elem._domain elif isinstance(elem, viennagrid.Segment): elem = elem._segment except AttributeError: raise TypeError('parameter at position 1 is not a valid element') return viennagrid.wrapper.volume(elem)
[docs]def scale(dom, factor): """ Scale a domain by a given factor. :param dom: Domain to be scaled :type dom: :class:`viennagrid.Domain` :param factor: Scale factor :type factor: float :raises: TypeError """ try: dom = dom._domain except AttributeError: raise TypeError('parameter at position 1 is not a valid domain') viennagrid.wrapper.scale(dom, factor)
[docs]def spanned_volume(*args): """ Calculate the volume spanned by a set of points. As arguments you have to pass an arbitrary number of points (:class:`viennagrid.Point` objects). :returns: float --- the volume spanned by the set of points :raises: TypeError """ point_list = [] for i, point in enumerate(args): # Get the low-level point try: point = point._point except AttributeError: raise TypeError('parameter at position %(pos)d is not a valid point' % {'pos': i + 1}) # If point is not cartesian, convert it if point.coord_system != 'cartesian': point = point.to_cartesian() # Append the point to the list point_list.append(point) return viennagrid.wrapper.spanned_volume(*point_list)