Skip to content

Commit 0b742f5

Browse files
Address PR comments for high-level APIs
Add Rust sibling functions and tests, add Python tests, fix Julia versioning for CI.
1 parent 11b88dd commit 0b742f5

File tree

7 files changed

+412
-7
lines changed

7 files changed

+412
-7
lines changed

julia/LibCEED.jl/src/LibCEED.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ include("Request.jl")
150150
include("Operator.jl")
151151
include("Misc.jl")
152152

153-
const minimum_libceed_version = v"0.10.0"
153+
const minimum_libceed_version = v"0.12.0"
154154

155155
function __init__()
156156
if !ceedversion_ge(minimum_libceed_version)

julia/LibCEED.jl/src/generated/libceed_bindings.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1374,7 +1374,7 @@ const CEED_VERSION_MINOR = 11
13741374

13751375
const CEED_VERSION_PATCH = 0
13761376

1377-
const CEED_VERSION_RELEASE = true
1377+
const CEED_VERSION_RELEASE = false
13781378

13791379
# Skipping MacroDefinition: CEED_INTERN extern CEED_VISIBILITY ( hidden )
13801380

python/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from .ceed import Ceed
99
from .ceed_vector import Vector
10-
from .ceed_basis import Basis, BasisTensorH1, BasisTensorH1Lagrange, BasisH1
10+
from .ceed_basis import Basis, BasisTensorH1, BasisTensorH1Lagrange, BasisH1, BasisHdiv, BasisHcurl
1111
from .ceed_elemrestriction import ElemRestriction, StridedElemRestriction, BlockedElemRestriction, BlockedStridedElemRestriction
1212
from .ceed_qfunction import QFunction, QFunctionByName, IdentityQFunction
1313
from .ceed_operator import Operator, CompositeOperator
@@ -18,7 +18,7 @@
1818
# ------------------------------------------------------------------------------
1919
__all__ = ["Ceed",
2020
"Vector",
21-
"Basis", "BasisTensorH1", "BasisTensorH1Lagrange", "BasisH1",
21+
"Basis", "BasisTensorH1", "BasisTensorH1Lagrange", "BasisH1", "BasisHdiv", "BasisHcurl",
2222
"ElemRestriction", "StridedElemRestriction", "BlockedElemRestriction", "BlockedStridedelemRestriction",
2323
"QFunction", "QFunctionByName", "IdentityQFunction",
2424
"Operator", "CompositeOperator",

python/ceed.py

+55-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import tempfile
1414
from abc import ABC
1515
from .ceed_vector import Vector
16-
from .ceed_basis import BasisTensorH1, BasisTensorH1Lagrange, BasisH1
16+
from .ceed_basis import BasisTensorH1, BasisTensorH1Lagrange, BasisH1, BasisHdiv, BasisHcurl
1717
from .ceed_elemrestriction import ElemRestriction, StridedElemRestriction, BlockedElemRestriction, BlockedStridedElemRestriction
1818
from .ceed_qfunction import QFunction, QFunctionByName, IdentityQFunction
1919
from .ceed_qfunctioncontext import QFunctionContext
@@ -356,7 +356,7 @@ def BasisH1(self, topo, ncomp, nnodes, nqpts, interp, grad, qref, qweight):
356356
*interp: Numpy array holding the row-major (nqpts * nnodes) matrix
357357
expressing the values of nodal basis functions at
358358
quadrature points
359-
*grad: Numpy array holding the row-major (nqpts * dim * nnodes)
359+
*grad: Numpy array holding the row-major (dim * nqpts * nnodes)
360360
matrix expressing the derivatives of nodal basis functions
361361
at quadrature points
362362
*qref: Numpy array of length (nqpts * dim) holding the locations of
@@ -370,6 +370,59 @@ def BasisH1(self, topo, ncomp, nnodes, nqpts, interp, grad, qref, qweight):
370370
return BasisH1(self, topo, ncomp, nnodes, nqpts,
371371
interp, grad, qref, qweight)
372372

373+
def BasisHdiv(self, topo, ncomp, nnodes, nqpts, interp, div, qref, qweight):
374+
"""Ceed Hdiv Basis: finite element non tensor-product basis for H(div)
375+
discretizations.
376+
377+
Args:
378+
topo: topology of the element, e.g. hypercube, simplex, etc
379+
ncomp: number of field components (1 for scalar fields)
380+
nnodes: total number of nodes
381+
nqpts: total number of quadrature points
382+
*interp: Numpy array holding the row-major (dim * nqpts * nnodes)
383+
matrix expressing the values of basis functions at
384+
quadrature points
385+
*div: Numpy array holding the row-major (nqpts * nnodes) matrix
386+
expressing the divergence of basis functions at
387+
quadrature points
388+
*qref: Numpy array of length (nqpts * dim) holding the locations of
389+
quadrature points on the reference element [-1, 1]
390+
*qweight: Numpy array of length nnodes holding the quadrature
391+
weights on the reference element
392+
393+
Returns:
394+
basis: Ceed Basis"""
395+
396+
return BasisHdiv(self, topo, ncomp, nnodes, nqpts,
397+
interp, div, qref, qweight)
398+
399+
def BasisHcurl(self, topo, ncomp, nnodes, nqpts,
400+
interp, curl, qref, qweight):
401+
"""Ceed Hcurl Basis: finite element non tensor-product basis for H(curl)
402+
discretizations.
403+
404+
Args:
405+
topo: topology of the element, e.g. hypercube, simplex, etc
406+
ncomp: number of field components (1 for scalar fields)
407+
nnodes: total number of nodes
408+
nqpts: total number of quadrature points
409+
*interp: Numpy array holding the row-major (dim * nqpts * nnodes)
410+
matrix expressing the values of basis functions at
411+
quadrature points
412+
*curl: Numpy array holding the row-major (curlcomp * nqpts * nnodes),
413+
curlcomp = 1 if dim < 3 else dim, matrix expressing the curl
414+
of basis functions at quadrature points
415+
*qref: Numpy array of length (nqpts * dim) holding the locations of
416+
quadrature points on the reference element [-1, 1]
417+
*qweight: Numpy array of length nnodes holding the quadrature
418+
weights on the reference element
419+
420+
Returns:
421+
basis: Ceed Basis"""
422+
423+
return BasisHcurl(self, topo, ncomp, nnodes, nqpts,
424+
interp, curl, qref, qweight)
425+
373426
# CeedQFunction
374427
def QFunction(self, vlength, f, source):
375428
"""Ceed QFunction: point-wise operation at quadrature points for

python/tests/buildmats.py

+77
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,80 @@ def buildmats(qref, qweight, mat_dtype="float64"):
4747
grad[(i + Q) * P + 5] = 2. * (1. * (x2 - 1. / 2.) + x2 * 1.)
4848

4949
return interp, grad
50+
51+
52+
def buildmatshdiv(qref, qweight, mat_dtype="float64"):
53+
P, Q, dim = 4, 4, 2
54+
interp = np.empty(dim * P * Q, dtype=mat_dtype)
55+
div = np.empty(P * Q, dtype=mat_dtype)
56+
57+
qref[0] = -1. / np.sqrt(3.)
58+
qref[1] = qref[0]
59+
qref[2] = qref[0]
60+
qref[3] = -qref[0]
61+
qref[4] = -qref[0]
62+
qref[5] = -qref[0]
63+
qref[6] = qref[0]
64+
qref[7] = qref[0]
65+
qweight[0] = 1.
66+
qweight[1] = 1.
67+
qweight[2] = 1.
68+
qweight[3] = 1.
69+
70+
# Loop over quadrature points
71+
for i in range(Q):
72+
x1 = qref[0 * Q + i]
73+
x2 = qref[1 * Q + i]
74+
# Interp
75+
interp[(i + 0) * P + 0] = 0.
76+
interp[(i + Q) * P + 0] = 1. - x2
77+
interp[(i + 0) * P + 1] = x1 - 1.
78+
interp[(i + Q) * P + 1] = 0.
79+
interp[(i + 0) * P + 2] = -x1
80+
interp[(i + Q) * P + 2] = 0.
81+
interp[(i + 0) * P + 3] = 0.
82+
interp[(i + Q) * P + 3] = x2
83+
# Div
84+
div[i * P + 0] = -1.
85+
div[i * P + 1] = 1.
86+
div[i * P + 2] = -1.
87+
div[i * P + 3] = 1.
88+
89+
return interp, div
90+
91+
92+
def buildmatshcurl(qref, qweight, mat_dtype="float64"):
93+
P, Q, dim = 3, 4, 2
94+
interp = np.empty(dim * P * Q, dtype=mat_dtype)
95+
curl = np.empty(P * Q, dtype=mat_dtype)
96+
97+
qref[0] = 0.2
98+
qref[1] = 0.6
99+
qref[2] = 1. / 3.
100+
qref[3] = 0.2
101+
qref[4] = 0.2
102+
qref[5] = 0.2
103+
qref[6] = 1. / 3.
104+
qref[7] = 0.6
105+
qweight[0] = 25. / 96.
106+
qweight[1] = 25. / 96.
107+
qweight[2] = -27. / 96.
108+
qweight[3] = 25. / 96.
109+
110+
# Loop over quadrature points
111+
for i in range(Q):
112+
x1 = qref[0 * Q + i]
113+
x2 = qref[1 * Q + i]
114+
# Interp
115+
interp[(i + 0) * P + 0] = -x2
116+
interp[(i + Q) * P + 0] = x1
117+
interp[(i + 0) * P + 1] = x2
118+
interp[(i + Q) * P + 1] = 1. - x1
119+
interp[(i + 0) * P + 2] = 1. - x2
120+
interp[(i + Q) * P + 2] = x1
121+
# Curl
122+
curl[i * P + 0] = 2.
123+
curl[i * P + 1] = -2.
124+
curl[i * P + 2] = -2.
125+
126+
return interp, curl

python/tests/test-3-basis.py

+83
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,86 @@ def test_323(ceed_resource):
303303
assert math.fabs(out_array[1 * Q + i] - value) < 10. * TOL
304304

305305
# -------------------------------------------------------------------------------
306+
# Test interpolation with a 2D Quad non-tensor H(div) basis
307+
# -------------------------------------------------------------------------------
308+
309+
310+
def test_330(ceed_resource):
311+
ceed = libceed.Ceed(ceed_resource)
312+
313+
P, Q, dim = 4, 4, 2
314+
315+
in_array = np.ones(P, dtype=ceed.scalar_type())
316+
qref = np.empty(dim * Q, dtype=ceed.scalar_type())
317+
qweight = np.empty(Q, dtype=ceed.scalar_type())
318+
319+
interp, div = bm.buildmatshdiv(qref, qweight, libceed.scalar_types[
320+
libceed.lib.CEED_SCALAR_TYPE])
321+
322+
b = ceed.BasisHdiv(libceed.QUAD, 1, P, Q, interp, div, qref, qweight)
323+
324+
# Interpolate function to quadrature points
325+
in_vec = ceed.Vector(P)
326+
in_vec.set_array(in_array, cmode=libceed.USE_POINTER)
327+
out_vec = ceed.Vector(Q * dim)
328+
out_vec.set_value(0)
329+
330+
b.apply(1, libceed.EVAL_INTERP, in_vec, out_vec)
331+
332+
# Check values at quadrature points
333+
with out_vec.array_read() as out_array:
334+
for i in range(Q):
335+
assert math.fabs(out_array[0 * Q + i] + 1.) < 10. * TOL
336+
assert math.fabs(out_array[1 * Q + i] - 1.) < 10. * TOL
337+
338+
# -------------------------------------------------------------------------------
339+
# Test interpolation with a 2D Simplex non-tensor H(curl) basis
340+
# -------------------------------------------------------------------------------
341+
342+
343+
def test_340(ceed_resource):
344+
ceed = libceed.Ceed(ceed_resource)
345+
346+
P, Q, dim = 3, 4, 2
347+
348+
in_array = np.empty(P, dtype=ceed.scalar_type())
349+
qref = np.empty(dim * Q, dtype=ceed.scalar_type())
350+
qweight = np.empty(Q, dtype=ceed.scalar_type())
351+
352+
interp, curl = bm.buildmatshcurl(qref, qweight, libceed.scalar_types[
353+
libceed.lib.CEED_SCALAR_TYPE])
354+
355+
b = ceed.BasisHcurl(libceed.TRIANGLE, 1, P, Q, interp, curl, qref, qweight)
356+
357+
# Interpolate function to quadrature points
358+
in_array[0] = 1.
359+
in_array[1] = 2.
360+
in_array[2] = 1.
361+
362+
in_vec = ceed.Vector(P)
363+
in_vec.set_array(in_array, cmode=libceed.USE_POINTER)
364+
out_vec = ceed.Vector(Q * dim)
365+
out_vec.set_value(0)
366+
367+
b.apply(1, libceed.EVAL_INTERP, in_vec, out_vec)
368+
369+
# Check values at quadrature points
370+
with out_vec.array_read() as out_array:
371+
for i in range(Q):
372+
assert math.fabs(out_array[0 * Q + i] - 1.) < 10. * TOL
373+
374+
# Interpolate function to quadrature points
375+
in_array[0] = -1.
376+
in_array[1] = 1.
377+
in_array[2] = 2.
378+
379+
out_vec.set_value(0)
380+
381+
b.apply(1, libceed.EVAL_INTERP, in_vec, out_vec)
382+
383+
# Check values at quadrature points
384+
with out_vec.array_read() as out_array:
385+
for i in range(Q):
386+
assert math.fabs(out_array[1 * Q + i] - 1.) < 10. * TOL
387+
388+
# -------------------------------------------------------------------------------

0 commit comments

Comments
 (0)