10ef72598Sjeremylt# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 20ef72598Sjeremylt# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 30ef72598Sjeremylt# reserved. See files LICENSE and NOTICE for details. 40ef72598Sjeremylt# 50ef72598Sjeremylt# This file is part of CEED, a collection of benchmarks, miniapps, software 60ef72598Sjeremylt# libraries and APIs for efficient high-order finite element and spectral 70ef72598Sjeremylt# element discretizations for exascale applications. For more information and 80ef72598Sjeremylt# source code availability see http://github.com/ceed. 90ef72598Sjeremylt# 100ef72598Sjeremylt# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 110ef72598Sjeremylt# a collaborative effort of two U.S. Department of Energy organizations (Office 120ef72598Sjeremylt# of Science and the National Nuclear Security Administration) responsible for 130ef72598Sjeremylt# the planning and preparation of a capable exascale ecosystem, including 140ef72598Sjeremylt# software, applications, hardware, advanced system engineering and early 150ef72598Sjeremylt# testbed platforms, in support of the nation's exascale computing imperative. 160ef72598Sjeremylt 170ef72598Sjeremylt# @file 180ef72598Sjeremylt# Test Ceed Operator functionality 190ef72598Sjeremylt 200ef72598Sjeremyltimport os 210ef72598Sjeremyltimport libceed 220ef72598Sjeremyltimport numpy as np 230ef72598Sjeremyltimport check 240ef72598Sjeremyltimport buildmats as bm 250ef72598Sjeremylt 260ef72598SjeremyltTOL = np.finfo(float).eps * 256 270ef72598Sjeremylt 280ef72598Sjeremylt# ------------------------------------------------------------------------------- 290ef72598Sjeremylt# Utility 300ef72598Sjeremylt# ------------------------------------------------------------------------------- 310ef72598Sjeremylt 320ef72598Sjeremylt 330ef72598Sjeremyltdef load_qfs_so(): 340ef72598Sjeremylt from distutils.sysconfig import get_config_var 350ef72598Sjeremylt import ctypes 360ef72598Sjeremylt 370ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 380ef72598Sjeremylt qfs_so = os.path.join( 390ef72598Sjeremylt file_dir, 400ef72598Sjeremylt "libceed_qfunctions" + get_config_var("EXT_SUFFIX")) 410ef72598Sjeremylt 420ef72598Sjeremylt # Load library 430ef72598Sjeremylt return ctypes.cdll.LoadLibrary(qfs_so) 440ef72598Sjeremylt 450ef72598Sjeremylt# ------------------------------------------------------------------------------- 460ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator 470ef72598Sjeremylt# ------------------------------------------------------------------------------- 480ef72598Sjeremylt 490ef72598Sjeremylt 500ef72598Sjeremyltdef test_500(ceed_resource): 510ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 520ef72598Sjeremylt 530ef72598Sjeremylt nelem = 15 540ef72598Sjeremylt p = 5 550ef72598Sjeremylt q = 8 560ef72598Sjeremylt nx = nelem + 1 570ef72598Sjeremylt nu = nelem * (p - 1) + 1 580ef72598Sjeremylt 590ef72598Sjeremylt # Vectors 600ef72598Sjeremylt x = ceed.Vector(nx) 610ef72598Sjeremylt x_array = np.zeros(nx) 620ef72598Sjeremylt for i in range(nx): 630ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 640ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 650ef72598Sjeremylt 660ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 670ef72598Sjeremylt u = ceed.Vector(nu) 680ef72598Sjeremylt v = ceed.Vector(nu) 690ef72598Sjeremylt 700ef72598Sjeremylt # Restrictions 710ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 720ef72598Sjeremylt for i in range(nx): 730ef72598Sjeremylt indx[2 * i + 0] = i 740ef72598Sjeremylt indx[2 * i + 1] = i + 1 750ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 760ef72598Sjeremylt cmode=libceed.USE_POINTER) 770ef72598Sjeremylt 780ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 790ef72598Sjeremylt for i in range(nelem): 800ef72598Sjeremylt for j in range(p): 810ef72598Sjeremylt indu[p * i + j] = i * (p - 1) + j 820ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, nu, indu, 830ef72598Sjeremylt cmode=libceed.USE_POINTER) 840ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 850ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 860ef72598Sjeremylt 870ef72598Sjeremylt # Bases 880ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 890ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS) 900ef72598Sjeremylt 910ef72598Sjeremylt # QFunctions 920ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 930ef72598Sjeremylt qfs = load_qfs_so() 940ef72598Sjeremylt 950ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 960ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 970ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 980ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 990ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 1000ef72598Sjeremylt 1010ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 1020ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 1030ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 1040ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 1050ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 1060ef72598Sjeremylt 1070ef72598Sjeremylt # Operators 1080ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 1090ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 1100ef72598Sjeremylt libceed.VECTOR_NONE) 1110ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 1120ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 1130ef72598Sjeremylt libceed.VECTOR_ACTIVE) 1140ef72598Sjeremylt 1150ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 1160ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 1170ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 1180ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 1190ef72598Sjeremylt 1200ef72598Sjeremylt # Setup 1210ef72598Sjeremylt op_setup.apply(x, qdata) 1220ef72598Sjeremylt 1230ef72598Sjeremylt # Apply mass matrix 1240ef72598Sjeremylt u.set_value(0) 1250ef72598Sjeremylt op_mass.apply(u, v) 1260ef72598Sjeremylt 1270ef72598Sjeremylt # Check 1280ef72598Sjeremylt with v.array_read() as v_array: 1290ef72598Sjeremylt for i in range(q): 1300ef72598Sjeremylt assert abs(v_array[i]) < TOL 1310ef72598Sjeremylt 1320ef72598Sjeremylt# ------------------------------------------------------------------------------- 1330ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator 1340ef72598Sjeremylt# ------------------------------------------------------------------------------- 1350ef72598Sjeremylt 1360ef72598Sjeremylt 1370ef72598Sjeremyltdef test_501(ceed_resource): 1380ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1390ef72598Sjeremylt 1400ef72598Sjeremylt nelem = 15 1410ef72598Sjeremylt p = 5 1420ef72598Sjeremylt q = 8 1430ef72598Sjeremylt nx = nelem + 1 1440ef72598Sjeremylt nu = nelem * (p - 1) + 1 1450ef72598Sjeremylt 1460ef72598Sjeremylt # Vectors 1470ef72598Sjeremylt x = ceed.Vector(nx) 1480ef72598Sjeremylt x_array = np.zeros(nx) 1490ef72598Sjeremylt for i in range(nx): 1500ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 1510ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 1520ef72598Sjeremylt 1530ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 1540ef72598Sjeremylt u = ceed.Vector(nu) 1550ef72598Sjeremylt v = ceed.Vector(nu) 1560ef72598Sjeremylt 1570ef72598Sjeremylt # Restrictions 1580ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 1590ef72598Sjeremylt for i in range(nx): 1600ef72598Sjeremylt indx[2 * i + 0] = i 1610ef72598Sjeremylt indx[2 * i + 1] = i + 1 1620ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 1630ef72598Sjeremylt cmode=libceed.USE_POINTER) 1640ef72598Sjeremylt 1650ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 1660ef72598Sjeremylt for i in range(nelem): 1670ef72598Sjeremylt for j in range(p): 1680ef72598Sjeremylt indu[p * i + j] = i * (p - 1) + j 1690ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, nu, indu, 1700ef72598Sjeremylt cmode=libceed.USE_POINTER) 1710ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 1720ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 1730ef72598Sjeremylt 1740ef72598Sjeremylt # Bases 1750ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 1760ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS) 1770ef72598Sjeremylt 1780ef72598Sjeremylt # QFunctions 1790ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 1800ef72598Sjeremylt qfs = load_qfs_so() 1810ef72598Sjeremylt 1820ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 1830ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 1840ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 1850ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 1860ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 1870ef72598Sjeremylt 1880ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 1890ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 1900ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 1910ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 1920ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 1930ef72598Sjeremylt 1940ef72598Sjeremylt # Operators 1950ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 1960ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 1970ef72598Sjeremylt libceed.VECTOR_NONE) 1980ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 1990ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 2000ef72598Sjeremylt libceed.VECTOR_ACTIVE) 2010ef72598Sjeremylt 2020ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 2030ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 2040ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 2050ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 2060ef72598Sjeremylt 2070ef72598Sjeremylt # Setup 2080ef72598Sjeremylt op_setup.apply(x, qdata) 2090ef72598Sjeremylt 2100ef72598Sjeremylt # Apply mass matrix 2110ef72598Sjeremylt u.set_value(1.) 2120ef72598Sjeremylt op_mass.apply(u, v) 2130ef72598Sjeremylt 2140ef72598Sjeremylt # Check 2150ef72598Sjeremylt with v.array_read() as v_array: 2160ef72598Sjeremylt total = 0.0 2170ef72598Sjeremylt for i in range(nu): 2180ef72598Sjeremylt total = total + v_array[i] 2190ef72598Sjeremylt assert abs(total - 1.0) < TOL 2200ef72598Sjeremylt 2210ef72598Sjeremylt# ------------------------------------------------------------------------------- 2220ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with multiple 2230ef72598Sjeremylt# components 2240ef72598Sjeremylt# ------------------------------------------------------------------------------- 2250ef72598Sjeremylt 2260ef72598Sjeremylt 2270ef72598Sjeremyltdef test_502(ceed_resource): 2280ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 2290ef72598Sjeremylt 2300ef72598Sjeremylt nelem = 15 2310ef72598Sjeremylt p = 5 2320ef72598Sjeremylt q = 8 2330ef72598Sjeremylt nx = nelem + 1 2340ef72598Sjeremylt nu = nelem * (p - 1) + 1 2350ef72598Sjeremylt 2360ef72598Sjeremylt # Vectors 2370ef72598Sjeremylt x = ceed.Vector(nx) 2380ef72598Sjeremylt x_array = np.zeros(nx) 2390ef72598Sjeremylt for i in range(nx): 2400ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 2410ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 2420ef72598Sjeremylt 2430ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 2440ef72598Sjeremylt u = ceed.Vector(2 * nu) 2450ef72598Sjeremylt v = ceed.Vector(2 * nu) 2460ef72598Sjeremylt 2470ef72598Sjeremylt # Restrictions 2480ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 2490ef72598Sjeremylt for i in range(nx): 2500ef72598Sjeremylt indx[2 * i + 0] = i 2510ef72598Sjeremylt indx[2 * i + 1] = i + 1 2520ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 2530ef72598Sjeremylt cmode=libceed.USE_POINTER) 2540ef72598Sjeremylt 2550ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 2560ef72598Sjeremylt for i in range(nelem): 2570ef72598Sjeremylt for j in range(p): 2580ef72598Sjeremylt indu[p * i + j] = 2 * (i * (p - 1) + j) 2590ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 2, 1, 2 * nu, indu, 2600ef72598Sjeremylt cmode=libceed.USE_POINTER) 2610ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 2620ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 2630ef72598Sjeremylt 2640ef72598Sjeremylt # Bases 2650ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 2660ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 2, p, q, libceed.GAUSS) 2670ef72598Sjeremylt 2680ef72598Sjeremylt # QFunctions 2690ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 2700ef72598Sjeremylt qfs = load_qfs_so() 2710ef72598Sjeremylt 2720ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 2730ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 2740ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 2750ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 2760ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 2770ef72598Sjeremylt 2780ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass_two, 2790ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass_two")) 2800ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 2810ef72598Sjeremylt qf_mass.add_input("u", 2, libceed.EVAL_INTERP) 2820ef72598Sjeremylt qf_mass.add_output("v", 2, libceed.EVAL_INTERP) 2830ef72598Sjeremylt 2840ef72598Sjeremylt # Operators 2850ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 2860ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 2870ef72598Sjeremylt libceed.VECTOR_NONE) 2880ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 2890ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 2900ef72598Sjeremylt libceed.VECTOR_ACTIVE) 2910ef72598Sjeremylt 2920ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 2930ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 2940ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 2950ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 2960ef72598Sjeremylt 2970ef72598Sjeremylt # Setup 2980ef72598Sjeremylt op_setup.apply(x, qdata) 2990ef72598Sjeremylt 3000ef72598Sjeremylt # Apply mass matrix 3010ef72598Sjeremylt with u.array() as u_array: 3020ef72598Sjeremylt for i in range(nu): 3030ef72598Sjeremylt u_array[2 * i] = 1. 3040ef72598Sjeremylt u_array[2 * i + 1] = 2. 3050ef72598Sjeremylt op_mass.apply(u, v) 3060ef72598Sjeremylt 3070ef72598Sjeremylt # Check 3080ef72598Sjeremylt with v.array_read() as v_array: 3090ef72598Sjeremylt total_1 = 0.0 3100ef72598Sjeremylt total_2 = 0.0 3110ef72598Sjeremylt for i in range(nu): 3120ef72598Sjeremylt total_1 = total_1 + v_array[2 * i] 3130ef72598Sjeremylt total_2 = total_2 + v_array[2 * i + 1] 3140ef72598Sjeremylt assert abs(total_1 - 1.0) < 1E-13 3150ef72598Sjeremylt assert abs(total_2 - 2.0) < 1E-13 3160ef72598Sjeremylt 3170ef72598Sjeremylt# ------------------------------------------------------------------------------- 3180ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with passive 3190ef72598Sjeremylt# inputs and outputs 3200ef72598Sjeremylt# ------------------------------------------------------------------------------- 3210ef72598Sjeremylt 3220ef72598Sjeremylt 3230ef72598Sjeremyltdef test_503(ceed_resource): 3240ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 3250ef72598Sjeremylt 3260ef72598Sjeremylt nelem = 15 3270ef72598Sjeremylt p = 5 3280ef72598Sjeremylt q = 8 3290ef72598Sjeremylt nx = nelem + 1 3300ef72598Sjeremylt nu = nelem * (p - 1) + 1 3310ef72598Sjeremylt 3320ef72598Sjeremylt # Vectors 3330ef72598Sjeremylt x = ceed.Vector(nx) 3340ef72598Sjeremylt x_array = np.zeros(nx) 3350ef72598Sjeremylt for i in range(nx): 3360ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 3370ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 3380ef72598Sjeremylt 3390ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 3400ef72598Sjeremylt u = ceed.Vector(nu) 3410ef72598Sjeremylt v = ceed.Vector(nu) 3420ef72598Sjeremylt 3430ef72598Sjeremylt # Restrictions 3440ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 3450ef72598Sjeremylt for i in range(nx): 3460ef72598Sjeremylt indx[2 * i + 0] = i 3470ef72598Sjeremylt indx[2 * i + 1] = i + 1 3480ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 3490ef72598Sjeremylt cmode=libceed.USE_POINTER) 3500ef72598Sjeremylt 3510ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 3520ef72598Sjeremylt for i in range(nelem): 3530ef72598Sjeremylt for j in range(p): 3540ef72598Sjeremylt indu[p * i + j] = i * (p - 1) + j 3550ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, nu, indu, 3560ef72598Sjeremylt cmode=libceed.USE_POINTER) 3570ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 3580ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 3590ef72598Sjeremylt 3600ef72598Sjeremylt # Bases 3610ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 3620ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS) 3630ef72598Sjeremylt 3640ef72598Sjeremylt # QFunctions 3650ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 3660ef72598Sjeremylt qfs = load_qfs_so() 3670ef72598Sjeremylt 3680ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 3690ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 3700ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 3710ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 3720ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 3730ef72598Sjeremylt 3740ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 3750ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 3760ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 3770ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 3780ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 3790ef72598Sjeremylt 3800ef72598Sjeremylt # Operators 3810ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 3820ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 3830ef72598Sjeremylt libceed.VECTOR_NONE) 3840ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 3850ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 3860ef72598Sjeremylt libceed.VECTOR_ACTIVE) 3870ef72598Sjeremylt 3880ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 3890ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 3900ef72598Sjeremylt op_mass.set_field("u", ru, bu, u) 3910ef72598Sjeremylt op_mass.set_field("v", ru, bu, v) 3920ef72598Sjeremylt 3930ef72598Sjeremylt # Setup 3940ef72598Sjeremylt op_setup.apply(x, qdata) 3950ef72598Sjeremylt 3960ef72598Sjeremylt # Apply mass matrix 3970ef72598Sjeremylt u.set_value(1) 3980ef72598Sjeremylt op_mass.apply(libceed.VECTOR_NONE, libceed.VECTOR_NONE) 3990ef72598Sjeremylt 4000ef72598Sjeremylt # Check 4010ef72598Sjeremylt with v.array_read() as v_array: 4020ef72598Sjeremylt total = 0.0 4030ef72598Sjeremylt for i in range(nu): 4040ef72598Sjeremylt total = total + v_array[i] 4050ef72598Sjeremylt assert abs(total - 1.0) < 1E-13 4060ef72598Sjeremylt 4070ef72598Sjeremylt# ------------------------------------------------------------------------------- 4080ef72598Sjeremylt# Test viewing of mass matrix operator 4090ef72598Sjeremylt# ------------------------------------------------------------------------------- 4100ef72598Sjeremylt 4110ef72598Sjeremylt 4120ef72598Sjeremyltdef test_504(ceed_resource, capsys): 4130ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 4140ef72598Sjeremylt 4150ef72598Sjeremylt nelem = 15 4160ef72598Sjeremylt p = 5 4170ef72598Sjeremylt q = 8 4180ef72598Sjeremylt nx = nelem + 1 4190ef72598Sjeremylt nu = nelem * (p - 1) + 1 4200ef72598Sjeremylt 4210ef72598Sjeremylt # Vectors 4220ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 4230ef72598Sjeremylt 4240ef72598Sjeremylt # Restrictions 4250ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 4260ef72598Sjeremylt for i in range(nx): 4270ef72598Sjeremylt indx[2 * i + 0] = i 4280ef72598Sjeremylt indx[2 * i + 1] = i + 1 4290ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 4300ef72598Sjeremylt cmode=libceed.USE_POINTER) 4310ef72598Sjeremylt 4320ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 4330ef72598Sjeremylt for i in range(nelem): 4340ef72598Sjeremylt for j in range(p): 4350ef72598Sjeremylt indu[p * i + j] = i * (p - 1) + j 4360ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, nu, indu, 4370ef72598Sjeremylt cmode=libceed.USE_POINTER) 4380ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 4390ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 4400ef72598Sjeremylt 4410ef72598Sjeremylt # Bases 4420ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 4430ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS) 4440ef72598Sjeremylt 4450ef72598Sjeremylt # QFunctions 4460ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 4470ef72598Sjeremylt qfs = load_qfs_so() 4480ef72598Sjeremylt 4490ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 4500ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 4510ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 4520ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 4530ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 4540ef72598Sjeremylt 4550ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 4560ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 4570ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 4580ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 4590ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 4600ef72598Sjeremylt 4610ef72598Sjeremylt # Operators 4620ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 4630ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 4640ef72598Sjeremylt libceed.VECTOR_NONE) 4650ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 4660ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 4670ef72598Sjeremylt libceed.VECTOR_ACTIVE) 4680ef72598Sjeremylt 4690ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 4700ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 4710ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 4720ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 4730ef72598Sjeremylt 4740ef72598Sjeremylt # View 4750ef72598Sjeremylt print(op_setup) 4760ef72598Sjeremylt print(op_mass) 4770ef72598Sjeremylt 4780ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 4790ef72598Sjeremylt assert not stderr 4800ef72598Sjeremylt assert stdout == ref_stdout 4810ef72598Sjeremylt 4820ef72598Sjeremylt# ------------------------------------------------------------------------------- 4830ef72598Sjeremylt# Test CeedOperatorApplyAdd 4840ef72598Sjeremylt# ------------------------------------------------------------------------------- 4850ef72598Sjeremylt 4860ef72598Sjeremylt 4870ef72598Sjeremyltdef test_505(ceed_resource): 4880ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 4890ef72598Sjeremylt 4900ef72598Sjeremylt nelem = 15 4910ef72598Sjeremylt p = 5 4920ef72598Sjeremylt q = 8 4930ef72598Sjeremylt nx = nelem + 1 4940ef72598Sjeremylt nu = nelem * (p - 1) + 1 4950ef72598Sjeremylt 4960ef72598Sjeremylt # Vectors 4970ef72598Sjeremylt x = ceed.Vector(nx) 4980ef72598Sjeremylt x_array = np.zeros(nx) 4990ef72598Sjeremylt for i in range(nx): 5000ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 5010ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 5020ef72598Sjeremylt 5030ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 5040ef72598Sjeremylt u = ceed.Vector(nu) 5050ef72598Sjeremylt v = ceed.Vector(nu) 5060ef72598Sjeremylt 5070ef72598Sjeremylt # Restrictions 5080ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 5090ef72598Sjeremylt for i in range(nx): 5100ef72598Sjeremylt indx[2 * i + 0] = i 5110ef72598Sjeremylt indx[2 * i + 1] = i + 1 5120ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 5130ef72598Sjeremylt cmode=libceed.USE_POINTER) 5140ef72598Sjeremylt 5150ef72598Sjeremylt indu = np.zeros(nelem * p, dtype="int32") 5160ef72598Sjeremylt for i in range(nelem): 5170ef72598Sjeremylt for j in range(p): 5180ef72598Sjeremylt indu[p * i + j] = i * (p - 1) + j 5190ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, nu, indu, 5200ef72598Sjeremylt cmode=libceed.USE_POINTER) 5210ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 5220ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 5230ef72598Sjeremylt 5240ef72598Sjeremylt # Bases 5250ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 5260ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS) 5270ef72598Sjeremylt 5280ef72598Sjeremylt # QFunctions 5290ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 5300ef72598Sjeremylt qfs = load_qfs_so() 5310ef72598Sjeremylt 5320ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 5330ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 5340ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 5350ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 5360ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 5370ef72598Sjeremylt 5380ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 5390ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 5400ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 5410ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 5420ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 5430ef72598Sjeremylt 5440ef72598Sjeremylt # Operators 5450ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 5460ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 5470ef72598Sjeremylt libceed.VECTOR_NONE) 5480ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 5490ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 5500ef72598Sjeremylt libceed.VECTOR_ACTIVE) 5510ef72598Sjeremylt 5520ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 5530ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 5540ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 5550ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 5560ef72598Sjeremylt 5570ef72598Sjeremylt # Setup 5580ef72598Sjeremylt op_setup.apply(x, qdata) 5590ef72598Sjeremylt 5600ef72598Sjeremylt # Apply mass matrix with v = 0 5610ef72598Sjeremylt u.set_value(1.) 5620ef72598Sjeremylt v.set_value(0.) 5630ef72598Sjeremylt op_mass.apply_add(u, v) 5640ef72598Sjeremylt 5650ef72598Sjeremylt # Check 5660ef72598Sjeremylt with v.array_read() as v_array: 5670ef72598Sjeremylt total = 0.0 5680ef72598Sjeremylt for i in range(nu): 5690ef72598Sjeremylt total = total + v_array[i] 5700ef72598Sjeremylt assert abs(total - 1.0) < TOL 5710ef72598Sjeremylt 5720ef72598Sjeremylt # Apply mass matrix with v = 0 5730ef72598Sjeremylt v.set_value(1.) 5740ef72598Sjeremylt op_mass.apply_add(u, v) 5750ef72598Sjeremylt 5760ef72598Sjeremylt # Check 5770ef72598Sjeremylt with v.array_read() as v_array: 5780ef72598Sjeremylt total = -nu 5790ef72598Sjeremylt for i in range(nu): 5800ef72598Sjeremylt total = total + v_array[i] 5810ef72598Sjeremylt assert abs(total - 1.0) < 1E-10 5820ef72598Sjeremylt 5830ef72598Sjeremylt# ------------------------------------------------------------------------------- 5840ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator 5850ef72598Sjeremylt# ------------------------------------------------------------------------------- 5860ef72598Sjeremylt 5870ef72598Sjeremylt 5880ef72598Sjeremyltdef test_510(ceed_resource): 5890ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 5900ef72598Sjeremylt 5910ef72598Sjeremylt nelem = 12 5920ef72598Sjeremylt dim = 2 5930ef72598Sjeremylt p = 6 5940ef72598Sjeremylt q = 4 5950ef72598Sjeremylt nx, ny = 3, 2 5960ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 5970ef72598Sjeremylt nqpts = nelem * q 5980ef72598Sjeremylt 5990ef72598Sjeremylt # Vectors 6000ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 6010ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 6020ef72598Sjeremylt for i in range(ndofs): 6030ef72598Sjeremylt x_array[i] = (1. / (nx * 2)) * (i % (nx * 2 + 1)) 6040ef72598Sjeremylt x_array[i + ndofs] = (1. / (ny * 2)) * (i / (nx * 2 + 1)) 6050ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 6060ef72598Sjeremylt 6070ef72598Sjeremylt qdata = ceed.Vector(nqpts) 6080ef72598Sjeremylt u = ceed.Vector(ndofs) 6090ef72598Sjeremylt v = ceed.Vector(ndofs) 6100ef72598Sjeremylt 6110ef72598Sjeremylt # Restrictions 6120ef72598Sjeremylt indx = np.zeros(nelem * p, dtype="int32") 6130ef72598Sjeremylt for i in range(nelem // 2): 6140ef72598Sjeremylt col = i % nx 6150ef72598Sjeremylt row = i // nx 6160ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 6170ef72598Sjeremylt 6180ef72598Sjeremylt indx[i * 2 * p + 0] = 2 + offset 6190ef72598Sjeremylt indx[i * 2 * p + 1] = 9 + offset 6200ef72598Sjeremylt indx[i * 2 * p + 2] = 16 + offset 6210ef72598Sjeremylt indx[i * 2 * p + 3] = 1 + offset 6220ef72598Sjeremylt indx[i * 2 * p + 4] = 8 + offset 6230ef72598Sjeremylt indx[i * 2 * p + 5] = 0 + offset 6240ef72598Sjeremylt 6250ef72598Sjeremylt indx[i * 2 * p + 6] = 14 + offset 6260ef72598Sjeremylt indx[i * 2 * p + 7] = 7 + offset 6270ef72598Sjeremylt indx[i * 2 * p + 8] = 0 + offset 6280ef72598Sjeremylt indx[i * 2 * p + 9] = 15 + offset 6290ef72598Sjeremylt indx[i * 2 * p + 10] = 8 + offset 6300ef72598Sjeremylt indx[i * 2 * p + 11] = 16 + offset 6310ef72598Sjeremylt 6320ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, p, dim, ndofs, dim * ndofs, indx, 6330ef72598Sjeremylt cmode=libceed.USE_POINTER) 6340ef72598Sjeremylt 6350ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, ndofs, indx, 6360ef72598Sjeremylt cmode=libceed.USE_POINTER) 6370ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 6380ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, nqpts, strides) 6390ef72598Sjeremylt 6400ef72598Sjeremylt # Bases 6410ef72598Sjeremylt qref = np.empty(dim * q, dtype="float64") 6420ef72598Sjeremylt qweight = np.empty(q, dtype="float64") 6430ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 6440ef72598Sjeremylt 6450ef72598Sjeremylt bx = ceed.BasisH1(libceed.TRIANGLE, dim, p, q, interp, grad, qref, qweight) 6460ef72598Sjeremylt bu = ceed.BasisH1(libceed.TRIANGLE, 1, p, q, interp, grad, qref, qweight) 6470ef72598Sjeremylt 6480ef72598Sjeremylt # QFunctions 6490ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 6500ef72598Sjeremylt qfs = load_qfs_so() 6510ef72598Sjeremylt 6520ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass_2d, 6530ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 6540ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 6550ef72598Sjeremylt qf_setup.add_input("dx", dim * dim, libceed.EVAL_GRAD) 6560ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 6570ef72598Sjeremylt 6580ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 6590ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 6600ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 6610ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 6620ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 6630ef72598Sjeremylt 6640ef72598Sjeremylt # Operators 6650ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 6660ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 6670ef72598Sjeremylt libceed.VECTOR_NONE) 6680ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 6690ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 6700ef72598Sjeremylt libceed.VECTOR_ACTIVE) 6710ef72598Sjeremylt 6720ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 6730ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 6740ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 6750ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 6760ef72598Sjeremylt 6770ef72598Sjeremylt # Setup 6780ef72598Sjeremylt op_setup.apply(x, qdata) 6790ef72598Sjeremylt 6800ef72598Sjeremylt # Apply mass matrix 6810ef72598Sjeremylt u.set_value(0.) 6820ef72598Sjeremylt op_mass.apply(u, v) 6830ef72598Sjeremylt 6840ef72598Sjeremylt # Check 6850ef72598Sjeremylt with v.array_read() as v_array: 6860ef72598Sjeremylt for i in range(ndofs): 6870ef72598Sjeremylt assert abs(v_array[i]) < TOL 6880ef72598Sjeremylt 6890ef72598Sjeremylt# ------------------------------------------------------------------------------- 6900ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator 6910ef72598Sjeremylt# ------------------------------------------------------------------------------- 6920ef72598Sjeremylt 6930ef72598Sjeremylt 6940ef72598Sjeremyltdef test_511(ceed_resource): 6950ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 6960ef72598Sjeremylt 6970ef72598Sjeremylt nelem = 12 6980ef72598Sjeremylt dim = 2 6990ef72598Sjeremylt p = 6 7000ef72598Sjeremylt q = 4 7010ef72598Sjeremylt nx, ny = 3, 2 7020ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 7030ef72598Sjeremylt nqpts = nelem * q 7040ef72598Sjeremylt 7050ef72598Sjeremylt # Vectors 7060ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 7070ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 7080ef72598Sjeremylt for i in range(ndofs): 7090ef72598Sjeremylt x_array[i] = (1. / (nx * 2)) * (i % (nx * 2 + 1)) 7100ef72598Sjeremylt x_array[i + ndofs] = (1. / (ny * 2)) * (i / (nx * 2 + 1)) 7110ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 7120ef72598Sjeremylt 7130ef72598Sjeremylt qdata = ceed.Vector(nqpts) 7140ef72598Sjeremylt u = ceed.Vector(ndofs) 7150ef72598Sjeremylt v = ceed.Vector(ndofs) 7160ef72598Sjeremylt 7170ef72598Sjeremylt # Restrictions 7180ef72598Sjeremylt indx = np.zeros(nelem * p, dtype="int32") 7190ef72598Sjeremylt for i in range(nelem // 2): 7200ef72598Sjeremylt col = i % nx 7210ef72598Sjeremylt row = i // nx 7220ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 7230ef72598Sjeremylt 7240ef72598Sjeremylt indx[i * 2 * p + 0] = 2 + offset 7250ef72598Sjeremylt indx[i * 2 * p + 1] = 9 + offset 7260ef72598Sjeremylt indx[i * 2 * p + 2] = 16 + offset 7270ef72598Sjeremylt indx[i * 2 * p + 3] = 1 + offset 7280ef72598Sjeremylt indx[i * 2 * p + 4] = 8 + offset 7290ef72598Sjeremylt indx[i * 2 * p + 5] = 0 + offset 7300ef72598Sjeremylt 7310ef72598Sjeremylt indx[i * 2 * p + 6] = 14 + offset 7320ef72598Sjeremylt indx[i * 2 * p + 7] = 7 + offset 7330ef72598Sjeremylt indx[i * 2 * p + 8] = 0 + offset 7340ef72598Sjeremylt indx[i * 2 * p + 9] = 15 + offset 7350ef72598Sjeremylt indx[i * 2 * p + 10] = 8 + offset 7360ef72598Sjeremylt indx[i * 2 * p + 11] = 16 + offset 7370ef72598Sjeremylt 7380ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, p, dim, ndofs, dim * ndofs, indx, 7390ef72598Sjeremylt cmode=libceed.USE_POINTER) 7400ef72598Sjeremylt 7410ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, ndofs, indx, 7420ef72598Sjeremylt cmode=libceed.USE_POINTER) 7430ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 7440ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, nqpts, strides) 7450ef72598Sjeremylt 7460ef72598Sjeremylt # Bases 7470ef72598Sjeremylt qref = np.empty(dim * q, dtype="float64") 7480ef72598Sjeremylt qweight = np.empty(q, dtype="float64") 7490ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 7500ef72598Sjeremylt 7510ef72598Sjeremylt bx = ceed.BasisH1(libceed.TRIANGLE, dim, p, q, interp, grad, qref, qweight) 7520ef72598Sjeremylt bu = ceed.BasisH1(libceed.TRIANGLE, 1, p, q, interp, grad, qref, qweight) 7530ef72598Sjeremylt 7540ef72598Sjeremylt # QFunctions 7550ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 7560ef72598Sjeremylt qfs = load_qfs_so() 7570ef72598Sjeremylt 7580ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass_2d, 7590ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 7600ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 7610ef72598Sjeremylt qf_setup.add_input("dx", dim * dim, libceed.EVAL_GRAD) 7620ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 7630ef72598Sjeremylt 7640ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 7650ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 7660ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 7670ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 7680ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 7690ef72598Sjeremylt 7700ef72598Sjeremylt # Operators 7710ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 7720ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 7730ef72598Sjeremylt libceed.VECTOR_NONE) 7740ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 7750ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 7760ef72598Sjeremylt libceed.VECTOR_ACTIVE) 7770ef72598Sjeremylt 7780ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 7790ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 7800ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 7810ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 7820ef72598Sjeremylt 7830ef72598Sjeremylt # Setup 7840ef72598Sjeremylt op_setup.apply(x, qdata) 7850ef72598Sjeremylt 7860ef72598Sjeremylt # Apply mass matrix 7870ef72598Sjeremylt u.set_value(1.) 7880ef72598Sjeremylt op_mass.apply(u, v) 7890ef72598Sjeremylt 7900ef72598Sjeremylt # Check 7910ef72598Sjeremylt with v.array_read() as v_array: 7920ef72598Sjeremylt total = 0.0 7930ef72598Sjeremylt for i in range(ndofs): 7940ef72598Sjeremylt total = total + v_array[i] 7950ef72598Sjeremylt assert abs(total - 1.0) < 1E-10 7960ef72598Sjeremylt 7970ef72598Sjeremylt# ------------------------------------------------------------------------------- 7980ef72598Sjeremylt# Test creation, action, and destruction for composite mass matrix operator 7990ef72598Sjeremylt# ------------------------------------------------------------------------------- 8000ef72598Sjeremylt 8010ef72598Sjeremylt 8020ef72598Sjeremyltdef test_520(ceed_resource): 8030ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 8040ef72598Sjeremylt 8050ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 8060ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 8070ef72598Sjeremylt nx, ny = 3, 3 8080ef72598Sjeremylt dim = 2 8090ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 8100ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 8110ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 8120ef72598Sjeremylt 8130ef72598Sjeremylt # Vectors 8140ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 8150ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 8160ef72598Sjeremylt for i in range(ny * 2 + 1): 8170ef72598Sjeremylt for j in range(nx * 2 + 1): 8180ef72598Sjeremylt x_array[i + j * (ny * 2 + 1)] = i / (2 * ny) 8190ef72598Sjeremylt x_array[i + j * (ny * 2 + 1) + ndofs] = j / (2 * nx) 8200ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 8210ef72598Sjeremylt 8220ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 8230ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 8240ef72598Sjeremylt u = ceed.Vector(ndofs) 8250ef72598Sjeremylt v = ceed.Vector(ndofs) 8260ef72598Sjeremylt 8270ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 8280ef72598Sjeremylt 8290ef72598Sjeremylt # Restrictions 8300ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 8310ef72598Sjeremylt for i in range(nelem_tet // 2): 8320ef72598Sjeremylt col = i % nx 8330ef72598Sjeremylt row = i // nx 8340ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 8350ef72598Sjeremylt 8360ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 8370ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 8380ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 8390ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 8400ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 8410ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 8420ef72598Sjeremylt 8430ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 8440ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 8450ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 8460ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 8470ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 8480ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 8490ef72598Sjeremylt 8500ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 8510ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 8520ef72598Sjeremylt 8530ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 8540ef72598Sjeremylt cmode=libceed.USE_POINTER) 8550ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 8560ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 8570ef72598Sjeremylt strides) 8580ef72598Sjeremylt 8590ef72598Sjeremylt # Bases 8600ef72598Sjeremylt qref = np.empty(dim * q_tet, dtype="float64") 8610ef72598Sjeremylt qweight = np.empty(q_tet, dtype="float64") 8620ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 8630ef72598Sjeremylt 8640ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 8650ef72598Sjeremylt qweight) 8660ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 8670ef72598Sjeremylt qweight) 8680ef72598Sjeremylt 8690ef72598Sjeremylt # QFunctions 8700ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 8710ef72598Sjeremylt qfs = load_qfs_so() 8720ef72598Sjeremylt 8730ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 8740ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 8750ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 8760ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 8770ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 8780ef72598Sjeremylt 8790ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 8800ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 8810ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 8820ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 8830ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 8840ef72598Sjeremylt 8850ef72598Sjeremylt # Operators 8860ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 8870ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 8880ef72598Sjeremylt libceed.VECTOR_NONE) 8890ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 8900ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 8910ef72598Sjeremylt qdata_tet) 8920ef72598Sjeremylt 8930ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 8940ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 8950ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 8960ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 8970ef72598Sjeremylt 8980ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 8990ef72598Sjeremylt 9000ef72598Sjeremylt # Restrictions 9010ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 9020ef72598Sjeremylt for i in range(nelem_hex): 9030ef72598Sjeremylt col = i % nx_hex 9040ef72598Sjeremylt row = i // nx_hex 9050ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 9060ef72598Sjeremylt 9070ef72598Sjeremylt for j in range(p_hex): 9080ef72598Sjeremylt for k in range(p_hex): 9090ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 9100ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 9110ef72598Sjeremylt 9120ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 9130ef72598Sjeremylt dim * ndofs, indx_hex, cmode=libceed.USE_POINTER) 9140ef72598Sjeremylt 9150ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 9160ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 9170ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 9180ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 9190ef72598Sjeremylt nqpts_hex, strides) 9200ef72598Sjeremylt 9210ef72598Sjeremylt # Bases 9220ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 9230ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 9240ef72598Sjeremylt 9250ef72598Sjeremylt # QFunctions 9260ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 9270ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 9280ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 9290ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 9300ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 9310ef72598Sjeremylt 9320ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 9330ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 9340ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 9350ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 9360ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 9370ef72598Sjeremylt 9380ef72598Sjeremylt # Operators 9390ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 9400ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 9410ef72598Sjeremylt libceed.VECTOR_NONE) 9420ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 9430ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 9440ef72598Sjeremylt qdata_hex) 9450ef72598Sjeremylt 9460ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 9470ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 9480ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 9490ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 9500ef72598Sjeremylt 9510ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 9520ef72598Sjeremylt 9530ef72598Sjeremylt # Setup 9540ef72598Sjeremylt op_setup = ceed.CompositeOperator() 9550ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 9560ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 9570ef72598Sjeremylt op_setup.apply(x, libceed.VECTOR_NONE) 9580ef72598Sjeremylt 9590ef72598Sjeremylt # Apply mass matrix 9600ef72598Sjeremylt op_mass = ceed.CompositeOperator() 9610ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 9620ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 9630ef72598Sjeremylt 9640ef72598Sjeremylt u.set_value(0.) 9650ef72598Sjeremylt op_mass.apply(u, v) 9660ef72598Sjeremylt 9670ef72598Sjeremylt # Check 9680ef72598Sjeremylt with v.array_read() as v_array: 9690ef72598Sjeremylt for i in range(ndofs): 9700ef72598Sjeremylt assert abs(v_array[i]) < TOL 9710ef72598Sjeremylt 9720ef72598Sjeremylt# ------------------------------------------------------------------------------- 9730ef72598Sjeremylt# Test creation, action, and destruction for composite mass matrix operator 9740ef72598Sjeremylt# ------------------------------------------------------------------------------- 9750ef72598Sjeremylt 9760ef72598Sjeremylt 9770ef72598Sjeremyltdef test_521(ceed_resource): 9780ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 9790ef72598Sjeremylt 9800ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 9810ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 9820ef72598Sjeremylt nx, ny = 3, 3 9830ef72598Sjeremylt dim = 2 9840ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 9850ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 9860ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 9870ef72598Sjeremylt 9880ef72598Sjeremylt # Vectors 9890ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 9900ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 9910ef72598Sjeremylt for i in range(ny * 2 + 1): 9920ef72598Sjeremylt for j in range(nx * 2 + 1): 9930ef72598Sjeremylt x_array[i + j * (ny * 2 + 1)] = i / (2 * ny) 9940ef72598Sjeremylt x_array[i + j * (ny * 2 + 1) + ndofs] = j / (2 * nx) 9950ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 9960ef72598Sjeremylt 9970ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 9980ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 9990ef72598Sjeremylt u = ceed.Vector(ndofs) 10000ef72598Sjeremylt v = ceed.Vector(ndofs) 10010ef72598Sjeremylt 10020ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 10030ef72598Sjeremylt 10040ef72598Sjeremylt # Restrictions 10050ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 10060ef72598Sjeremylt for i in range(nelem_tet // 2): 10070ef72598Sjeremylt col = i % nx 10080ef72598Sjeremylt row = i // nx 10090ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 10100ef72598Sjeremylt 10110ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 10120ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 10130ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 10140ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 10150ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 10160ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 10170ef72598Sjeremylt 10180ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 10190ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 10200ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 10210ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 10220ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 10230ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 10240ef72598Sjeremylt 10250ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 10260ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 10270ef72598Sjeremylt 10280ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 10290ef72598Sjeremylt cmode=libceed.USE_POINTER) 10300ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 10310ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 10320ef72598Sjeremylt strides) 10330ef72598Sjeremylt 10340ef72598Sjeremylt # Bases 10350ef72598Sjeremylt qref = np.empty(dim * q_tet, dtype="float64") 10360ef72598Sjeremylt qweight = np.empty(q_tet, dtype="float64") 10370ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 10380ef72598Sjeremylt 10390ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 10400ef72598Sjeremylt qweight) 10410ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 10420ef72598Sjeremylt qweight) 10430ef72598Sjeremylt 10440ef72598Sjeremylt # QFunctions 10450ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 10460ef72598Sjeremylt qfs = load_qfs_so() 10470ef72598Sjeremylt 10480ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 10490ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 10500ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 10510ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 10520ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 10530ef72598Sjeremylt 10540ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 10550ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 10560ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 10570ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 10580ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 10590ef72598Sjeremylt 10600ef72598Sjeremylt # Operators 10610ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 10620ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 10630ef72598Sjeremylt libceed.VECTOR_NONE) 10640ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 10650ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 10660ef72598Sjeremylt qdata_tet) 10670ef72598Sjeremylt 10680ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 10690ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 10700ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 10710ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 10720ef72598Sjeremylt 10730ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 10740ef72598Sjeremylt 10750ef72598Sjeremylt # Restrictions 10760ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 10770ef72598Sjeremylt for i in range(nelem_hex): 10780ef72598Sjeremylt col = i % nx_hex 10790ef72598Sjeremylt row = i // nx_hex 10800ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 10810ef72598Sjeremylt 10820ef72598Sjeremylt for j in range(p_hex): 10830ef72598Sjeremylt for k in range(p_hex): 10840ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 10850ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 10860ef72598Sjeremylt 10870ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 10880ef72598Sjeremylt dim * ndofs, indx_hex, cmode=libceed.USE_POINTER) 10890ef72598Sjeremylt 10900ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 10910ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 10920ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 10930ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 10940ef72598Sjeremylt nqpts_hex, strides) 10950ef72598Sjeremylt 10960ef72598Sjeremylt # Bases 10970ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 10980ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 10990ef72598Sjeremylt 11000ef72598Sjeremylt # QFunctions 11010ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 11020ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 11030ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 11040ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 11050ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 11060ef72598Sjeremylt 11070ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 11080ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 11090ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 11100ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 11110ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 11120ef72598Sjeremylt 11130ef72598Sjeremylt # Operators 11140ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 11150ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 11160ef72598Sjeremylt libceed.VECTOR_NONE) 11170ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 11180ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 11190ef72598Sjeremylt qdata_hex) 11200ef72598Sjeremylt 11210ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 11220ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 11230ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 11240ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 11250ef72598Sjeremylt 11260ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 11270ef72598Sjeremylt 11280ef72598Sjeremylt # Setup 11290ef72598Sjeremylt op_setup = ceed.CompositeOperator() 11300ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 11310ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 11320ef72598Sjeremylt op_setup.apply(x, libceed.VECTOR_NONE) 11330ef72598Sjeremylt 11340ef72598Sjeremylt # Apply mass matrix 11350ef72598Sjeremylt op_mass = ceed.CompositeOperator() 11360ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 11370ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 11380ef72598Sjeremylt u.set_value(1.) 11390ef72598Sjeremylt op_mass.apply(u, v) 11400ef72598Sjeremylt 11410ef72598Sjeremylt # Check 11420ef72598Sjeremylt with v.array_read() as v_array: 11430ef72598Sjeremylt total = 0.0 11440ef72598Sjeremylt for i in range(ndofs): 11450ef72598Sjeremylt total = total + v_array[i] 11460ef72598Sjeremylt assert abs(total - 1.0) < 1E-10 11470ef72598Sjeremylt 11480ef72598Sjeremylt# ------------------------------------------------------------------------------- 11490ef72598Sjeremylt# Test viewing of composite mass matrix operator 11500ef72598Sjeremylt# ------------------------------------------------------------------------------- 11510ef72598Sjeremylt 11520ef72598Sjeremylt 11530ef72598Sjeremyltdef test_523(ceed_resource, capsys): 11540ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 11550ef72598Sjeremylt 11560ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 11570ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 11580ef72598Sjeremylt nx, ny = 3, 3 11590ef72598Sjeremylt dim = 2 11600ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 11610ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 11620ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 11630ef72598Sjeremylt 11640ef72598Sjeremylt # Vectors 11650ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 11660ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 11670ef72598Sjeremylt 11680ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 11690ef72598Sjeremylt 11700ef72598Sjeremylt # Restrictions 11710ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 11720ef72598Sjeremylt for i in range(nelem_tet // 2): 11730ef72598Sjeremylt col = i % nx 11740ef72598Sjeremylt row = i // nx 11750ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 11760ef72598Sjeremylt 11770ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 11780ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 11790ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 11800ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 11810ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 11820ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 11830ef72598Sjeremylt 11840ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 11850ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 11860ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 11870ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 11880ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 11890ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 11900ef72598Sjeremylt 11910ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 11920ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 11930ef72598Sjeremylt 11940ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 11950ef72598Sjeremylt cmode=libceed.USE_POINTER) 11960ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 11970ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 11980ef72598Sjeremylt strides) 11990ef72598Sjeremylt 12000ef72598Sjeremylt # Bases 12010ef72598Sjeremylt qref = np.empty(dim * q_tet, dtype="float64") 12020ef72598Sjeremylt qweight = np.empty(q_tet, dtype="float64") 12030ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 12040ef72598Sjeremylt 12050ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 12060ef72598Sjeremylt qweight) 12070ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 12080ef72598Sjeremylt qweight) 12090ef72598Sjeremylt 12100ef72598Sjeremylt # QFunctions 12110ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 12120ef72598Sjeremylt qfs = load_qfs_so() 12130ef72598Sjeremylt 12140ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 12150ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 12160ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 12170ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 12180ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 12190ef72598Sjeremylt 12200ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 12210ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 12220ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 12230ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 12240ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 12250ef72598Sjeremylt 12260ef72598Sjeremylt # Operators 12270ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 12280ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 12290ef72598Sjeremylt libceed.VECTOR_NONE) 12300ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 12310ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 12320ef72598Sjeremylt qdata_tet) 12330ef72598Sjeremylt 12340ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 12350ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 12360ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 12370ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 12380ef72598Sjeremylt 12390ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 12400ef72598Sjeremylt 12410ef72598Sjeremylt # Restrictions 12420ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 12430ef72598Sjeremylt for i in range(nelem_hex): 12440ef72598Sjeremylt col = i % nx_hex 12450ef72598Sjeremylt row = i // nx_hex 12460ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 12470ef72598Sjeremylt 12480ef72598Sjeremylt for j in range(p_hex): 12490ef72598Sjeremylt for k in range(p_hex): 12500ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 12510ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 12520ef72598Sjeremylt 12530ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 12540ef72598Sjeremylt dim * ndofs, indx_hex, 12550ef72598Sjeremylt cmode=libceed.USE_POINTER) 12560ef72598Sjeremylt 12570ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 12580ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 12590ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 12600ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 12610ef72598Sjeremylt nqpts_hex, strides) 12620ef72598Sjeremylt 12630ef72598Sjeremylt # Bases 12640ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 12650ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 12660ef72598Sjeremylt 12670ef72598Sjeremylt # QFunctions 12680ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 12690ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 12700ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 12710ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 12720ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 12730ef72598Sjeremylt 12740ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 12750ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 12760ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 12770ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 12780ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 12790ef72598Sjeremylt 12800ef72598Sjeremylt # Operators 12810ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 12820ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 12830ef72598Sjeremylt libceed.VECTOR_NONE) 12840ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 12850ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 12860ef72598Sjeremylt qdata_hex) 12870ef72598Sjeremylt 12880ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 12890ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 12900ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 12910ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 12920ef72598Sjeremylt 12930ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 12940ef72598Sjeremylt 12950ef72598Sjeremylt # Setup 12960ef72598Sjeremylt op_setup = ceed.CompositeOperator() 12970ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 12980ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 12990ef72598Sjeremylt 13000ef72598Sjeremylt # Apply mass matrix 13010ef72598Sjeremylt op_mass = ceed.CompositeOperator() 13020ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 13030ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 13040ef72598Sjeremylt 13050ef72598Sjeremylt # View 13060ef72598Sjeremylt print(op_setup) 13070ef72598Sjeremylt print(op_mass) 13080ef72598Sjeremylt 13090ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 13100ef72598Sjeremylt assert not stderr 13110ef72598Sjeremylt assert stdout == ref_stdout 13120ef72598Sjeremylt 13130ef72598Sjeremylt# ------------------------------------------------------------------------------- 13140ef72598Sjeremylt# CeedOperatorApplyAdd for composite operator 13150ef72598Sjeremylt# ------------------------------------------------------------------------------- 13160ef72598Sjeremylt 13170ef72598Sjeremylt 13180ef72598Sjeremyltdef test_524(ceed_resource): 13190ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 13200ef72598Sjeremylt 13210ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 13220ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 13230ef72598Sjeremylt nx, ny = 3, 3 13240ef72598Sjeremylt dim = 2 13250ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 13260ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 13270ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 13280ef72598Sjeremylt 13290ef72598Sjeremylt # Vectors 13300ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 13310ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 13320ef72598Sjeremylt for i in range(ny * 2 + 1): 13330ef72598Sjeremylt for j in range(nx * 2 + 1): 13340ef72598Sjeremylt x_array[i + j * (ny * 2 + 1)] = i / (2 * ny) 13350ef72598Sjeremylt x_array[i + j * (ny * 2 + 1) + ndofs] = j / (2 * nx) 13360ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 13370ef72598Sjeremylt 13380ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 13390ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 13400ef72598Sjeremylt u = ceed.Vector(ndofs) 13410ef72598Sjeremylt v = ceed.Vector(ndofs) 13420ef72598Sjeremylt 13430ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 13440ef72598Sjeremylt 13450ef72598Sjeremylt # Restrictions 13460ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 13470ef72598Sjeremylt for i in range(nelem_tet // 2): 13480ef72598Sjeremylt col = i % nx 13490ef72598Sjeremylt row = i // nx 13500ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 13510ef72598Sjeremylt 13520ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 13530ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 13540ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 13550ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 13560ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 13570ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 13580ef72598Sjeremylt 13590ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 13600ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 13610ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 13620ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 13630ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 13640ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 13650ef72598Sjeremylt 13660ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 13670ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 13680ef72598Sjeremylt 13690ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 13700ef72598Sjeremylt cmode=libceed.USE_POINTER) 13710ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 13720ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 13730ef72598Sjeremylt strides) 13740ef72598Sjeremylt 13750ef72598Sjeremylt # Bases 13760ef72598Sjeremylt qref = np.empty(dim * q_tet, dtype="float64") 13770ef72598Sjeremylt qweight = np.empty(q_tet, dtype="float64") 13780ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 13790ef72598Sjeremylt 13800ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 13810ef72598Sjeremylt qweight) 13820ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 13830ef72598Sjeremylt qweight) 13840ef72598Sjeremylt 13850ef72598Sjeremylt # QFunctions 13860ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 13870ef72598Sjeremylt qfs = load_qfs_so() 13880ef72598Sjeremylt 13890ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 13900ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 13910ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 13920ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 13930ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 13940ef72598Sjeremylt 13950ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 13960ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 13970ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 13980ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 13990ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 14000ef72598Sjeremylt 14010ef72598Sjeremylt # Operators 14020ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 14030ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 14040ef72598Sjeremylt libceed.VECTOR_NONE) 14050ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 14060ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 14070ef72598Sjeremylt qdata_tet) 14080ef72598Sjeremylt 14090ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 14100ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 14110ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 14120ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 14130ef72598Sjeremylt 14140ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 14150ef72598Sjeremylt 14160ef72598Sjeremylt # Restrictions 14170ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 14180ef72598Sjeremylt for i in range(nelem_hex): 14190ef72598Sjeremylt col = i % nx_hex 14200ef72598Sjeremylt row = i // nx_hex 14210ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 14220ef72598Sjeremylt 14230ef72598Sjeremylt for j in range(p_hex): 14240ef72598Sjeremylt for k in range(p_hex): 14250ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 14260ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 14270ef72598Sjeremylt 14280ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 14290ef72598Sjeremylt dim * ndofs, indx_hex, 14300ef72598Sjeremylt cmode=libceed.USE_POINTER) 14310ef72598Sjeremylt 14320ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 14330ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 14340ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 14350ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 14360ef72598Sjeremylt nqpts_hex, strides) 14370ef72598Sjeremylt 14380ef72598Sjeremylt # Bases 14390ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 14400ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 14410ef72598Sjeremylt 14420ef72598Sjeremylt # QFunctions 14430ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 14440ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 14450ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 14460ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 14470ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 14480ef72598Sjeremylt 14490ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 14500ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 14510ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 14520ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 14530ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 14540ef72598Sjeremylt 14550ef72598Sjeremylt # Operators 14560ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 14570ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 14580ef72598Sjeremylt libceed.VECTOR_NONE) 14590ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 14600ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 14610ef72598Sjeremylt qdata_hex) 14620ef72598Sjeremylt 14630ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 14640ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 14650ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 14660ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 14670ef72598Sjeremylt 14680ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 14690ef72598Sjeremylt 14700ef72598Sjeremylt # Setup 14710ef72598Sjeremylt op_setup = ceed.CompositeOperator() 14720ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 14730ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 14740ef72598Sjeremylt op_setup.apply(x, libceed.VECTOR_NONE) 14750ef72598Sjeremylt 14760ef72598Sjeremylt # Apply mass matrix 14770ef72598Sjeremylt op_mass = ceed.CompositeOperator() 14780ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 14790ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 14800ef72598Sjeremylt u.set_value(1.) 14810ef72598Sjeremylt op_mass.apply(u, v) 14820ef72598Sjeremylt 14830ef72598Sjeremylt # Check 14840ef72598Sjeremylt with v.array_read() as v_array: 14850ef72598Sjeremylt total = 0.0 14860ef72598Sjeremylt for i in range(ndofs): 14870ef72598Sjeremylt total = total + v_array[i] 14880ef72598Sjeremylt assert abs(total - 1.0) < 1E-10 14890ef72598Sjeremylt 14900ef72598Sjeremylt # ApplyAdd mass matrix 14910ef72598Sjeremylt v.set_value(1.) 14920ef72598Sjeremylt op_mass.apply_add(u, v) 14930ef72598Sjeremylt 14940ef72598Sjeremylt # Check 14950ef72598Sjeremylt with v.array_read() as v_array: 14960ef72598Sjeremylt total = -ndofs 14970ef72598Sjeremylt for i in range(ndofs): 14980ef72598Sjeremylt total = total + v_array[i] 14990ef72598Sjeremylt assert abs(total - 1.0) < 1E-10 15000ef72598Sjeremylt 15010ef72598Sjeremylt# ------------------------------------------------------------------------------- 15020ef72598Sjeremylt# Test assembly of mass matrix operator diagonal 15030ef72598Sjeremylt# ------------------------------------------------------------------------------- 15040ef72598Sjeremylt 15050ef72598Sjeremylt 15060ef72598Sjeremyltdef test_533(ceed_resource): 15070ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 15080ef72598Sjeremylt 15090ef72598Sjeremylt nelem = 6 15100ef72598Sjeremylt p = 3 15110ef72598Sjeremylt q = 4 15120ef72598Sjeremylt dim = 2 15130ef72598Sjeremylt nx = 3 15140ef72598Sjeremylt ny = 2 15150ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 15160ef72598Sjeremylt nqpts = nelem * q * q 15170ef72598Sjeremylt 15180ef72598Sjeremylt # Vectors 15190ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 15200ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 15210ef72598Sjeremylt for i in range(nx * 2 + 1): 15220ef72598Sjeremylt for j in range(ny * 2 + 1): 15230ef72598Sjeremylt x_array[i + j * (nx * 2 + 1) + 0 * ndofs] = i / (2 * nx) 15240ef72598Sjeremylt x_array[i + j * (nx * 2 + 1) + 1 * ndofs] = j / (2 * ny) 15250ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 15260ef72598Sjeremylt 15270ef72598Sjeremylt qdata = ceed.Vector(nqpts) 15280ef72598Sjeremylt u = ceed.Vector(ndofs) 15290ef72598Sjeremylt v = ceed.Vector(ndofs) 15300ef72598Sjeremylt 15310ef72598Sjeremylt # Restrictions 15320ef72598Sjeremylt indx = np.zeros(nelem * p * p, dtype="int32") 15330ef72598Sjeremylt for i in range(nelem): 15340ef72598Sjeremylt col = i % nx 15350ef72598Sjeremylt row = i // nx 15360ef72598Sjeremylt offset = col * (p - 1) + row * (nx * 2 + 1) * (p - 1) 15370ef72598Sjeremylt for j in range(p): 15380ef72598Sjeremylt for k in range(p): 15390ef72598Sjeremylt indx[p * (p * i + k) + j] = offset + k * (nx * 2 + 1) + j 15400ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, p * p, dim, ndofs, dim * ndofs, 15410ef72598Sjeremylt indx, cmode=libceed.USE_POINTER) 15420ef72598Sjeremylt 15430ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p * p, 1, 1, ndofs, indx, 15440ef72598Sjeremylt cmode=libceed.USE_POINTER) 15450ef72598Sjeremylt strides = np.array([1, q * q, q * q], dtype="int32") 15460ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q * q, 1, nqpts, strides) 15470ef72598Sjeremylt 15480ef72598Sjeremylt # Bases 15490ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(dim, dim, p, q, libceed.GAUSS) 15500ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(dim, 1, p, q, libceed.GAUSS) 15510ef72598Sjeremylt 15520ef72598Sjeremylt # QFunctions 15530ef72598Sjeremylt qf_setup = ceed.QFunctionByName("Mass2DBuild") 15540ef72598Sjeremylt 15550ef72598Sjeremylt# ------------------------------------------------------------------------------- 15560ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 15570ef72598Sjeremylt# multigrid level, tensor basis and interpolation basis generation 15580ef72598Sjeremylt# ------------------------------------------------------------------------------- 15590ef72598Sjeremylt 15600ef72598Sjeremylt 15610ef72598Sjeremyltdef test_550(ceed_resource): 15620ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 15630ef72598Sjeremylt 15640ef72598Sjeremylt nelem = 15 15650ef72598Sjeremylt p_coarse = 3 15660ef72598Sjeremylt p_fine = 5 15670ef72598Sjeremylt q = 8 15680ef72598Sjeremylt ncomp = 2 15690ef72598Sjeremylt nx = nelem + 1 15700ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 15710ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 15720ef72598Sjeremylt 15730ef72598Sjeremylt # Vectors 15740ef72598Sjeremylt x = ceed.Vector(nx) 15750ef72598Sjeremylt x_array = np.zeros(nx) 15760ef72598Sjeremylt for i in range(nx): 15770ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 15780ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 15790ef72598Sjeremylt 15800ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 15810ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 15820ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 15830ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 15840ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 15850ef72598Sjeremylt 15860ef72598Sjeremylt # Restrictions 15870ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 15880ef72598Sjeremylt for i in range(nx): 15890ef72598Sjeremylt indx[2 * i + 0] = i 15900ef72598Sjeremylt indx[2 * i + 1] = i + 1 15910ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 15920ef72598Sjeremylt cmode=libceed.USE_POINTER) 15930ef72598Sjeremylt 15940ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 15950ef72598Sjeremylt for i in range(nelem): 15960ef72598Sjeremylt for j in range(p_coarse): 15970ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 15980ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 15990ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 16000ef72598Sjeremylt cmode=libceed.USE_POINTER) 16010ef72598Sjeremylt 16020ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 16030ef72598Sjeremylt for i in range(nelem): 16040ef72598Sjeremylt for j in range(p_fine): 16050ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 16060ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 16070ef72598Sjeremylt ncomp * nu_fine, indu_fine, 16080ef72598Sjeremylt cmode=libceed.USE_POINTER) 16090ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 16100ef72598Sjeremylt 16110ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 16120ef72598Sjeremylt 16130ef72598Sjeremylt # Bases 16140ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 16150ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 16160ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 16170ef72598Sjeremylt 16180ef72598Sjeremylt # QFunctions 16190ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 16200ef72598Sjeremylt qfs = load_qfs_so() 16210ef72598Sjeremylt 16220ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 16230ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 16240ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 16250ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 16260ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 16270ef72598Sjeremylt 16280ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass_two, 16290ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass_two")) 16300ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 16310ef72598Sjeremylt qf_mass.add_input("u", ncomp, libceed.EVAL_INTERP) 16320ef72598Sjeremylt qf_mass.add_output("v", ncomp, libceed.EVAL_INTERP) 16330ef72598Sjeremylt 16340ef72598Sjeremylt # Operators 16350ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 16360ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 16370ef72598Sjeremylt libceed.VECTOR_NONE) 16380ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 16390ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 16400ef72598Sjeremylt libceed.VECTOR_ACTIVE) 16410ef72598Sjeremylt 16420ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 16430ef72598Sjeremylt op_mass_fine.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 16440ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 16450ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 16460ef72598Sjeremylt 16470ef72598Sjeremylt # Setup 16480ef72598Sjeremylt op_setup.apply(x, qdata) 16490ef72598Sjeremylt 16500ef72598Sjeremylt # Create multigrid level 16510ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 16520ef72598Sjeremylt p_mult_fine.set_value(1.0) 16530ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create(p_mult_fine, 16540ef72598Sjeremylt ru_coarse, 16550ef72598Sjeremylt bu_coarse) 16560ef72598Sjeremylt 16570ef72598Sjeremylt # Apply coarse mass matrix 16580ef72598Sjeremylt u_coarse.set_value(1.0) 16590ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 16600ef72598Sjeremylt 16610ef72598Sjeremylt # Check 16620ef72598Sjeremylt with v_coarse.array_read() as v_array: 16630ef72598Sjeremylt total = 0.0 16640ef72598Sjeremylt for i in range(nu_coarse * ncomp): 16650ef72598Sjeremylt total = total + v_array[i] 16660ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 16670ef72598Sjeremylt 16680ef72598Sjeremylt # Prolong coarse u 16690ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 16700ef72598Sjeremylt 16710ef72598Sjeremylt # Apply mass matrix 16720ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 16730ef72598Sjeremylt 16740ef72598Sjeremylt # Check 16750ef72598Sjeremylt with v_fine.array_read() as v_array: 16760ef72598Sjeremylt total = 0.0 16770ef72598Sjeremylt for i in range(nu_fine * ncomp): 16780ef72598Sjeremylt total = total + v_array[i] 16790ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 16800ef72598Sjeremylt 16810ef72598Sjeremylt # Restrict state to coarse grid 16820ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 16830ef72598Sjeremylt 16840ef72598Sjeremylt # Check 16850ef72598Sjeremylt with v_coarse.array_read() as v_array: 16860ef72598Sjeremylt total = 0.0 16870ef72598Sjeremylt for i in range(nu_coarse * ncomp): 16880ef72598Sjeremylt total = total + v_array[i] 16890ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 16900ef72598Sjeremylt 16910ef72598Sjeremylt# ------------------------------------------------------------------------------- 16920ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 16930ef72598Sjeremylt# multigrid level, tensor basis 16940ef72598Sjeremylt# ------------------------------------------------------------------------------- 16950ef72598Sjeremylt 16960ef72598Sjeremylt 16970ef72598Sjeremyltdef test_552(ceed_resource): 16980ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 16990ef72598Sjeremylt 17000ef72598Sjeremylt nelem = 15 17010ef72598Sjeremylt p_coarse = 3 17020ef72598Sjeremylt p_fine = 5 17030ef72598Sjeremylt q = 8 17040ef72598Sjeremylt ncomp = 2 17050ef72598Sjeremylt nx = nelem + 1 17060ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 17070ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 17080ef72598Sjeremylt 17090ef72598Sjeremylt # Vectors 17100ef72598Sjeremylt x = ceed.Vector(nx) 17110ef72598Sjeremylt x_array = np.zeros(nx) 17120ef72598Sjeremylt for i in range(nx): 17130ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 17140ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 17150ef72598Sjeremylt 17160ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 17170ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 17180ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 17190ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 17200ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 17210ef72598Sjeremylt 17220ef72598Sjeremylt # Restrictions 17230ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 17240ef72598Sjeremylt for i in range(nx): 17250ef72598Sjeremylt indx[2 * i + 0] = i 17260ef72598Sjeremylt indx[2 * i + 1] = i + 1 17270ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 17280ef72598Sjeremylt cmode=libceed.USE_POINTER) 17290ef72598Sjeremylt 17300ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 17310ef72598Sjeremylt for i in range(nelem): 17320ef72598Sjeremylt for j in range(p_coarse): 17330ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 17340ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 17350ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 17360ef72598Sjeremylt cmode=libceed.USE_POINTER) 17370ef72598Sjeremylt 17380ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 17390ef72598Sjeremylt for i in range(nelem): 17400ef72598Sjeremylt for j in range(p_fine): 17410ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 17420ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 17430ef72598Sjeremylt ncomp * nu_fine, indu_fine, 17440ef72598Sjeremylt cmode=libceed.USE_POINTER) 17450ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 17460ef72598Sjeremylt 17470ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 17480ef72598Sjeremylt 17490ef72598Sjeremylt # Bases 17500ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 17510ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 17520ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 17530ef72598Sjeremylt 17540ef72598Sjeremylt # QFunctions 17550ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 17560ef72598Sjeremylt qfs = load_qfs_so() 17570ef72598Sjeremylt 17580ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 17590ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 17600ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 17610ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 17620ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 17630ef72598Sjeremylt 17640ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass_two, 17650ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass_two")) 17660ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 17670ef72598Sjeremylt qf_mass.add_input("u", ncomp, libceed.EVAL_INTERP) 17680ef72598Sjeremylt qf_mass.add_output("v", ncomp, libceed.EVAL_INTERP) 17690ef72598Sjeremylt 17700ef72598Sjeremylt # Operators 17710ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 17720ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 17730ef72598Sjeremylt libceed.VECTOR_NONE) 17740ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 17750ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 17760ef72598Sjeremylt libceed.VECTOR_ACTIVE) 17770ef72598Sjeremylt 17780ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 17790ef72598Sjeremylt op_mass_fine.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 17800ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 17810ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 17820ef72598Sjeremylt 17830ef72598Sjeremylt # Setup 17840ef72598Sjeremylt op_setup.apply(x, qdata) 17850ef72598Sjeremylt 17860ef72598Sjeremylt # Create multigrid level 17870ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 17880ef72598Sjeremylt p_mult_fine.set_value(1.0) 17890ef72598Sjeremylt b_c_to_f = ceed.BasisTensorH1Lagrange( 17900ef72598Sjeremylt 1, ncomp, p_coarse, p_fine, libceed.GAUSS_LOBATTO) 1791*66ce82e0Sjeremylt interp_C_to_F = b_c_to_f.get_interp_1d() 17920ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create_tensor_h1(p_mult_fine, 17930ef72598Sjeremylt ru_coarse, bu_coarse, interp_C_to_F) 17940ef72598Sjeremylt 17950ef72598Sjeremylt # Apply coarse mass matrix 17960ef72598Sjeremylt u_coarse.set_value(1.0) 17970ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 17980ef72598Sjeremylt 17990ef72598Sjeremylt # Check 18000ef72598Sjeremylt with v_coarse.array_read() as v_array: 18010ef72598Sjeremylt total = 0.0 18020ef72598Sjeremylt for i in range(nu_coarse * ncomp): 18030ef72598Sjeremylt total = total + v_array[i] 18040ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 18050ef72598Sjeremylt 18060ef72598Sjeremylt # Prolong coarse u 18070ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 18080ef72598Sjeremylt 18090ef72598Sjeremylt # Apply mass matrix 18100ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 18110ef72598Sjeremylt 18120ef72598Sjeremylt # Check 18130ef72598Sjeremylt with v_fine.array_read() as v_array: 18140ef72598Sjeremylt total = 0.0 18150ef72598Sjeremylt for i in range(nu_fine * ncomp): 18160ef72598Sjeremylt total = total + v_array[i] 18170ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 18180ef72598Sjeremylt 18190ef72598Sjeremylt # Restrict state to coarse grid 18200ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 18210ef72598Sjeremylt 18220ef72598Sjeremylt # Check 18230ef72598Sjeremylt with v_coarse.array_read() as v_array: 18240ef72598Sjeremylt total = 0.0 18250ef72598Sjeremylt for i in range(nu_coarse * ncomp): 18260ef72598Sjeremylt total = total + v_array[i] 18270ef72598Sjeremylt assert abs(total - 2.0) < 1E-13 18280ef72598Sjeremylt 18290ef72598Sjeremylt# ------------------------------------------------------------------------------- 18300ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 18310ef72598Sjeremylt# multigrid level, non-tensor basis 18320ef72598Sjeremylt# ------------------------------------------------------------------------------- 18330ef72598Sjeremylt 18340ef72598Sjeremylt 18350ef72598Sjeremyltdef test_553(ceed_resource): 18360ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 18370ef72598Sjeremylt 18380ef72598Sjeremylt nelem = 15 18390ef72598Sjeremylt p_coarse = 3 18400ef72598Sjeremylt p_fine = 5 18410ef72598Sjeremylt q = 8 18420ef72598Sjeremylt ncomp = 1 18430ef72598Sjeremylt nx = nelem + 1 18440ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 18450ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 18460ef72598Sjeremylt 18470ef72598Sjeremylt # Vectors 18480ef72598Sjeremylt x = ceed.Vector(nx) 18490ef72598Sjeremylt x_array = np.zeros(nx) 18500ef72598Sjeremylt for i in range(nx): 18510ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 18520ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 18530ef72598Sjeremylt 18540ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 18550ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 18560ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 18570ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 18580ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 18590ef72598Sjeremylt 18600ef72598Sjeremylt # Restrictions 18610ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 18620ef72598Sjeremylt for i in range(nx): 18630ef72598Sjeremylt indx[2 * i + 0] = i 18640ef72598Sjeremylt indx[2 * i + 1] = i + 1 18650ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 18660ef72598Sjeremylt cmode=libceed.USE_POINTER) 18670ef72598Sjeremylt 18680ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 18690ef72598Sjeremylt for i in range(nelem): 18700ef72598Sjeremylt for j in range(p_coarse): 18710ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 18720ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 18730ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 18740ef72598Sjeremylt cmode=libceed.USE_POINTER) 18750ef72598Sjeremylt 18760ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 18770ef72598Sjeremylt for i in range(nelem): 18780ef72598Sjeremylt for j in range(p_fine): 18790ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 18800ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 18810ef72598Sjeremylt ncomp * nu_fine, indu_fine, 18820ef72598Sjeremylt cmode=libceed.USE_POINTER) 18830ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 18840ef72598Sjeremylt 18850ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 18860ef72598Sjeremylt 18870ef72598Sjeremylt # Bases 18880ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 18890ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 18900ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 18910ef72598Sjeremylt 18920ef72598Sjeremylt # QFunctions 18930ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 18940ef72598Sjeremylt qfs = load_qfs_so() 18950ef72598Sjeremylt 18960ef72598Sjeremylt qf_setup = ceed.QFunctionByName("Mass1DBuild") 18970ef72598Sjeremylt qf_mass = ceed.QFunctionByName("MassApply") 18980ef72598Sjeremylt 18990ef72598Sjeremylt # Operators 19000ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 19010ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 19020ef72598Sjeremylt libceed.VECTOR_NONE) 19030ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 19040ef72598Sjeremylt op_setup.set_field("qdata", rui, libceed.BASIS_COLLOCATED, 19050ef72598Sjeremylt libceed.VECTOR_ACTIVE) 19060ef72598Sjeremylt 19070ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 19080ef72598Sjeremylt op_mass_fine.set_field("qdata", rui, libceed.BASIS_COLLOCATED, qdata) 19090ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 19100ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 19110ef72598Sjeremylt 19120ef72598Sjeremylt # Setup 19130ef72598Sjeremylt op_setup.apply(x, qdata) 19140ef72598Sjeremylt 19150ef72598Sjeremylt # Create multigrid level 19160ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 19170ef72598Sjeremylt p_mult_fine.set_value(1.0) 19180ef72598Sjeremylt b_c_to_f = ceed.BasisTensorH1Lagrange( 19190ef72598Sjeremylt 1, ncomp, p_coarse, p_fine, libceed.GAUSS_LOBATTO) 1920*66ce82e0Sjeremylt interp_C_to_F = b_c_to_f.get_interp_1d() 19210ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create_h1(p_mult_fine, 19220ef72598Sjeremylt ru_coarse, bu_coarse, interp_C_to_F) 19230ef72598Sjeremylt 19240ef72598Sjeremylt # Apply coarse mass matrix 19250ef72598Sjeremylt u_coarse.set_value(1.0) 19260ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 19270ef72598Sjeremylt 19280ef72598Sjeremylt # Check 19290ef72598Sjeremylt with v_coarse.array_read() as v_array: 19300ef72598Sjeremylt total = 0.0 19310ef72598Sjeremylt for i in range(nu_coarse * ncomp): 19320ef72598Sjeremylt total = total + v_array[i] 19330ef72598Sjeremylt assert abs(total - 1.0) < 1E-13 19340ef72598Sjeremylt 19350ef72598Sjeremylt # Prolong coarse u 19360ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 19370ef72598Sjeremylt 19380ef72598Sjeremylt # Apply mass matrix 19390ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 19400ef72598Sjeremylt 19410ef72598Sjeremylt # Check 19420ef72598Sjeremylt with v_fine.array_read() as v_array: 19430ef72598Sjeremylt total = 0.0 19440ef72598Sjeremylt for i in range(nu_fine * ncomp): 19450ef72598Sjeremylt total = total + v_array[i] 19460ef72598Sjeremylt assert abs(total - 1.0) < 1E-13 19470ef72598Sjeremylt 19480ef72598Sjeremylt # Restrict state to coarse grid 19490ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 19500ef72598Sjeremylt 19510ef72598Sjeremylt # Check 19520ef72598Sjeremylt with v_coarse.array_read() as v_array: 19530ef72598Sjeremylt total = 0.0 19540ef72598Sjeremylt for i in range(nu_coarse * ncomp): 19550ef72598Sjeremylt total = total + v_array[i] 19560ef72598Sjeremylt assert abs(total - 1.0) < 1E-13 19570ef72598Sjeremylt 19580ef72598Sjeremylt# ------------------------------------------------------------------------------- 1959