def domain_area(cid): """Calculates area of the domain bounded by the contour :param cid: grid or contour identifier :returns: positive float or zero for open contours """ icheck(0, ACont2D()) return flow.receiver.get_any_contour(cid).area()
def triangulate_domain(domain, constr=[], pts=[], fill='3'): """Builds constrained triangulation within given domain :param domain: single or list of closed contours representing bounding domain :param constr: single or list of contours representing triangulation constraints :param pts: set of points in ``[len0, [x0, y0], ...]`` format where ``x, y`` are coordinates of internal vertices which should be embedded into the resulting grid, ``len`` - size of adjacent cells :param str fill: if '3' then triangulates area; '4' runs recombination algorithm to make mostly quadrangular mesh :return: grid identifier A contour tree will be built using all closed contours passed as **domain** parameter. Only the interior parts of this tree will be meshed. Contours passed by **domain** should not intersect each other, but could intersect **constr** contours. **constr** could contain any set of closed and open contours. See details in :ref:`unstructured-meshing`. """ icheck(0, UListOr1(ACont2D())) icheck(1, UListOr1(ACont2D())) icheck(2, CompoundList(Float(grthan=0.0), Point2D())) icheck(3, OneOf('3', '4')) if fill == '3': return _triquad(domain, constr, pts, '3') elif fill == '4': return _triquad(domain, constr, pts, '4')
def pick_contour(pnt, contlist=[]): """ Returns contour closest to given point :param pnt: point as [x, y] list :param contlist: list of contour identifier to choose from :returns: closest contour identifier If **contlist** is empty then looks over all registered contours. This procedure does not take 2d grid contours into account. """ icheck(0, Point2D()) icheck(1, List(ACont2D())) conts = map(flow.receiver.get_any_contour, contlist) cc = closest_contour(conts, pnt) ind = conts.index(cc) return contlist[ind]
def stripe(cont, partition, tip='no', bnd=0): """ Build a structured grid to the both sides of contour line :param cont: closed or open contour identifier :param ascending-list-of-double partition: partition perpendicular to source contour :param str tip: stripe endings meshing algorithm * ``"no"`` - no grid at endings * ``"radial"`` - radial grid at endings :param float-or-list-of-floats bnd: boundary types for input grid. List of four values provides respective values for bottom, left, right, top sides of resulting grid with respect to contour direction. :return: grid identifier Horizontal partition is taken from contour partition. Vertical partition is given by user with ``partition`` list parameter. If it starts with non zero value then grid will not contain contour nodes as its vertices. Use :func:`partition_segment` to define non-equidistant **partition** with any desired refinement if needed. """ icheck(0, ACont2D()) icheck(1, IncList(Float(grthan=0.0))) icheck(2, OneOf('no', 'radial')) icheck(3, ListOr1(ZType(), llen=4)) bnd = bnd[:4] if isinstance(bnd, list) else [bnd, bnd, bnd, bnd] arg = {"source": cont, "partition": partition, "tip": tip, "bnd": bnd} c = com.gridcom.StripeGrid(arg) flow.exec_command(c) return c.added_grids2()[0]
def info_contour(cid): """Get contour structure information :param cid: contour or grid identifier :returns: dictionary representing contour length, total number of nodes, edges, number of edges in each subcontour and number of edges of each boundary type:: {'Nnodes': int, 'Nedges': int, 'subcont': [list-of-int], # edges number in each subcontour 'btypes': {btype(int): int} # boundary type: number of edges 'length': float } """ icheck(0, ACont2D()) cont = flow.receiver.get_any_contour(cid).contour2() ret = {} ret['Nnodes'] = cont.n_vertices() ret['Nedges'] = cont.n_edges() sep = [Contour2(s) for s in c2core.quick_separate(cont.cdata)] ret['subcont'] = [s.n_edges() for s in sep] bt = cont.raw_data('bt') ret['btypes'] = {} for s in bt: if s not in ret['btypes']: ret['btypes'][s] = 1 else: ret['btypes'][s] += 1 ret['length'] = cont.length() return ret
def get_point(obj, ind=None, vclosest=None, eclosest=None, cclosest=None, only_contour=True): """ Returns object point :param obj: grid or contour identifier :param int ind: index of point :param vclosest: :param eclosest: :param cclosest: point as [x, y] list :param bool only_contour: If that is true then if **objs** is a grid then respective grid contour will be used :returns: point as [x, y] list Only one of **ind**, **vclosest**, **eclosest**, **cclosest** arguments should be defined. If **ind** is defined then returns point at given index. If **vvlosest** point is defined then returns object vertex closest to this point. If **eclosest** point is defined then returns point owned by an object edge closest to input point. If **cclosest** point is defined then returns non straight line object contour vertex closest to input point. """ icheck(0, ACont2D()) icheck(1, NoneOr(UInt())) icheck(2, NoneOr(Point2D())) icheck(3, NoneOr(Point2D())) icheck(4, NoneOr(Point2D())) icheck(5, Bool()) if ind is None and vclosest is None and eclosest is None and\ cclosest is None: raise InvalidArgument("Define point location") try: tar = flow.receiver.get_contour2(obj) except KeyError: tar = flow.receiver.get_grid2(obj) if only_contour or cclosest is not None: tar = tar.contour() if cclosest is not None: tar = tar.deepcopy() c2core.simplify(tar.cdata, 0, False) vclosest = cclosest if vclosest is not None: return tar.closest_points([vclosest], "vertex")[0] elif eclosest is not None: return tar.closest_points([eclosest], "edge")[0] elif ind is not None: return tar.point_at(ind)