示例#1
0
    def test_cubic_curve(self):
        t = np.linspace(0, 1, 80)  # interpolation points
        s = np.linspace(0, 1, 150)  # evaluation points
        x = np.zeros((80, 2))  # physical points

        # test PERIODIC curves
        x[:, 0] = 16 * t * t * (1 - t) * (1 - t)
        x[:, 1] = 1 - x[:, 0]
        crv = CurveFactory.cubic_curve(x, CurveFactory.Boundary.PERIODIC, t)
        y = crv(s)
        # exact solution is t^4, cubic approximation gives t^3, needs atol
        self.assertTrue(
            np.allclose(y[:, 0], 16 * s * s * (1 - s) * (1 - s), atol=1e-2))
        self.assertTrue(
            np.allclose(y[:, 1], 1 - 16 * s * s * (1 - s) * (1 - s),
                        atol=1e-2))

        # test FREE boundary type
        x[:, 0] = 12 * t * t * t + 2 * t
        x[:, 1] = 12 * t * t * t - 3 * t * t
        crv = CurveFactory.cubic_curve(x, CurveFactory.Boundary.FREE, t=t)
        y = crv(s)
        self.assertTrue(np.allclose(y[:, 0], 12 * s * s * s + 2 * s))
        self.assertTrue(np.allclose(y[:, 1], 12 * s * s * s - 3 * s * s))

        # test NATURAL boundary type (x''(t)=0 at the boundary)
        x[:, 0] = t
        x[:, 1] = 3
        crv = CurveFactory.cubic_curve(x, CurveFactory.Boundary.NATURAL, t=t)
        y = crv(s)
        self.assertTrue(np.allclose(y[:, 0], s))
        self.assertTrue(np.allclose(y[:, 1], 3.0))

        # test TANGENT boundary type (x'(t)=g at both endpoints)
        x[:, 0] = t * t + t - 1
        x[:, 1] = 3 * t * t - 3 * t + 1
        dx = [[2 * t[0] + 1, 6 * t[0] - 3], [2 * t[-1] + 1, 6 * t[-1] - 3]]
        crv = CurveFactory.cubic_curve(x,
                                       CurveFactory.Boundary.TANGENT,
                                       t=t,
                                       tangents=dx)
        y = crv(s)
        self.assertTrue(np.allclose(y[:, 0], s * s + s - 1))
        self.assertTrue(np.allclose(y[:, 1], 3 * s * s - 3 * s + 1))

        # test HERMITE boundary type (x'(t)=g(t) at all interior points)
        x[:, 0] = t * t + t - 1
        x[:, 1] = 3 * t * t - 3 * t + 1
        dx = np.vstack([[2 * t + 1], [6 * t - 3]]).T
        crv = CurveFactory.cubic_curve(x,
                                       CurveFactory.Boundary.HERMITE,
                                       t=t,
                                       tangents=dx)
        y = crv(s)
        self.assertTrue(np.allclose(y[:, 0], s * s + s - 1))
        self.assertTrue(np.allclose(y[:, 1], 3 * s * s - 3 * s + 1))
    def test_cubic_curve(self):
        t = np.linspace(0,1,80)  # interpolation points
        s = np.linspace(0,1,150) # evaluation points
        x = np.zeros((80,2))     # physical points

        # test PERIODIC curves
        x[:,0] = 16*t*t*(1-t)*(1-t)
        x[:,1] = 1-x[:,0]
        crv = CurveFactory.cubic_curve(x, CurveFactory.Boundary.PERIODIC, t)
        y = crv(s)
        # exact solution is t^4, cubic approximation gives t^3, needs atol
        self.assertTrue(np.allclose(y[:,0],   16*s*s*(1-s)*(1-s), atol=1e-2))
        self.assertTrue(np.allclose(y[:,1], 1-16*s*s*(1-s)*(1-s), atol=1e-2))

        # test FREE boundary type
        x[:,0] = 12*t*t*t         + 2*t
        x[:,1] = 12*t*t*t - 3*t*t 
        crv = CurveFactory.cubic_curve(x, CurveFactory.Boundary.FREE, t=t)
        y = crv(s)
        self.assertTrue(np.allclose(y[:,0], 12*s*s*s         + 2*s))
        self.assertTrue(np.allclose(y[:,1], 12*s*s*s - 3*s*s      ))

        # test NATURAL boundary type (x''(t)=0 at the boundary)
        x[:,0] = t
        x[:,1] = 3
        crv = CurveFactory.cubic_curve(x, CurveFactory.Boundary.NATURAL, t=t)
        y = crv(s)
        self.assertTrue(np.allclose(y[:,0],   s))
        self.assertTrue(np.allclose(y[:,1], 3.0))

        # test TANGENT boundary type (x'(t)=g at both endpoints)
        x[:,0] =   t*t +   t - 1
        x[:,1] = 3*t*t - 3*t + 1
        dx     = [[2*t[ 0] + 1, 6*t[ 0]-3],
                  [2*t[-1] + 1, 6*t[-1]-3]]
        crv = CurveFactory.cubic_curve(x, CurveFactory.Boundary.TANGENT, t=t, tangents=dx)
        y = crv(s)
        self.assertTrue(np.allclose(y[:,0],   s*s +   s - 1))
        self.assertTrue(np.allclose(y[:,1], 3*s*s - 3*s + 1))

        # test HERMITE boundary type (x'(t)=g(t) at all interior points)
        x[:,0] =   t*t +   t - 1
        x[:,1] = 3*t*t - 3*t + 1
        dx     = np.vstack([[2*t + 1], [6*t-3]]).T
        crv = CurveFactory.cubic_curve(x, CurveFactory.Boundary.HERMITE, t=t, tangents=dx)
        y = crv(s)
        self.assertTrue(np.allclose(y[:,0],   s*s +   s - 1))
        self.assertTrue(np.allclose(y[:,1], 3*s*s - 3*s + 1))
