Example #1
0
 def test_multiplicity(self):
     surf = Surface()
     surf.refine(1)
     surf.raise_order(1)
     surf.refine(1)
     self.assertTrue(
         np.allclose(multiplicities(surf),
                     [[3, 1, 2, 1, 3], [3, 1, 2, 1, 3]]))
Example #2
0
    def test_raise_order(self):
        # more or less random 2D surface with p=[2,2] and n=[4,3]
        controlpoints = [[0, 0], [-1, 1], [0, 2], [1, -1], [1, 0], [1, 1],
                         [2, 1], [2, 2], [2, 3], [3, 0], [4, 1], [3, 2]]
        basis1 = BSplineBasis(3, [0, 0, 0, .4, 1, 1, 1])
        basis2 = BSplineBasis(3, [0, 0, 0, 1, 1, 1])
        surf = Surface(basis1, basis2, controlpoints)

        self.assertEqual(surf.order()[0], 3)
        self.assertEqual(surf.order()[1], 3)
        evaluation_point1 = surf(
            0.23, 0.37)  # pick some evaluation point (could be anything)

        surf.raise_order(1, 2)

        self.assertEqual(surf.order()[0], 4)
        self.assertEqual(surf.order()[1], 5)
        evaluation_point2 = surf(0.23, 0.37)

        # evaluation before and after RaiseOrder should remain unchanged
        self.assertAlmostEqual(evaluation_point1[0], evaluation_point2[0])
        self.assertAlmostEqual(evaluation_point1[1], evaluation_point2[1])

        # test a rational 2D surface
        controlpoints = [[0, 0, 1], [-1, 1, .96], [0, 2, 1], [1, -1, 1],
                         [1, 0, .8], [1, 1, 1], [2, 1, .89], [2, 2, .9],
                         [2, 3, 1], [3, 0, 1], [4, 1, 1], [3, 2, 1]]
        basis1 = BSplineBasis(3, [0, 0, 0, .4, 1, 1, 1])
        basis2 = BSplineBasis(3, [0, 0, 0, 1, 1, 1])
        surf = Surface(basis1, basis2, controlpoints, True)

        self.assertEqual(surf.order()[0], 3)
        self.assertEqual(surf.order()[1], 3)
        evaluation_point1 = surf(0.23, 0.37)

        surf.raise_order(1, 2)

        self.assertEqual(surf.order()[0], 4)
        self.assertEqual(surf.order()[1], 5)
        evaluation_point2 = surf(0.23, 0.37)

        # evaluation before and after RaiseOrder should remain unchanged
        self.assertAlmostEqual(evaluation_point1[0], evaluation_point2[0])
        self.assertAlmostEqual(evaluation_point1[1], evaluation_point2[1])
Example #3
0
def finitestrain_patch(bottom, right, top, left):
    from nutils import version
    if int(version[0]) != 4:
        raise ImportError(
            'Mismatching nutils version detected, only version 4 supported. Upgrade by \"pip install --upgrade nutils\"'
        )

    from nutils import mesh, function
    from nutils import _, log, solver

    # error test input
    if not (left.dimension == right.dimension == top.dimension ==
            bottom.dimension == 2):
        raise RuntimeError(
            'finitestrain_patch only supported for planar (2D) geometries')
    if left.rational or right.rational or top.rational or bottom.rational:
        raise RuntimeError(
            'finitestrain_patch not supported for rational splines')

    # these are given as a oriented loop, so make all run in positive parametric direction
    top.reverse()
    left.reverse()

    # in order to add spline surfaces, they need identical parametrization
    Curve.make_splines_identical(top, bottom)
    Curve.make_splines_identical(left, right)

    # create an initial mesh (correct corners) which we will morph into the right one
    p1 = bottom.order(0)
    p2 = left.order(0)
    p = max(p1, p2)
    linear = BSplineBasis(2)
    srf = Surface(linear, linear, [bottom[0], bottom[-1], top[0], top[-1]])
    srf.raise_order(p1 - 2, p2 - 2)
    for k in bottom.knots(0, True)[p1:-p1]:
        srf.insert_knot(k, 0)
    for k in left.knots(0, True)[p2:-p2]:
        srf.insert_knot(k, 1)

    # create computational mesh
    n1 = len(bottom)
    n2 = len(left)
    dim = left.dimension
    domain, geom = mesh.rectilinear(srf.knots())
    ns = function.Namespace()
    ns.basis = domain.basis('spline',
                            degree(srf),
                            knotmultiplicities=multiplicities(srf)).vector(2)
    ns.phi = domain.basis('spline',
                          degree(srf),
                          knotmultiplicities=multiplicities(srf))
    ns.eye = np.array([[1, 0], [0, 1]])
    ns.cp = controlpoints(srf)
    ns.x_i = 'cp_ni phi_n'
    ns.lmbda = 1
    ns.mu = 1

    # add total boundary conditions
    # for hard problems these will be taken in steps and multiplied by dt every
    # time (quasi-static iterations)
    constraints = np.array([[[np.nan] * n2] * n1] * dim)
    for d in range(dim):
        constraints[d, 0, :] = (left[:, d] - srf[0, :, d])
        constraints[d, -1, :] = (right[:, d] - srf[-1, :, d])
        constraints[d, :, 0] = (bottom[:, d] - srf[:, 0, d])
        constraints[d, :, -1] = (top[:, d] - srf[:, -1, d])
    # TODO: Take a close look at the logic below

    # in order to iterate, we let t0=0 be current configuration and t1=1 our target configuration
    # if solver divergeces (too large deformation), we will try with dt=0.5. If this still
    # fails we will resort to dt=0.25 until a suitable small iterations size have been found

    # dt = 1
    # t0 = 0
    # t1 = 1
    # while t0 < 1:
    # dt = t1-t0
    n = 10
    dt = 1 / n
    for i in range(n):
        # print(' ==== Quasi-static '+str(t0*100)+'-'+str(t1*100)+' % ====')
        print(' ==== Quasi-static ' + str(i / (n - 1) * 100) + ' % ====')

        # define the non-linear finite strain problem formulation
        ns.cp = np.reshape(srf[:, :, :].swapaxes(0, 1), (n1 * n2, dim),
                           order='F')
        ns.x_i = 'cp_ni phi_n'  # geometric mapping (reference geometry)
        ns.u_i = 'basis_ki ?w_k'  # displacement (unknown coefficients w_k)
        ns.X_i = 'x_i + u_i'  # displaced geometry
        ns.strain_ij = '.5 (u_i,j + u_j,i + u_k,i u_k,j)'
        ns.stress_ij = 'lmbda strain_kk eye_ij + 2 mu strain_ij'

        # try:
        residual = domain.integral(ns.eval_n('stress_ij basis_ni,j d:X'),
                                   degree=2 * p)
        cons = np.ndarray.flatten(constraints * dt, order='C')
        lhs = solver.newton('w', residual, constrain=cons).solve(
            tol=state.controlpoint_absolute_tolerance, maxiter=8)

        # store the results on a splipy object and continue
        geom = lhs.reshape((n2, n1, dim), order='F')
        srf[:, :, :] += geom.swapaxes(0, 1)

        # t0 += dt
        # t1 = 1
        # except solver.SolverError: # newton method fail to converge, try a smaller step length 'dt'
        # t1 = (t1+t0)/2
    return srf
Example #4
0
 def test_multiplicity(self):
     surf = Surface()
     surf.refine(1)
     surf.raise_order(1)
     surf.refine(1)
     self.assertTrue(np.allclose(multiplicities(surf), [[3, 1, 2, 1, 3], [3, 1, 2, 1, 3]]))