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