def test_lr_spline_insert_line_multiple(): LR = init_tensor_product_LR_spline(1, 1, [0, 1, 2, 3], [0, 1, 2]) M1 = Meshline(0, 2, constant_value=0.5, axis=1) # horizontal split M2 = Meshline(0, 1, constant_value=1.5, axis=0) # vertical split LR.insert_line(M1) LR.insert_line(M2) # expected functions b1 = BSpline(1, 1, [0, 1, 1.5], [0, 0.5, 1]) b2 = BSpline(1, 1, [1, 1.5, 2], [0, 0.5, 1]) b3 = BSpline(1, 1, [0, 1, 2], [0.5, 1, 2]) b4 = BSpline(1, 1, [1, 2, 3], [0, 1, 2]) assert b1 in LR.S assert b2 in LR.S assert b3 in LR.S assert b3 in LR.S assert len(LR.S) == 4 expected_elements = [ Element(0, 0, 1, 0.5), Element(1, 0, 1.5, 0.5), Element(1.5, 0, 2, 0.5), Element(0, 0.5, 1, 1), Element(1, 0.5, 1.5, 1), Element(1.5, 0.5, 2, 1), Element(2, 0, 3, 1), Element(0, 1, 1, 2), Element(1, 1, 2, 2), Element(2, 1, 3, 2) ] assert all([LR.contains_element(e) for e in expected_elements]) assert len(LR.M) == 10
def test_lr_spline_minimal_span_line_superficial(): """ Constructed example, won't occur in practice. """ element = Element(0.5, 0, 1, 2) ku1 = [-1, 0, 1] kv1 = [0, 1, 2] ku2 = [0, 0.5, 1] kv2 = [0, 1, 3] b1 = BSpline(1, 1, ku1, kv1) b2 = BSpline(1, 1, ku2, kv2) element.add_supported_b_spline(b1) element.add_supported_b_spline(b2) small_span_meshline_vertical = LRSpline.get_minimal_span_meshline(element, axis=0) small_span_meshline_horizontal = LRSpline.get_minimal_span_meshline( element, axis=1) assert small_span_meshline_vertical.start == 0 assert small_span_meshline_vertical.stop == 2 assert small_span_meshline_vertical.constant_value == 0.75 assert small_span_meshline_horizontal.start == 0 assert small_span_meshline_horizontal.stop == 1 assert small_span_meshline_horizontal.constant_value == 1
def test_meshline_splits_basis(): start = 0 stop = 1 constant_value = 0.5 m1 = Meshline(start, stop, constant_value, 0) m2 = Meshline(start, stop, constant_value, 1) b1 = BSpline(2, 2, [0, 1, 2, 3], [0, 1, 2, 3]) b2 = BSpline(2, 2, [0, 1, 2, 3], [0, 0.25, 0.5, 0.75, 1]) assert not m1.splits_basis(b1) assert m1.splits_basis(b2) assert not m2.splits_basis(b1) assert not m2.splits_basis(b2)
def test_meshline_number_of_knots(): b1 = BSpline(1, 1, [0, 1, 2], [0, 1, 2]) m1 = Meshline(0, 2, constant_value=1, axis=0) m2 = Meshline(0, 2, constant_value=0.5, axis=1) assert m1.number_of_knots_contained(b1) == 1 assert m2.number_of_knots_contained(b1) == 0
def test_aux_split_methods(): d1 = 2 d2 = 2 ku = [0, 1, 2, 4] kv = [1, 2, 4, 5] B = BSpline(d1, d2, ku, kv) m = Meshline(0, 5, constant_value=3, axis=0) eps = 1.0E-14 b1, b2 = split_single_basis_function(m, B) assert b1.weight == 1 assert (b2.weight - 1 / 3) < eps assert np.allclose(b1.knots_u, [0, 1, 2, 3]) assert np.allclose(b2.knots_u, [1, 2, 3, 4])
def test_minimal_support_split(): B = BSpline(1, 1, [3, 3.5, 4], [2, 3, 4]) m = Meshline(2, 4, 2.5, axis=1) assert m.splits_basis(B)
def init_tensor_product_LR_spline(d1: int, d2: int, ku: Vector, kv: Vector) -> 'LRSpline': """ Initializes an LR spline at the tensor product level of bidegree (d1, d2). :param d1: first component degree :param d2: second component degree :param ku: knots in u_direction :param kv: knots in v_direction :return: corresponding LR_spline """ elements = [] basis = [] meshlines = [] unique_ku = np.unique(ku) unique_kv = np.unique(kv) for i in range(len(unique_ku) - 1): for j in range(len(unique_kv) - 1): elements.append( Element(unique_ku[i], unique_kv[j], unique_ku[i + 1], unique_kv[j + 1])) for i in range(len(ku) - d1 - 1): for j in range(len(kv) - d2 - 1): end_u = _at_end(ku, i + d1 + 1) end_v = _at_end(kv, j + d2 + 1) # TODO: This only works if the knot vectors are p+1-extended. north = j == len(kv) - d2 - 2 south = j == 0 east = i == len(ku) - d1 - 2 west = i == 0 basis.append( BSpline(d1, d2, ku[i:i + d1 + 2], kv[j:j + d2 + 2], end_u=end_u, end_v=end_v, north=north, south=south, east=east, west=west)) for b in basis: for e in elements: if b.add_to_support_if_intersects(e): e.add_supported_b_spline(b) for i in range(len(unique_ku)): for j in range(len(unique_kv) - 1): new_m = Meshline(start=unique_kv[j], stop=unique_kv[j + 1], constant_value=unique_ku[i], axis=0) new_m.set_multiplicity(ku) meshlines.append(new_m) for i in range(len(unique_kv)): for j in range(len(unique_ku) - 1): new_m = Meshline(start=unique_ku[j], stop=unique_ku[j + 1], constant_value=unique_kv[i], axis=1) new_m.set_multiplicity(kv) meshlines.append(new_m) u_range = [ku[0], ku[-1]] v_range = [kv[0], kv[-1]] return LRSpline(elements, basis, meshlines, u_range, v_range, unique_ku, unique_kv)
def _split(alpha_1: float, alpha_2: float, b: BSpline, m: Meshline, new_knots: np.ndarray) -> typing.Tuple[ BSpline, BSpline]: """ Given two split weights, a b spline marked for splitting by the given meshline and a set of new knots, return the two resulting BSplines :param alpha_1: left split weight :param alpha_2: right split weight :param b: old BSpline :param m: meshline to split by :param new_knots: knots with inserted knot :return: two resulting b-splines """ if m.axis == 0: # vertical split b1 = BSpline(b.degree_u, b.degree_v, new_knots[:-1], b.knots_v, b.weight * alpha_1) b2 = BSpline(b.degree_u, b.degree_v, new_knots[1:], b.knots_v, b.weight * alpha_2) b1.end_v = b.end_v b2.end_v = b.end_v b1.north = b.north b2.north = b.north b1.south = b.south b2.south = b.south if b.end_u: b1.end_u = False b2.end_u = True if b.east: b2.east = True if b.west: b1.west = True elif m.axis == 1: # horizontal split b1 = BSpline(b.degree_u, b.degree_v, b.knots_u, new_knots[:-1], b.weight * alpha_1) b2 = BSpline(b.degree_u, b.degree_v, b.knots_u, new_knots[1:], b.weight * alpha_2) b1.end_u = b.end_u b2.end_u = b.end_u b1.east = b.east b2.east = b.east b1.west = b.west b2.west = b.west if b.end_v: b1.end_v = False b2.end_v = True if b.north: b2.north = True if b.south: b1.south = True return b1, b2