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 Operator functionality 19*0ef72598Sjeremylt 20*0ef72598Sjeremyltimport os 21*0ef72598Sjeremyltimport libceed 22*0ef72598Sjeremyltimport numpy as np 23*0ef72598Sjeremyltimport check 24*0ef72598Sjeremyltimport buildmats as bm 25*0ef72598Sjeremylt 26*0ef72598SjeremyltTOL = np.finfo(float).eps * 256 27*0ef72598Sjeremylt 28*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 29*0ef72598Sjeremylt# Utility 30*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 31*0ef72598Sjeremylt 32*0ef72598Sjeremylt 33*0ef72598Sjeremyltdef load_qfs_so(): 34*0ef72598Sjeremylt from distutils.sysconfig import get_config_var 35*0ef72598Sjeremylt import ctypes 36*0ef72598Sjeremylt 37*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 38*0ef72598Sjeremylt qfs_so = os.path.join( 39*0ef72598Sjeremylt file_dir, 40*0ef72598Sjeremylt "libceed_qfunctions" + get_config_var("EXT_SUFFIX")) 41*0ef72598Sjeremylt 42*0ef72598Sjeremylt # Load library 43*0ef72598Sjeremylt return ctypes.cdll.LoadLibrary(qfs_so) 44*0ef72598Sjeremylt 45*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 46*0ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator 47*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 48*0ef72598Sjeremylt 49*0ef72598Sjeremylt 50*0ef72598Sjeremyltdef test_500(ceed_resource): 51*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 52*0ef72598Sjeremylt 53*0ef72598Sjeremylt nelem = 15 54*0ef72598Sjeremylt p = 5 55*0ef72598Sjeremylt q = 8 56*0ef72598Sjeremylt nx = nelem + 1 57*0ef72598Sjeremylt nu = nelem * (p - 1) + 1 58*0ef72598Sjeremylt 59*0ef72598Sjeremylt # Vectors 60*0ef72598Sjeremylt x = ceed.Vector(nx) 61*0ef72598Sjeremylt x_array = np.zeros(nx) 62*0ef72598Sjeremylt for i in range(nx): 63*0ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 64*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 65*0ef72598Sjeremylt 66*0ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 67*0ef72598Sjeremylt u = ceed.Vector(nu) 68*0ef72598Sjeremylt v = ceed.Vector(nu) 69*0ef72598Sjeremylt 70*0ef72598Sjeremylt # Restrictions 71*0ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 72*0ef72598Sjeremylt for i in range(nx): 73*0ef72598Sjeremylt indx[2 * i + 0] = i 74*0ef72598Sjeremylt indx[2 * i + 1] = i + 1 75*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 76*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 77*0ef72598Sjeremylt 78*0ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 79*0ef72598Sjeremylt for i in range(nelem): 80*0ef72598Sjeremylt for j in range(p): 81*0ef72598Sjeremylt indu[p * i + j] = i * (p - 1) + j 82*0ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, nu, indu, 83*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 84*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 85*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 86*0ef72598Sjeremylt 87*0ef72598Sjeremylt # Bases 88*0ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 89*0ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS) 90*0ef72598Sjeremylt 91*0ef72598Sjeremylt # QFunctions 92*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 93*0ef72598Sjeremylt qfs = load_qfs_so() 94*0ef72598Sjeremylt 95*0ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 96*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 97*0ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 98*0ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 99*0ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 100*0ef72598Sjeremylt 101*0ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 102*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 103*0ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 104*0ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 105*0ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 106*0ef72598Sjeremylt 107*0ef72598Sjeremylt # Operators 108*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 109*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 110*0ef72598Sjeremylt libceed.VECTOR_NONE) 111*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 112*0ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 113*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 114*0ef72598Sjeremylt 115*0ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 116*0ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 117*0ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 118*0ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 119*0ef72598Sjeremylt 120*0ef72598Sjeremylt # Setup 121*0ef72598Sjeremylt op_setup.apply(x, qdata) 122*0ef72598Sjeremylt 123*0ef72598Sjeremylt # Apply mass matrix 124*0ef72598Sjeremylt u.set_value(0) 125*0ef72598Sjeremylt op_mass.apply(u, v) 126*0ef72598Sjeremylt 127*0ef72598Sjeremylt # Check 128*0ef72598Sjeremylt with v.array_read() as v_array: 129*0ef72598Sjeremylt for i in range(q): 130*0ef72598Sjeremylt assert abs(v_array[i]) < TOL 131*0ef72598Sjeremylt 132*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 133*0ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator 134*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 135*0ef72598Sjeremylt 136*0ef72598Sjeremylt 137*0ef72598Sjeremyltdef test_501(ceed_resource): 138*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 139*0ef72598Sjeremylt 140*0ef72598Sjeremylt nelem = 15 141*0ef72598Sjeremylt p = 5 142*0ef72598Sjeremylt q = 8 143*0ef72598Sjeremylt nx = nelem + 1 144*0ef72598Sjeremylt nu = nelem * (p - 1) + 1 145*0ef72598Sjeremylt 146*0ef72598Sjeremylt # Vectors 147*0ef72598Sjeremylt x = ceed.Vector(nx) 148*0ef72598Sjeremylt x_array = np.zeros(nx) 149*0ef72598Sjeremylt for i in range(nx): 150*0ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 151*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 152*0ef72598Sjeremylt 153*0ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 154*0ef72598Sjeremylt u = ceed.Vector(nu) 155*0ef72598Sjeremylt v = ceed.Vector(nu) 156*0ef72598Sjeremylt 157*0ef72598Sjeremylt # Restrictions 158*0ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 159*0ef72598Sjeremylt for i in range(nx): 160*0ef72598Sjeremylt indx[2 * i + 0] = i 161*0ef72598Sjeremylt indx[2 * i + 1] = i + 1 162*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 163*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 164*0ef72598Sjeremylt 165*0ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 166*0ef72598Sjeremylt for i in range(nelem): 167*0ef72598Sjeremylt for j in range(p): 168*0ef72598Sjeremylt indu[p * i + j] = i * (p - 1) + j 169*0ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, nu, indu, 170*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 171*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 172*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 173*0ef72598Sjeremylt 174*0ef72598Sjeremylt # Bases 175*0ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 176*0ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS) 177*0ef72598Sjeremylt 178*0ef72598Sjeremylt # QFunctions 179*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 180*0ef72598Sjeremylt qfs = load_qfs_so() 181*0ef72598Sjeremylt 182*0ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 183*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 184*0ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 185*0ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 186*0ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 187*0ef72598Sjeremylt 188*0ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 189*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 190*0ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 191*0ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 192*0ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 193*0ef72598Sjeremylt 194*0ef72598Sjeremylt # Operators 195*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 196*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 197*0ef72598Sjeremylt libceed.VECTOR_NONE) 198*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 199*0ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 200*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 201*0ef72598Sjeremylt 202*0ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 203*0ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 204*0ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 205*0ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 206*0ef72598Sjeremylt 207*0ef72598Sjeremylt # Setup 208*0ef72598Sjeremylt op_setup.apply(x, qdata) 209*0ef72598Sjeremylt 210*0ef72598Sjeremylt # Apply mass matrix 211*0ef72598Sjeremylt u.set_value(1.) 212*0ef72598Sjeremylt op_mass.apply(u, v) 213*0ef72598Sjeremylt 214*0ef72598Sjeremylt # Check 215*0ef72598Sjeremylt with v.array_read() as v_array: 216*0ef72598Sjeremylt total = 0.0 217*0ef72598Sjeremylt for i in range(nu): 218*0ef72598Sjeremylt total = total + v_array[i] 219*0ef72598Sjeremylt assert abs(total - 1.0) < TOL 220*0ef72598Sjeremylt 221*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 222*0ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with multiple 223*0ef72598Sjeremylt# components 224*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 225*0ef72598Sjeremylt 226*0ef72598Sjeremylt 227*0ef72598Sjeremyltdef test_502(ceed_resource): 228*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 229*0ef72598Sjeremylt 230*0ef72598Sjeremylt nelem = 15 231*0ef72598Sjeremylt p = 5 232*0ef72598Sjeremylt q = 8 233*0ef72598Sjeremylt nx = nelem + 1 234*0ef72598Sjeremylt nu = nelem * (p - 1) + 1 235*0ef72598Sjeremylt 236*0ef72598Sjeremylt # Vectors 237*0ef72598Sjeremylt x = ceed.Vector(nx) 238*0ef72598Sjeremylt x_array = np.zeros(nx) 239*0ef72598Sjeremylt for i in range(nx): 240*0ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 241*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 242*0ef72598Sjeremylt 243*0ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 244*0ef72598Sjeremylt u = ceed.Vector(2 * nu) 245*0ef72598Sjeremylt v = ceed.Vector(2 * nu) 246*0ef72598Sjeremylt 247*0ef72598Sjeremylt # Restrictions 248*0ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 249*0ef72598Sjeremylt for i in range(nx): 250*0ef72598Sjeremylt indx[2 * i + 0] = i 251*0ef72598Sjeremylt indx[2 * i + 1] = i + 1 252*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 253*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 254*0ef72598Sjeremylt 255*0ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 256*0ef72598Sjeremylt for i in range(nelem): 257*0ef72598Sjeremylt for j in range(p): 258*0ef72598Sjeremylt indu[p * i + j] = 2 * (i * (p - 1) + j) 259*0ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 2, 1, 2 * nu, indu, 260*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 261*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 262*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 263*0ef72598Sjeremylt 264*0ef72598Sjeremylt # Bases 265*0ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 266*0ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 2, p, q, libceed.GAUSS) 267*0ef72598Sjeremylt 268*0ef72598Sjeremylt # QFunctions 269*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 270*0ef72598Sjeremylt qfs = load_qfs_so() 271*0ef72598Sjeremylt 272*0ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 273*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 274*0ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 275*0ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 276*0ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 277*0ef72598Sjeremylt 278*0ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass_two, 279*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass_two")) 280*0ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 281*0ef72598Sjeremylt qf_mass.add_input("u", 2, libceed.EVAL_INTERP) 282*0ef72598Sjeremylt qf_mass.add_output("v", 2, libceed.EVAL_INTERP) 283*0ef72598Sjeremylt 284*0ef72598Sjeremylt # Operators 285*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 286*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 287*0ef72598Sjeremylt libceed.VECTOR_NONE) 288*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 289*0ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 290*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 291*0ef72598Sjeremylt 292*0ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 293*0ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 294*0ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 295*0ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 296*0ef72598Sjeremylt 297*0ef72598Sjeremylt # Setup 298*0ef72598Sjeremylt op_setup.apply(x, qdata) 299*0ef72598Sjeremylt 300*0ef72598Sjeremylt # Apply mass matrix 301*0ef72598Sjeremylt with u.array() as u_array: 302*0ef72598Sjeremylt for i in range(nu): 303*0ef72598Sjeremylt u_array[2 * i] = 1. 304*0ef72598Sjeremylt u_array[2 * i + 1] = 2. 305*0ef72598Sjeremylt op_mass.apply(u, v) 306*0ef72598Sjeremylt 307*0ef72598Sjeremylt # Check 308*0ef72598Sjeremylt with v.array_read() as v_array: 309*0ef72598Sjeremylt total_1 = 0.0 310*0ef72598Sjeremylt total_2 = 0.0 311*0ef72598Sjeremylt for i in range(nu): 312*0ef72598Sjeremylt total_1 = total_1 + v_array[2 * i] 313*0ef72598Sjeremylt total_2 = total_2 + v_array[2 * i + 1] 314*0ef72598Sjeremylt assert abs(total_1 - 1.0) < 1E-13 315*0ef72598Sjeremylt assert abs(total_2 - 2.0) < 1E-13 316*0ef72598Sjeremylt 317*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 318*0ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with passive 319*0ef72598Sjeremylt# inputs and outputs 320*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 321*0ef72598Sjeremylt 322*0ef72598Sjeremylt 323*0ef72598Sjeremyltdef test_503(ceed_resource): 324*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 325*0ef72598Sjeremylt 326*0ef72598Sjeremylt nelem = 15 327*0ef72598Sjeremylt p = 5 328*0ef72598Sjeremylt q = 8 329*0ef72598Sjeremylt nx = nelem + 1 330*0ef72598Sjeremylt nu = nelem * (p - 1) + 1 331*0ef72598Sjeremylt 332*0ef72598Sjeremylt # Vectors 333*0ef72598Sjeremylt x = ceed.Vector(nx) 334*0ef72598Sjeremylt x_array = np.zeros(nx) 335*0ef72598Sjeremylt for i in range(nx): 336*0ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 337*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 338*0ef72598Sjeremylt 339*0ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 340*0ef72598Sjeremylt u = ceed.Vector(nu) 341*0ef72598Sjeremylt v = ceed.Vector(nu) 342*0ef72598Sjeremylt 343*0ef72598Sjeremylt # Restrictions 344*0ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 345*0ef72598Sjeremylt for i in range(nx): 346*0ef72598Sjeremylt indx[2 * i + 0] = i 347*0ef72598Sjeremylt indx[2 * i + 1] = i + 1 348*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 349*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 350*0ef72598Sjeremylt 351*0ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 352*0ef72598Sjeremylt for i in range(nelem): 353*0ef72598Sjeremylt for j in range(p): 354*0ef72598Sjeremylt indu[p * i + j] = i * (p - 1) + j 355*0ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, nu, indu, 356*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 357*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 358*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 359*0ef72598Sjeremylt 360*0ef72598Sjeremylt # Bases 361*0ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 362*0ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS) 363*0ef72598Sjeremylt 364*0ef72598Sjeremylt # QFunctions 365*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 366*0ef72598Sjeremylt qfs = load_qfs_so() 367*0ef72598Sjeremylt 368*0ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 369*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 370*0ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 371*0ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 372*0ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 373*0ef72598Sjeremylt 374*0ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 375*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 376*0ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 377*0ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 378*0ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 379*0ef72598Sjeremylt 380*0ef72598Sjeremylt # Operators 381*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 382*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 383*0ef72598Sjeremylt libceed.VECTOR_NONE) 384*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 385*0ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 386*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 387*0ef72598Sjeremylt 388*0ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 389*0ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 390*0ef72598Sjeremylt op_mass.set_field("u", ru, bu, u) 391*0ef72598Sjeremylt op_mass.set_field("v", ru, bu, v) 392*0ef72598Sjeremylt 393*0ef72598Sjeremylt # Setup 394*0ef72598Sjeremylt op_setup.apply(x, qdata) 395*0ef72598Sjeremylt 396*0ef72598Sjeremylt # Apply mass matrix 397*0ef72598Sjeremylt u.set_value(1) 398*0ef72598Sjeremylt op_mass.apply(libceed.VECTOR_NONE, libceed.VECTOR_NONE) 399*0ef72598Sjeremylt 400*0ef72598Sjeremylt # Check 401*0ef72598Sjeremylt with v.array_read() as v_array: 402*0ef72598Sjeremylt total = 0.0 403*0ef72598Sjeremylt for i in range(nu): 404*0ef72598Sjeremylt total = total + v_array[i] 405*0ef72598Sjeremylt assert abs(total - 1.0) < 1E-13 406*0ef72598Sjeremylt 407*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 408*0ef72598Sjeremylt# Test viewing of mass matrix operator 409*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 410*0ef72598Sjeremylt 411*0ef72598Sjeremylt 412*0ef72598Sjeremyltdef test_504(ceed_resource, capsys): 413*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 414*0ef72598Sjeremylt 415*0ef72598Sjeremylt nelem = 15 416*0ef72598Sjeremylt p = 5 417*0ef72598Sjeremylt q = 8 418*0ef72598Sjeremylt nx = nelem + 1 419*0ef72598Sjeremylt nu = nelem * (p - 1) + 1 420*0ef72598Sjeremylt 421*0ef72598Sjeremylt # Vectors 422*0ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 423*0ef72598Sjeremylt 424*0ef72598Sjeremylt # Restrictions 425*0ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 426*0ef72598Sjeremylt for i in range(nx): 427*0ef72598Sjeremylt indx[2 * i + 0] = i 428*0ef72598Sjeremylt indx[2 * i + 1] = i + 1 429*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 430*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 431*0ef72598Sjeremylt 432*0ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 433*0ef72598Sjeremylt for i in range(nelem): 434*0ef72598Sjeremylt for j in range(p): 435*0ef72598Sjeremylt indu[p * i + j] = i * (p - 1) + j 436*0ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, nu, indu, 437*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 438*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 439*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 440*0ef72598Sjeremylt 441*0ef72598Sjeremylt # Bases 442*0ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 443*0ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS) 444*0ef72598Sjeremylt 445*0ef72598Sjeremylt # QFunctions 446*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 447*0ef72598Sjeremylt qfs = load_qfs_so() 448*0ef72598Sjeremylt 449*0ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 450*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 451*0ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 452*0ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 453*0ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 454*0ef72598Sjeremylt 455*0ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 456*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 457*0ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 458*0ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 459*0ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 460*0ef72598Sjeremylt 461*0ef72598Sjeremylt # Operators 462*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 463*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 464*0ef72598Sjeremylt libceed.VECTOR_NONE) 465*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 466*0ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 467*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 468*0ef72598Sjeremylt 469*0ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 470*0ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 471*0ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 472*0ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 473*0ef72598Sjeremylt 474*0ef72598Sjeremylt # View 475*0ef72598Sjeremylt print(op_setup) 476*0ef72598Sjeremylt print(op_mass) 477*0ef72598Sjeremylt 478*0ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 479*0ef72598Sjeremylt assert not stderr 480*0ef72598Sjeremylt assert stdout == ref_stdout 481*0ef72598Sjeremylt 482*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 483*0ef72598Sjeremylt# Test CeedOperatorApplyAdd 484*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 485*0ef72598Sjeremylt 486*0ef72598Sjeremylt 487*0ef72598Sjeremyltdef test_505(ceed_resource): 488*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 489*0ef72598Sjeremylt 490*0ef72598Sjeremylt nelem = 15 491*0ef72598Sjeremylt p = 5 492*0ef72598Sjeremylt q = 8 493*0ef72598Sjeremylt nx = nelem + 1 494*0ef72598Sjeremylt nu = nelem * (p - 1) + 1 495*0ef72598Sjeremylt 496*0ef72598Sjeremylt # Vectors 497*0ef72598Sjeremylt x = ceed.Vector(nx) 498*0ef72598Sjeremylt x_array = np.zeros(nx) 499*0ef72598Sjeremylt for i in range(nx): 500*0ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 501*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 502*0ef72598Sjeremylt 503*0ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 504*0ef72598Sjeremylt u = ceed.Vector(nu) 505*0ef72598Sjeremylt v = ceed.Vector(nu) 506*0ef72598Sjeremylt 507*0ef72598Sjeremylt # Restrictions 508*0ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 509*0ef72598Sjeremylt for i in range(nx): 510*0ef72598Sjeremylt indx[2 * i + 0] = i 511*0ef72598Sjeremylt indx[2 * i + 1] = i + 1 512*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 513*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 514*0ef72598Sjeremylt 515*0ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 516*0ef72598Sjeremylt for i in range(nelem): 517*0ef72598Sjeremylt for j in range(p): 518*0ef72598Sjeremylt indu[p * i + j] = i * (p - 1) + j 519*0ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, nu, indu, 520*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 521*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 522*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 523*0ef72598Sjeremylt 524*0ef72598Sjeremylt # Bases 525*0ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 526*0ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS) 527*0ef72598Sjeremylt 528*0ef72598Sjeremylt # QFunctions 529*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 530*0ef72598Sjeremylt qfs = load_qfs_so() 531*0ef72598Sjeremylt 532*0ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 533*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 534*0ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 535*0ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 536*0ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 537*0ef72598Sjeremylt 538*0ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 539*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 540*0ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 541*0ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 542*0ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 543*0ef72598Sjeremylt 544*0ef72598Sjeremylt # Operators 545*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 546*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 547*0ef72598Sjeremylt libceed.VECTOR_NONE) 548*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 549*0ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 550*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 551*0ef72598Sjeremylt 552*0ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 553*0ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 554*0ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 555*0ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 556*0ef72598Sjeremylt 557*0ef72598Sjeremylt # Setup 558*0ef72598Sjeremylt op_setup.apply(x, qdata) 559*0ef72598Sjeremylt 560*0ef72598Sjeremylt # Apply mass matrix with v = 0 561*0ef72598Sjeremylt u.set_value(1.) 562*0ef72598Sjeremylt v.set_value(0.) 563*0ef72598Sjeremylt op_mass.apply_add(u, v) 564*0ef72598Sjeremylt 565*0ef72598Sjeremylt # Check 566*0ef72598Sjeremylt with v.array_read() as v_array: 567*0ef72598Sjeremylt total = 0.0 568*0ef72598Sjeremylt for i in range(nu): 569*0ef72598Sjeremylt total = total + v_array[i] 570*0ef72598Sjeremylt assert abs(total - 1.0) < TOL 571*0ef72598Sjeremylt 572*0ef72598Sjeremylt # Apply mass matrix with v = 0 573*0ef72598Sjeremylt v.set_value(1.) 574*0ef72598Sjeremylt op_mass.apply_add(u, v) 575*0ef72598Sjeremylt 576*0ef72598Sjeremylt # Check 577*0ef72598Sjeremylt with v.array_read() as v_array: 578*0ef72598Sjeremylt total = -nu 579*0ef72598Sjeremylt for i in range(nu): 580*0ef72598Sjeremylt total = total + v_array[i] 581*0ef72598Sjeremylt assert abs(total - 1.0) < 1E-10 582*0ef72598Sjeremylt 583*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 584*0ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator 585*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 586*0ef72598Sjeremylt 587*0ef72598Sjeremylt 588*0ef72598Sjeremyltdef test_510(ceed_resource): 589*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 590*0ef72598Sjeremylt 591*0ef72598Sjeremylt nelem = 12 592*0ef72598Sjeremylt dim = 2 593*0ef72598Sjeremylt p = 6 594*0ef72598Sjeremylt q = 4 595*0ef72598Sjeremylt nx, ny = 3, 2 596*0ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 597*0ef72598Sjeremylt nqpts = nelem * q 598*0ef72598Sjeremylt 599*0ef72598Sjeremylt # Vectors 600*0ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 601*0ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 602*0ef72598Sjeremylt for i in range(ndofs): 603*0ef72598Sjeremylt x_array[i] = (1. / (nx * 2)) * (i % (nx * 2 + 1)) 604*0ef72598Sjeremylt x_array[i + ndofs] = (1. / (ny * 2)) * (i / (nx * 2 + 1)) 605*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 606*0ef72598Sjeremylt 607*0ef72598Sjeremylt qdata = ceed.Vector(nqpts) 608*0ef72598Sjeremylt u = ceed.Vector(ndofs) 609*0ef72598Sjeremylt v = ceed.Vector(ndofs) 610*0ef72598Sjeremylt 611*0ef72598Sjeremylt # Restrictions 612*0ef72598Sjeremylt indx = np.zeros(nelem * p, dtype="int32") 613*0ef72598Sjeremylt for i in range(nelem // 2): 614*0ef72598Sjeremylt col = i % nx 615*0ef72598Sjeremylt row = i // nx 616*0ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 617*0ef72598Sjeremylt 618*0ef72598Sjeremylt indx[i * 2 * p + 0] = 2 + offset 619*0ef72598Sjeremylt indx[i * 2 * p + 1] = 9 + offset 620*0ef72598Sjeremylt indx[i * 2 * p + 2] = 16 + offset 621*0ef72598Sjeremylt indx[i * 2 * p + 3] = 1 + offset 622*0ef72598Sjeremylt indx[i * 2 * p + 4] = 8 + offset 623*0ef72598Sjeremylt indx[i * 2 * p + 5] = 0 + offset 624*0ef72598Sjeremylt 625*0ef72598Sjeremylt indx[i * 2 * p + 6] = 14 + offset 626*0ef72598Sjeremylt indx[i * 2 * p + 7] = 7 + offset 627*0ef72598Sjeremylt indx[i * 2 * p + 8] = 0 + offset 628*0ef72598Sjeremylt indx[i * 2 * p + 9] = 15 + offset 629*0ef72598Sjeremylt indx[i * 2 * p + 10] = 8 + offset 630*0ef72598Sjeremylt indx[i * 2 * p + 11] = 16 + offset 631*0ef72598Sjeremylt 632*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, p, dim, ndofs, dim * ndofs, indx, 633*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 634*0ef72598Sjeremylt 635*0ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, ndofs, indx, 636*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 637*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 638*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, nqpts, strides) 639*0ef72598Sjeremylt 640*0ef72598Sjeremylt # Bases 641*0ef72598Sjeremylt qref = np.empty(dim * q, dtype="float64") 642*0ef72598Sjeremylt qweight = np.empty(q, dtype="float64") 643*0ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 644*0ef72598Sjeremylt 645*0ef72598Sjeremylt bx = ceed.BasisH1(libceed.TRIANGLE, dim, p, q, interp, grad, qref, qweight) 646*0ef72598Sjeremylt bu = ceed.BasisH1(libceed.TRIANGLE, 1, p, q, interp, grad, qref, qweight) 647*0ef72598Sjeremylt 648*0ef72598Sjeremylt # QFunctions 649*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 650*0ef72598Sjeremylt qfs = load_qfs_so() 651*0ef72598Sjeremylt 652*0ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass_2d, 653*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 654*0ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 655*0ef72598Sjeremylt qf_setup.add_input("dx", dim * dim, libceed.EVAL_GRAD) 656*0ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 657*0ef72598Sjeremylt 658*0ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 659*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 660*0ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 661*0ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 662*0ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 663*0ef72598Sjeremylt 664*0ef72598Sjeremylt # Operators 665*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 666*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 667*0ef72598Sjeremylt libceed.VECTOR_NONE) 668*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 669*0ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 670*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 671*0ef72598Sjeremylt 672*0ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 673*0ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 674*0ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 675*0ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 676*0ef72598Sjeremylt 677*0ef72598Sjeremylt # Setup 678*0ef72598Sjeremylt op_setup.apply(x, qdata) 679*0ef72598Sjeremylt 680*0ef72598Sjeremylt # Apply mass matrix 681*0ef72598Sjeremylt u.set_value(0.) 682*0ef72598Sjeremylt op_mass.apply(u, v) 683*0ef72598Sjeremylt 684*0ef72598Sjeremylt # Check 685*0ef72598Sjeremylt with v.array_read() as v_array: 686*0ef72598Sjeremylt for i in range(ndofs): 687*0ef72598Sjeremylt assert abs(v_array[i]) < TOL 688*0ef72598Sjeremylt 689*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 690*0ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator 691*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 692*0ef72598Sjeremylt 693*0ef72598Sjeremylt 694*0ef72598Sjeremyltdef test_511(ceed_resource): 695*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 696*0ef72598Sjeremylt 697*0ef72598Sjeremylt nelem = 12 698*0ef72598Sjeremylt dim = 2 699*0ef72598Sjeremylt p = 6 700*0ef72598Sjeremylt q = 4 701*0ef72598Sjeremylt nx, ny = 3, 2 702*0ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 703*0ef72598Sjeremylt nqpts = nelem * q 704*0ef72598Sjeremylt 705*0ef72598Sjeremylt # Vectors 706*0ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 707*0ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 708*0ef72598Sjeremylt for i in range(ndofs): 709*0ef72598Sjeremylt x_array[i] = (1. / (nx * 2)) * (i % (nx * 2 + 1)) 710*0ef72598Sjeremylt x_array[i + ndofs] = (1. / (ny * 2)) * (i / (nx * 2 + 1)) 711*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 712*0ef72598Sjeremylt 713*0ef72598Sjeremylt qdata = ceed.Vector(nqpts) 714*0ef72598Sjeremylt u = ceed.Vector(ndofs) 715*0ef72598Sjeremylt v = ceed.Vector(ndofs) 716*0ef72598Sjeremylt 717*0ef72598Sjeremylt # Restrictions 718*0ef72598Sjeremylt indx = np.zeros(nelem * p, dtype="int32") 719*0ef72598Sjeremylt for i in range(nelem // 2): 720*0ef72598Sjeremylt col = i % nx 721*0ef72598Sjeremylt row = i // nx 722*0ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 723*0ef72598Sjeremylt 724*0ef72598Sjeremylt indx[i * 2 * p + 0] = 2 + offset 725*0ef72598Sjeremylt indx[i * 2 * p + 1] = 9 + offset 726*0ef72598Sjeremylt indx[i * 2 * p + 2] = 16 + offset 727*0ef72598Sjeremylt indx[i * 2 * p + 3] = 1 + offset 728*0ef72598Sjeremylt indx[i * 2 * p + 4] = 8 + offset 729*0ef72598Sjeremylt indx[i * 2 * p + 5] = 0 + offset 730*0ef72598Sjeremylt 731*0ef72598Sjeremylt indx[i * 2 * p + 6] = 14 + offset 732*0ef72598Sjeremylt indx[i * 2 * p + 7] = 7 + offset 733*0ef72598Sjeremylt indx[i * 2 * p + 8] = 0 + offset 734*0ef72598Sjeremylt indx[i * 2 * p + 9] = 15 + offset 735*0ef72598Sjeremylt indx[i * 2 * p + 10] = 8 + offset 736*0ef72598Sjeremylt indx[i * 2 * p + 11] = 16 + offset 737*0ef72598Sjeremylt 738*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, p, dim, ndofs, dim * ndofs, indx, 739*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 740*0ef72598Sjeremylt 741*0ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, ndofs, indx, 742*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 743*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 744*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, nqpts, strides) 745*0ef72598Sjeremylt 746*0ef72598Sjeremylt # Bases 747*0ef72598Sjeremylt qref = np.empty(dim * q, dtype="float64") 748*0ef72598Sjeremylt qweight = np.empty(q, dtype="float64") 749*0ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 750*0ef72598Sjeremylt 751*0ef72598Sjeremylt bx = ceed.BasisH1(libceed.TRIANGLE, dim, p, q, interp, grad, qref, qweight) 752*0ef72598Sjeremylt bu = ceed.BasisH1(libceed.TRIANGLE, 1, p, q, interp, grad, qref, qweight) 753*0ef72598Sjeremylt 754*0ef72598Sjeremylt # QFunctions 755*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 756*0ef72598Sjeremylt qfs = load_qfs_so() 757*0ef72598Sjeremylt 758*0ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass_2d, 759*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 760*0ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 761*0ef72598Sjeremylt qf_setup.add_input("dx", dim * dim, libceed.EVAL_GRAD) 762*0ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 763*0ef72598Sjeremylt 764*0ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 765*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 766*0ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 767*0ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 768*0ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 769*0ef72598Sjeremylt 770*0ef72598Sjeremylt # Operators 771*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 772*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 773*0ef72598Sjeremylt libceed.VECTOR_NONE) 774*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 775*0ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 776*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 777*0ef72598Sjeremylt 778*0ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 779*0ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 780*0ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 781*0ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 782*0ef72598Sjeremylt 783*0ef72598Sjeremylt # Setup 784*0ef72598Sjeremylt op_setup.apply(x, qdata) 785*0ef72598Sjeremylt 786*0ef72598Sjeremylt # Apply mass matrix 787*0ef72598Sjeremylt u.set_value(1.) 788*0ef72598Sjeremylt op_mass.apply(u, v) 789*0ef72598Sjeremylt 790*0ef72598Sjeremylt # Check 791*0ef72598Sjeremylt with v.array_read() as v_array: 792*0ef72598Sjeremylt total = 0.0 793*0ef72598Sjeremylt for i in range(ndofs): 794*0ef72598Sjeremylt total = total + v_array[i] 795*0ef72598Sjeremylt assert abs(total - 1.0) < 1E-10 796*0ef72598Sjeremylt 797*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 798*0ef72598Sjeremylt# Test creation, action, and destruction for composite mass matrix operator 799*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 800*0ef72598Sjeremylt 801*0ef72598Sjeremylt 802*0ef72598Sjeremyltdef test_520(ceed_resource): 803*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 804*0ef72598Sjeremylt 805*0ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 806*0ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 807*0ef72598Sjeremylt nx, ny = 3, 3 808*0ef72598Sjeremylt dim = 2 809*0ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 810*0ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 811*0ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 812*0ef72598Sjeremylt 813*0ef72598Sjeremylt # Vectors 814*0ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 815*0ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 816*0ef72598Sjeremylt for i in range(ny * 2 + 1): 817*0ef72598Sjeremylt for j in range(nx * 2 + 1): 818*0ef72598Sjeremylt x_array[i + j * (ny * 2 + 1)] = i / (2 * ny) 819*0ef72598Sjeremylt x_array[i + j * (ny * 2 + 1) + ndofs] = j / (2 * nx) 820*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 821*0ef72598Sjeremylt 822*0ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 823*0ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 824*0ef72598Sjeremylt u = ceed.Vector(ndofs) 825*0ef72598Sjeremylt v = ceed.Vector(ndofs) 826*0ef72598Sjeremylt 827*0ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 828*0ef72598Sjeremylt 829*0ef72598Sjeremylt # Restrictions 830*0ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 831*0ef72598Sjeremylt for i in range(nelem_tet // 2): 832*0ef72598Sjeremylt col = i % nx 833*0ef72598Sjeremylt row = i // nx 834*0ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 835*0ef72598Sjeremylt 836*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 837*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 838*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 839*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 840*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 841*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 842*0ef72598Sjeremylt 843*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 844*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 845*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 846*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 847*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 848*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 849*0ef72598Sjeremylt 850*0ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 851*0ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 852*0ef72598Sjeremylt 853*0ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 854*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 855*0ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 856*0ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 857*0ef72598Sjeremylt strides) 858*0ef72598Sjeremylt 859*0ef72598Sjeremylt # Bases 860*0ef72598Sjeremylt qref = np.empty(dim * q_tet, dtype="float64") 861*0ef72598Sjeremylt qweight = np.empty(q_tet, dtype="float64") 862*0ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 863*0ef72598Sjeremylt 864*0ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 865*0ef72598Sjeremylt qweight) 866*0ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 867*0ef72598Sjeremylt qweight) 868*0ef72598Sjeremylt 869*0ef72598Sjeremylt # QFunctions 870*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 871*0ef72598Sjeremylt qfs = load_qfs_so() 872*0ef72598Sjeremylt 873*0ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 874*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 875*0ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 876*0ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 877*0ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 878*0ef72598Sjeremylt 879*0ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 880*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 881*0ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 882*0ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 883*0ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 884*0ef72598Sjeremylt 885*0ef72598Sjeremylt # Operators 886*0ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 887*0ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 888*0ef72598Sjeremylt libceed.VECTOR_NONE) 889*0ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 890*0ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 891*0ef72598Sjeremylt qdata_tet) 892*0ef72598Sjeremylt 893*0ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 894*0ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 895*0ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 896*0ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 897*0ef72598Sjeremylt 898*0ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 899*0ef72598Sjeremylt 900*0ef72598Sjeremylt # Restrictions 901*0ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 902*0ef72598Sjeremylt for i in range(nelem_hex): 903*0ef72598Sjeremylt col = i % nx_hex 904*0ef72598Sjeremylt row = i // nx_hex 905*0ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 906*0ef72598Sjeremylt 907*0ef72598Sjeremylt for j in range(p_hex): 908*0ef72598Sjeremylt for k in range(p_hex): 909*0ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 910*0ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 911*0ef72598Sjeremylt 912*0ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 913*0ef72598Sjeremylt dim * ndofs, indx_hex, cmode=libceed.USE_POINTER) 914*0ef72598Sjeremylt 915*0ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 916*0ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 917*0ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 918*0ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 919*0ef72598Sjeremylt nqpts_hex, strides) 920*0ef72598Sjeremylt 921*0ef72598Sjeremylt # Bases 922*0ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 923*0ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 924*0ef72598Sjeremylt 925*0ef72598Sjeremylt # QFunctions 926*0ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 927*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 928*0ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 929*0ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 930*0ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 931*0ef72598Sjeremylt 932*0ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 933*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 934*0ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 935*0ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 936*0ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 937*0ef72598Sjeremylt 938*0ef72598Sjeremylt # Operators 939*0ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 940*0ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 941*0ef72598Sjeremylt libceed.VECTOR_NONE) 942*0ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 943*0ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 944*0ef72598Sjeremylt qdata_hex) 945*0ef72598Sjeremylt 946*0ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 947*0ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 948*0ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 949*0ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 950*0ef72598Sjeremylt 951*0ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 952*0ef72598Sjeremylt 953*0ef72598Sjeremylt # Setup 954*0ef72598Sjeremylt op_setup = ceed.CompositeOperator() 955*0ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 956*0ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 957*0ef72598Sjeremylt op_setup.apply(x, libceed.VECTOR_NONE) 958*0ef72598Sjeremylt 959*0ef72598Sjeremylt # Apply mass matrix 960*0ef72598Sjeremylt op_mass = ceed.CompositeOperator() 961*0ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 962*0ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 963*0ef72598Sjeremylt 964*0ef72598Sjeremylt u.set_value(0.) 965*0ef72598Sjeremylt op_mass.apply(u, v) 966*0ef72598Sjeremylt 967*0ef72598Sjeremylt # Check 968*0ef72598Sjeremylt with v.array_read() as v_array: 969*0ef72598Sjeremylt for i in range(ndofs): 970*0ef72598Sjeremylt assert abs(v_array[i]) < TOL 971*0ef72598Sjeremylt 972*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 973*0ef72598Sjeremylt# Test creation, action, and destruction for composite mass matrix operator 974*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 975*0ef72598Sjeremylt 976*0ef72598Sjeremylt 977*0ef72598Sjeremyltdef test_521(ceed_resource): 978*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 979*0ef72598Sjeremylt 980*0ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 981*0ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 982*0ef72598Sjeremylt nx, ny = 3, 3 983*0ef72598Sjeremylt dim = 2 984*0ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 985*0ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 986*0ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 987*0ef72598Sjeremylt 988*0ef72598Sjeremylt # Vectors 989*0ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 990*0ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 991*0ef72598Sjeremylt for i in range(ny * 2 + 1): 992*0ef72598Sjeremylt for j in range(nx * 2 + 1): 993*0ef72598Sjeremylt x_array[i + j * (ny * 2 + 1)] = i / (2 * ny) 994*0ef72598Sjeremylt x_array[i + j * (ny * 2 + 1) + ndofs] = j / (2 * nx) 995*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 996*0ef72598Sjeremylt 997*0ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 998*0ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 999*0ef72598Sjeremylt u = ceed.Vector(ndofs) 1000*0ef72598Sjeremylt v = ceed.Vector(ndofs) 1001*0ef72598Sjeremylt 1002*0ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 1003*0ef72598Sjeremylt 1004*0ef72598Sjeremylt # Restrictions 1005*0ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 1006*0ef72598Sjeremylt for i in range(nelem_tet // 2): 1007*0ef72598Sjeremylt col = i % nx 1008*0ef72598Sjeremylt row = i // nx 1009*0ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 1010*0ef72598Sjeremylt 1011*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 1012*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 1013*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 1014*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 1015*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 1016*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 1017*0ef72598Sjeremylt 1018*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 1019*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 1020*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 1021*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 1022*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 1023*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 1024*0ef72598Sjeremylt 1025*0ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 1026*0ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 1027*0ef72598Sjeremylt 1028*0ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 1029*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1030*0ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 1031*0ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 1032*0ef72598Sjeremylt strides) 1033*0ef72598Sjeremylt 1034*0ef72598Sjeremylt # Bases 1035*0ef72598Sjeremylt qref = np.empty(dim * q_tet, dtype="float64") 1036*0ef72598Sjeremylt qweight = np.empty(q_tet, dtype="float64") 1037*0ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 1038*0ef72598Sjeremylt 1039*0ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 1040*0ef72598Sjeremylt qweight) 1041*0ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 1042*0ef72598Sjeremylt qweight) 1043*0ef72598Sjeremylt 1044*0ef72598Sjeremylt # QFunctions 1045*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 1046*0ef72598Sjeremylt qfs = load_qfs_so() 1047*0ef72598Sjeremylt 1048*0ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 1049*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 1050*0ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 1051*0ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 1052*0ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 1053*0ef72598Sjeremylt 1054*0ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 1055*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 1056*0ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 1057*0ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 1058*0ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 1059*0ef72598Sjeremylt 1060*0ef72598Sjeremylt # Operators 1061*0ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 1062*0ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 1063*0ef72598Sjeremylt libceed.VECTOR_NONE) 1064*0ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 1065*0ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 1066*0ef72598Sjeremylt qdata_tet) 1067*0ef72598Sjeremylt 1068*0ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 1069*0ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 1070*0ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 1071*0ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 1072*0ef72598Sjeremylt 1073*0ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 1074*0ef72598Sjeremylt 1075*0ef72598Sjeremylt # Restrictions 1076*0ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 1077*0ef72598Sjeremylt for i in range(nelem_hex): 1078*0ef72598Sjeremylt col = i % nx_hex 1079*0ef72598Sjeremylt row = i // nx_hex 1080*0ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 1081*0ef72598Sjeremylt 1082*0ef72598Sjeremylt for j in range(p_hex): 1083*0ef72598Sjeremylt for k in range(p_hex): 1084*0ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 1085*0ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 1086*0ef72598Sjeremylt 1087*0ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 1088*0ef72598Sjeremylt dim * ndofs, indx_hex, cmode=libceed.USE_POINTER) 1089*0ef72598Sjeremylt 1090*0ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 1091*0ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 1092*0ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 1093*0ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 1094*0ef72598Sjeremylt nqpts_hex, strides) 1095*0ef72598Sjeremylt 1096*0ef72598Sjeremylt # Bases 1097*0ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 1098*0ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 1099*0ef72598Sjeremylt 1100*0ef72598Sjeremylt # QFunctions 1101*0ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 1102*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 1103*0ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 1104*0ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 1105*0ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 1106*0ef72598Sjeremylt 1107*0ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 1108*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 1109*0ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 1110*0ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 1111*0ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 1112*0ef72598Sjeremylt 1113*0ef72598Sjeremylt # Operators 1114*0ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 1115*0ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 1116*0ef72598Sjeremylt libceed.VECTOR_NONE) 1117*0ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 1118*0ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 1119*0ef72598Sjeremylt qdata_hex) 1120*0ef72598Sjeremylt 1121*0ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 1122*0ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 1123*0ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 1124*0ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 1125*0ef72598Sjeremylt 1126*0ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 1127*0ef72598Sjeremylt 1128*0ef72598Sjeremylt # Setup 1129*0ef72598Sjeremylt op_setup = ceed.CompositeOperator() 1130*0ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 1131*0ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 1132*0ef72598Sjeremylt op_setup.apply(x, libceed.VECTOR_NONE) 1133*0ef72598Sjeremylt 1134*0ef72598Sjeremylt # Apply mass matrix 1135*0ef72598Sjeremylt op_mass = ceed.CompositeOperator() 1136*0ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 1137*0ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 1138*0ef72598Sjeremylt u.set_value(1.) 1139*0ef72598Sjeremylt op_mass.apply(u, v) 1140*0ef72598Sjeremylt 1141*0ef72598Sjeremylt # Check 1142*0ef72598Sjeremylt with v.array_read() as v_array: 1143*0ef72598Sjeremylt total = 0.0 1144*0ef72598Sjeremylt for i in range(ndofs): 1145*0ef72598Sjeremylt total = total + v_array[i] 1146*0ef72598Sjeremylt assert abs(total - 1.0) < 1E-10 1147*0ef72598Sjeremylt 1148*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1149*0ef72598Sjeremylt# Test viewing of composite mass matrix operator 1150*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1151*0ef72598Sjeremylt 1152*0ef72598Sjeremylt 1153*0ef72598Sjeremyltdef test_523(ceed_resource, capsys): 1154*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1155*0ef72598Sjeremylt 1156*0ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 1157*0ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 1158*0ef72598Sjeremylt nx, ny = 3, 3 1159*0ef72598Sjeremylt dim = 2 1160*0ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 1161*0ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 1162*0ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 1163*0ef72598Sjeremylt 1164*0ef72598Sjeremylt # Vectors 1165*0ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 1166*0ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 1167*0ef72598Sjeremylt 1168*0ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 1169*0ef72598Sjeremylt 1170*0ef72598Sjeremylt # Restrictions 1171*0ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 1172*0ef72598Sjeremylt for i in range(nelem_tet // 2): 1173*0ef72598Sjeremylt col = i % nx 1174*0ef72598Sjeremylt row = i // nx 1175*0ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 1176*0ef72598Sjeremylt 1177*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 1178*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 1179*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 1180*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 1181*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 1182*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 1183*0ef72598Sjeremylt 1184*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 1185*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 1186*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 1187*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 1188*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 1189*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 1190*0ef72598Sjeremylt 1191*0ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 1192*0ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 1193*0ef72598Sjeremylt 1194*0ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 1195*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1196*0ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 1197*0ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 1198*0ef72598Sjeremylt strides) 1199*0ef72598Sjeremylt 1200*0ef72598Sjeremylt # Bases 1201*0ef72598Sjeremylt qref = np.empty(dim * q_tet, dtype="float64") 1202*0ef72598Sjeremylt qweight = np.empty(q_tet, dtype="float64") 1203*0ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 1204*0ef72598Sjeremylt 1205*0ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 1206*0ef72598Sjeremylt qweight) 1207*0ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 1208*0ef72598Sjeremylt qweight) 1209*0ef72598Sjeremylt 1210*0ef72598Sjeremylt # QFunctions 1211*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 1212*0ef72598Sjeremylt qfs = load_qfs_so() 1213*0ef72598Sjeremylt 1214*0ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 1215*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 1216*0ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 1217*0ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 1218*0ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 1219*0ef72598Sjeremylt 1220*0ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 1221*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 1222*0ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 1223*0ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 1224*0ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 1225*0ef72598Sjeremylt 1226*0ef72598Sjeremylt # Operators 1227*0ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 1228*0ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 1229*0ef72598Sjeremylt libceed.VECTOR_NONE) 1230*0ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 1231*0ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 1232*0ef72598Sjeremylt qdata_tet) 1233*0ef72598Sjeremylt 1234*0ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 1235*0ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 1236*0ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 1237*0ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 1238*0ef72598Sjeremylt 1239*0ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 1240*0ef72598Sjeremylt 1241*0ef72598Sjeremylt # Restrictions 1242*0ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 1243*0ef72598Sjeremylt for i in range(nelem_hex): 1244*0ef72598Sjeremylt col = i % nx_hex 1245*0ef72598Sjeremylt row = i // nx_hex 1246*0ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 1247*0ef72598Sjeremylt 1248*0ef72598Sjeremylt for j in range(p_hex): 1249*0ef72598Sjeremylt for k in range(p_hex): 1250*0ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 1251*0ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 1252*0ef72598Sjeremylt 1253*0ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 1254*0ef72598Sjeremylt dim * ndofs, indx_hex, 1255*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1256*0ef72598Sjeremylt 1257*0ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 1258*0ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 1259*0ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 1260*0ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 1261*0ef72598Sjeremylt nqpts_hex, strides) 1262*0ef72598Sjeremylt 1263*0ef72598Sjeremylt # Bases 1264*0ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 1265*0ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 1266*0ef72598Sjeremylt 1267*0ef72598Sjeremylt # QFunctions 1268*0ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 1269*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 1270*0ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 1271*0ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 1272*0ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 1273*0ef72598Sjeremylt 1274*0ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 1275*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 1276*0ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 1277*0ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 1278*0ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 1279*0ef72598Sjeremylt 1280*0ef72598Sjeremylt # Operators 1281*0ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 1282*0ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 1283*0ef72598Sjeremylt libceed.VECTOR_NONE) 1284*0ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 1285*0ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 1286*0ef72598Sjeremylt qdata_hex) 1287*0ef72598Sjeremylt 1288*0ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 1289*0ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 1290*0ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 1291*0ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 1292*0ef72598Sjeremylt 1293*0ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 1294*0ef72598Sjeremylt 1295*0ef72598Sjeremylt # Setup 1296*0ef72598Sjeremylt op_setup = ceed.CompositeOperator() 1297*0ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 1298*0ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 1299*0ef72598Sjeremylt 1300*0ef72598Sjeremylt # Apply mass matrix 1301*0ef72598Sjeremylt op_mass = ceed.CompositeOperator() 1302*0ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 1303*0ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 1304*0ef72598Sjeremylt 1305*0ef72598Sjeremylt # View 1306*0ef72598Sjeremylt print(op_setup) 1307*0ef72598Sjeremylt print(op_mass) 1308*0ef72598Sjeremylt 1309*0ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 1310*0ef72598Sjeremylt assert not stderr 1311*0ef72598Sjeremylt assert stdout == ref_stdout 1312*0ef72598Sjeremylt 1313*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1314*0ef72598Sjeremylt# CeedOperatorApplyAdd for composite operator 1315*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1316*0ef72598Sjeremylt 1317*0ef72598Sjeremylt 1318*0ef72598Sjeremyltdef test_524(ceed_resource): 1319*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1320*0ef72598Sjeremylt 1321*0ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 1322*0ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 1323*0ef72598Sjeremylt nx, ny = 3, 3 1324*0ef72598Sjeremylt dim = 2 1325*0ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 1326*0ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 1327*0ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 1328*0ef72598Sjeremylt 1329*0ef72598Sjeremylt # Vectors 1330*0ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 1331*0ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 1332*0ef72598Sjeremylt for i in range(ny * 2 + 1): 1333*0ef72598Sjeremylt for j in range(nx * 2 + 1): 1334*0ef72598Sjeremylt x_array[i + j * (ny * 2 + 1)] = i / (2 * ny) 1335*0ef72598Sjeremylt x_array[i + j * (ny * 2 + 1) + ndofs] = j / (2 * nx) 1336*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 1337*0ef72598Sjeremylt 1338*0ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 1339*0ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 1340*0ef72598Sjeremylt u = ceed.Vector(ndofs) 1341*0ef72598Sjeremylt v = ceed.Vector(ndofs) 1342*0ef72598Sjeremylt 1343*0ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 1344*0ef72598Sjeremylt 1345*0ef72598Sjeremylt # Restrictions 1346*0ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 1347*0ef72598Sjeremylt for i in range(nelem_tet // 2): 1348*0ef72598Sjeremylt col = i % nx 1349*0ef72598Sjeremylt row = i // nx 1350*0ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 1351*0ef72598Sjeremylt 1352*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 1353*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 1354*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 1355*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 1356*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 1357*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 1358*0ef72598Sjeremylt 1359*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 1360*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 1361*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 1362*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 1363*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 1364*0ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 1365*0ef72598Sjeremylt 1366*0ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 1367*0ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 1368*0ef72598Sjeremylt 1369*0ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 1370*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1371*0ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 1372*0ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 1373*0ef72598Sjeremylt strides) 1374*0ef72598Sjeremylt 1375*0ef72598Sjeremylt # Bases 1376*0ef72598Sjeremylt qref = np.empty(dim * q_tet, dtype="float64") 1377*0ef72598Sjeremylt qweight = np.empty(q_tet, dtype="float64") 1378*0ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 1379*0ef72598Sjeremylt 1380*0ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 1381*0ef72598Sjeremylt qweight) 1382*0ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 1383*0ef72598Sjeremylt qweight) 1384*0ef72598Sjeremylt 1385*0ef72598Sjeremylt # QFunctions 1386*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 1387*0ef72598Sjeremylt qfs = load_qfs_so() 1388*0ef72598Sjeremylt 1389*0ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 1390*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 1391*0ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 1392*0ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 1393*0ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 1394*0ef72598Sjeremylt 1395*0ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 1396*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 1397*0ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 1398*0ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 1399*0ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 1400*0ef72598Sjeremylt 1401*0ef72598Sjeremylt # Operators 1402*0ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 1403*0ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 1404*0ef72598Sjeremylt libceed.VECTOR_NONE) 1405*0ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 1406*0ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 1407*0ef72598Sjeremylt qdata_tet) 1408*0ef72598Sjeremylt 1409*0ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 1410*0ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 1411*0ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 1412*0ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 1413*0ef72598Sjeremylt 1414*0ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 1415*0ef72598Sjeremylt 1416*0ef72598Sjeremylt # Restrictions 1417*0ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 1418*0ef72598Sjeremylt for i in range(nelem_hex): 1419*0ef72598Sjeremylt col = i % nx_hex 1420*0ef72598Sjeremylt row = i // nx_hex 1421*0ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 1422*0ef72598Sjeremylt 1423*0ef72598Sjeremylt for j in range(p_hex): 1424*0ef72598Sjeremylt for k in range(p_hex): 1425*0ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 1426*0ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 1427*0ef72598Sjeremylt 1428*0ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 1429*0ef72598Sjeremylt dim * ndofs, indx_hex, 1430*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1431*0ef72598Sjeremylt 1432*0ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 1433*0ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 1434*0ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 1435*0ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 1436*0ef72598Sjeremylt nqpts_hex, strides) 1437*0ef72598Sjeremylt 1438*0ef72598Sjeremylt # Bases 1439*0ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 1440*0ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 1441*0ef72598Sjeremylt 1442*0ef72598Sjeremylt # QFunctions 1443*0ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 1444*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 1445*0ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 1446*0ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 1447*0ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 1448*0ef72598Sjeremylt 1449*0ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 1450*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 1451*0ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 1452*0ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 1453*0ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 1454*0ef72598Sjeremylt 1455*0ef72598Sjeremylt # Operators 1456*0ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 1457*0ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 1458*0ef72598Sjeremylt libceed.VECTOR_NONE) 1459*0ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 1460*0ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 1461*0ef72598Sjeremylt qdata_hex) 1462*0ef72598Sjeremylt 1463*0ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 1464*0ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 1465*0ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 1466*0ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 1467*0ef72598Sjeremylt 1468*0ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 1469*0ef72598Sjeremylt 1470*0ef72598Sjeremylt # Setup 1471*0ef72598Sjeremylt op_setup = ceed.CompositeOperator() 1472*0ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 1473*0ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 1474*0ef72598Sjeremylt op_setup.apply(x, libceed.VECTOR_NONE) 1475*0ef72598Sjeremylt 1476*0ef72598Sjeremylt # Apply mass matrix 1477*0ef72598Sjeremylt op_mass = ceed.CompositeOperator() 1478*0ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 1479*0ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 1480*0ef72598Sjeremylt u.set_value(1.) 1481*0ef72598Sjeremylt op_mass.apply(u, v) 1482*0ef72598Sjeremylt 1483*0ef72598Sjeremylt # Check 1484*0ef72598Sjeremylt with v.array_read() as v_array: 1485*0ef72598Sjeremylt total = 0.0 1486*0ef72598Sjeremylt for i in range(ndofs): 1487*0ef72598Sjeremylt total = total + v_array[i] 1488*0ef72598Sjeremylt assert abs(total - 1.0) < 1E-10 1489*0ef72598Sjeremylt 1490*0ef72598Sjeremylt # ApplyAdd mass matrix 1491*0ef72598Sjeremylt v.set_value(1.) 1492*0ef72598Sjeremylt op_mass.apply_add(u, v) 1493*0ef72598Sjeremylt 1494*0ef72598Sjeremylt # Check 1495*0ef72598Sjeremylt with v.array_read() as v_array: 1496*0ef72598Sjeremylt total = -ndofs 1497*0ef72598Sjeremylt for i in range(ndofs): 1498*0ef72598Sjeremylt total = total + v_array[i] 1499*0ef72598Sjeremylt assert abs(total - 1.0) < 1E-10 1500*0ef72598Sjeremylt 1501*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1502*0ef72598Sjeremylt# Test assembly of mass matrix operator diagonal 1503*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1504*0ef72598Sjeremylt 1505*0ef72598Sjeremylt 1506*0ef72598Sjeremyltdef test_533(ceed_resource): 1507*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1508*0ef72598Sjeremylt 1509*0ef72598Sjeremylt nelem = 6 1510*0ef72598Sjeremylt p = 3 1511*0ef72598Sjeremylt q = 4 1512*0ef72598Sjeremylt dim = 2 1513*0ef72598Sjeremylt nx = 3 1514*0ef72598Sjeremylt ny = 2 1515*0ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 1516*0ef72598Sjeremylt nqpts = nelem * q * q 1517*0ef72598Sjeremylt 1518*0ef72598Sjeremylt # Vectors 1519*0ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 1520*0ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 1521*0ef72598Sjeremylt for i in range(nx * 2 + 1): 1522*0ef72598Sjeremylt for j in range(ny * 2 + 1): 1523*0ef72598Sjeremylt x_array[i + j * (nx * 2 + 1) + 0 * ndofs] = i / (2 * nx) 1524*0ef72598Sjeremylt x_array[i + j * (nx * 2 + 1) + 1 * ndofs] = j / (2 * ny) 1525*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 1526*0ef72598Sjeremylt 1527*0ef72598Sjeremylt qdata = ceed.Vector(nqpts) 1528*0ef72598Sjeremylt u = ceed.Vector(ndofs) 1529*0ef72598Sjeremylt v = ceed.Vector(ndofs) 1530*0ef72598Sjeremylt 1531*0ef72598Sjeremylt # Restrictions 1532*0ef72598Sjeremylt indx = np.zeros(nelem * p * p, dtype="int32") 1533*0ef72598Sjeremylt for i in range(nelem): 1534*0ef72598Sjeremylt col = i % nx 1535*0ef72598Sjeremylt row = i // nx 1536*0ef72598Sjeremylt offset = col * (p - 1) + row * (nx * 2 + 1) * (p - 1) 1537*0ef72598Sjeremylt for j in range(p): 1538*0ef72598Sjeremylt for k in range(p): 1539*0ef72598Sjeremylt indx[p * (p * i + k) + j] = offset + k * (nx * 2 + 1) + j 1540*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, p * p, dim, ndofs, dim * ndofs, 1541*0ef72598Sjeremylt indx, cmode=libceed.USE_POINTER) 1542*0ef72598Sjeremylt 1543*0ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p * p, 1, 1, ndofs, indx, 1544*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1545*0ef72598Sjeremylt strides = np.array([1, q * q, q * q], dtype="int32") 1546*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q * q, 1, nqpts, strides) 1547*0ef72598Sjeremylt 1548*0ef72598Sjeremylt # Bases 1549*0ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(dim, dim, p, q, libceed.GAUSS) 1550*0ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(dim, 1, p, q, libceed.GAUSS) 1551*0ef72598Sjeremylt 1552*0ef72598Sjeremylt # QFunctions 1553*0ef72598Sjeremylt qf_setup = ceed.QFunctionByName("Mass2DBuild") 1554*0ef72598Sjeremylt 1555*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1556*0ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 1557*0ef72598Sjeremylt# multigrid level, tensor basis and interpolation basis generation 1558*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1559*0ef72598Sjeremylt 1560*0ef72598Sjeremylt 1561*0ef72598Sjeremyltdef test_550(ceed_resource): 1562*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1563*0ef72598Sjeremylt 1564*0ef72598Sjeremylt nelem = 15 1565*0ef72598Sjeremylt p_coarse = 3 1566*0ef72598Sjeremylt p_fine = 5 1567*0ef72598Sjeremylt q = 8 1568*0ef72598Sjeremylt ncomp = 2 1569*0ef72598Sjeremylt nx = nelem + 1 1570*0ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 1571*0ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 1572*0ef72598Sjeremylt 1573*0ef72598Sjeremylt # Vectors 1574*0ef72598Sjeremylt x = ceed.Vector(nx) 1575*0ef72598Sjeremylt x_array = np.zeros(nx) 1576*0ef72598Sjeremylt for i in range(nx): 1577*0ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 1578*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 1579*0ef72598Sjeremylt 1580*0ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 1581*0ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 1582*0ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 1583*0ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 1584*0ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 1585*0ef72598Sjeremylt 1586*0ef72598Sjeremylt # Restrictions 1587*0ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 1588*0ef72598Sjeremylt for i in range(nx): 1589*0ef72598Sjeremylt indx[2 * i + 0] = i 1590*0ef72598Sjeremylt indx[2 * i + 1] = i + 1 1591*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 1592*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1593*0ef72598Sjeremylt 1594*0ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 1595*0ef72598Sjeremylt for i in range(nelem): 1596*0ef72598Sjeremylt for j in range(p_coarse): 1597*0ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 1598*0ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 1599*0ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 1600*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1601*0ef72598Sjeremylt 1602*0ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 1603*0ef72598Sjeremylt for i in range(nelem): 1604*0ef72598Sjeremylt for j in range(p_fine): 1605*0ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 1606*0ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 1607*0ef72598Sjeremylt ncomp * nu_fine, indu_fine, 1608*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1609*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 1610*0ef72598Sjeremylt 1611*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 1612*0ef72598Sjeremylt 1613*0ef72598Sjeremylt # Bases 1614*0ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 1615*0ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 1616*0ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 1617*0ef72598Sjeremylt 1618*0ef72598Sjeremylt # QFunctions 1619*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 1620*0ef72598Sjeremylt qfs = load_qfs_so() 1621*0ef72598Sjeremylt 1622*0ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 1623*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 1624*0ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 1625*0ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 1626*0ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 1627*0ef72598Sjeremylt 1628*0ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass_two, 1629*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass_two")) 1630*0ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 1631*0ef72598Sjeremylt qf_mass.add_input("u", ncomp, libceed.EVAL_INTERP) 1632*0ef72598Sjeremylt qf_mass.add_output("v", ncomp, libceed.EVAL_INTERP) 1633*0ef72598Sjeremylt 1634*0ef72598Sjeremylt # Operators 1635*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 1636*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 1637*0ef72598Sjeremylt libceed.VECTOR_NONE) 1638*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 1639*0ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 1640*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 1641*0ef72598Sjeremylt 1642*0ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 1643*0ef72598Sjeremylt op_mass_fine.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 1644*0ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 1645*0ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 1646*0ef72598Sjeremylt 1647*0ef72598Sjeremylt # Setup 1648*0ef72598Sjeremylt op_setup.apply(x, qdata) 1649*0ef72598Sjeremylt 1650*0ef72598Sjeremylt # Create multigrid level 1651*0ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 1652*0ef72598Sjeremylt p_mult_fine.set_value(1.0) 1653*0ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create(p_mult_fine, 1654*0ef72598Sjeremylt ru_coarse, 1655*0ef72598Sjeremylt bu_coarse) 1656*0ef72598Sjeremylt 1657*0ef72598Sjeremylt # Apply coarse mass matrix 1658*0ef72598Sjeremylt u_coarse.set_value(1.0) 1659*0ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 1660*0ef72598Sjeremylt 1661*0ef72598Sjeremylt # Check 1662*0ef72598Sjeremylt with v_coarse.array_read() as v_array: 1663*0ef72598Sjeremylt total = 0.0 1664*0ef72598Sjeremylt for i in range(nu_coarse * ncomp): 1665*0ef72598Sjeremylt total = total + v_array[i] 1666*0ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 1667*0ef72598Sjeremylt 1668*0ef72598Sjeremylt # Prolong coarse u 1669*0ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 1670*0ef72598Sjeremylt 1671*0ef72598Sjeremylt # Apply mass matrix 1672*0ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 1673*0ef72598Sjeremylt 1674*0ef72598Sjeremylt # Check 1675*0ef72598Sjeremylt with v_fine.array_read() as v_array: 1676*0ef72598Sjeremylt total = 0.0 1677*0ef72598Sjeremylt for i in range(nu_fine * ncomp): 1678*0ef72598Sjeremylt total = total + v_array[i] 1679*0ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 1680*0ef72598Sjeremylt 1681*0ef72598Sjeremylt # Restrict state to coarse grid 1682*0ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 1683*0ef72598Sjeremylt 1684*0ef72598Sjeremylt # Check 1685*0ef72598Sjeremylt with v_coarse.array_read() as v_array: 1686*0ef72598Sjeremylt total = 0.0 1687*0ef72598Sjeremylt for i in range(nu_coarse * ncomp): 1688*0ef72598Sjeremylt total = total + v_array[i] 1689*0ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 1690*0ef72598Sjeremylt 1691*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1692*0ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 1693*0ef72598Sjeremylt# multigrid level, tensor basis 1694*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1695*0ef72598Sjeremylt 1696*0ef72598Sjeremylt 1697*0ef72598Sjeremyltdef test_552(ceed_resource): 1698*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1699*0ef72598Sjeremylt 1700*0ef72598Sjeremylt nelem = 15 1701*0ef72598Sjeremylt p_coarse = 3 1702*0ef72598Sjeremylt p_fine = 5 1703*0ef72598Sjeremylt q = 8 1704*0ef72598Sjeremylt ncomp = 2 1705*0ef72598Sjeremylt nx = nelem + 1 1706*0ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 1707*0ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 1708*0ef72598Sjeremylt 1709*0ef72598Sjeremylt # Vectors 1710*0ef72598Sjeremylt x = ceed.Vector(nx) 1711*0ef72598Sjeremylt x_array = np.zeros(nx) 1712*0ef72598Sjeremylt for i in range(nx): 1713*0ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 1714*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 1715*0ef72598Sjeremylt 1716*0ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 1717*0ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 1718*0ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 1719*0ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 1720*0ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 1721*0ef72598Sjeremylt 1722*0ef72598Sjeremylt # Restrictions 1723*0ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 1724*0ef72598Sjeremylt for i in range(nx): 1725*0ef72598Sjeremylt indx[2 * i + 0] = i 1726*0ef72598Sjeremylt indx[2 * i + 1] = i + 1 1727*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 1728*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1729*0ef72598Sjeremylt 1730*0ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 1731*0ef72598Sjeremylt for i in range(nelem): 1732*0ef72598Sjeremylt for j in range(p_coarse): 1733*0ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 1734*0ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 1735*0ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 1736*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1737*0ef72598Sjeremylt 1738*0ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 1739*0ef72598Sjeremylt for i in range(nelem): 1740*0ef72598Sjeremylt for j in range(p_fine): 1741*0ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 1742*0ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 1743*0ef72598Sjeremylt ncomp * nu_fine, indu_fine, 1744*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1745*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 1746*0ef72598Sjeremylt 1747*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 1748*0ef72598Sjeremylt 1749*0ef72598Sjeremylt # Bases 1750*0ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 1751*0ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 1752*0ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 1753*0ef72598Sjeremylt 1754*0ef72598Sjeremylt # QFunctions 1755*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 1756*0ef72598Sjeremylt qfs = load_qfs_so() 1757*0ef72598Sjeremylt 1758*0ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 1759*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 1760*0ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 1761*0ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 1762*0ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 1763*0ef72598Sjeremylt 1764*0ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass_two, 1765*0ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass_two")) 1766*0ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 1767*0ef72598Sjeremylt qf_mass.add_input("u", ncomp, libceed.EVAL_INTERP) 1768*0ef72598Sjeremylt qf_mass.add_output("v", ncomp, libceed.EVAL_INTERP) 1769*0ef72598Sjeremylt 1770*0ef72598Sjeremylt # Operators 1771*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 1772*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 1773*0ef72598Sjeremylt libceed.VECTOR_NONE) 1774*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 1775*0ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 1776*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 1777*0ef72598Sjeremylt 1778*0ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 1779*0ef72598Sjeremylt op_mass_fine.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 1780*0ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 1781*0ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 1782*0ef72598Sjeremylt 1783*0ef72598Sjeremylt # Setup 1784*0ef72598Sjeremylt op_setup.apply(x, qdata) 1785*0ef72598Sjeremylt 1786*0ef72598Sjeremylt # Create multigrid level 1787*0ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 1788*0ef72598Sjeremylt p_mult_fine.set_value(1.0) 1789*0ef72598Sjeremylt b_c_to_f = ceed.BasisTensorH1Lagrange( 1790*0ef72598Sjeremylt 1, ncomp, p_coarse, p_fine, libceed.GAUSS_LOBATTO) 1791*0ef72598Sjeremylt interp_C_to_F = b_c_to_f.get_interp1d() 1792*0ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create_tensor_h1(p_mult_fine, 1793*0ef72598Sjeremylt ru_coarse, bu_coarse, interp_C_to_F) 1794*0ef72598Sjeremylt 1795*0ef72598Sjeremylt # Apply coarse mass matrix 1796*0ef72598Sjeremylt u_coarse.set_value(1.0) 1797*0ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 1798*0ef72598Sjeremylt 1799*0ef72598Sjeremylt # Check 1800*0ef72598Sjeremylt with v_coarse.array_read() as v_array: 1801*0ef72598Sjeremylt total = 0.0 1802*0ef72598Sjeremylt for i in range(nu_coarse * ncomp): 1803*0ef72598Sjeremylt total = total + v_array[i] 1804*0ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 1805*0ef72598Sjeremylt 1806*0ef72598Sjeremylt # Prolong coarse u 1807*0ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 1808*0ef72598Sjeremylt 1809*0ef72598Sjeremylt # Apply mass matrix 1810*0ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 1811*0ef72598Sjeremylt 1812*0ef72598Sjeremylt # Check 1813*0ef72598Sjeremylt with v_fine.array_read() as v_array: 1814*0ef72598Sjeremylt total = 0.0 1815*0ef72598Sjeremylt for i in range(nu_fine * ncomp): 1816*0ef72598Sjeremylt total = total + v_array[i] 1817*0ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 1818*0ef72598Sjeremylt 1819*0ef72598Sjeremylt # Restrict state to coarse grid 1820*0ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 1821*0ef72598Sjeremylt 1822*0ef72598Sjeremylt # Check 1823*0ef72598Sjeremylt with v_coarse.array_read() as v_array: 1824*0ef72598Sjeremylt total = 0.0 1825*0ef72598Sjeremylt for i in range(nu_coarse * ncomp): 1826*0ef72598Sjeremylt total = total + v_array[i] 1827*0ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 1828*0ef72598Sjeremylt 1829*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1830*0ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 1831*0ef72598Sjeremylt# multigrid level, non-tensor basis 1832*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1833*0ef72598Sjeremylt 1834*0ef72598Sjeremylt 1835*0ef72598Sjeremyltdef test_553(ceed_resource): 1836*0ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1837*0ef72598Sjeremylt 1838*0ef72598Sjeremylt nelem = 15 1839*0ef72598Sjeremylt p_coarse = 3 1840*0ef72598Sjeremylt p_fine = 5 1841*0ef72598Sjeremylt q = 8 1842*0ef72598Sjeremylt ncomp = 1 1843*0ef72598Sjeremylt nx = nelem + 1 1844*0ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 1845*0ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 1846*0ef72598Sjeremylt 1847*0ef72598Sjeremylt # Vectors 1848*0ef72598Sjeremylt x = ceed.Vector(nx) 1849*0ef72598Sjeremylt x_array = np.zeros(nx) 1850*0ef72598Sjeremylt for i in range(nx): 1851*0ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 1852*0ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 1853*0ef72598Sjeremylt 1854*0ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 1855*0ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 1856*0ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 1857*0ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 1858*0ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 1859*0ef72598Sjeremylt 1860*0ef72598Sjeremylt # Restrictions 1861*0ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 1862*0ef72598Sjeremylt for i in range(nx): 1863*0ef72598Sjeremylt indx[2 * i + 0] = i 1864*0ef72598Sjeremylt indx[2 * i + 1] = i + 1 1865*0ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 1866*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1867*0ef72598Sjeremylt 1868*0ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 1869*0ef72598Sjeremylt for i in range(nelem): 1870*0ef72598Sjeremylt for j in range(p_coarse): 1871*0ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 1872*0ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 1873*0ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 1874*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1875*0ef72598Sjeremylt 1876*0ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 1877*0ef72598Sjeremylt for i in range(nelem): 1878*0ef72598Sjeremylt for j in range(p_fine): 1879*0ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 1880*0ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 1881*0ef72598Sjeremylt ncomp * nu_fine, indu_fine, 1882*0ef72598Sjeremylt cmode=libceed.USE_POINTER) 1883*0ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 1884*0ef72598Sjeremylt 1885*0ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 1886*0ef72598Sjeremylt 1887*0ef72598Sjeremylt # Bases 1888*0ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 1889*0ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 1890*0ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 1891*0ef72598Sjeremylt 1892*0ef72598Sjeremylt # QFunctions 1893*0ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 1894*0ef72598Sjeremylt qfs = load_qfs_so() 1895*0ef72598Sjeremylt 1896*0ef72598Sjeremylt qf_setup = ceed.QFunctionByName("Mass1DBuild") 1897*0ef72598Sjeremylt qf_mass = ceed.QFunctionByName("MassApply") 1898*0ef72598Sjeremylt 1899*0ef72598Sjeremylt # Operators 1900*0ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 1901*0ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 1902*0ef72598Sjeremylt libceed.VECTOR_NONE) 1903*0ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 1904*0ef72598Sjeremylt op_setup.set_field("qdata", rui, libceed.BASIS_COLLOCATED, 1905*0ef72598Sjeremylt libceed.VECTOR_ACTIVE) 1906*0ef72598Sjeremylt 1907*0ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 1908*0ef72598Sjeremylt op_mass_fine.set_field("qdata", rui, libceed.BASIS_COLLOCATED, qdata) 1909*0ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 1910*0ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 1911*0ef72598Sjeremylt 1912*0ef72598Sjeremylt # Setup 1913*0ef72598Sjeremylt op_setup.apply(x, qdata) 1914*0ef72598Sjeremylt 1915*0ef72598Sjeremylt # Create multigrid level 1916*0ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 1917*0ef72598Sjeremylt p_mult_fine.set_value(1.0) 1918*0ef72598Sjeremylt b_c_to_f = ceed.BasisTensorH1Lagrange( 1919*0ef72598Sjeremylt 1, ncomp, p_coarse, p_fine, libceed.GAUSS_LOBATTO) 1920*0ef72598Sjeremylt interp_C_to_F = b_c_to_f.get_interp1d() 1921*0ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create_h1(p_mult_fine, 1922*0ef72598Sjeremylt ru_coarse, bu_coarse, interp_C_to_F) 1923*0ef72598Sjeremylt 1924*0ef72598Sjeremylt # Apply coarse mass matrix 1925*0ef72598Sjeremylt u_coarse.set_value(1.0) 1926*0ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 1927*0ef72598Sjeremylt 1928*0ef72598Sjeremylt # Check 1929*0ef72598Sjeremylt with v_coarse.array_read() as v_array: 1930*0ef72598Sjeremylt total = 0.0 1931*0ef72598Sjeremylt for i in range(nu_coarse * ncomp): 1932*0ef72598Sjeremylt total = total + v_array[i] 1933*0ef72598Sjeremylt assert abs(total - 1.0) < 1E-13 1934*0ef72598Sjeremylt 1935*0ef72598Sjeremylt # Prolong coarse u 1936*0ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 1937*0ef72598Sjeremylt 1938*0ef72598Sjeremylt # Apply mass matrix 1939*0ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 1940*0ef72598Sjeremylt 1941*0ef72598Sjeremylt # Check 1942*0ef72598Sjeremylt with v_fine.array_read() as v_array: 1943*0ef72598Sjeremylt total = 0.0 1944*0ef72598Sjeremylt for i in range(nu_fine * ncomp): 1945*0ef72598Sjeremylt total = total + v_array[i] 1946*0ef72598Sjeremylt assert abs(total - 1.0) < 1E-13 1947*0ef72598Sjeremylt 1948*0ef72598Sjeremylt # Restrict state to coarse grid 1949*0ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 1950*0ef72598Sjeremylt 1951*0ef72598Sjeremylt # Check 1952*0ef72598Sjeremylt with v_coarse.array_read() as v_array: 1953*0ef72598Sjeremylt total = 0.0 1954*0ef72598Sjeremylt for i in range(nu_coarse * ncomp): 1955*0ef72598Sjeremylt total = total + v_array[i] 1956*0ef72598Sjeremylt assert abs(total - 1.0) < 1E-13 1957*0ef72598Sjeremylt 1958*0ef72598Sjeremylt# ------------------------------------------------------------------------------- 1959