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