示例#3
0
    def test_torsion(self):
        # planar curves have zero torsion
        controlpoints = [[1, 0, 1], [1, 1, .7], [0, 1, .89], [-1, 1, 0.5],
                         [-1, 0, 1], [-1, -.5, 1], [1, -.5, 1]]
        basis = BSplineBasis(4,
                             [-3, -2, -1, 0, 1, 2, 2.5, 4, 5, 6, 7, 8, 9, 9.5],
                             2)
        crv = Curve(basis, controlpoints, rational=True)
        self.assertAlmostEqual(crv.torsion(.3), 0.0)

        # test multiple evaluation points
        t = np.linspace(0, 1, 10)
        k = crv.torsion(t)
        self.assertEqual(len(k.shape), 1)  # is vector
        self.assertEqual(k.shape[0], 10)  # length 10 vector
        self.assertTrue(np.allclose(k, 0.0))  # zero torsion for planar curves

        # test helix: [a*cos(t), a*sin(t), b*t]
        t = np.linspace(0, 6 * pi, 300)
        a = 3.0
        b = 2.0
        x = np.array([a * np.cos(t), a * np.sin(t), b * t])
        crv = cf.cubic_curve(x.T, t=t)
        t = np.linspace(0, 6 * pi, 10)
        k = crv.torsion(t)

        # this is a helix approximation, hence atol=1e-3
        self.assertTrue(np.allclose(k, b / (a**2 + b**2),
                                    atol=1e-3))  # helix have const. torsion
示例#4
0
    def _generate_instance(self):
        """
        Internal function of the CurveDatasetGenerator that generates a problem instance containing <_num_curves>
        generated curves based on <_num_control_points> Control points along <_num_eval_points> uniformly spaced points
        with at least a minimal distance of <_min_distance> between each pair of curves.
        
        :return: Instance of curves as dict, where keys are the string names of the curves and the associated values are
            lists of points representing the curves
        """
        instance = {}

        for i in range(self._num_curves):
            curve_points = np.array([])
            valid_curve = False
            # The while loop will be executed until a valid curve is found. Each iteration of the for loop will produce
            # one valid curve, but it may take a while with large numbers in self._num_curves due to multiple
            # iterations of the while loop
            while not valid_curve:
                controlpoints = np.array([
                    np.array([
                        random.uniform(-.5, 1.5),
                        random.uniform(-.5, 1.5),
                        random.uniform(-.5, 1.5)
                    ]) for _ in range(self._num_control_points)
                ])
                curve = curve_factory.cubic_curve(controlpoints, 4)
                eval_points = np.linspace(0, 1, self._num_eval_points)
                curve_points = np.array(curve(eval_points))

                # get all points outside of the unit cube and delete them
                rows_to_delete = np.append(
                    np.where(curve_points < 0)[0],
                    np.where(curve_points > 1)[0])
                reference_rows = np.array(range(len(curve_points)))
                reference_rows = np.delete(reference_rows, rows_to_delete)
                # checks whether the generated curve is valid or not
                if len(reference_rows) < self._min_length or max(
                        np.diff(reference_rows)) > 1:
                    # All points are out of the unit cube or the segment which is outside of the unit cube which will be
                    # deleted splits the curve in half, thus creating two seperate curve segments in the unit cube
                    continue

                curve_points = np.delete(curve_points, rows_to_delete, axis=0)

                if len(instance) == 0:
                    # First generated curve, therefore it cant be invalid in terms of minimal distance to other curves
                    break

                for tmp_curve_id, tmp_curve_points in instance.items():
                    distances = cdist(curve_points, tmp_curve_points)
                    if np.min(distances) <= self._min_distance:
                        # Generates new curve, because the current one is too close to at least one other curve
                        valid_curve = False
                        break
                    # valid_curve is only true if the distances to all other curves is at least <_min_distance>
                    valid_curve = True

            instance[f"curve_{i}"] = curve_points
        return instance
