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