lsdo-function-spaces 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lsdo_function_spaces/__init__.py +64 -0
- lsdo_function_spaces/core/__init__.py +0 -0
- lsdo_function_spaces/core/function.py +1322 -0
- lsdo_function_spaces/core/function_set.py +1081 -0
- lsdo_function_spaces/core/function_set_space.py +379 -0
- lsdo_function_spaces/core/function_space.py +482 -0
- lsdo_function_spaces/core/operations/__init__.py +0 -0
- lsdo_function_spaces/core/operations/basic_ops.py +85 -0
- lsdo_function_spaces/core/operations/operations.py +5 -0
- lsdo_function_spaces/core/optimization.py +183 -0
- lsdo_function_spaces/core/spaces/__init__.py +0 -0
- lsdo_function_spaces/core/spaces/b_spline_space.py +418 -0
- lsdo_function_spaces/core/spaces/conditional_space.py +65 -0
- lsdo_function_spaces/core/spaces/constant_space.py +57 -0
- lsdo_function_spaces/core/spaces/idw_space.py +271 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/__init__.py +0 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/b_spline_csdl_custom_ops.py +420 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/b_spline_patch_projection.py +1022 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/b_spline_patch_projection_non_differentiable.py +186 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/b_spline_patch_projection_optimized.py +594 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/b_spline_space_new.py +6 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/compute_basis_matrix_jax.py +172 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/compute_basis_matrix_jax_factory.py +382 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/compute_basis_matrix_jax_stencil.py +451 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/compute_basis_matrix_numpy.py +249 -0
- lsdo_function_spaces/core/spaces/non_cython_bsplines/compute_basis_matrix_numpy_factory.py +391 -0
- lsdo_function_spaces/core/spaces/operation_space.py +64 -0
- lsdo_function_spaces/core/spaces/polynomial_space.py +79 -0
- lsdo_function_spaces/core/spaces/rbf_space.py +136 -0
- lsdo_function_spaces/core/spaces/tri_space.py +256 -0
- lsdo_function_spaces/utils/__init__.py +0 -0
- lsdo_function_spaces/utils/file_io.py +484 -0
- lsdo_function_spaces/utils/internal_utilities.py +11 -0
- lsdo_function_spaces/utils/plotting_functions.py +357 -0
- lsdo_function_spaces/utils/utility_functions.py +148 -0
- lsdo_function_spaces-1.0.0.dist-info/METADATA +189 -0
- lsdo_function_spaces-1.0.0.dist-info/RECORD +40 -0
- lsdo_function_spaces-1.0.0.dist-info/WHEEL +5 -0
- lsdo_function_spaces-1.0.0.dist-info/licenses/LICENSE.txt +165 -0
- lsdo_function_spaces-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import csdl_alpha as csdl
|
|
2
|
+
import numpy as np
|
|
3
|
+
import jax
|
|
4
|
+
import jax.numpy as jnp
|
|
5
|
+
import warnings
|
|
6
|
+
|
|
7
|
+
from lsdo_function_spaces.core.spaces.non_cython_bsplines.compute_basis_matrix_jax import compute_basis_matrix_jax
|
|
8
|
+
try:
|
|
9
|
+
_CustomExplicitOperation = csdl.experimental.CustomExplicitOperationBeta
|
|
10
|
+
except AttributeError:
|
|
11
|
+
_CustomExplicitOperation = object
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BasisMatrixCustomOpVJP(_CustomExplicitOperation):
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
knots: tuple,
|
|
18
|
+
degree: tuple,
|
|
19
|
+
coefficients_shape: tuple,
|
|
20
|
+
der_orders: tuple = None,
|
|
21
|
+
):
|
|
22
|
+
super().__init__()
|
|
23
|
+
self.knots = knots
|
|
24
|
+
self.degree = degree
|
|
25
|
+
self.coefficients_shape = coefficients_shape
|
|
26
|
+
self.der_orders = der_orders
|
|
27
|
+
|
|
28
|
+
def compute_basis_matrix(parametric_coordinates):
|
|
29
|
+
return compute_basis_matrix_jax(
|
|
30
|
+
us=parametric_coordinates,
|
|
31
|
+
degrees=self.degree,
|
|
32
|
+
knot_vectors=self.knots,
|
|
33
|
+
der_orders=self.der_orders,
|
|
34
|
+
).todense()
|
|
35
|
+
|
|
36
|
+
def compute_basis_matrix_vjp(parametric_coordinates):
|
|
37
|
+
return jax.vjp(
|
|
38
|
+
compute_basis_matrix,
|
|
39
|
+
parametric_coordinates,
|
|
40
|
+
)[1]
|
|
41
|
+
|
|
42
|
+
self.vjp_fun = compute_basis_matrix_vjp
|
|
43
|
+
|
|
44
|
+
self._cache = {}
|
|
45
|
+
|
|
46
|
+
def evaluate(self, inputs, d_outputs):
|
|
47
|
+
para_coords = inputs["parametric_coordinates"]
|
|
48
|
+
d_basis_mat = d_outputs["basis_matrix"]
|
|
49
|
+
|
|
50
|
+
self.declare_input("parametric_coordinates", para_coords)
|
|
51
|
+
self.declare_input("d_basis_matrix", d_basis_mat)
|
|
52
|
+
|
|
53
|
+
d_para_coords = self.create_output(
|
|
54
|
+
"d_parametric_coordinates",
|
|
55
|
+
shape=para_coords.shape,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
d_inputs = {
|
|
59
|
+
"parametric_coordinates": d_para_coords,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return d_inputs
|
|
63
|
+
|
|
64
|
+
def compute(self, inputs, outputs):
|
|
65
|
+
parametric_coordinates = inputs["parametric_coordinates"]
|
|
66
|
+
d_basis_matrix = inputs["d_basis_matrix"]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
save_name = f"para_coords_shape_{parametric_coordinates.shape}"
|
|
70
|
+
|
|
71
|
+
if save_name in self._cache:
|
|
72
|
+
basis_matrix_fun = self._cache[save_name]
|
|
73
|
+
else:
|
|
74
|
+
basis_matrix_fun = jax.jit(
|
|
75
|
+
self.vjp_fun,
|
|
76
|
+
)
|
|
77
|
+
self._cache[save_name] = basis_matrix_fun
|
|
78
|
+
d_parametric_coordinates = basis_matrix_fun(jnp.array(parametric_coordinates))(jnp.array(d_basis_matrix))[0]
|
|
79
|
+
outputs["d_parametric_coordinates"] = np.array(d_parametric_coordinates)
|
|
80
|
+
|
|
81
|
+
class BasisMatrixCustomOp(_CustomExplicitOperation):
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
knots: tuple,
|
|
85
|
+
degree: tuple,
|
|
86
|
+
coefficients_shape: tuple,
|
|
87
|
+
der_orders: tuple = None,
|
|
88
|
+
):
|
|
89
|
+
super().__init__()
|
|
90
|
+
self.knots = knots
|
|
91
|
+
self.degree = degree
|
|
92
|
+
self.coefficients_shape = coefficients_shape
|
|
93
|
+
self.der_orders = der_orders
|
|
94
|
+
|
|
95
|
+
def compute_basis_matrix(parametric_coordinates):
|
|
96
|
+
result = compute_basis_matrix_jax(
|
|
97
|
+
us=parametric_coordinates,
|
|
98
|
+
degrees=self.degree,
|
|
99
|
+
knot_vectors=self.knots,
|
|
100
|
+
der_orders=self.der_orders,
|
|
101
|
+
).todense()
|
|
102
|
+
# Only squeeze the last axis if it's size 1 (for scalar case)
|
|
103
|
+
# but preserve the first axis (number of points)
|
|
104
|
+
if result.shape[-1] == 1:
|
|
105
|
+
return result.squeeze(axis=-1)
|
|
106
|
+
return result
|
|
107
|
+
self.basis_matrix_computation_function = compute_basis_matrix
|
|
108
|
+
|
|
109
|
+
self._cache = {}
|
|
110
|
+
|
|
111
|
+
def evaluate(self, parametric_coordinates):
|
|
112
|
+
"""Compute the (DENSE!) basis matrix for the given parametric coordinates.
|
|
113
|
+
CSDL does not support sparse matrices (as CSDL variables), so we return a dense matrix.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
parametric_coordinates : csdl.Variable
|
|
118
|
+
The parametric coordinates at which to evaluate the basis functions.
|
|
119
|
+
|
|
120
|
+
Returns
|
|
121
|
+
-------
|
|
122
|
+
csdl.Variable
|
|
123
|
+
A dense matrix containing the evaluated basis functions.
|
|
124
|
+
"""
|
|
125
|
+
self.declare_input("parametric_coordinates", parametric_coordinates)
|
|
126
|
+
|
|
127
|
+
basis_matrix = self.create_output(
|
|
128
|
+
"basis_matrix",
|
|
129
|
+
shape=(parametric_coordinates.shape[0], np.prod(self.coefficients_shape)),
|
|
130
|
+
)
|
|
131
|
+
self.basis_matrix_shape = basis_matrix.shape
|
|
132
|
+
|
|
133
|
+
self.declare_vjp_function(
|
|
134
|
+
BasisMatrixCustomOpVJP,
|
|
135
|
+
knots=self.knots,
|
|
136
|
+
degree=self.degree,
|
|
137
|
+
coefficients_shape=self.coefficients_shape,
|
|
138
|
+
der_orders=self.der_orders,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
return basis_matrix
|
|
142
|
+
|
|
143
|
+
def compute(self, inputs, outputs):
|
|
144
|
+
parametric_coordinates = inputs["parametric_coordinates"]
|
|
145
|
+
|
|
146
|
+
save_name = f"para_coords_shape_{parametric_coordinates.shape}"
|
|
147
|
+
|
|
148
|
+
if save_name in self._cache:
|
|
149
|
+
basis_matrix_fun = self._cache[save_name]
|
|
150
|
+
else:
|
|
151
|
+
basis_matrix_fun = jax.jit(
|
|
152
|
+
self.basis_matrix_computation_function,
|
|
153
|
+
)
|
|
154
|
+
self._cache[save_name] = basis_matrix_fun
|
|
155
|
+
|
|
156
|
+
basis_matrix = basis_matrix_fun(jnp.array(parametric_coordinates))
|
|
157
|
+
outputs["basis_matrix"] = np.array(basis_matrix).reshape(self.basis_matrix_shape)
|
|
158
|
+
|
|
159
|
+
class BSplineEvalCustomOpVJP(_CustomExplicitOperation):
|
|
160
|
+
def __init__(
|
|
161
|
+
self,
|
|
162
|
+
knots,
|
|
163
|
+
degree,
|
|
164
|
+
coefficients_shape,
|
|
165
|
+
der_orders=None
|
|
166
|
+
):
|
|
167
|
+
super().__init__()
|
|
168
|
+
self.knots = knots
|
|
169
|
+
self.degree = degree
|
|
170
|
+
self.coefficients_shape = coefficients_shape
|
|
171
|
+
self.der_orders = der_orders
|
|
172
|
+
|
|
173
|
+
def evluate_b_spline(us, p, knots_jnp, coeffs, der_orders=None):
|
|
174
|
+
ndim = len(p)
|
|
175
|
+
if der_orders is None:
|
|
176
|
+
der_orders = (0,) * ndim
|
|
177
|
+
num_phys_dims = coeffs.shape[-1]
|
|
178
|
+
basis_matrix = compute_basis_matrix_jax(us, p, knots_jnp, der_orders)
|
|
179
|
+
return basis_matrix @ coeffs.reshape(-1, num_phys_dims)
|
|
180
|
+
|
|
181
|
+
def evaluate_b_spline_jax_wrapped(us, coeffs):
|
|
182
|
+
return evluate_b_spline(us, self.degree, self.knots, coeffs, self.der_orders)
|
|
183
|
+
|
|
184
|
+
def compute_vjp(us, coeffs):
|
|
185
|
+
return jax.vjp(
|
|
186
|
+
evaluate_b_spline_jax_wrapped,
|
|
187
|
+
us,
|
|
188
|
+
coeffs,
|
|
189
|
+
)[1]
|
|
190
|
+
|
|
191
|
+
self.vjp_fun = compute_vjp
|
|
192
|
+
|
|
193
|
+
self._cache = {}
|
|
194
|
+
|
|
195
|
+
def evaluate(self, inputs, d_outputs):
|
|
196
|
+
parametric_coordinates = inputs["parametric_coordinates"]
|
|
197
|
+
coefficients = inputs["coefficients"]
|
|
198
|
+
d_b_spline_values = d_outputs["b_spline_values"]
|
|
199
|
+
|
|
200
|
+
self.declare_input("parametric_coordinates", parametric_coordinates)
|
|
201
|
+
self.declare_input("coefficients", coefficients)
|
|
202
|
+
self.declare_input("d_b_spline_values", d_b_spline_values)
|
|
203
|
+
|
|
204
|
+
d_parametric_coordinates = self.create_output(
|
|
205
|
+
"d_parametric_coordinates",
|
|
206
|
+
shape=parametric_coordinates.shape,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
d_coefficients = self.create_output(
|
|
210
|
+
"d_coefficients",
|
|
211
|
+
shape=coefficients.shape,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
d_inputs = {
|
|
215
|
+
"parametric_coordinates": d_parametric_coordinates,
|
|
216
|
+
"coefficients": d_coefficients,
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return d_inputs
|
|
220
|
+
|
|
221
|
+
def compute(self, inputs, outputs):
|
|
222
|
+
parametric_coordinates = inputs["parametric_coordinates"]
|
|
223
|
+
coefficients = inputs["coefficients"]
|
|
224
|
+
d_b_spline_values = inputs["d_b_spline_values"]
|
|
225
|
+
|
|
226
|
+
save_name = f"para_coords_shape_{parametric_coordinates.shape}_coeffs_shape_{coefficients.shape}"
|
|
227
|
+
|
|
228
|
+
if save_name in self._cache:
|
|
229
|
+
evaluate_b_spline_jax = self._cache[save_name]
|
|
230
|
+
else:
|
|
231
|
+
evaluate_b_spline_jax = jax.jit(
|
|
232
|
+
self.vjp_fun,
|
|
233
|
+
)
|
|
234
|
+
self._cache[save_name] = evaluate_b_spline_jax
|
|
235
|
+
|
|
236
|
+
d_parametric_coordinates, d_coefficients = evaluate_b_spline_jax(
|
|
237
|
+
jnp.array(parametric_coordinates),
|
|
238
|
+
jnp.array(coefficients),
|
|
239
|
+
)(jnp.array(d_b_spline_values))
|
|
240
|
+
|
|
241
|
+
outputs["d_parametric_coordinates"] = np.array(d_parametric_coordinates)
|
|
242
|
+
outputs["d_coefficients"] = np.array(d_coefficients)
|
|
243
|
+
|
|
244
|
+
class BSplineEvalCustomOp(_CustomExplicitOperation):
|
|
245
|
+
def __init__(self, knots, degree, coefficients_shape, der_orders=None):
|
|
246
|
+
super().__init__()
|
|
247
|
+
self.knots = tuple(jnp.array(knots_i) for knots_i in knots)
|
|
248
|
+
self.degree = degree
|
|
249
|
+
self.coefficients_shape = coefficients_shape
|
|
250
|
+
self.der_orders = der_orders
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def evluate_b_spline(us, p, knots_jnp, coeffs, der_orders=None):
|
|
254
|
+
ndim = len(p)
|
|
255
|
+
if der_orders is None:
|
|
256
|
+
der_orders = (0,) * ndim
|
|
257
|
+
num_phys_dims = coeffs.shape[-1]
|
|
258
|
+
basis_matrix = compute_basis_matrix_jax(us, p, knots_jnp, der_orders)
|
|
259
|
+
return basis_matrix @ coeffs.reshape(-1, num_phys_dims)
|
|
260
|
+
|
|
261
|
+
def evaluate_b_spline_jax_wrapped(us, coeffs):
|
|
262
|
+
return evluate_b_spline(us, self.degree, self.knots, coeffs, self.der_orders).squeeze()
|
|
263
|
+
|
|
264
|
+
self.evaluate_b_spline_jax = evaluate_b_spline_jax_wrapped
|
|
265
|
+
|
|
266
|
+
self._cache = {}
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def evaluate(self, parametric_coordinates, coefficients):
|
|
270
|
+
"""Evaluate the B-spline basis functions at the given parametric coordinates.
|
|
271
|
+
|
|
272
|
+
Parameters
|
|
273
|
+
----------
|
|
274
|
+
parametric_coordinates : csdl.Variable
|
|
275
|
+
The parametric coordinates at which to evaluate the basis functions.
|
|
276
|
+
shape=(num_points, num_parametric_dimensions)
|
|
277
|
+
|
|
278
|
+
coefficients : csdl.Variable
|
|
279
|
+
The coefficients of the B-spline basis functions.
|
|
280
|
+
shape=(ncp_x, ncp_y, ..., num_physical_dimensions)
|
|
281
|
+
|
|
282
|
+
Returns
|
|
283
|
+
-------
|
|
284
|
+
csdl.Variable
|
|
285
|
+
The evaluated B-spline values at the given parametric coordinates.
|
|
286
|
+
shape=(num_points, num_physical_dimensions)
|
|
287
|
+
"""
|
|
288
|
+
self.declare_input("parametric_coordinates", parametric_coordinates)
|
|
289
|
+
self.declare_input("coefficients", coefficients)
|
|
290
|
+
|
|
291
|
+
num_eval_points = parametric_coordinates.shape[0]
|
|
292
|
+
num_physical_dimensions = coefficients.shape[-1]
|
|
293
|
+
output_shape = (num_eval_points, num_physical_dimensions)
|
|
294
|
+
|
|
295
|
+
b_spline_values = self.create_output("b_spline_values", shape=output_shape)
|
|
296
|
+
|
|
297
|
+
self.declare_vjp_function(
|
|
298
|
+
BSplineEvalCustomOpVJP,
|
|
299
|
+
knots=self.knots,
|
|
300
|
+
degree=self.degree,
|
|
301
|
+
coefficients_shape=self.coefficients_shape,
|
|
302
|
+
der_orders=self.der_orders,
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
return b_spline_values
|
|
306
|
+
|
|
307
|
+
def compute(self, inputs, outputs):
|
|
308
|
+
parametric_coordinates = inputs["parametric_coordinates"]
|
|
309
|
+
coefficients = inputs["coefficients"]
|
|
310
|
+
|
|
311
|
+
save_name = f"para_coords_shape_{parametric_coordinates.shape}_coeffs_shape_{coefficients.shape}"
|
|
312
|
+
|
|
313
|
+
if save_name in self._cache:
|
|
314
|
+
evaluate_b_spline_jax = self._cache[save_name]
|
|
315
|
+
else:
|
|
316
|
+
evaluate_b_spline_jax = jax.jit(
|
|
317
|
+
self.evaluate_b_spline_jax,
|
|
318
|
+
)
|
|
319
|
+
self._cache[save_name] = evaluate_b_spline_jax
|
|
320
|
+
|
|
321
|
+
b_spline_values = evaluate_b_spline_jax(
|
|
322
|
+
jnp.array(parametric_coordinates),
|
|
323
|
+
jnp.array(coefficients),
|
|
324
|
+
)
|
|
325
|
+
outputs["b_spline_values"] = np.array(b_spline_values).reshape(
|
|
326
|
+
(parametric_coordinates.shape[0], coefficients.shape[-1])
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
if __name__ == "__main__":
|
|
331
|
+
np.random.seed(42) # For reproducibility
|
|
332
|
+
import lsdo_function_spaces as lfs
|
|
333
|
+
import time
|
|
334
|
+
|
|
335
|
+
# Define the B-spline space parameters
|
|
336
|
+
num_cp_x = 10
|
|
337
|
+
num_cp_y = 8
|
|
338
|
+
nx = num_cp_x - 1 # Number of control points - 1
|
|
339
|
+
ny = num_cp_y - 1 # Number of control points - 1
|
|
340
|
+
px = 3 # Degree of the B-spline
|
|
341
|
+
py = 2 # Degree of the B-spline
|
|
342
|
+
p = (px, py)
|
|
343
|
+
coefficients_shape = (num_cp_x, num_cp_y)
|
|
344
|
+
derivative_orders = (1, 0) # # derivatives for the evaluation
|
|
345
|
+
|
|
346
|
+
knots_x = np.concatenate(
|
|
347
|
+
[np.zeros(px),
|
|
348
|
+
np.linspace(0, 1, num_cp_x - px + 1),
|
|
349
|
+
np.ones(px)]
|
|
350
|
+
)
|
|
351
|
+
knots_y = np.concatenate(
|
|
352
|
+
[np.zeros(py),
|
|
353
|
+
np.linspace(0, 1, num_cp_y - py + 1),
|
|
354
|
+
np.ones(py)]
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
knots = (knots_x, knots_y) # Knot vectors for each dimension
|
|
358
|
+
knots_jnp = (jnp.array(knots_x), jnp.array(knots_y)) # JAX-compatible knot vectors
|
|
359
|
+
|
|
360
|
+
coeffs_x, coeffs_y = np.meshgrid(np.linspace(0, 5, num_cp_x), np.linspace(0, 2, num_cp_y), indexing='ij')
|
|
361
|
+
coeffs = np.array(np.stack((coeffs_x, coeffs_y, 0.2 * np.random.rand(num_cp_x, num_cp_y)), axis=-1))
|
|
362
|
+
|
|
363
|
+
rec = csdl.Recorder(inline=True)
|
|
364
|
+
rec.start()
|
|
365
|
+
|
|
366
|
+
coeffs_csdl = csdl.Variable(
|
|
367
|
+
name="coefficients",
|
|
368
|
+
value=coeffs,
|
|
369
|
+
)
|
|
370
|
+
coeffs_csdl.set_as_design_variable()
|
|
371
|
+
|
|
372
|
+
num_para_coords = 20 # NOTE: the actual number is squared
|
|
373
|
+
epsilon = 1e-8
|
|
374
|
+
u, v = np.meshgrid(np.linspace(epsilon, 1-epsilon, num_para_coords),
|
|
375
|
+
np.linspace(epsilon, 1-epsilon, num_para_coords), indexing='ij')
|
|
376
|
+
us = np.array(np.stack((u.flatten(), v.flatten()), axis=-1))
|
|
377
|
+
|
|
378
|
+
us_csdl = csdl.Variable(name="parametric_coordinates", value=us)
|
|
379
|
+
us_csdl.set_as_design_variable()
|
|
380
|
+
|
|
381
|
+
b_spline_eval_comp = BSplineEvalCustomOp(
|
|
382
|
+
knots=knots_jnp,
|
|
383
|
+
degree=p,
|
|
384
|
+
coefficients_shape=coefficients_shape,
|
|
385
|
+
der_orders=derivative_orders,
|
|
386
|
+
)
|
|
387
|
+
new_eval_points = b_spline_eval_comp.evaluate(us_csdl, coeffs_csdl)
|
|
388
|
+
objective = csdl.sum((new_eval_points))
|
|
389
|
+
objective.set_as_objective()
|
|
390
|
+
|
|
391
|
+
jax_sim = csdl.experimental.JaxSimulator(
|
|
392
|
+
rec,
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
jax_sim.check_optimization_derivatives(step_size=epsilon)
|
|
396
|
+
|
|
397
|
+
b_spline_space_old = lfs.BSplineSpace(
|
|
398
|
+
num_parametric_dimensions=2,
|
|
399
|
+
degree=p,
|
|
400
|
+
coefficients_shape=coefficients_shape,
|
|
401
|
+
)
|
|
402
|
+
old_b_spline_fun = lfs.Function(
|
|
403
|
+
space=b_spline_space_old,
|
|
404
|
+
coefficients=coeffs_csdl,
|
|
405
|
+
)
|
|
406
|
+
old_eval_points = old_b_spline_fun.evaluate(
|
|
407
|
+
parametric_coordinates=us,
|
|
408
|
+
parametric_derivative_orders=derivative_orders,
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
# compare the results
|
|
412
|
+
print("Evaluated points (new):", new_eval_points.value)
|
|
413
|
+
print("Evaluated points (old):", old_eval_points.value)
|
|
414
|
+
# Check if the results are the same
|
|
415
|
+
if np.allclose(new_eval_points.value, old_eval_points.value):
|
|
416
|
+
print("The evaluated points are equal.")
|
|
417
|
+
else:
|
|
418
|
+
print("The evaluated points are NOT equal.")
|
|
419
|
+
print("Max difference:", np.max(np.abs(new_eval_points.value - old_eval_points.value)))
|
|
420
|
+
|