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 26*80a9ef05SNatalie BeamsTOL = libceed.EPSILON * 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) 148*80a9ef05SNatalie Beams x_array = np.zeros(nx, dtype=ceed.scalar_type()) 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) 238*80a9ef05SNatalie Beams x_array = np.zeros(nx, dtype=ceed.scalar_type()) 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] 314*80a9ef05SNatalie Beams assert abs(total_1 - 1.0) < TOL 315*80a9ef05SNatalie Beams assert abs(total_2 - 2.0) < TOL 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) 334*80a9ef05SNatalie Beams x_array = np.zeros(nx, dtype=ceed.scalar_type()) 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] 405*80a9ef05SNatalie Beams assert abs(total - 1.0) < TOL 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) 498*80a9ef05SNatalie Beams x_array = np.zeros(nx, dtype=ceed.scalar_type()) 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] 581*80a9ef05SNatalie Beams assert abs(total - 1.0) < 10. * TOL 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 641*80a9ef05SNatalie Beams qref = np.empty(dim * q, dtype=ceed.scalar_type()) 642*80a9ef05SNatalie Beams qweight = np.empty(q, dtype=ceed.scalar_type()) 643*80a9ef05SNatalie Beams interp, grad = bm.buildmats(qref, qweight, libceed.scalar_types[ 644*80a9ef05SNatalie Beams libceed.lib.CEED_SCALAR_TYPE]) 6450ef72598Sjeremylt 6460ef72598Sjeremylt bx = ceed.BasisH1(libceed.TRIANGLE, dim, p, q, interp, grad, qref, qweight) 6470ef72598Sjeremylt bu = ceed.BasisH1(libceed.TRIANGLE, 1, p, q, interp, grad, qref, qweight) 6480ef72598Sjeremylt 6490ef72598Sjeremylt # QFunctions 6500ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 6510ef72598Sjeremylt qfs = load_qfs_so() 6520ef72598Sjeremylt 6530ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass_2d, 6540ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 6550ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 6560ef72598Sjeremylt qf_setup.add_input("dx", dim * dim, libceed.EVAL_GRAD) 6570ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 6580ef72598Sjeremylt 6590ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 6600ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 6610ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 6620ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 6630ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 6640ef72598Sjeremylt 6650ef72598Sjeremylt # Operators 6660ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 6670ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 6680ef72598Sjeremylt libceed.VECTOR_NONE) 6690ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 6700ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 6710ef72598Sjeremylt libceed.VECTOR_ACTIVE) 6720ef72598Sjeremylt 6730ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 6740ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 6750ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 6760ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 6770ef72598Sjeremylt 6780ef72598Sjeremylt # Setup 6790ef72598Sjeremylt op_setup.apply(x, qdata) 6800ef72598Sjeremylt 6810ef72598Sjeremylt # Apply mass matrix 6820ef72598Sjeremylt u.set_value(0.) 6830ef72598Sjeremylt op_mass.apply(u, v) 6840ef72598Sjeremylt 6850ef72598Sjeremylt # Check 6860ef72598Sjeremylt with v.array_read() as v_array: 6870ef72598Sjeremylt for i in range(ndofs): 6880ef72598Sjeremylt assert abs(v_array[i]) < TOL 6890ef72598Sjeremylt 6900ef72598Sjeremylt# ------------------------------------------------------------------------------- 6910ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator 6920ef72598Sjeremylt# ------------------------------------------------------------------------------- 6930ef72598Sjeremylt 6940ef72598Sjeremylt 6950ef72598Sjeremyltdef test_511(ceed_resource): 6960ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 6970ef72598Sjeremylt 6980ef72598Sjeremylt nelem = 12 6990ef72598Sjeremylt dim = 2 7000ef72598Sjeremylt p = 6 7010ef72598Sjeremylt q = 4 7020ef72598Sjeremylt nx, ny = 3, 2 7030ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 7040ef72598Sjeremylt nqpts = nelem * q 7050ef72598Sjeremylt 7060ef72598Sjeremylt # Vectors 7070ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 708*80a9ef05SNatalie Beams x_array = np.zeros(dim * ndofs, dtype=ceed.scalar_type()) 7090ef72598Sjeremylt for i in range(ndofs): 7100ef72598Sjeremylt x_array[i] = (1. / (nx * 2)) * (i % (nx * 2 + 1)) 7110ef72598Sjeremylt x_array[i + ndofs] = (1. / (ny * 2)) * (i / (nx * 2 + 1)) 7120ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 7130ef72598Sjeremylt 7140ef72598Sjeremylt qdata = ceed.Vector(nqpts) 7150ef72598Sjeremylt u = ceed.Vector(ndofs) 7160ef72598Sjeremylt v = ceed.Vector(ndofs) 7170ef72598Sjeremylt 7180ef72598Sjeremylt # Restrictions 7190ef72598Sjeremylt indx = np.zeros(nelem * p, dtype="int32") 7200ef72598Sjeremylt for i in range(nelem // 2): 7210ef72598Sjeremylt col = i % nx 7220ef72598Sjeremylt row = i // nx 7230ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 7240ef72598Sjeremylt 7250ef72598Sjeremylt indx[i * 2 * p + 0] = 2 + offset 7260ef72598Sjeremylt indx[i * 2 * p + 1] = 9 + offset 7270ef72598Sjeremylt indx[i * 2 * p + 2] = 16 + offset 7280ef72598Sjeremylt indx[i * 2 * p + 3] = 1 + offset 7290ef72598Sjeremylt indx[i * 2 * p + 4] = 8 + offset 7300ef72598Sjeremylt indx[i * 2 * p + 5] = 0 + offset 7310ef72598Sjeremylt 7320ef72598Sjeremylt indx[i * 2 * p + 6] = 14 + offset 7330ef72598Sjeremylt indx[i * 2 * p + 7] = 7 + offset 7340ef72598Sjeremylt indx[i * 2 * p + 8] = 0 + offset 7350ef72598Sjeremylt indx[i * 2 * p + 9] = 15 + offset 7360ef72598Sjeremylt indx[i * 2 * p + 10] = 8 + offset 7370ef72598Sjeremylt indx[i * 2 * p + 11] = 16 + offset 7380ef72598Sjeremylt 7390ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, p, dim, ndofs, dim * ndofs, indx, 7400ef72598Sjeremylt cmode=libceed.USE_POINTER) 7410ef72598Sjeremylt 7420ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p, 1, 1, ndofs, indx, 7430ef72598Sjeremylt cmode=libceed.USE_POINTER) 7440ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 7450ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, nqpts, strides) 7460ef72598Sjeremylt 7470ef72598Sjeremylt # Bases 748*80a9ef05SNatalie Beams qref = np.empty(dim * q, dtype=ceed.scalar_type()) 749*80a9ef05SNatalie Beams qweight = np.empty(q, dtype=ceed.scalar_type()) 750*80a9ef05SNatalie Beams interp, grad = bm.buildmats(qref, qweight, libceed.scalar_types[ 751*80a9ef05SNatalie Beams libceed.lib.CEED_SCALAR_TYPE]) 7520ef72598Sjeremylt 7530ef72598Sjeremylt bx = ceed.BasisH1(libceed.TRIANGLE, dim, p, q, interp, grad, qref, qweight) 7540ef72598Sjeremylt bu = ceed.BasisH1(libceed.TRIANGLE, 1, p, q, interp, grad, qref, qweight) 7550ef72598Sjeremylt 7560ef72598Sjeremylt # QFunctions 7570ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 7580ef72598Sjeremylt qfs = load_qfs_so() 7590ef72598Sjeremylt 7600ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass_2d, 7610ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 7620ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 7630ef72598Sjeremylt qf_setup.add_input("dx", dim * dim, libceed.EVAL_GRAD) 7640ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 7650ef72598Sjeremylt 7660ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass, 7670ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 7680ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 7690ef72598Sjeremylt qf_mass.add_input("u", 1, libceed.EVAL_INTERP) 7700ef72598Sjeremylt qf_mass.add_output("v", 1, libceed.EVAL_INTERP) 7710ef72598Sjeremylt 7720ef72598Sjeremylt # Operators 7730ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 7740ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 7750ef72598Sjeremylt libceed.VECTOR_NONE) 7760ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 7770ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 7780ef72598Sjeremylt libceed.VECTOR_ACTIVE) 7790ef72598Sjeremylt 7800ef72598Sjeremylt op_mass = ceed.Operator(qf_mass) 7810ef72598Sjeremylt op_mass.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 7820ef72598Sjeremylt op_mass.set_field("u", ru, bu, libceed.VECTOR_ACTIVE) 7830ef72598Sjeremylt op_mass.set_field("v", ru, bu, libceed.VECTOR_ACTIVE) 7840ef72598Sjeremylt 7850ef72598Sjeremylt # Setup 7860ef72598Sjeremylt op_setup.apply(x, qdata) 7870ef72598Sjeremylt 7880ef72598Sjeremylt # Apply mass matrix 7890ef72598Sjeremylt u.set_value(1.) 7900ef72598Sjeremylt op_mass.apply(u, v) 7910ef72598Sjeremylt 7920ef72598Sjeremylt # Check 7930ef72598Sjeremylt with v.array_read() as v_array: 7940ef72598Sjeremylt total = 0.0 7950ef72598Sjeremylt for i in range(ndofs): 7960ef72598Sjeremylt total = total + v_array[i] 797*80a9ef05SNatalie Beams assert abs(total - 1.0) < 10. * TOL 7980ef72598Sjeremylt 7990ef72598Sjeremylt# ------------------------------------------------------------------------------- 8000ef72598Sjeremylt# Test creation, action, and destruction for composite mass matrix operator 8010ef72598Sjeremylt# ------------------------------------------------------------------------------- 8020ef72598Sjeremylt 8030ef72598Sjeremylt 8040ef72598Sjeremyltdef test_520(ceed_resource): 8050ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 8060ef72598Sjeremylt 8070ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 8080ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 8090ef72598Sjeremylt nx, ny = 3, 3 8100ef72598Sjeremylt dim = 2 8110ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 8120ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 8130ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 8140ef72598Sjeremylt 8150ef72598Sjeremylt # Vectors 8160ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 8170ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 8180ef72598Sjeremylt for i in range(ny * 2 + 1): 8190ef72598Sjeremylt for j in range(nx * 2 + 1): 8200ef72598Sjeremylt x_array[i + j * (ny * 2 + 1)] = i / (2 * ny) 8210ef72598Sjeremylt x_array[i + j * (ny * 2 + 1) + ndofs] = j / (2 * nx) 8220ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 8230ef72598Sjeremylt 8240ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 8250ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 8260ef72598Sjeremylt u = ceed.Vector(ndofs) 8270ef72598Sjeremylt v = ceed.Vector(ndofs) 8280ef72598Sjeremylt 8290ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 8300ef72598Sjeremylt 8310ef72598Sjeremylt # Restrictions 8320ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 8330ef72598Sjeremylt for i in range(nelem_tet // 2): 8340ef72598Sjeremylt col = i % nx 8350ef72598Sjeremylt row = i // nx 8360ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 8370ef72598Sjeremylt 8380ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 8390ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 8400ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 8410ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 8420ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 8430ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 8440ef72598Sjeremylt 8450ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 8460ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 8470ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 8480ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 8490ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 8500ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 8510ef72598Sjeremylt 8520ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 8530ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 8540ef72598Sjeremylt 8550ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 8560ef72598Sjeremylt cmode=libceed.USE_POINTER) 8570ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 8580ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 8590ef72598Sjeremylt strides) 8600ef72598Sjeremylt 8610ef72598Sjeremylt # Bases 862*80a9ef05SNatalie Beams qref = np.empty(dim * q_tet, dtype=ceed.scalar_type()) 863*80a9ef05SNatalie Beams qweight = np.empty(q_tet, dtype=ceed.scalar_type()) 864*80a9ef05SNatalie Beams interp, grad = bm.buildmats(qref, qweight, libceed.scalar_types[ 865*80a9ef05SNatalie Beams libceed.lib.CEED_SCALAR_TYPE]) 8660ef72598Sjeremylt 8670ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 8680ef72598Sjeremylt qweight) 8690ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 8700ef72598Sjeremylt qweight) 8710ef72598Sjeremylt 8720ef72598Sjeremylt # QFunctions 8730ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 8740ef72598Sjeremylt qfs = load_qfs_so() 8750ef72598Sjeremylt 8760ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 8770ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 8780ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 8790ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 8800ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 8810ef72598Sjeremylt 8820ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 8830ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 8840ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 8850ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 8860ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 8870ef72598Sjeremylt 8880ef72598Sjeremylt # Operators 8890ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 8900ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 8910ef72598Sjeremylt libceed.VECTOR_NONE) 8920ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 8930ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 8940ef72598Sjeremylt qdata_tet) 8950ef72598Sjeremylt 8960ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 8970ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 8980ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 8990ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 9000ef72598Sjeremylt 9010ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 9020ef72598Sjeremylt 9030ef72598Sjeremylt # Restrictions 9040ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 9050ef72598Sjeremylt for i in range(nelem_hex): 9060ef72598Sjeremylt col = i % nx_hex 9070ef72598Sjeremylt row = i // nx_hex 9080ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 9090ef72598Sjeremylt 9100ef72598Sjeremylt for j in range(p_hex): 9110ef72598Sjeremylt for k in range(p_hex): 9120ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 9130ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 9140ef72598Sjeremylt 9150ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 9160ef72598Sjeremylt dim * ndofs, indx_hex, cmode=libceed.USE_POINTER) 9170ef72598Sjeremylt 9180ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 9190ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 9200ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 9210ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 9220ef72598Sjeremylt nqpts_hex, strides) 9230ef72598Sjeremylt 9240ef72598Sjeremylt # Bases 9250ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 9260ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 9270ef72598Sjeremylt 9280ef72598Sjeremylt # QFunctions 9290ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 9300ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 9310ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 9320ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 9330ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 9340ef72598Sjeremylt 9350ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 9360ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 9370ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 9380ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 9390ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 9400ef72598Sjeremylt 9410ef72598Sjeremylt # Operators 9420ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 9430ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 9440ef72598Sjeremylt libceed.VECTOR_NONE) 9450ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 9460ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 9470ef72598Sjeremylt qdata_hex) 9480ef72598Sjeremylt 9490ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 9500ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 9510ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 9520ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 9530ef72598Sjeremylt 9540ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 9550ef72598Sjeremylt 9560ef72598Sjeremylt # Setup 9570ef72598Sjeremylt op_setup = ceed.CompositeOperator() 9580ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 9590ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 9600ef72598Sjeremylt op_setup.apply(x, libceed.VECTOR_NONE) 9610ef72598Sjeremylt 9620ef72598Sjeremylt # Apply mass matrix 9630ef72598Sjeremylt op_mass = ceed.CompositeOperator() 9640ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 9650ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 9660ef72598Sjeremylt 9670ef72598Sjeremylt u.set_value(0.) 9680ef72598Sjeremylt op_mass.apply(u, v) 9690ef72598Sjeremylt 9700ef72598Sjeremylt # Check 9710ef72598Sjeremylt with v.array_read() as v_array: 9720ef72598Sjeremylt for i in range(ndofs): 9730ef72598Sjeremylt assert abs(v_array[i]) < TOL 9740ef72598Sjeremylt 9750ef72598Sjeremylt# ------------------------------------------------------------------------------- 9760ef72598Sjeremylt# Test creation, action, and destruction for composite mass matrix operator 9770ef72598Sjeremylt# ------------------------------------------------------------------------------- 9780ef72598Sjeremylt 9790ef72598Sjeremylt 9800ef72598Sjeremyltdef test_521(ceed_resource): 9810ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 9820ef72598Sjeremylt 9830ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 9840ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 9850ef72598Sjeremylt nx, ny = 3, 3 9860ef72598Sjeremylt dim = 2 9870ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 9880ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 9890ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 9900ef72598Sjeremylt 9910ef72598Sjeremylt # Vectors 9920ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 993*80a9ef05SNatalie Beams x_array = np.zeros(dim * ndofs, dtype=ceed.scalar_type()) 9940ef72598Sjeremylt for i in range(ny * 2 + 1): 9950ef72598Sjeremylt for j in range(nx * 2 + 1): 9960ef72598Sjeremylt x_array[i + j * (ny * 2 + 1)] = i / (2 * ny) 9970ef72598Sjeremylt x_array[i + j * (ny * 2 + 1) + ndofs] = j / (2 * nx) 9980ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 9990ef72598Sjeremylt 10000ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 10010ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 10020ef72598Sjeremylt u = ceed.Vector(ndofs) 10030ef72598Sjeremylt v = ceed.Vector(ndofs) 10040ef72598Sjeremylt 10050ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 10060ef72598Sjeremylt 10070ef72598Sjeremylt # Restrictions 10080ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 10090ef72598Sjeremylt for i in range(nelem_tet // 2): 10100ef72598Sjeremylt col = i % nx 10110ef72598Sjeremylt row = i // nx 10120ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 10130ef72598Sjeremylt 10140ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 10150ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 10160ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 10170ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 10180ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 10190ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 10200ef72598Sjeremylt 10210ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 10220ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 10230ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 10240ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 10250ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 10260ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 10270ef72598Sjeremylt 10280ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 10290ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 10300ef72598Sjeremylt 10310ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 10320ef72598Sjeremylt cmode=libceed.USE_POINTER) 10330ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 10340ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 10350ef72598Sjeremylt strides) 10360ef72598Sjeremylt 10370ef72598Sjeremylt # Bases 1038*80a9ef05SNatalie Beams qref = np.empty(dim * q_tet, dtype=ceed.scalar_type()) 1039*80a9ef05SNatalie Beams qweight = np.empty(q_tet, dtype=ceed.scalar_type()) 1040*80a9ef05SNatalie Beams interp, grad = bm.buildmats(qref, qweight, libceed.scalar_types[ 1041*80a9ef05SNatalie Beams libceed.lib.CEED_SCALAR_TYPE]) 10420ef72598Sjeremylt 10430ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 10440ef72598Sjeremylt qweight) 10450ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 10460ef72598Sjeremylt qweight) 10470ef72598Sjeremylt 10480ef72598Sjeremylt # QFunctions 10490ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 10500ef72598Sjeremylt qfs = load_qfs_so() 10510ef72598Sjeremylt 10520ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 10530ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 10540ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 10550ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 10560ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 10570ef72598Sjeremylt 10580ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 10590ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 10600ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 10610ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 10620ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 10630ef72598Sjeremylt 10640ef72598Sjeremylt # Operators 10650ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 10660ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 10670ef72598Sjeremylt libceed.VECTOR_NONE) 10680ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 10690ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 10700ef72598Sjeremylt qdata_tet) 10710ef72598Sjeremylt 10720ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 10730ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 10740ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 10750ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 10760ef72598Sjeremylt 10770ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 10780ef72598Sjeremylt 10790ef72598Sjeremylt # Restrictions 10800ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 10810ef72598Sjeremylt for i in range(nelem_hex): 10820ef72598Sjeremylt col = i % nx_hex 10830ef72598Sjeremylt row = i // nx_hex 10840ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 10850ef72598Sjeremylt 10860ef72598Sjeremylt for j in range(p_hex): 10870ef72598Sjeremylt for k in range(p_hex): 10880ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 10890ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 10900ef72598Sjeremylt 10910ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 10920ef72598Sjeremylt dim * ndofs, indx_hex, cmode=libceed.USE_POINTER) 10930ef72598Sjeremylt 10940ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 10950ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 10960ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 10970ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 10980ef72598Sjeremylt nqpts_hex, strides) 10990ef72598Sjeremylt 11000ef72598Sjeremylt # Bases 11010ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 11020ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 11030ef72598Sjeremylt 11040ef72598Sjeremylt # QFunctions 11050ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 11060ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 11070ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 11080ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 11090ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 11100ef72598Sjeremylt 11110ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 11120ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 11130ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 11140ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 11150ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 11160ef72598Sjeremylt 11170ef72598Sjeremylt # Operators 11180ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 11190ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 11200ef72598Sjeremylt libceed.VECTOR_NONE) 11210ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 11220ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 11230ef72598Sjeremylt qdata_hex) 11240ef72598Sjeremylt 11250ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 11260ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 11270ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 11280ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 11290ef72598Sjeremylt 11300ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 11310ef72598Sjeremylt 11320ef72598Sjeremylt # Setup 11330ef72598Sjeremylt op_setup = ceed.CompositeOperator() 11340ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 11350ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 11360ef72598Sjeremylt op_setup.apply(x, libceed.VECTOR_NONE) 11370ef72598Sjeremylt 11380ef72598Sjeremylt # Apply mass matrix 11390ef72598Sjeremylt op_mass = ceed.CompositeOperator() 11400ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 11410ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 11420ef72598Sjeremylt u.set_value(1.) 11430ef72598Sjeremylt op_mass.apply(u, v) 11440ef72598Sjeremylt 11450ef72598Sjeremylt # Check 11460ef72598Sjeremylt with v.array_read() as v_array: 11470ef72598Sjeremylt total = 0.0 11480ef72598Sjeremylt for i in range(ndofs): 11490ef72598Sjeremylt total = total + v_array[i] 1150*80a9ef05SNatalie Beams assert abs(total - 1.0) < 10. * TOL 11510ef72598Sjeremylt 11520ef72598Sjeremylt# ------------------------------------------------------------------------------- 11530ef72598Sjeremylt# Test viewing of composite mass matrix operator 11540ef72598Sjeremylt# ------------------------------------------------------------------------------- 11550ef72598Sjeremylt 11560ef72598Sjeremylt 11570ef72598Sjeremyltdef test_523(ceed_resource, capsys): 11580ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 11590ef72598Sjeremylt 11600ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 11610ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 11620ef72598Sjeremylt nx, ny = 3, 3 11630ef72598Sjeremylt dim = 2 11640ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 11650ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 11660ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 11670ef72598Sjeremylt 11680ef72598Sjeremylt # Vectors 11690ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 11700ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 11710ef72598Sjeremylt 11720ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 11730ef72598Sjeremylt 11740ef72598Sjeremylt # Restrictions 11750ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 11760ef72598Sjeremylt for i in range(nelem_tet // 2): 11770ef72598Sjeremylt col = i % nx 11780ef72598Sjeremylt row = i // nx 11790ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 11800ef72598Sjeremylt 11810ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 11820ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 11830ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 11840ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 11850ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 11860ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 11870ef72598Sjeremylt 11880ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 11890ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 11900ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 11910ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 11920ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 11930ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 11940ef72598Sjeremylt 11950ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 11960ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 11970ef72598Sjeremylt 11980ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 11990ef72598Sjeremylt cmode=libceed.USE_POINTER) 12000ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 12010ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 12020ef72598Sjeremylt strides) 12030ef72598Sjeremylt 12040ef72598Sjeremylt # Bases 1205*80a9ef05SNatalie Beams qref = np.empty(dim * q_tet, dtype=ceed.scalar_type()) 1206*80a9ef05SNatalie Beams qweight = np.empty(q_tet, dtype=ceed.scalar_type()) 1207*80a9ef05SNatalie Beams interp, grad = bm.buildmats(qref, qweight, libceed.scalar_types[ 1208*80a9ef05SNatalie Beams libceed.lib.CEED_SCALAR_TYPE]) 12090ef72598Sjeremylt 12100ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 12110ef72598Sjeremylt qweight) 12120ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 12130ef72598Sjeremylt qweight) 12140ef72598Sjeremylt 12150ef72598Sjeremylt # QFunctions 12160ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 12170ef72598Sjeremylt qfs = load_qfs_so() 12180ef72598Sjeremylt 12190ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 12200ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 12210ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 12220ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 12230ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 12240ef72598Sjeremylt 12250ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 12260ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 12270ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 12280ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 12290ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 12300ef72598Sjeremylt 12310ef72598Sjeremylt # Operators 12320ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 12330ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 12340ef72598Sjeremylt libceed.VECTOR_NONE) 12350ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 12360ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 12370ef72598Sjeremylt qdata_tet) 12380ef72598Sjeremylt 12390ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 12400ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 12410ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 12420ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 12430ef72598Sjeremylt 12440ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 12450ef72598Sjeremylt 12460ef72598Sjeremylt # Restrictions 12470ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 12480ef72598Sjeremylt for i in range(nelem_hex): 12490ef72598Sjeremylt col = i % nx_hex 12500ef72598Sjeremylt row = i // nx_hex 12510ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 12520ef72598Sjeremylt 12530ef72598Sjeremylt for j in range(p_hex): 12540ef72598Sjeremylt for k in range(p_hex): 12550ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 12560ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 12570ef72598Sjeremylt 12580ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 12590ef72598Sjeremylt dim * ndofs, indx_hex, 12600ef72598Sjeremylt cmode=libceed.USE_POINTER) 12610ef72598Sjeremylt 12620ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 12630ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 12640ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 12650ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 12660ef72598Sjeremylt nqpts_hex, strides) 12670ef72598Sjeremylt 12680ef72598Sjeremylt # Bases 12690ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 12700ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 12710ef72598Sjeremylt 12720ef72598Sjeremylt # QFunctions 12730ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 12740ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 12750ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 12760ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 12770ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 12780ef72598Sjeremylt 12790ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 12800ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 12810ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 12820ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 12830ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 12840ef72598Sjeremylt 12850ef72598Sjeremylt # Operators 12860ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 12870ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 12880ef72598Sjeremylt libceed.VECTOR_NONE) 12890ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 12900ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 12910ef72598Sjeremylt qdata_hex) 12920ef72598Sjeremylt 12930ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 12940ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 12950ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 12960ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 12970ef72598Sjeremylt 12980ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 12990ef72598Sjeremylt 13000ef72598Sjeremylt # Setup 13010ef72598Sjeremylt op_setup = ceed.CompositeOperator() 13020ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 13030ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 13040ef72598Sjeremylt 13050ef72598Sjeremylt # Apply mass matrix 13060ef72598Sjeremylt op_mass = ceed.CompositeOperator() 13070ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 13080ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 13090ef72598Sjeremylt 13100ef72598Sjeremylt # View 13110ef72598Sjeremylt print(op_setup) 13120ef72598Sjeremylt print(op_mass) 13130ef72598Sjeremylt 13140ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 13150ef72598Sjeremylt assert not stderr 13160ef72598Sjeremylt assert stdout == ref_stdout 13170ef72598Sjeremylt 13180ef72598Sjeremylt# ------------------------------------------------------------------------------- 13190ef72598Sjeremylt# CeedOperatorApplyAdd for composite operator 13200ef72598Sjeremylt# ------------------------------------------------------------------------------- 13210ef72598Sjeremylt 13220ef72598Sjeremylt 13230ef72598Sjeremyltdef test_524(ceed_resource): 13240ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 13250ef72598Sjeremylt 13260ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 13270ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 13280ef72598Sjeremylt nx, ny = 3, 3 13290ef72598Sjeremylt dim = 2 13300ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 13310ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 13320ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 13330ef72598Sjeremylt 13340ef72598Sjeremylt # Vectors 13350ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 1336*80a9ef05SNatalie Beams x_array = np.zeros(dim * ndofs, dtype=ceed.scalar_type()) 13370ef72598Sjeremylt for i in range(ny * 2 + 1): 13380ef72598Sjeremylt for j in range(nx * 2 + 1): 13390ef72598Sjeremylt x_array[i + j * (ny * 2 + 1)] = i / (2 * ny) 13400ef72598Sjeremylt x_array[i + j * (ny * 2 + 1) + ndofs] = j / (2 * nx) 13410ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 13420ef72598Sjeremylt 13430ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 13440ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 13450ef72598Sjeremylt u = ceed.Vector(ndofs) 13460ef72598Sjeremylt v = ceed.Vector(ndofs) 13470ef72598Sjeremylt 13480ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 13490ef72598Sjeremylt 13500ef72598Sjeremylt # Restrictions 13510ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 13520ef72598Sjeremylt for i in range(nelem_tet // 2): 13530ef72598Sjeremylt col = i % nx 13540ef72598Sjeremylt row = i // nx 13550ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 13560ef72598Sjeremylt 13570ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 13580ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 13590ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 13600ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 13610ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 13620ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 13630ef72598Sjeremylt 13640ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 13650ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 13660ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 13670ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 13680ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 13690ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 13700ef72598Sjeremylt 13710ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 13720ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 13730ef72598Sjeremylt 13740ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 13750ef72598Sjeremylt cmode=libceed.USE_POINTER) 13760ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 13770ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 13780ef72598Sjeremylt strides) 13790ef72598Sjeremylt 13800ef72598Sjeremylt # Bases 1381*80a9ef05SNatalie Beams qref = np.empty(dim * q_tet, dtype=ceed.scalar_type()) 1382*80a9ef05SNatalie Beams qweight = np.empty(q_tet, dtype=ceed.scalar_type()) 1383*80a9ef05SNatalie Beams interp, grad = bm.buildmats(qref, qweight, libceed.scalar_types[ 1384*80a9ef05SNatalie Beams libceed.lib.CEED_SCALAR_TYPE]) 13850ef72598Sjeremylt 13860ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 13870ef72598Sjeremylt qweight) 13880ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 13890ef72598Sjeremylt qweight) 13900ef72598Sjeremylt 13910ef72598Sjeremylt # QFunctions 13920ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 13930ef72598Sjeremylt qfs = load_qfs_so() 13940ef72598Sjeremylt 13950ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 13960ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 13970ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 13980ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 13990ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 14000ef72598Sjeremylt 14010ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 14020ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 14030ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 14040ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 14050ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 14060ef72598Sjeremylt 14070ef72598Sjeremylt # Operators 14080ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 14090ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 14100ef72598Sjeremylt libceed.VECTOR_NONE) 14110ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 14120ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 14130ef72598Sjeremylt qdata_tet) 14140ef72598Sjeremylt 14150ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 14160ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 14170ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 14180ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 14190ef72598Sjeremylt 14200ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 14210ef72598Sjeremylt 14220ef72598Sjeremylt # Restrictions 14230ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 14240ef72598Sjeremylt for i in range(nelem_hex): 14250ef72598Sjeremylt col = i % nx_hex 14260ef72598Sjeremylt row = i // nx_hex 14270ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 14280ef72598Sjeremylt 14290ef72598Sjeremylt for j in range(p_hex): 14300ef72598Sjeremylt for k in range(p_hex): 14310ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 14320ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 14330ef72598Sjeremylt 14340ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 14350ef72598Sjeremylt dim * ndofs, indx_hex, 14360ef72598Sjeremylt cmode=libceed.USE_POINTER) 14370ef72598Sjeremylt 14380ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 14390ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 14400ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 14410ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 14420ef72598Sjeremylt nqpts_hex, strides) 14430ef72598Sjeremylt 14440ef72598Sjeremylt # Bases 14450ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 14460ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 14470ef72598Sjeremylt 14480ef72598Sjeremylt # QFunctions 14490ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 14500ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 14510ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 14520ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 14530ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 14540ef72598Sjeremylt 14550ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 14560ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 14570ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 14580ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 14590ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 14600ef72598Sjeremylt 14610ef72598Sjeremylt # Operators 14620ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 14630ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 14640ef72598Sjeremylt libceed.VECTOR_NONE) 14650ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 14660ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 14670ef72598Sjeremylt qdata_hex) 14680ef72598Sjeremylt 14690ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 14700ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 14710ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 14720ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 14730ef72598Sjeremylt 14740ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 14750ef72598Sjeremylt 14760ef72598Sjeremylt # Setup 14770ef72598Sjeremylt op_setup = ceed.CompositeOperator() 14780ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 14790ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 14800ef72598Sjeremylt op_setup.apply(x, libceed.VECTOR_NONE) 14810ef72598Sjeremylt 14820ef72598Sjeremylt # Apply mass matrix 14830ef72598Sjeremylt op_mass = ceed.CompositeOperator() 14840ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 14850ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 14860ef72598Sjeremylt u.set_value(1.) 14870ef72598Sjeremylt op_mass.apply(u, v) 14880ef72598Sjeremylt 14890ef72598Sjeremylt # Check 14900ef72598Sjeremylt with v.array_read() as v_array: 14910ef72598Sjeremylt total = 0.0 14920ef72598Sjeremylt for i in range(ndofs): 14930ef72598Sjeremylt total = total + v_array[i] 1494*80a9ef05SNatalie Beams assert abs(total - 1.0) < 10. * TOL 14950ef72598Sjeremylt 14960ef72598Sjeremylt # ApplyAdd mass matrix 14970ef72598Sjeremylt v.set_value(1.) 14980ef72598Sjeremylt op_mass.apply_add(u, v) 14990ef72598Sjeremylt 15000ef72598Sjeremylt # Check 15010ef72598Sjeremylt with v.array_read() as v_array: 15020ef72598Sjeremylt total = -ndofs 15030ef72598Sjeremylt for i in range(ndofs): 15040ef72598Sjeremylt total = total + v_array[i] 1505*80a9ef05SNatalie Beams assert abs(total - 1.0) < 10. * TOL 15060ef72598Sjeremylt 15070ef72598Sjeremylt# ------------------------------------------------------------------------------- 15080ef72598Sjeremylt# Test assembly of mass matrix operator diagonal 15090ef72598Sjeremylt# ------------------------------------------------------------------------------- 15100ef72598Sjeremylt 15110ef72598Sjeremylt 15120ef72598Sjeremyltdef test_533(ceed_resource): 15130ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 15140ef72598Sjeremylt 15150ef72598Sjeremylt nelem = 6 15160ef72598Sjeremylt p = 3 15170ef72598Sjeremylt q = 4 15180ef72598Sjeremylt dim = 2 15190ef72598Sjeremylt nx = 3 15200ef72598Sjeremylt ny = 2 15210ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 15220ef72598Sjeremylt nqpts = nelem * q * q 15230ef72598Sjeremylt 15240ef72598Sjeremylt # Vectors 15250ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 15260ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 15270ef72598Sjeremylt for i in range(nx * 2 + 1): 15280ef72598Sjeremylt for j in range(ny * 2 + 1): 15290ef72598Sjeremylt x_array[i + j * (nx * 2 + 1) + 0 * ndofs] = i / (2 * nx) 15300ef72598Sjeremylt x_array[i + j * (nx * 2 + 1) + 1 * ndofs] = j / (2 * ny) 15310ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 15320ef72598Sjeremylt 15330ef72598Sjeremylt qdata = ceed.Vector(nqpts) 15340ef72598Sjeremylt u = ceed.Vector(ndofs) 15350ef72598Sjeremylt v = ceed.Vector(ndofs) 15360ef72598Sjeremylt 15370ef72598Sjeremylt # Restrictions 15380ef72598Sjeremylt indx = np.zeros(nelem * p * p, dtype="int32") 15390ef72598Sjeremylt for i in range(nelem): 15400ef72598Sjeremylt col = i % nx 15410ef72598Sjeremylt row = i // nx 15420ef72598Sjeremylt offset = col * (p - 1) + row * (nx * 2 + 1) * (p - 1) 15430ef72598Sjeremylt for j in range(p): 15440ef72598Sjeremylt for k in range(p): 15450ef72598Sjeremylt indx[p * (p * i + k) + j] = offset + k * (nx * 2 + 1) + j 15460ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, p * p, dim, ndofs, dim * ndofs, 15470ef72598Sjeremylt indx, cmode=libceed.USE_POINTER) 15480ef72598Sjeremylt 15490ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p * p, 1, 1, ndofs, indx, 15500ef72598Sjeremylt cmode=libceed.USE_POINTER) 15510ef72598Sjeremylt strides = np.array([1, q * q, q * q], dtype="int32") 15520ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q * q, 1, nqpts, strides) 15530ef72598Sjeremylt 15540ef72598Sjeremylt # Bases 15550ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(dim, dim, p, q, libceed.GAUSS) 15560ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(dim, 1, p, q, libceed.GAUSS) 15570ef72598Sjeremylt 15580ef72598Sjeremylt # QFunctions 15590ef72598Sjeremylt qf_setup = ceed.QFunctionByName("Mass2DBuild") 15600ef72598Sjeremylt 15610ef72598Sjeremylt# ------------------------------------------------------------------------------- 15620ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 15630ef72598Sjeremylt# multigrid level, tensor basis and interpolation basis generation 15640ef72598Sjeremylt# ------------------------------------------------------------------------------- 15650ef72598Sjeremylt 15660ef72598Sjeremylt 15670ef72598Sjeremyltdef test_550(ceed_resource): 15680ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 15690ef72598Sjeremylt 15700ef72598Sjeremylt nelem = 15 15710ef72598Sjeremylt p_coarse = 3 15720ef72598Sjeremylt p_fine = 5 15730ef72598Sjeremylt q = 8 15740ef72598Sjeremylt ncomp = 2 15750ef72598Sjeremylt nx = nelem + 1 15760ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 15770ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 15780ef72598Sjeremylt 15790ef72598Sjeremylt # Vectors 15800ef72598Sjeremylt x = ceed.Vector(nx) 1581*80a9ef05SNatalie Beams x_array = np.zeros(nx, dtype=ceed.scalar_type()) 15820ef72598Sjeremylt for i in range(nx): 15830ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 15840ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 15850ef72598Sjeremylt 15860ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 15870ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 15880ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 15890ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 15900ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 15910ef72598Sjeremylt 15920ef72598Sjeremylt # Restrictions 15930ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 15940ef72598Sjeremylt for i in range(nx): 15950ef72598Sjeremylt indx[2 * i + 0] = i 15960ef72598Sjeremylt indx[2 * i + 1] = i + 1 15970ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 15980ef72598Sjeremylt cmode=libceed.USE_POINTER) 15990ef72598Sjeremylt 16000ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 16010ef72598Sjeremylt for i in range(nelem): 16020ef72598Sjeremylt for j in range(p_coarse): 16030ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 16040ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 16050ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 16060ef72598Sjeremylt cmode=libceed.USE_POINTER) 16070ef72598Sjeremylt 16080ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 16090ef72598Sjeremylt for i in range(nelem): 16100ef72598Sjeremylt for j in range(p_fine): 16110ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 16120ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 16130ef72598Sjeremylt ncomp * nu_fine, indu_fine, 16140ef72598Sjeremylt cmode=libceed.USE_POINTER) 16150ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 16160ef72598Sjeremylt 16170ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 16180ef72598Sjeremylt 16190ef72598Sjeremylt # Bases 16200ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 16210ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 16220ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 16230ef72598Sjeremylt 16240ef72598Sjeremylt # QFunctions 16250ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 16260ef72598Sjeremylt qfs = load_qfs_so() 16270ef72598Sjeremylt 16280ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 16290ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 16300ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 16310ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 16320ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 16330ef72598Sjeremylt 16340ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass_two, 16350ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass_two")) 16360ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 16370ef72598Sjeremylt qf_mass.add_input("u", ncomp, libceed.EVAL_INTERP) 16380ef72598Sjeremylt qf_mass.add_output("v", ncomp, libceed.EVAL_INTERP) 16390ef72598Sjeremylt 16400ef72598Sjeremylt # Operators 16410ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 16420ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 16430ef72598Sjeremylt libceed.VECTOR_NONE) 16440ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 16450ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 16460ef72598Sjeremylt libceed.VECTOR_ACTIVE) 16470ef72598Sjeremylt 16480ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 16490ef72598Sjeremylt op_mass_fine.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 16500ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 16510ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 16520ef72598Sjeremylt 16530ef72598Sjeremylt # Setup 16540ef72598Sjeremylt op_setup.apply(x, qdata) 16550ef72598Sjeremylt 16560ef72598Sjeremylt # Create multigrid level 16570ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 16580ef72598Sjeremylt p_mult_fine.set_value(1.0) 16590ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create(p_mult_fine, 16600ef72598Sjeremylt ru_coarse, 16610ef72598Sjeremylt bu_coarse) 16620ef72598Sjeremylt 16630ef72598Sjeremylt # Apply coarse mass matrix 16640ef72598Sjeremylt u_coarse.set_value(1.0) 16650ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 16660ef72598Sjeremylt 16670ef72598Sjeremylt # Check 16680ef72598Sjeremylt with v_coarse.array_read() as v_array: 16690ef72598Sjeremylt total = 0.0 16700ef72598Sjeremylt for i in range(nu_coarse * ncomp): 16710ef72598Sjeremylt total = total + v_array[i] 1672*80a9ef05SNatalie Beams assert abs(total - 2.0) < 10. * TOL 16730ef72598Sjeremylt 16740ef72598Sjeremylt # Prolong coarse u 16750ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 16760ef72598Sjeremylt 16770ef72598Sjeremylt # Apply mass matrix 16780ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 16790ef72598Sjeremylt 16800ef72598Sjeremylt # Check 16810ef72598Sjeremylt with v_fine.array_read() as v_array: 16820ef72598Sjeremylt total = 0.0 16830ef72598Sjeremylt for i in range(nu_fine * ncomp): 16840ef72598Sjeremylt total = total + v_array[i] 1685*80a9ef05SNatalie Beams assert abs(total - 2.0) < 10. * TOL 16860ef72598Sjeremylt 16870ef72598Sjeremylt # Restrict state to coarse grid 16880ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 16890ef72598Sjeremylt 16900ef72598Sjeremylt # Check 16910ef72598Sjeremylt with v_coarse.array_read() as v_array: 16920ef72598Sjeremylt total = 0.0 16930ef72598Sjeremylt for i in range(nu_coarse * ncomp): 16940ef72598Sjeremylt total = total + v_array[i] 1695*80a9ef05SNatalie Beams assert abs(total - 2.0) < 10. * TOL 16960ef72598Sjeremylt 16970ef72598Sjeremylt# ------------------------------------------------------------------------------- 16980ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 16990ef72598Sjeremylt# multigrid level, tensor basis 17000ef72598Sjeremylt# ------------------------------------------------------------------------------- 17010ef72598Sjeremylt 17020ef72598Sjeremylt 17030ef72598Sjeremyltdef test_552(ceed_resource): 17040ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 17050ef72598Sjeremylt 17060ef72598Sjeremylt nelem = 15 17070ef72598Sjeremylt p_coarse = 3 17080ef72598Sjeremylt p_fine = 5 17090ef72598Sjeremylt q = 8 17100ef72598Sjeremylt ncomp = 2 17110ef72598Sjeremylt nx = nelem + 1 17120ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 17130ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 17140ef72598Sjeremylt 17150ef72598Sjeremylt # Vectors 17160ef72598Sjeremylt x = ceed.Vector(nx) 1717*80a9ef05SNatalie Beams x_array = np.zeros(nx, dtype=ceed.scalar_type()) 17180ef72598Sjeremylt for i in range(nx): 17190ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 17200ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 17210ef72598Sjeremylt 17220ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 17230ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 17240ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 17250ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 17260ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 17270ef72598Sjeremylt 17280ef72598Sjeremylt # Restrictions 17290ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 17300ef72598Sjeremylt for i in range(nx): 17310ef72598Sjeremylt indx[2 * i + 0] = i 17320ef72598Sjeremylt indx[2 * i + 1] = i + 1 17330ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 17340ef72598Sjeremylt cmode=libceed.USE_POINTER) 17350ef72598Sjeremylt 17360ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 17370ef72598Sjeremylt for i in range(nelem): 17380ef72598Sjeremylt for j in range(p_coarse): 17390ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 17400ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 17410ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 17420ef72598Sjeremylt cmode=libceed.USE_POINTER) 17430ef72598Sjeremylt 17440ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 17450ef72598Sjeremylt for i in range(nelem): 17460ef72598Sjeremylt for j in range(p_fine): 17470ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 17480ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 17490ef72598Sjeremylt ncomp * nu_fine, indu_fine, 17500ef72598Sjeremylt cmode=libceed.USE_POINTER) 17510ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 17520ef72598Sjeremylt 17530ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 17540ef72598Sjeremylt 17550ef72598Sjeremylt # Bases 17560ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 17570ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 17580ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 17590ef72598Sjeremylt 17600ef72598Sjeremylt # QFunctions 17610ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 17620ef72598Sjeremylt qfs = load_qfs_so() 17630ef72598Sjeremylt 17640ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 17650ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 17660ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 17670ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 17680ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 17690ef72598Sjeremylt 17700ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass_two, 17710ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass_two")) 17720ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 17730ef72598Sjeremylt qf_mass.add_input("u", ncomp, libceed.EVAL_INTERP) 17740ef72598Sjeremylt qf_mass.add_output("v", ncomp, libceed.EVAL_INTERP) 17750ef72598Sjeremylt 17760ef72598Sjeremylt # Operators 17770ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 17780ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 17790ef72598Sjeremylt libceed.VECTOR_NONE) 17800ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 17810ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 17820ef72598Sjeremylt libceed.VECTOR_ACTIVE) 17830ef72598Sjeremylt 17840ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 17850ef72598Sjeremylt op_mass_fine.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 17860ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 17870ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 17880ef72598Sjeremylt 17890ef72598Sjeremylt # Setup 17900ef72598Sjeremylt op_setup.apply(x, qdata) 17910ef72598Sjeremylt 17920ef72598Sjeremylt # Create multigrid level 17930ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 17940ef72598Sjeremylt p_mult_fine.set_value(1.0) 17950ef72598Sjeremylt b_c_to_f = ceed.BasisTensorH1Lagrange( 17960ef72598Sjeremylt 1, ncomp, p_coarse, p_fine, libceed.GAUSS_LOBATTO) 179766ce82e0Sjeremylt interp_C_to_F = b_c_to_f.get_interp_1d() 17980ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create_tensor_h1(p_mult_fine, 17990ef72598Sjeremylt ru_coarse, bu_coarse, interp_C_to_F) 18000ef72598Sjeremylt 18010ef72598Sjeremylt # Apply coarse mass matrix 18020ef72598Sjeremylt u_coarse.set_value(1.0) 18030ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 18040ef72598Sjeremylt 18050ef72598Sjeremylt # Check 18060ef72598Sjeremylt with v_coarse.array_read() as v_array: 18070ef72598Sjeremylt total = 0.0 18080ef72598Sjeremylt for i in range(nu_coarse * ncomp): 18090ef72598Sjeremylt total = total + v_array[i] 1810*80a9ef05SNatalie Beams assert abs(total - 2.0) < TOL 18110ef72598Sjeremylt 18120ef72598Sjeremylt # Prolong coarse u 18130ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 18140ef72598Sjeremylt 18150ef72598Sjeremylt # Apply mass matrix 18160ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 18170ef72598Sjeremylt 18180ef72598Sjeremylt # Check 18190ef72598Sjeremylt with v_fine.array_read() as v_array: 18200ef72598Sjeremylt total = 0.0 18210ef72598Sjeremylt for i in range(nu_fine * ncomp): 18220ef72598Sjeremylt total = total + v_array[i] 1823*80a9ef05SNatalie Beams assert abs(total - 2.0) < TOL 18240ef72598Sjeremylt 18250ef72598Sjeremylt # Restrict state to coarse grid 18260ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 18270ef72598Sjeremylt 18280ef72598Sjeremylt # Check 18290ef72598Sjeremylt with v_coarse.array_read() as v_array: 18300ef72598Sjeremylt total = 0.0 18310ef72598Sjeremylt for i in range(nu_coarse * ncomp): 18320ef72598Sjeremylt total = total + v_array[i] 1833*80a9ef05SNatalie Beams assert abs(total - 2.0) < TOL 18340ef72598Sjeremylt 18350ef72598Sjeremylt# ------------------------------------------------------------------------------- 18360ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 18370ef72598Sjeremylt# multigrid level, non-tensor basis 18380ef72598Sjeremylt# ------------------------------------------------------------------------------- 18390ef72598Sjeremylt 18400ef72598Sjeremylt 18410ef72598Sjeremyltdef test_553(ceed_resource): 18420ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 18430ef72598Sjeremylt 18440ef72598Sjeremylt nelem = 15 18450ef72598Sjeremylt p_coarse = 3 18460ef72598Sjeremylt p_fine = 5 18470ef72598Sjeremylt q = 8 18480ef72598Sjeremylt ncomp = 1 18490ef72598Sjeremylt nx = nelem + 1 18500ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 18510ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 18520ef72598Sjeremylt 18530ef72598Sjeremylt # Vectors 18540ef72598Sjeremylt x = ceed.Vector(nx) 1855*80a9ef05SNatalie Beams x_array = np.zeros(nx, dtype=ceed.scalar_type()) 18560ef72598Sjeremylt for i in range(nx): 18570ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 18580ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 18590ef72598Sjeremylt 18600ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 18610ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 18620ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 18630ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 18640ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 18650ef72598Sjeremylt 18660ef72598Sjeremylt # Restrictions 18670ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 18680ef72598Sjeremylt for i in range(nx): 18690ef72598Sjeremylt indx[2 * i + 0] = i 18700ef72598Sjeremylt indx[2 * i + 1] = i + 1 18710ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 18720ef72598Sjeremylt cmode=libceed.USE_POINTER) 18730ef72598Sjeremylt 18740ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 18750ef72598Sjeremylt for i in range(nelem): 18760ef72598Sjeremylt for j in range(p_coarse): 18770ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 18780ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 18790ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 18800ef72598Sjeremylt cmode=libceed.USE_POINTER) 18810ef72598Sjeremylt 18820ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 18830ef72598Sjeremylt for i in range(nelem): 18840ef72598Sjeremylt for j in range(p_fine): 18850ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 18860ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 18870ef72598Sjeremylt ncomp * nu_fine, indu_fine, 18880ef72598Sjeremylt cmode=libceed.USE_POINTER) 18890ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 18900ef72598Sjeremylt 18910ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 18920ef72598Sjeremylt 18930ef72598Sjeremylt # Bases 18940ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 18950ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 18960ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 18970ef72598Sjeremylt 18980ef72598Sjeremylt # QFunctions 18990ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 19000ef72598Sjeremylt qfs = load_qfs_so() 19010ef72598Sjeremylt 19020ef72598Sjeremylt qf_setup = ceed.QFunctionByName("Mass1DBuild") 19030ef72598Sjeremylt qf_mass = ceed.QFunctionByName("MassApply") 19040ef72598Sjeremylt 19050ef72598Sjeremylt # Operators 19060ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 19070ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 19080ef72598Sjeremylt libceed.VECTOR_NONE) 19090ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 19100ef72598Sjeremylt op_setup.set_field("qdata", rui, libceed.BASIS_COLLOCATED, 19110ef72598Sjeremylt libceed.VECTOR_ACTIVE) 19120ef72598Sjeremylt 19130ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 19140ef72598Sjeremylt op_mass_fine.set_field("qdata", rui, libceed.BASIS_COLLOCATED, qdata) 19150ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 19160ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 19170ef72598Sjeremylt 19180ef72598Sjeremylt # Setup 19190ef72598Sjeremylt op_setup.apply(x, qdata) 19200ef72598Sjeremylt 19210ef72598Sjeremylt # Create multigrid level 19220ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 19230ef72598Sjeremylt p_mult_fine.set_value(1.0) 19240ef72598Sjeremylt b_c_to_f = ceed.BasisTensorH1Lagrange( 19250ef72598Sjeremylt 1, ncomp, p_coarse, p_fine, libceed.GAUSS_LOBATTO) 192666ce82e0Sjeremylt interp_C_to_F = b_c_to_f.get_interp_1d() 19270ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create_h1(p_mult_fine, 19280ef72598Sjeremylt ru_coarse, bu_coarse, interp_C_to_F) 19290ef72598Sjeremylt 19300ef72598Sjeremylt # Apply coarse mass matrix 19310ef72598Sjeremylt u_coarse.set_value(1.0) 19320ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 19330ef72598Sjeremylt 19340ef72598Sjeremylt # Check 19350ef72598Sjeremylt with v_coarse.array_read() as v_array: 19360ef72598Sjeremylt total = 0.0 19370ef72598Sjeremylt for i in range(nu_coarse * ncomp): 19380ef72598Sjeremylt total = total + v_array[i] 1939*80a9ef05SNatalie Beams assert abs(total - 1.0) < TOL 19400ef72598Sjeremylt 19410ef72598Sjeremylt # Prolong coarse u 19420ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 19430ef72598Sjeremylt 19440ef72598Sjeremylt # Apply mass matrix 19450ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 19460ef72598Sjeremylt 19470ef72598Sjeremylt # Check 19480ef72598Sjeremylt with v_fine.array_read() as v_array: 19490ef72598Sjeremylt total = 0.0 19500ef72598Sjeremylt for i in range(nu_fine * ncomp): 19510ef72598Sjeremylt total = total + v_array[i] 1952*80a9ef05SNatalie Beams assert abs(total - 1.0) < TOL 19530ef72598Sjeremylt 19540ef72598Sjeremylt # Restrict state to coarse grid 19550ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 19560ef72598Sjeremylt 19570ef72598Sjeremylt # Check 19580ef72598Sjeremylt with v_coarse.array_read() as v_array: 19590ef72598Sjeremylt total = 0.0 19600ef72598Sjeremylt for i in range(nu_coarse * ncomp): 19610ef72598Sjeremylt total = total + v_array[i] 1962*80a9ef05SNatalie Beams assert abs(total - 1.0) < TOL 19630ef72598Sjeremylt 19640ef72598Sjeremylt# ------------------------------------------------------------------------------- 1965