示例#5
0
    def test_cubic_curve_1D(self):
        n_elems = 30
        t = np.linspace(0, 1, n_elems)
        x = (t**2).reshape(-1, 1)

        crv = cf.cubic_curve(x, cf.Boundary.FREE, t=t.tolist())
        self.assertEqual(crv.dimension, 1)
        self.assertFalse(crv.rational)
示例#6
0
    def test_cubic_curve(self):
        t = np.linspace(0,1,80)
        x = np.zeros((80,2))
        x[:,0] = 16*t*t*(1-t)*(1-t)
        x[:,1] = 1-x[:,0]
        crv = CurveFactory.cubic_curve(x, CurveFactory.Boundary.PERIODIC, t)

        t = np.linspace(0,1,150)
        x = crv(t)
        # exact solution is t^4, cubic approximation gives t^3, needs atol
        self.assertTrue(np.allclose(x[:,0],   16*t*t*(1-t)*(1-t), atol=1e-2))
        self.assertTrue(np.allclose(x[:,1], 1-16*t*t*(1-t)*(1-t), atol=1e-2))
示例#7
0
def lissajous(a, b, d):
  # request a,b integers, so we have closed, periodic curves
  n = gcd(a,b)
  N = (a/n) * (b/n) # number of periods before looping

  # error test input
  if N > 1e4:       # non-integer (a,b) or otherwise too irregular
    raise Exception('Non-periodic', 'a,b must be integers (of moderate size)')

  # compute a set of interpolation points
  numb_pts = max(3*N, 100) # using 3N interpolation points is decent enough
  t = np.linspace(0,2*pi/n, numb_pts)
  x = np.array([np.sin(a*t + d), np.sin(b*t)])

  # do a cubic curve interpolation with periodic boundary conditions
  return curve_factory.cubic_curve(x.T, curve_factory.Boundary.PERIODIC)
