Skip to content

Commit 95ec435

Browse files
committed
Extract field data as C-contiguous array
this enhances the time spent on assembly
1 parent 2961ad1 commit 95ec435

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

src/felupe/field/_base.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def _indices_per_cell(self, cells, dim):
138138

139139
return cai, ai
140140

141-
def grad(self, sym=False, dtype=None, out=None):
141+
def grad(self, sym=False, dtype=None, out=None, order="C"):
142142
r"""Gradient as partial derivative of field values w.r.t. undeformed
143143
coordinates, evaluated at the integration points of all cells in the region.
144144
Optionally, the symmetric part the gradient is evaluated.
@@ -159,6 +159,12 @@ def grad(self, sym=False, dtype=None, out=None):
159159
A location into which the result is stored. If provided, it must have a
160160
shape that the inputs broadcast to. If not provided or None, a freshly-
161161
allocated array is returned (default is None).
162+
order : {'C', 'F', 'A', 'K'}, optional
163+
Controls the memory layout of the output. 'C' means it should be C
164+
contiguous. 'F' means it should be Fortran contiguous, 'A' means it should
165+
be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as
166+
close to the layout as the inputs as is possible, including arbitrarily
167+
permuted axes. Default is 'C'.
162168
163169
Returns
164170
-------
@@ -177,14 +183,15 @@ def grad(self, sym=False, dtype=None, out=None):
177183
self.region.dhdX,
178184
dtype=dtype,
179185
out=out,
186+
order=order,
180187
)
181188

182189
if sym:
183190
return symmetric(g, out=g)
184191
else:
185192
return g
186193

187-
def hess(self, dtype=None, out=None):
194+
def hess(self, dtype=None, out=None, order="C"):
188195
r"""Hessian as second partial derivative of field values w.r.t. undeformed
189196
coordinates, evaluated at the integration points of all cells in the region.
190197
@@ -204,6 +211,12 @@ def hess(self, dtype=None, out=None):
204211
A location into which the result is stored. If provided, it must have a
205212
shape that the inputs broadcast to. If not provided or None, a freshly-
206213
allocated array is returned (default is None).
214+
order : {'C', 'F', 'A', 'K'}, optional
215+
Controls the memory layout of the output. 'C' means it should be C
216+
contiguous. 'F' means it should be Fortran contiguous, 'A' means it should
217+
be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as
218+
close to the layout as the inputs as is possible, including arbitrarily
219+
permuted axes. Default is 'C'.
207220
208221
Returns
209222
-------
@@ -222,11 +235,12 @@ def hess(self, dtype=None, out=None):
222235
self.region.d2hdXdX,
223236
dtype=dtype,
224237
out=out,
238+
order=order,
225239
)
226240

227241
return h
228242

229-
def interpolate(self, dtype=None, out=None):
243+
def interpolate(self, dtype=None, out=None, order="C"):
230244
r"""Interpolate field values located at mesh-points to the quadrature points
231245
``q`` of cells ``c`` in the region.
232246
@@ -243,6 +257,12 @@ def interpolate(self, dtype=None, out=None):
243257
A location into which the result is stored. If provided, it must have a
244258
shape that the inputs broadcast to. If not provided or None, a freshly-
245259
allocated array is returned (default is None).
260+
order : {'C', 'F', 'A', 'K'}, optional
261+
Controls the memory layout of the output. 'C' means it should be C
262+
contiguous. 'F' means it should be Fortran contiguous, 'A' means it should
263+
be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as
264+
close to the layout as the inputs as is possible, including arbitrarily
265+
permuted axes. Default is 'C'.
246266
247267
Returns
248268
-------
@@ -259,10 +279,13 @@ def interpolate(self, dtype=None, out=None):
259279
self.values[self.region.mesh.cells],
260280
self.region.h,
261281
dtype=dtype,
262-
out=None,
282+
out=out,
283+
order=order,
263284
)
264285

265-
def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None):
286+
def extract(
287+
self, grad=True, sym=False, add_identity=True, dtype=None, out=None, order="C"
288+
):
266289
"""Generalized extraction method which evaluates either the gradient or the
267290
field values at the integration points of all cells in the region. Optionally,
268291
the symmetric part of the gradient is evaluated and/or the identity matrix is
@@ -284,6 +307,12 @@ def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None)
284307
A location into which the result is stored. If provided, it must have a
285308
shape that the inputs broadcast to. If not provided or None, a freshly-
286309
allocated array is returned (default is None).
310+
order : {'C', 'F', 'A', 'K'}, optional
311+
Controls the memory layout of the outputs. 'C' means it should be C
312+
contiguous. 'F' means it should be Fortran contiguous, 'A' means it should
313+
be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as
314+
close to the layout as the inputs as is possible, including arbitrarily
315+
permuted axes. Default is 'C'.
287316
288317
Returns
289318
-------
@@ -298,7 +327,7 @@ def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None)
298327
"""
299328

300329
if grad:
301-
gr = self.grad(out=out, dtype=dtype)
330+
gr = self.grad(out=out, dtype=dtype, order=order)
302331

303332
if sym:
304333
gr = symmetric(gr, out=gr)
@@ -308,7 +337,7 @@ def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None)
308337

309338
return gr
310339
else:
311-
return self.interpolate(out=out, dtype=dtype)
340+
return self.interpolate(out=out, dtype=dtype, order=order)
312341

313342
def copy(self):
314343
"Return a copy of the field."

src/felupe/region/_region.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,8 @@ def reload(
344344
if uniform:
345345
cells = cells[:1]
346346

347-
region.dXdr = np.ascontiguousarray(
348-
np.einsum("caI,aJqc->IJqc", region.mesh.points[cells], region.dhdr)
347+
region.dXdr = np.einsum(
348+
"caI,aJqc->IJqc", region.mesh.points[cells], region.dhdr, order="C"
349349
)
350350

351351
# determinant and inverse of dXdr

0 commit comments

Comments
 (0)