xref: /libCEED/python/tests/test-4-qfunction.py (revision 0ef725981a32b9079ff6c5100673b913b8f4d7c0)
1*0ef72598Sjeremylt# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2*0ef72598Sjeremylt# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3*0ef72598Sjeremylt# reserved. See files LICENSE and NOTICE for details.
4*0ef72598Sjeremylt#
5*0ef72598Sjeremylt# This file is part of CEED, a collection of benchmarks, miniapps, software
6*0ef72598Sjeremylt# libraries and APIs for efficient high-order finite element and spectral
7*0ef72598Sjeremylt# element discretizations for exascale applications. For more information and
8*0ef72598Sjeremylt# source code availability see http://github.com/ceed.
9*0ef72598Sjeremylt#
10*0ef72598Sjeremylt# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11*0ef72598Sjeremylt# a collaborative effort of two U.S. Department of Energy organizations (Office
12*0ef72598Sjeremylt# of Science and the National Nuclear Security Administration) responsible for
13*0ef72598Sjeremylt# the planning and preparation of a capable exascale ecosystem, including
14*0ef72598Sjeremylt# software, applications, hardware, advanced system engineering and early
15*0ef72598Sjeremylt# testbed platforms, in support of the nation's exascale computing imperative.
16*0ef72598Sjeremylt
17*0ef72598Sjeremylt# @file
18*0ef72598Sjeremylt# Test Ceed QFunction functionality
19*0ef72598Sjeremylt
20*0ef72598Sjeremyltimport os
21*0ef72598Sjeremyltimport libceed
22*0ef72598Sjeremyltimport numpy as np
23*0ef72598Sjeremyltimport check
24*0ef72598Sjeremylt
25*0ef72598Sjeremylt# -------------------------------------------------------------------------------
26*0ef72598Sjeremylt# Utility
27*0ef72598Sjeremylt# -------------------------------------------------------------------------------
28*0ef72598Sjeremylt
29*0ef72598Sjeremylt
30*0ef72598Sjeremyltdef load_qfs_so():
31*0ef72598Sjeremylt    from distutils.sysconfig import get_config_var
32*0ef72598Sjeremylt    import ctypes
33*0ef72598Sjeremylt
34*0ef72598Sjeremylt    file_dir = os.path.dirname(os.path.abspath(__file__))
35*0ef72598Sjeremylt    qfs_so = os.path.join(
36*0ef72598Sjeremylt        file_dir,
37*0ef72598Sjeremylt        "libceed_qfunctions" + get_config_var("EXT_SUFFIX"))
38*0ef72598Sjeremylt
39*0ef72598Sjeremylt    # Load library
40*0ef72598Sjeremylt    return ctypes.cdll.LoadLibrary(qfs_so)
41*0ef72598Sjeremylt
42*0ef72598Sjeremylt# -------------------------------------------------------------------------------
43*0ef72598Sjeremylt# Test creation, evaluation, and destruction for qfunction
44*0ef72598Sjeremylt# -------------------------------------------------------------------------------
45*0ef72598Sjeremylt
46*0ef72598Sjeremylt
47*0ef72598Sjeremyltdef test_400(ceed_resource):
48*0ef72598Sjeremylt    ceed = libceed.Ceed(ceed_resource)
49*0ef72598Sjeremylt
50*0ef72598Sjeremylt    file_dir = os.path.dirname(os.path.abspath(__file__))
51*0ef72598Sjeremylt    qfs = load_qfs_so()
52*0ef72598Sjeremylt
53*0ef72598Sjeremylt    qf_setup = ceed.QFunction(1, qfs.setup_mass,
54*0ef72598Sjeremylt                              os.path.join(file_dir, "test-qfunctions.h:setup_mass"))
55*0ef72598Sjeremylt    qf_setup.add_input("w", 1, libceed.EVAL_WEIGHT)
56*0ef72598Sjeremylt    qf_setup.add_input("dx", 1, libceed.EVAL_GRAD)
57*0ef72598Sjeremylt    qf_setup.add_output("qdata", 1, libceed.EVAL_NONE)
58*0ef72598Sjeremylt
59*0ef72598Sjeremylt    qf_mass = ceed.QFunction(1, qfs.apply_mass,
60*0ef72598Sjeremylt                             os.path.join(file_dir, "test-qfunctions.h:apply_mass"))
61*0ef72598Sjeremylt    qf_mass.add_input("qdata", 1, libceed.EVAL_NONE)
62*0ef72598Sjeremylt    qf_mass.add_input("u", 1, libceed.EVAL_INTERP)
63*0ef72598Sjeremylt    qf_mass.add_output("v", 1, libceed.EVAL_INTERP)
64*0ef72598Sjeremylt
65*0ef72598Sjeremylt    q = 8
66*0ef72598Sjeremylt
67*0ef72598Sjeremylt    w_array = np.zeros(q, dtype="float64")
68*0ef72598Sjeremylt    u_array = np.zeros(q, dtype="float64")
69*0ef72598Sjeremylt    v_true = np.zeros(q, dtype="float64")
70*0ef72598Sjeremylt    for i in range(q):
71*0ef72598Sjeremylt        x = 2. * i / (q - 1) - 1
72*0ef72598Sjeremylt        w_array[i] = 1 - x * x
73*0ef72598Sjeremylt        u_array[i] = 2 + 3 * x + 5 * x * x
74*0ef72598Sjeremylt        v_true[i] = w_array[i] * u_array[i]
75*0ef72598Sjeremylt
76*0ef72598Sjeremylt    dx = ceed.Vector(q)
77*0ef72598Sjeremylt    dx.set_value(1)
78*0ef72598Sjeremylt    w = ceed.Vector(q)
79*0ef72598Sjeremylt    w.set_array(w_array, cmode=libceed.USE_POINTER)
80*0ef72598Sjeremylt    u = ceed.Vector(q)
81*0ef72598Sjeremylt    u.set_array(u_array, cmode=libceed.USE_POINTER)
82*0ef72598Sjeremylt    v = ceed.Vector(q)
83*0ef72598Sjeremylt    v.set_value(0)
84*0ef72598Sjeremylt    qdata = ceed.Vector(q)
85*0ef72598Sjeremylt    qdata.set_value(0)
86*0ef72598Sjeremylt
87*0ef72598Sjeremylt    inputs = [dx, w]
88*0ef72598Sjeremylt    outputs = [qdata]
89*0ef72598Sjeremylt    qf_setup.apply(q, inputs, outputs)
90*0ef72598Sjeremylt
91*0ef72598Sjeremylt    inputs = [qdata, u]
92*0ef72598Sjeremylt    outputs = [v]
93*0ef72598Sjeremylt    qf_mass.apply(q, inputs, outputs)
94*0ef72598Sjeremylt
95*0ef72598Sjeremylt    with v.array_read() as v_array:
96*0ef72598Sjeremylt        for i in range(q):
97*0ef72598Sjeremylt            assert v_array[i] == v_true[i]
98*0ef72598Sjeremylt
99*0ef72598Sjeremylt# -------------------------------------------------------------------------------
100*0ef72598Sjeremylt# Test creation, evaluation, and destruction for qfunction
101*0ef72598Sjeremylt# -------------------------------------------------------------------------------
102*0ef72598Sjeremylt
103*0ef72598Sjeremylt
104*0ef72598Sjeremyltdef test_401(ceed_resource):
105*0ef72598Sjeremylt    ceed = libceed.Ceed(ceed_resource)
106*0ef72598Sjeremylt
107*0ef72598Sjeremylt    file_dir = os.path.dirname(os.path.abspath(__file__))
108*0ef72598Sjeremylt    qfs = load_qfs_so()
109*0ef72598Sjeremylt
110*0ef72598Sjeremylt    qf_setup = ceed.QFunction(1, qfs.setup_mass,
111*0ef72598Sjeremylt                              os.path.join(file_dir, "test-qfunctions.h:setup_mass"))
112*0ef72598Sjeremylt    qf_setup.add_input("w", 1, libceed.EVAL_WEIGHT)
113*0ef72598Sjeremylt    qf_setup.add_input("dx", 1, libceed.EVAL_GRAD)
114*0ef72598Sjeremylt    qf_setup.add_output("qdata", 1, libceed.EVAL_NONE)
115*0ef72598Sjeremylt
116*0ef72598Sjeremylt    qf_mass = ceed.QFunction(1, qfs.apply_mass,
117*0ef72598Sjeremylt                             os.path.join(file_dir, "t400-qfunction.h:apply_mass"))
118*0ef72598Sjeremylt    qf_mass.add_input("qdata", 1, libceed.EVAL_NONE)
119*0ef72598Sjeremylt    qf_mass.add_input("u", 1, libceed.EVAL_INTERP)
120*0ef72598Sjeremylt    qf_mass.add_output("v", 1, libceed.EVAL_INTERP)
121*0ef72598Sjeremylt
122*0ef72598Sjeremylt    ctx_data = np.array([1., 2., 3., 4., 5.])
123*0ef72598Sjeremylt    ctx = ceed.QFunctionContext()
124*0ef72598Sjeremylt    ctx.set_data(ctx_data)
125*0ef72598Sjeremylt    qf_mass.set_context(ctx)
126*0ef72598Sjeremylt
127*0ef72598Sjeremylt    q = 8
128*0ef72598Sjeremylt
129*0ef72598Sjeremylt    w_array = np.zeros(q, dtype="float64")
130*0ef72598Sjeremylt    u_array = np.zeros(q, dtype="float64")
131*0ef72598Sjeremylt    v_true = np.zeros(q, dtype="float64")
132*0ef72598Sjeremylt    for i in range(q):
133*0ef72598Sjeremylt        x = 2. * i / (q - 1) - 1
134*0ef72598Sjeremylt        w_array[i] = 1 - x * x
135*0ef72598Sjeremylt        u_array[i] = 2 + 3 * x + 5 * x * x
136*0ef72598Sjeremylt        v_true[i] = 5 * w_array[i] * u_array[i]
137*0ef72598Sjeremylt
138*0ef72598Sjeremylt    dx = ceed.Vector(q)
139*0ef72598Sjeremylt    dx.set_value(1)
140*0ef72598Sjeremylt    w = ceed.Vector(q)
141*0ef72598Sjeremylt    w.set_array(w_array, cmode=libceed.USE_POINTER)
142*0ef72598Sjeremylt    u = ceed.Vector(q)
143*0ef72598Sjeremylt    u.set_array(u_array, cmode=libceed.USE_POINTER)
144*0ef72598Sjeremylt    v = ceed.Vector(q)
145*0ef72598Sjeremylt    v.set_value(0)
146*0ef72598Sjeremylt    qdata = ceed.Vector(q)
147*0ef72598Sjeremylt    qdata.set_value(0)
148*0ef72598Sjeremylt
149*0ef72598Sjeremylt    inputs = [dx, w]
150*0ef72598Sjeremylt    outputs = [qdata]
151*0ef72598Sjeremylt    qf_setup.apply(q, inputs, outputs)
152*0ef72598Sjeremylt
153*0ef72598Sjeremylt    inputs = [qdata, u]
154*0ef72598Sjeremylt    outputs = [v]
155*0ef72598Sjeremylt    qf_mass.apply(q, inputs, outputs)
156*0ef72598Sjeremylt
157*0ef72598Sjeremylt    with v.array_read() as v_array:
158*0ef72598Sjeremylt        for i in range(q):
159*0ef72598Sjeremylt            assert v_array[i] == v_true[i]
160*0ef72598Sjeremylt
161*0ef72598Sjeremylt# -------------------------------------------------------------------------------
162*0ef72598Sjeremylt# Test viewing of qfunction
163*0ef72598Sjeremylt# -------------------------------------------------------------------------------
164*0ef72598Sjeremylt
165*0ef72598Sjeremylt
166*0ef72598Sjeremyltdef test_402(ceed_resource, capsys):
167*0ef72598Sjeremylt    ceed = libceed.Ceed(ceed_resource)
168*0ef72598Sjeremylt
169*0ef72598Sjeremylt    file_dir = os.path.dirname(os.path.abspath(__file__))
170*0ef72598Sjeremylt    qfs = load_qfs_so()
171*0ef72598Sjeremylt
172*0ef72598Sjeremylt    qf_setup = ceed.QFunction(1, qfs.setup_mass,
173*0ef72598Sjeremylt                              os.path.join(file_dir, "test-qfunctions.h:setup_mass"))
174*0ef72598Sjeremylt    qf_setup.add_input("w", 1, libceed.EVAL_WEIGHT)
175*0ef72598Sjeremylt    qf_setup.add_input("dx", 1, libceed.EVAL_GRAD)
176*0ef72598Sjeremylt    qf_setup.add_output("qdata", 1, libceed.EVAL_NONE)
177*0ef72598Sjeremylt
178*0ef72598Sjeremylt    qf_mass = ceed.QFunction(1, qfs.apply_mass,
179*0ef72598Sjeremylt                             os.path.join(file_dir, "t400-qfunction.h:apply_mass"))
180*0ef72598Sjeremylt    qf_mass.add_input("qdata", 1, libceed.EVAL_NONE)
181*0ef72598Sjeremylt    qf_mass.add_input("u", 1, libceed.EVAL_INTERP)
182*0ef72598Sjeremylt    qf_mass.add_output("v", 1, libceed.EVAL_INTERP)
183*0ef72598Sjeremylt
184*0ef72598Sjeremylt    print(qf_setup)
185*0ef72598Sjeremylt    print(qf_mass)
186*0ef72598Sjeremylt
187*0ef72598Sjeremylt    ctx_data = np.array([1., 2., 3., 4., 5.])
188*0ef72598Sjeremylt    ctx = ceed.QFunctionContext()
189*0ef72598Sjeremylt    ctx.set_data(ctx_data)
190*0ef72598Sjeremylt    print(ctx)
191*0ef72598Sjeremylt
192*0ef72598Sjeremylt    stdout, stderr, ref_stdout = check.output(capsys)
193*0ef72598Sjeremylt    assert not stderr
194*0ef72598Sjeremylt    assert stdout == ref_stdout
195*0ef72598Sjeremylt
196*0ef72598Sjeremylt# -------------------------------------------------------------------------------
197*0ef72598Sjeremylt# Test creation, evaluation, and destruction for qfunction by name
198*0ef72598Sjeremylt# -------------------------------------------------------------------------------
199*0ef72598Sjeremylt
200*0ef72598Sjeremylt
201*0ef72598Sjeremyltdef test_410(ceed_resource):
202*0ef72598Sjeremylt    ceed = libceed.Ceed(ceed_resource)
203*0ef72598Sjeremylt
204*0ef72598Sjeremylt    qf_setup = ceed.QFunctionByName("Mass1DBuild")
205*0ef72598Sjeremylt    qf_mass = ceed.QFunctionByName("MassApply")
206*0ef72598Sjeremylt
207*0ef72598Sjeremylt    q = 8
208*0ef72598Sjeremylt
209*0ef72598Sjeremylt    j_array = np.zeros(q, dtype="float64")
210*0ef72598Sjeremylt    w_array = np.zeros(q, dtype="float64")
211*0ef72598Sjeremylt    u_array = np.zeros(q, dtype="float64")
212*0ef72598Sjeremylt    v_true = np.zeros(q, dtype="float64")
213*0ef72598Sjeremylt    for i in range(q):
214*0ef72598Sjeremylt        x = 2. * i / (q - 1) - 1
215*0ef72598Sjeremylt        j_array[i] = 1
216*0ef72598Sjeremylt        w_array[i] = 1 - x * x
217*0ef72598Sjeremylt        u_array[i] = 2 + 3 * x + 5 * x * x
218*0ef72598Sjeremylt        v_true[i] = w_array[i] * u_array[i]
219*0ef72598Sjeremylt
220*0ef72598Sjeremylt    j = ceed.Vector(q)
221*0ef72598Sjeremylt    j.set_array(j_array, cmode=libceed.USE_POINTER)
222*0ef72598Sjeremylt    w = ceed.Vector(q)
223*0ef72598Sjeremylt    w.set_array(w_array, cmode=libceed.USE_POINTER)
224*0ef72598Sjeremylt    u = ceed.Vector(q)
225*0ef72598Sjeremylt    u.set_array(u_array, cmode=libceed.USE_POINTER)
226*0ef72598Sjeremylt    v = ceed.Vector(q)
227*0ef72598Sjeremylt    v.set_value(0)
228*0ef72598Sjeremylt    qdata = ceed.Vector(q)
229*0ef72598Sjeremylt    qdata.set_value(0)
230*0ef72598Sjeremylt
231*0ef72598Sjeremylt    inputs = [j, w]
232*0ef72598Sjeremylt    outputs = [qdata]
233*0ef72598Sjeremylt    qf_setup.apply(q, inputs, outputs)
234*0ef72598Sjeremylt
235*0ef72598Sjeremylt    inputs = [w, u]
236*0ef72598Sjeremylt    outputs = [v]
237*0ef72598Sjeremylt    qf_mass.apply(q, inputs, outputs)
238*0ef72598Sjeremylt
239*0ef72598Sjeremylt    with v.array_read() as v_array:
240*0ef72598Sjeremylt        for i in range(q):
241*0ef72598Sjeremylt            assert v_array[i] == v_true[i]
242*0ef72598Sjeremylt
243*0ef72598Sjeremylt# -------------------------------------------------------------------------------
244*0ef72598Sjeremylt# Test creation, evaluation, and destruction of identity qfunction
245*0ef72598Sjeremylt# -------------------------------------------------------------------------------
246*0ef72598Sjeremylt
247*0ef72598Sjeremylt
248*0ef72598Sjeremyltdef test_411(ceed_resource):
249*0ef72598Sjeremylt    ceed = libceed.Ceed(ceed_resource)
250*0ef72598Sjeremylt
251*0ef72598Sjeremylt    qf = ceed.IdentityQFunction(1, libceed.EVAL_INTERP, libceed.EVAL_INTERP)
252*0ef72598Sjeremylt
253*0ef72598Sjeremylt    q = 8
254*0ef72598Sjeremylt
255*0ef72598Sjeremylt    u_array = np.zeros(q, dtype="float64")
256*0ef72598Sjeremylt    for i in range(q):
257*0ef72598Sjeremylt        u_array[i] = i * i
258*0ef72598Sjeremylt
259*0ef72598Sjeremylt    u = ceed.Vector(q)
260*0ef72598Sjeremylt    u.set_array(u_array, cmode=libceed.USE_POINTER)
261*0ef72598Sjeremylt    v = ceed.Vector(q)
262*0ef72598Sjeremylt    v.set_value(0)
263*0ef72598Sjeremylt
264*0ef72598Sjeremylt    inputs = [u]
265*0ef72598Sjeremylt    outputs = [v]
266*0ef72598Sjeremylt    qf.apply(q, inputs, outputs)
267*0ef72598Sjeremylt
268*0ef72598Sjeremylt    with v.array_read() as v_array:
269*0ef72598Sjeremylt        for i in range(q):
270*0ef72598Sjeremylt            assert v_array[i] == i * i
271*0ef72598Sjeremylt
272*0ef72598Sjeremylt# -------------------------------------------------------------------------------
273*0ef72598Sjeremylt# Test creation, evaluation, and destruction of identity qfunction with size>1
274*0ef72598Sjeremylt# -------------------------------------------------------------------------------
275*0ef72598Sjeremylt
276*0ef72598Sjeremylt
277*0ef72598Sjeremyltdef test_412(ceed_resource):
278*0ef72598Sjeremylt    ceed = libceed.Ceed(ceed_resource)
279*0ef72598Sjeremylt
280*0ef72598Sjeremylt    size = 3
281*0ef72598Sjeremylt    qf = ceed.IdentityQFunction(size, libceed.EVAL_INTERP, libceed.EVAL_INTERP)
282*0ef72598Sjeremylt
283*0ef72598Sjeremylt    q = 8
284*0ef72598Sjeremylt
285*0ef72598Sjeremylt    u_array = np.zeros(q * size, dtype="float64")
286*0ef72598Sjeremylt    for i in range(q * size):
287*0ef72598Sjeremylt        u_array[i] = i * i
288*0ef72598Sjeremylt
289*0ef72598Sjeremylt    u = ceed.Vector(q * size)
290*0ef72598Sjeremylt    u.set_array(u_array, cmode=libceed.USE_POINTER)
291*0ef72598Sjeremylt    v = ceed.Vector(q * size)
292*0ef72598Sjeremylt    v.set_value(0)
293*0ef72598Sjeremylt
294*0ef72598Sjeremylt    inputs = [u]
295*0ef72598Sjeremylt    outputs = [v]
296*0ef72598Sjeremylt    qf.apply(q, inputs, outputs)
297*0ef72598Sjeremylt
298*0ef72598Sjeremylt    with v.array_read() as v_array:
299*0ef72598Sjeremylt        for i in range(q * size):
300*0ef72598Sjeremylt            assert v_array[i] == i * i
301*0ef72598Sjeremylt
302*0ef72598Sjeremylt# -------------------------------------------------------------------------------
303*0ef72598Sjeremylt# Test viewing of qfunction by name
304*0ef72598Sjeremylt# -------------------------------------------------------------------------------
305*0ef72598Sjeremylt
306*0ef72598Sjeremylt
307*0ef72598Sjeremyltdef test_413(ceed_resource, capsys):
308*0ef72598Sjeremylt    ceed = libceed.Ceed(ceed_resource)
309*0ef72598Sjeremylt
310*0ef72598Sjeremylt    qf_setup = ceed.QFunctionByName("Mass1DBuild")
311*0ef72598Sjeremylt    qf_mass = ceed.QFunctionByName("MassApply")
312*0ef72598Sjeremylt
313*0ef72598Sjeremylt    print(qf_setup)
314*0ef72598Sjeremylt    print(qf_mass)
315*0ef72598Sjeremylt
316*0ef72598Sjeremylt    stdout, stderr, ref_stdout = check.output(capsys)
317*0ef72598Sjeremylt    assert not stderr
318*0ef72598Sjeremylt    assert stdout == ref_stdout
319*0ef72598Sjeremylt
320*0ef72598Sjeremylt# -------------------------------------------------------------------------------
321