示例#8
0
def cut_square(width, height, radius, inner_radius, nel_ang, order, out):

    # Compute number of elements along each part
    rest1 = height - radius - inner_radius
    rest2 = width - radius - inner_radius
    nel_cyl = int(np.ceil(4/np.pi * (inner_radius - radius) / radius * nel_ang))
    nel_rest1 = int(np.ceil(4/np.pi * rest1 / radius * nel_ang))
    nel_rest2 = int(np.ceil(4/np.pi * rest2 / radius * nel_ang))

    # Create quarter circles
    theta = np.linspace(0, np.pi/2, 2*nel_ang+1)[::-1]
    pts = np.array([radius * np.cos(theta), radius * np.sin(theta)]).T
    circle = cf.cubic_curve(pts, boundary=cf.Boundary.NATURAL).set_dimension(3)
    knots = circle.knots('u')
    inner1, inner2 = circle.split(knots[len(knots) // 2])

    # Fill the cylinder patches
    factor = inner_radius / radius
    outer1, outer2 = inner1 * factor, inner2 * factor
    cyl1 = sf.edge_curves(inner1, outer1).set_order(4,4).refine(0, nel_cyl-1)
    cyl2 = sf.edge_curves(inner2, outer2).set_order(4,4).refine(0, nel_cyl-1)

    # Create the "curved rectangles"
    dist = np.sqrt(2) * radius
    edge1 = cf.line((0, height), (dist, height)).set_order(4).set_dimension(3).refine(nel_ang-1)
    rect1 = sf.edge_curves(outer1, edge1).set_order(4,4).refine(0, nel_rest1-1)
    edge2 = cf.line((width, dist), (width, 0)).set_order(4).set_dimension(3).refine(nel_ang-1)
    rect2 = sf.edge_curves(outer2, edge2).set_order(4,4).refine(0, nel_rest2-1)

    # Final square
    edge1 = rect2.section(u=0)
    edge2 = edge1 + (0, height - dist, 0)
    rect = sf.edge_curves(edge1, edge2).set_order(4,4).refine(0, nel_rest1-1)

    diff = 4 - order
    patches = [patch.lower_order(diff, diff) for patch in [cyl1, cyl2, rect1, rect2, rect]]

    with G2(out + '.g2') as f:
        f.write(patches)

    root = etree.Element('geometry')
    etree.SubElement(root, 'patchfile').text = out + '.g2'
    topology = etree.SubElement(root, 'topology')
    for mid, sid, midx, sidx, rev in [(1,2,2,1,False), (1,3,4,3,False), (2,4,4,3,False),
                                      (3,5,2,1,False), (4,5,1,3,False)]:
        etree.SubElement(topology, 'connection').attrib.update({
            'master': str(mid), 'slave': str(sid),
            'midx': str(midx), 'sidx': str(sidx),
            'reverse': 'true' if rev else 'false',
        })

    topsets = etree.SubElement(root, 'topologysets')
    for name, entries in [('Circle', [(1, (3,)), (2, (3,))]),
                          ('Left',   [(1, (1,)), (3, (1,))]),
                          ('Right',  [(4, (4,)), (5, (2,))]),
                          ('Top',    [(3, (4,)), (5, (4,))]),
                          ('Bottom', [(2, (2,)), (4, (2,))])]:
        topset = etree.SubElement(topsets, 'set')
        topset.attrib.update({'name': name, 'type': 'edge'})
        for pid, indices in entries:
            item = etree.SubElement(topset, 'item')
            item.attrib['patch'] = str(pid)
            item.text = ' '.join(str(i) for i in indices)

    with open(out + '.xinp', 'wb') as f:
        f.write(etree.tostring(
            root, pretty_print=True, encoding='utf-8', xml_declaration=True, standalone=False
        ))
示例#9
0
def cylinder(diam, width, front, back, side, height, re, grad, inner_elsize,
             nel_side, nel_bndl, nel_circ, nel_height, order, out,
             outer_graded, thickness):
    assert all(f >= width for f in [front, back, side])

    rad_cyl = diam / 2
    width *= rad_cyl
    back = back * rad_cyl - width
    front = front * rad_cyl - width
    side = side * rad_cyl - width
    elsize = width * 2 / nel_circ

    dim = 2 if height == 0.0 else 3
    vx_add = 8 if dim == 3 else 0
    patches = PatchDict(dim)

    if inner_elsize and nel_side:
        # Calculate grading factor based on first element size,
        # total length and number of elements
        dr = rad_cyl * inner_elsize
        grad = find_factor(dr, width - rad_cyl, nel_side)

    elif nel_bndl and grad:
        # Calculate first element size based on total length
        # and number of elements

        # We want nel_bndl elements inside the boundary layer
        # Calculate how small the inner element must be
        size_bndl = 1 / sqrt(re) * diam
        dr = (1 - grad) / (1 - grad**nel_bndl) * size_bndl

        # Potentially reduce element size so we get a whole number of elements
        # on either side of the cylinder
        #nel_side = int(ceil(log(1 - 1/dr * (1 - grad) * (width - rad_cyl)) / log(grad)))
        nel_side = int(
            round(
                log(1 - 1 / dr * (1 - grad) * (width - rad_cyl)) / log(grad)))
        dr = (1 - grad) / (1 - grad**nel_side) * (width - rad_cyl)
    else:
        print('Specify (inner-elsize and nel-side) or (nel-bndl and grad)',
              file=sys.stderr)
        sys.exit(1)

    # Graded radial space from cylinder to edge of domain
    radial_kts = graded_space(rad_cyl, dr, grad, nel_side) + [width]

    # Create a radial and divide it
    radial = cf.cubic_curve(np.matrix(radial_kts).T,
                            boundary=cf.Boundary.NATURAL)
    radial.set_dimension(3)
    radial_kts = radial.knots('u')
    # middle = radial_kts[len(radial_kts) // 2]
    middle = next(k for k in radial_kts if k >= thickness * diam)
    radial_inner, radial_outer = radial.split(middle, 'u')
    radial_inner.rotate(pi / 4)
    dl = np.linalg.norm(
        radial_outer(radial_outer.knots('u')[-2]) -
        radial_outer.section(u=-1)) * grad

    # Revolve the inner radial and divide it
    radials = [
        radial_inner.clone().rotate(v)
        for v in np.linspace(0, 2 * pi, 4 * nel_circ + 1)
    ]
    inner = sf.loft(radials)
    ikts = inner.knots('v')
    inner.insert_knot((ikts[0] + ikts[1]) / 2, 'v')
    inner.insert_knot((ikts[-1] + ikts[-2]) / 2, 'v')

    ikts = inner.knots('v')
    patches.add('iu', 'il', 'id', 'ir',
                inner.split([ikts[k * nel_circ] for k in range(5)][1:-1], 'v'))
    patches.connect(
        ('ir', 4, 'iu', 3),
        ('iu', 4, 'il', 3),
        ('il', 4, 'id', 3),
        ('id', 4, 'ir', 3),
    )
    patches.boundary('cylinder', 'ir', 1)
    patches.boundary('cylinder', 'iu', 1)
    patches.boundary('cylinder', 'il', 1)
    patches.boundary('cylinder', 'id', 1)

    # Create an outer section
    rc = radial_outer.section(u=0)
    alpha = (sqrt(2) * width - rc[0]) / (width - rc[0])
    right = ((radial_outer - rc) * alpha + rc).rotate(pi / 4)
    left = right.clone().rotate(pi / 2).reverse()
    outer = cf.line((-width, width, 0), (width, width, 0))
    outer.set_order(4).refine(nel_circ - 1)
    inner = patches['iu'].section(u=-1)
    outer = sf.edge_curves(right, outer, left, inner).reverse('v')

    patches.add('ou', 'ol', 'od', 'or',
                [outer.clone().rotate(v) for v in [0, pi / 2, pi, 3 * pi / 2]])
    patches.connect(
        ('or', 4, 'ou', 3),
        ('ou', 4, 'ol', 3),
        ('ol', 4, 'od', 3),
        ('od', 4, 'or', 3),
        ('or', 1, 'ir', 2),
        ('ou', 1, 'iu', 2),
        ('ol', 1, 'il', 2),
        ('od', 1, 'id', 2),
    )

    if front > 0:
        la = patches['ol'].section(u=-1)
        lb = la.clone() - (front, 0, 0)
        front_srf = sf.edge_curves(lb, la).set_order(4, 4).swap().reverse('v')
        nel = int(ceil(log(1 - 1 / dl * (1 - grad) * front) / log(grad)))
        geometric_refine(front_srf, grad, nel - 1, reverse=True)
        patches['fr'] = front_srf
        patches.connect(('fr', 2, 'ol', 2, 'rev'))
        patches.boundary('inflow', 'fr', 1)
    else:
        patches.boundary('inflow', 'ol', 2)
        patches.boundary('inflow', 'ou', 4, dim=-2, add=vx_add)
        patches.boundary('inflow', 'od', 2, dim=-2, add=vx_add)

    if back > 0:
        la = patches['or'].section(u=-1)
        lb = la.clone() + (back, 0, 0)
        back_srf = sf.edge_curves(la, lb).set_order(4, 4).swap()
        if outer_graded:
            nel = int(ceil(log(1 - 1 / dl * (1 - grad) * back) / log(grad)))
            geometric_refine(back_srf, grad, nel - 1)
        else:
            #nel = int(ceil(back / dl))
            nel = int(round(back / (2 * width) * nel_circ))
            back_srf.refine(nel - 1, direction='u')
        patches['ba'] = back_srf
        patches.connect(('ba', 1, 'or', 2))
        patches.boundary('outflow', 'ba', 2)
    else:
        patches.boundary('outflow', 'or', 2)

    if side > 0:
        la = patches['ou'].section(u=-1).reverse()
        lb = la + (0, side, 0)
        patches['up'] = sf.edge_curves(la, lb).set_order(4, 4)
        patches.connect(('up', 3, 'ou', 2, 'rev'), ('dn', 4, 'od', 2))
        patches.boundary('top', 'up', 4)
        patches.boundary('bottom', 'dn', 3)

        if 'fr' in patches:
            btm = front_srf.section(v=-1)
            right = patches['up'].section(u=0)
            top = (btm + (0, side, 0)).reverse()
            left = (right - (front, 0, 0)).reverse()
            patches['upfr'] = sf.edge_curves(btm, right, top, left)
            patches.connect(
                ('upfr', 3, 'fr', 4),
                ('upfr', 2, 'up', 1),
                ('dnfr', 4, 'fr', 3),
                ('dnfr', 2, 'dn', 1),
            )
            patches.boundary('wall', 'upfr', 4)
            patches.boundary('inflow', 'upfr', 1)
            patches.boundary('wall', 'dnfr', 3)
            patches.boundary('inflow', 'dnfr', 1)
        else:
            patches.boundary('inflow', 'up', 1)
            patches.boundary('inflow', 'dn', 1)

        if 'ba' in patches:
            btm = back_srf.section(v=-1)
            left = patches['up'].section(u=-1).reverse()
            top = (btm + (0, side, 0)).reverse()
            right = (left + (back, 0, 0)).reverse()
            patches['upba'] = sf.edge_curves(btm, right, top, left)
            patches.connect(
                ('upba', 3, 'ba', 4),
                ('upba', 1, 'up', 2),
                ('dnba', 4, 'ba', 3),
                ('dnba', 1, 'dn', 2),
            )
            patches.boundary('wall', 'upba', 4)
            patches.boundary('outflow', 'upfr', 2)
            patches.boundary('wall', 'dnba', 3)
            patches.boundary('outflow', 'dnba', 2)
        else:
            patches.boundary('outflow', 'up', 2)
            patches.boundary('outflow', 'dn', 2)

        nel = int(ceil(log(1 - 1 / dl * (1 - grad) * side) / log(grad)))
        for uk in {'up', 'upfr', 'upba'} & patches.keys():
            dk = 'dn' + uk[2:]
            patches[dk] = patches[uk] - (0, side + 2 * width, 0)
            geometric_refine(patches[uk], grad, nel - 1, direction='v')
            geometric_refine(patches[dk],
                             grad,
                             nel - 1,
                             direction='v',
                             reverse=True)

    else:
        patches.boundary('wall', 'ou', 2)
        patches.boundary('wall', 'od', 2)
        patches.boundary('wall', 'or', 4, dim=-2, add=vx_add)
        patches.boundary('wall', 'or', 2, dim=-2, add=vx_add)

        if 'fr' in patches:
            patches.boundary('wall', 'fr', 4)
            patches.boundary('wall', 'fr', 3)
            patches.boundary('wall', 'ol', 2, dim=-2, add=vx_add)
            patches.boundary('wall', 'ol', 4, dim=-2, add=vx_add)

        if 'ba' in patches:
            patches.boundary('wall', 'ba', 4)
            patches.boundary('wall', 'ba', 3)

    if height > 0.0:
        names = [
            'iu', 'il', 'id', 'ir', 'ou', 'ol', 'od', 'or', 'fr', 'ba', 'up',
            'upba', 'upfr', 'dn', 'dnba', 'dnfr'
        ]
        for pname in names:
            if pname not in patches:
                continue
            patch = patches[pname]
            patch = extrude(patch, (0, 0, height))
            patch.raise_order(0, 0, 2)
            patch.refine(nel_height - 1, direction='w')
            patches[pname] = patch
            patches.boundary('zup', pname, 6)
            patches.boundary('zdown', pname, 5)
            patches.connect((pname, 5, pname, 6, 'per'))

    patches.write(out, order=order)
    reverse_graft_rad_list = copy.deepcopy(graft_rad_list)
    reverse_graft_rad_list.reverse()
    possible_B = canGraft(radius_B, reverse_graft_rad_list[0], max_shrink)

    if possible_B[0]:
        shrink_B = possible_B[1]
        shrinkGraft(reverse_graft_rad_list, shrink_B)

        nb = len(graftPath)
        A = mainPath[pointA]
        B = mainPath[pointB]

        #splipy work
        # (https://pythonhosted.org/Splipy/basic_classes.html#splipy.Curve.curvature)
        coordinates = numpy.array([A, B])
        cb = cubic_curve(x=coordinates, boundary=5, t=None, tangents=tgt)
        bounding = SplineObject.bounding_box(cb)
        x_min, x_max = bounding[0][0], bounding[0][1]
        y_min, y_max = bounding[1][0], bounding[1][1]
        z_min, z_max = bounding[2][0], bounding[2][1]

        fin = SplineObject.end(cb)[0]
        tab = numpy.linspace(0, fin, nb)
        L = list(SplineObject.evaluate(cb, tab))

        curvat = curvature(cb, tab)
        max_curvature = numpy.max(curvat)

        tors = torsion(cb, tab)
        max_torsion = max(numpy.max(tors), -(numpy.min(tors)))
示例#11
0
def flag(diam, flag_width, flag_length, width, back, flag_grad, grad, nel_rad,
         nel_circ, nel_flag, order, out):
    assert (back > width)

    rad_cyl = diam / 2
    width *= rad_cyl
    back = back * rad_cyl - width

    # Create a circle
    angle = 2 * np.arcsin(flag_width / rad_cyl / 2)
    pts = rad_cyl * np.array(
        [(np.cos(a), np.sin(a))
         for a in np.linspace(angle, 2 * np.pi - angle, nel_circ + 1)])
    circle = cf.cubic_curve(pts, boundary=cf.Boundary.NATURAL)
    circle.set_dimension(3)

    # Subdivide it
    nels_side = int(round(nel_circ // 2 * 3 * np.pi / 4 / (np.pi - angle)))
    nels_front = (nel_circ // 2 - nels_side) * 2
    S = (-nel_flag * width + nels_side *
         (width + back)) / (nel_flag + nels_side)

    kts = circle.knots('u')
    kts = kts[nels_side], kts[nels_side + nels_front]
    circ_up, circ_front, circ_down = circle.split(kts)

    # Extend to boundary
    front = cf.line((-width, width),
                    (-width, -width)).set_order(4).refine(nels_front - 1)
    front = sf.edge_curves(front, circ_front).raise_order(0, 2)
    geometric_refine(front, grad, nel_rad - 1, direction='v', reverse=True)

    up = cf.line((S, width),
                 (-width, width)).set_order(4).refine(nels_side - 1)
    up = sf.edge_curves(up, circ_up).raise_order(0, 2)
    geometric_refine(up, grad, nel_rad - 1, direction='v', reverse=True)

    down = cf.line((-width, -width),
                   (S, -width)).set_order(4).refine(nels_side - 1)
    down = sf.edge_curves(down, circ_down).raise_order(0, 2)
    geometric_refine(down, grad, nel_rad - 1, direction='v', reverse=True)

    # Create the flag
    upt = circle(circle.start('u'))
    fl_up = cf.line((flag_length + rad_cyl, upt[1], 0), upt).raise_order(2)
    geometric_refine(fl_up,
                     flag_grad,
                     nel_flag - 1,
                     direction='u',
                     reverse=True)
    ln_up = cf.cubic_curve(np.array([((1 - i) * (width + back) + i * S, width)
                                     for i in np.linspace(0, 1, nel_flag + 1)
                                     ]),
                           boundary=cf.Boundary.NATURAL,
                           t=fl_up.knots('u'))
    fl_up = sf.edge_curves(ln_up, fl_up).raise_order(0, 2)
    geometric_refine(fl_up, grad, nel_rad - 1, direction='v', reverse=True)

    dpt = circle(circle.end('u'))
    fl_down = cf.line(dpt, (flag_length + rad_cyl, dpt[1], 0))
    geometric_refine(fl_down, flag_grad, nel_flag - 1, direction='u')
    ln_down = cf.cubic_curve(np.array([
        ((1 - i) * S + i * (width + back), -width)
        for i in np.linspace(0, 1, nel_flag + 1)
    ]),
                             boundary=cf.Boundary.NATURAL,
                             t=fl_down.knots('u'))
    fl_down = sf.edge_curves(ln_down, fl_down).raise_order(0, 2)
    geometric_refine(fl_down, grad, nel_rad - 1, direction='v', reverse=True)

    fl_back = cf.line((flag_length + rad_cyl, dpt[1], 0),
                      (flag_length + rad_cyl, upt[1], 0))
    ln_back = cf.line((width + back, -width, 0), (width + back, width, 0))
    fl_back = sf.edge_curves(ln_back,
                             fl_back).raise_order(2, 2).refine(40,
                                                               direction='u')
    geometric_refine(fl_back, grad, nel_rad - 1, direction='v', reverse=True)

    with G2(out + '.g2') as f:
        f.write([up, front, down, fl_up, fl_down, fl_back])

    root = etree.Element('geometry')
    etree.SubElement(root, 'patchfile').text = out + '.g2'
    topology = etree.SubElement(root, 'topology')
    for mid, sid, midx, sidx, rev in [(1, 2, 2, 1, False), (1, 4, 1, 2, False),
                                      (2, 3, 2, 1, False), (3, 5, 2, 1, False),
                                      (4, 6, 1, 2, False),
                                      (5, 6, 2, 1, False)]:
        etree.SubElement(topology, 'connection').attrib.update({
            'master':
            str(mid),
            'slave':
            str(sid),
            'midx':
            str(midx),
            'sidx':
            str(sidx),
            'reverse':
            'true' if rev else 'false',
        })

    topsets = etree.SubElement(root, 'topologysets')
    for name, index, entries in [('inflow', 3, [2]), ('outflow', 3, [6]),
                                 ('top', 3, [1, 4]), ('bottom', 3, [3, 5]),
                                 ('cylinder', 4, [1, 2, 3]),
                                 ('flag', 4, [4, 5, 6])]:
        topset = etree.SubElement(topsets, 'set')
        topset.attrib.update({'name': name, 'type': 'edge'})
        for pid in entries:
            item = etree.SubElement(topset, 'item')
            item.attrib['patch'] = str(pid)
            item.text = str(index)
    topset = etree.SubElement(topsets, 'set')
    topset.attrib.update({'name': 'inflow', 'type': 'vertex'})
    item = etree.SubElement(topset, 'item')
    item.attrib['patch'] = '2'
    item.text = '1 2'

    with open(out + '.xinp', 'wb') as f:
        f.write(
            etree.tostring(root,
                           pretty_print=True,
                           encoding='utf-8',
                           xml_declaration=True,
                           standalone=False))
示例#12
0
def cylinder(radius, length, elements_rad, elements_len, out):
    square = sf.square(size=2 * radius / 3,
                       lower_left=(-radius / 3, -radius / 3))
    square.set_dimension(3)
    square.raise_order(2, 2)
    square.refine(elements_rad - 1, elements_rad - 1)

    pts = np.zeros((elements_rad + 1, 3))
    angles = np.linspace(-np.pi / 4, np.pi / 4, elements_rad + 1)
    pts[:, 0] = radius * np.cos(angles)
    pts[:, 1] = radius * np.sin(angles)
    curve = cf.cubic_curve(pts, t=square.knots('v'))

    sector = sf.edge_curves(square.section(u=-1), curve)
    sector.raise_order(0, 2)
    sector.refine(0, elements_rad - 1)
    sector.swap()

    sectors = [
        sector.clone().rotate(angle)
        for angle in [0, np.pi / 2, np.pi, np.pi * 3 / 2]
    ]
    patches = [
        vf.extrude(patch, (0, 0, length)) for patch in [square] + sectors
    ]
    for patch in patches:
        patch.raise_order(0, 0, 2)
        patch.refine(0, 0, elements_len)

    with G2(out + '.g2') as f:
        f.write(patches)

    root = etree.Element('geometry')
    etree.SubElement(root, 'patchfile').text = out + '.g2'
    topology = etree.SubElement(root, 'topology')
    for mid, sid, midx, sidx, rev in [(1, 2, 2, 1, False), (1, 3, 4, 1, True),
                                      (1, 4, 1, 1, True), (1, 5, 3, 1, False),
                                      (2, 3, 4, 3, False), (2, 5, 3, 4, False),
                                      (3, 4, 4, 3, False),
                                      (4, 5, 4, 3, False)]:
        etree.SubElement(topology, 'connection').attrib.update({
            'master':
            str(mid),
            'slave':
            str(sid),
            'midx':
            str(midx),
            'sidx':
            str(sidx),
            'reverse':
            'true' if rev else 'false',
        })

    topsets = etree.SubElement(root, 'topologysets')

    for name, start, idx in [('wall', 2, 2), ('inflow', 1, 5),
                             ('outflow', 1, 6)]:
        topset = etree.SubElement(topsets, 'set')
        topset.attrib.update({'name': name, 'type': 'face'})
        for i in range(start, 6):
            item = etree.SubElement(topset, 'item')
            item.attrib['patch'] = str(i)
            item.text = str(idx)

    with open(out + '.xinp', 'wb') as f:
        f.write(
            etree.tostring(root,
                           pretty_print=True,
                           encoding='utf-8',
                           xml_declaration=True,
                           standalone=False))