def add_rect_contour(p0, p1, bnd=0): """Adds four point closed rectangular contour. :param list-of-floats p0: :param list-of-floats p1: bottom left and top right coordinates of the contour :param bnd: single or list of 4 boundary identifiers (bottom, right, top, left) for contour segments. With the default value no boundary types will be set. :return: Contour identifier """ icheck(0, Point2D()) icheck(1, Point2D(grthan=p0)) icheck(2, ListOr1(ZType(), llen=4)) if isinstance(bnd, list): b = bnd[0:4] else: b = [bnd, bnd, bnd, bnd] c = com.contcom.AddRectCont({"p0": p0, "p1": p1, "bnds": b}) flow.exec_command(c) return c.added_contours2()[0]
def create_spline_contour(pnts, bnds=0, nedges=100): """ Creates singly connected contour as a parametric cubic spline. :param list-of-list-of-floats pnts: sequence of points. If coordinates of first and last points are equal then resulting contour will be closed. :param single-or-list-of-boundary-identifiers bnds: boundary type for each contour segment bounded by **pnts** or single identifier for the whole contour. :param int nedges: number of line segments of resulting contour. Should be equal or greater than the number of sections defined by **pnts**. :returns: contour identifier """ icheck(0, List(Point2D(), minlen=3)) icheck(1, ListOr1(ZType(), llen=len(pnts) - 1)) icheck(2, UInt(minv=len(pnts) - 1)) b = bnds if isinstance(bnds, list) else [bnds] c = com.contcom.CreateSpline({"points": pnts, "bnds": b, "nedges": nedges}) flow.exec_command(c) return c.added_contours2()[0]
def add_triangle_grid(p0, p1, p2, nedge, bnd=0): """Creates structured grid in triangle area :param list-of-floats p0: :param list-of-floats p1: :param list-of-floats p2: triangle vertices in [x, y] format :param int nedge: partition of triangle edges :param int-or-list-of-int bnd: boundary types for outer contour :return: identifier of newly created grid Resulting grid will contain quadrangle cells everywhere except area near ``p0``-``p2`` edge where triangle cells will be built. """ icheck(0, Point2D()) icheck(1, Point2D(noteq=[p0])) icheck(2, Point2D(noteq=[p0, p1])) icheck(3, UInt(minv=1)) icheck(4, ListOr1(ZType(), llen=3)) bnd = bnd[:3] if isinstance(bnd, list) else [bnd, bnd, bnd] c = com.gridcom.AddTriGrid({ "vertices": [p0, p1, p2], "nedge": nedge, "bnd": bnd }) flow.exec_command(c) return c.added_grids2()[0]
def copy_geom(objs): """ Creates deep copies of geometry objects :param objs: identifier or list of identifiers of objects to copy :returns: list of identifiers of copied objects in oder prescribed by input list """ icheck(0, ListOr1(AObject())) if not isinstance(objs, list): objs = [objs] c = com.objcom.CopyGeom({"names": objs}) flow.exec_command(c) return c.odered_output()
def add_unf_ring_grid(p0, radinner, radouter, na, nr, coef=1.0, bnd=0): """Builds ring grid :param list-of-floats p0: center coordinates as [x, y] :param float radinner: :param float radouter: inner and outer radii :param int na: :param int nr: arc and radius partition respectively :param float coef: refinement coefficient: * ``coef = 1``: equidistant radius division * ``coef > 1``: refinement towards center of circle * ``0 < coef < 1``: refinement towards outer arc :param int-or-list-of-int bnd: boundary types for inner and outer ring boundaries :return: created grid identifier """ if radinner > radouter: radinner, radouter = radouter, radinner icheck(0, Point2D()) icheck(1, Float(grthan=0.0)) icheck(2, Float(grthan=0.0)) icheck(3, UInt(minv=3)) icheck(4, UInt(minv=1)) icheck(5, Float(grthan=0.0)) icheck(6, ListOr1(ZType(), llen=2)) bnd = bnd[:2] if isinstance(bnd, list) else [bnd, bnd] c = com.gridcom.AddUnfRingGrid({ "p0": p0, "radinner": radinner, "radouter": radouter, "na": na, "nr": nr, "coef": coef, "bnd": bnd }) flow.exec_command(c) return c.added_grids2()[0]
def create_contour(pnts, bnds=0): """ Create singly connected contour from sequence of points. :param list-of-list-of-floats pnts: sequence of points. If coordinates of first and last points are equal then contour is considered closed. :param single-or-list-of-boundary-identifiers bnds: boundary type for each contour segment or single identifier for the whole contour. :returns: contour identifier Example: >>> hmscript.create_contour([[0, 0], [1, 0], [1, 1], [0, 0]], [b1, b2, b3]) """ icheck(0, List(Point2D(), minlen=2)) icheck(1, ListOr1(ZType())) b = bnds if isinstance(bnds, list) else [bnds] c = com.contcom.CreateContour({"points": pnts, "bnds": b}) flow.exec_command(c) return c.added_contours2()[0]
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 set_boundary_type(obj, btps=None, bfun=None, bdict=None): """ Mark geometrical object with boundary types. :param obj: geometric object identifier :param btps: single identifier for the whole object or list of identifiers for each boundary segment. :param bfun: function which returns boundary type taking segment coordinates and old boundary type as arguments. :param bdict: {btype: [list-of-segment indicies]} dictionary which maps boundary type with object segments indicies Only one of **btps**, **bfun**, **bdict** arguments should be defined. **bfun** signature is: * ``(x0, y0, x1, y1, bt) -> btype`` for 2D objects, where *x0, y0, x1, y1* are edge end point coordinates, bt - old boundary type * ``(xc, yc, zc, bt) -> btype`` for 3D objects, where *xc, yc, zc* - approximate face center coordinates, bt - old boundary type If **obj** is a grid then only boundary segments will be passed to **bfun** function and **btps** list entries will be associated with boundary segments only. However **bdict** entries should contain global edge or face indicies. Example: .. literalinclude:: ../../testing/py/fromdoc/ex_setbtype.py :start-after: START OF EXAMPLE :end-before: END OF EXAMPLE """ icheck(0, AObject()) icheck(1, NoneOr(ListOr1(ZType()))) icheck(3, NoneOr(Dict(ZType(), List(UInt())))) t = flow.receiver.whatis(obj) if t in ['g2', 'c2']: icheck(2, NoneOr(Func(narg=5))) else: icheck(2, NoneOr(Func(narg=4))) if [btps, bfun, bdict].count(None) != 2: raise InvalidArgument("One of [btps, bfun, bdict] should be not None") args = {'name': obj, 'whole': None, 'btypes': {}} if isinstance(btps, int): args['whole'] = btps elif bdict is not None: args['btypes'] = bdict else: g = flow.receiver.get_object(obj) if t == 'g2': if btps is not None: _setbt_args_g2g3btps(g, btps, args['btypes']) if bfun is not None: _setbt_args_g2bfun(g, bfun, args['btypes']) if t == 'g3': if btps is not None: _setbt_args_g2g3btps(g, btps, args['btypes']) if bfun is not None: _setbt_args_g3bfun(g, bfun, args['btypes']) if t == 'c2': if btps is not None: _setbt_args_c2s3btps(g, btps, args['btypes']) if bfun is not None: _setbt_args_c2bfun(g, bfun, args['btypes']) if t == 's3': if btps is not None: _setbt_args_c2s3btps(g, btps, args['btypes']) if bfun is not None: _setbt_args_s3bfun(g, bfun, args['btypes']) c = com.objcom.SetBType(args) flow.exec_command(c)
def add_unf_rect_grid(p0=[0, 0], p1=[1, 1], nx=3, ny=3, custom_x=[], custom_y=[], bnd=0): """Builds rectangular grid. :param list-of-floats p0: :param list-of-floats p1: bottom left, top right points in [x, y] format. :param int nx: :param int ny: partition in x and y directions. :param float-or-list-of-floats custom_x: :param float-or-list-of-floats custom_y: custom x and y coordinates :param int-or-list-of-int: boundary types for bottom, right, top, left rectangle sides :returns: created grid identifier Builds a grid in a rectangular area formed by points **p0** and **p1**. **nx** and **ny** provide grid partition in x and y direction. If **custom_x**/**custom_y** is given by a single float value than it shows a step size in respective direction, hence values given by **nx**/**ny** parameters will be omitted. If **custom_x**/**custom_y** is given by a list of increasing floats it explicitly shows the partition in respective direction. In the latter case the respective **p0**, **p1** coordinates will also be ignored. Use :func:`partition_segment` to conveniently define **custom\_** fields if needed. """ icheck(0, Point2D()) icheck(1, Point2D(grthan=p0)) icheck(2, UInt(minv=1)) icheck(3, UInt(minv=1)) icheck(4, Or(Float(grthan=0.), IncList(Float()))) icheck(5, Or(Float(grthan=0.), IncList(Float()))) icheck(6, ListOr1(ZType(), llen=4)) bnd = bnd[:4] if isinstance(bnd, list) else [bnd, bnd, bnd, bnd] custom_x = custom_x if isinstance(custom_x, list) else [custom_x] custom_y = custom_y if isinstance(custom_y, list) else [custom_y] c = com.gridcom.AddUnfRectGrid({ "p0": p0, "p1": p1, "nx": nx, "ny": ny, "custom_x": custom_x, "custom_y": custom_y, "bnds": bnd }) flow.exec_command(c) return c.added_grids2()[0]