tataratat / splinepy

Library for prototyping spline geometries of arbitrary dimensions and degrees, and IGA
https://tataratat.github.io/splinepy
Other
47 stars 13 forks source link

Added second parameter to double lattice tile #365

Closed mkofler96 closed 8 months ago

mkofler96 commented 8 months ago

Overview

Added second parameter to the double lattice tile, which allows independent parametrization of diagonal and horizontal/vertical struts

Addressed issues

Showcase

Edge cases seem to look fine. Parameter sensitivity was compared to finite difference result.

import splinepy
import numpy as np

generator_base = splinepy.microstructure.tiles.DoubleLattice()
t1, d1 = generator_base.create_tile()
t2, d2 = generator_base.create_tile(parameters=np.array([[0.02, 0.02]]))
t3, d3 = generator_base.create_tile(parameters=np.array([[0.2, 0.2]]))
t4, d4 = generator_base.create_tile(contact_length=0.8)

generator = splinepy.microstructure.Microstructure()
generator.deformation_function = splinepy.Bezier(
    degrees=[1, 1],
    control_points=[[0, 0], [0.5,0], [0, 1], [0.5, 1]],
)

generator.microtile =  splinepy.microstructure.tiles.DoubleLattice()

generator.tiling = [4, 8]

def para_sens_function(x):
    return splinepy.utils.data.make_matrix(
        *para_spline.basis_and_support(x),
        para_spline.cps.shape[0],
        as_array=True,
    ).reshape(x.shape[0], 1, para_spline.cps.shape[0])

para_spline = splinepy.BSpline(
    degrees=[1, 1],
    knot_vectors=[[0, 0, 2, 2], [0, 0, 1, 1]],
    control_points=[[0.05], [0.05], [0.05], [0.1]],
)

def para_function(x):
    return para_spline.evaluate(x)

generator.parametrization_function  = para_function
generator.parameter_sensitivity_function = para_sens_function
ms = generator.create(macro_sensitivities=True)

coordinates_before_translation = ms.patches[0].evaluate([[1,1]])
AD = ms.fields[0].patches[0].evaluate([[1,1]])
print(f"(x,y) before translation: {coordinates_before_translation}")
print(f"(dx/dcps1, dy/dcps1): {AD}")

# finite difference
d = 0.0001

para_spline = splinepy.BSpline(
    degrees=[1, 1],
    knot_vectors=[[0, 0, 2, 2], [0, 0, 1, 1]],
    control_points=[[0.05+d], [0.05], [0.05], [0.1]],
)

def para_function(x):
    return para_spline.evaluate(x)
generator.parametrization_function = para_function
ms = generator.create()
coordinates_after_translation = ms.patches[0].evaluate([[1,1]])
print(f"(x,y) after translation: {coordinates_after_translation}")
FD = (coordinates_after_translation-coordinates_before_translation)/d
print(f"(dx/dcps1,dy/dcps1) from FD: {FD}")
assert(np.allclose(AD, FD))

Checklists

j042 commented 8 months ago

can you rebase and get rid of 5dd8cb2? Also, if you implemented changes, please leave a small comment and mark resolved

j042 commented 8 months ago

and re-request review