13d8e8822SJeremy L Thompson# Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors 23d8e8822SJeremy L Thompson# All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 30ef72598Sjeremylt# 43d8e8822SJeremy L Thompson# SPDX-License-Identifier: BSD-2-Clause 50ef72598Sjeremylt# 63d8e8822SJeremy 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) 1227*ea6b5821SJeremy L Thompson op_setup_tet.name('triangle elements') 12280ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 12290ef72598Sjeremylt libceed.VECTOR_NONE) 12300ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 12310ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 12320ef72598Sjeremylt qdata_tet) 12330ef72598Sjeremylt 12340ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 1235*ea6b5821SJeremy L Thompson op_mass_tet.name('triangle elements') 12360ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 12370ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 12380ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 12390ef72598Sjeremylt 12400ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 12410ef72598Sjeremylt 12420ef72598Sjeremylt # Restrictions 12430ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 12440ef72598Sjeremylt for i in range(nelem_hex): 12450ef72598Sjeremylt col = i % nx_hex 12460ef72598Sjeremylt row = i // nx_hex 12470ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 12480ef72598Sjeremylt 12490ef72598Sjeremylt for j in range(p_hex): 12500ef72598Sjeremylt for k in range(p_hex): 12510ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 12520ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 12530ef72598Sjeremylt 12540ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 12550ef72598Sjeremylt dim * ndofs, indx_hex, 12560ef72598Sjeremylt cmode=libceed.USE_POINTER) 12570ef72598Sjeremylt 12580ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 12590ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 12600ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 12610ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 12620ef72598Sjeremylt nqpts_hex, strides) 12630ef72598Sjeremylt 12640ef72598Sjeremylt # Bases 12650ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 12660ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 12670ef72598Sjeremylt 12680ef72598Sjeremylt # QFunctions 12690ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 12700ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 12710ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 12720ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 12730ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 12740ef72598Sjeremylt 12750ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 12760ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 12770ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 12780ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 12790ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 12800ef72598Sjeremylt 12810ef72598Sjeremylt # Operators 12820ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 1283*ea6b5821SJeremy L Thompson op_setup_hex.name("quadralateral elements") 12840ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 12850ef72598Sjeremylt libceed.VECTOR_NONE) 12860ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 12870ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 12880ef72598Sjeremylt qdata_hex) 12890ef72598Sjeremylt 12900ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 1291*ea6b5821SJeremy L Thompson op_mass_hex.name("quadralateral elements") 12920ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 12930ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 12940ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 12950ef72598Sjeremylt 12960ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 12970ef72598Sjeremylt 12980ef72598Sjeremylt # Setup 12990ef72598Sjeremylt op_setup = ceed.CompositeOperator() 1300*ea6b5821SJeremy L Thompson op_setup.name('setup') 13010ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 13020ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 13030ef72598Sjeremylt 13040ef72598Sjeremylt # Apply mass matrix 13050ef72598Sjeremylt op_mass = ceed.CompositeOperator() 1306*ea6b5821SJeremy L Thompson op_mass.name('mass') 13070ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 13080ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 13090ef72598Sjeremylt 13100ef72598Sjeremylt # View 13110ef72598Sjeremylt print(op_setup) 13120ef72598Sjeremylt print(op_mass) 13130ef72598Sjeremylt 13140ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 13150ef72598Sjeremylt assert not stderr 13160ef72598Sjeremylt assert stdout == ref_stdout 13170ef72598Sjeremylt 13180ef72598Sjeremylt# ------------------------------------------------------------------------------- 13190ef72598Sjeremylt# CeedOperatorApplyAdd for composite operator 13200ef72598Sjeremylt# ------------------------------------------------------------------------------- 13210ef72598Sjeremylt 13220ef72598Sjeremylt 13230ef72598Sjeremyltdef test_524(ceed_resource): 13240ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 13250ef72598Sjeremylt 13260ef72598Sjeremylt nelem_tet, p_tet, q_tet = 6, 6, 4 13270ef72598Sjeremylt nelem_hex, p_hex, q_hex = 6, 3, 4 13280ef72598Sjeremylt nx, ny = 3, 3 13290ef72598Sjeremylt dim = 2 13300ef72598Sjeremylt nx_tet, ny_tet, nx_hex = 3, 1, 3 13310ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 13320ef72598Sjeremylt nqpts_tet, nqpts_hex = nelem_tet * q_tet, nelem_hex * q_hex * q_hex 13330ef72598Sjeremylt 13340ef72598Sjeremylt # Vectors 13350ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 133680a9ef05SNatalie Beams x_array = np.zeros(dim * ndofs, dtype=ceed.scalar_type()) 13370ef72598Sjeremylt for i in range(ny * 2 + 1): 13380ef72598Sjeremylt for j in range(nx * 2 + 1): 13390ef72598Sjeremylt x_array[i + j * (ny * 2 + 1)] = i / (2 * ny) 13400ef72598Sjeremylt x_array[i + j * (ny * 2 + 1) + ndofs] = j / (2 * nx) 13410ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 13420ef72598Sjeremylt 13430ef72598Sjeremylt qdata_hex = ceed.Vector(nqpts_hex) 13440ef72598Sjeremylt qdata_tet = ceed.Vector(nqpts_tet) 13450ef72598Sjeremylt u = ceed.Vector(ndofs) 13460ef72598Sjeremylt v = ceed.Vector(ndofs) 13470ef72598Sjeremylt 13480ef72598Sjeremylt # ------------------------- Tet Elements ------------------------- 13490ef72598Sjeremylt 13500ef72598Sjeremylt # Restrictions 13510ef72598Sjeremylt indx_tet = np.zeros(nelem_tet * p_tet, dtype="int32") 13520ef72598Sjeremylt for i in range(nelem_tet // 2): 13530ef72598Sjeremylt col = i % nx 13540ef72598Sjeremylt row = i // nx 13550ef72598Sjeremylt offset = col * 2 + row * (nx * 2 + 1) * 2 13560ef72598Sjeremylt 13570ef72598Sjeremylt indx_tet[i * 2 * p_tet + 0] = 2 + offset 13580ef72598Sjeremylt indx_tet[i * 2 * p_tet + 1] = 9 + offset 13590ef72598Sjeremylt indx_tet[i * 2 * p_tet + 2] = 16 + offset 13600ef72598Sjeremylt indx_tet[i * 2 * p_tet + 3] = 1 + offset 13610ef72598Sjeremylt indx_tet[i * 2 * p_tet + 4] = 8 + offset 13620ef72598Sjeremylt indx_tet[i * 2 * p_tet + 5] = 0 + offset 13630ef72598Sjeremylt 13640ef72598Sjeremylt indx_tet[i * 2 * p_tet + 6] = 14 + offset 13650ef72598Sjeremylt indx_tet[i * 2 * p_tet + 7] = 7 + offset 13660ef72598Sjeremylt indx_tet[i * 2 * p_tet + 8] = 0 + offset 13670ef72598Sjeremylt indx_tet[i * 2 * p_tet + 9] = 15 + offset 13680ef72598Sjeremylt indx_tet[i * 2 * p_tet + 10] = 8 + offset 13690ef72598Sjeremylt indx_tet[i * 2 * p_tet + 11] = 16 + offset 13700ef72598Sjeremylt 13710ef72598Sjeremylt rx_tet = ceed.ElemRestriction(nelem_tet, p_tet, dim, ndofs, dim * ndofs, 13720ef72598Sjeremylt indx_tet, cmode=libceed.USE_POINTER) 13730ef72598Sjeremylt 13740ef72598Sjeremylt ru_tet = ceed.ElemRestriction(nelem_tet, p_tet, 1, 1, ndofs, indx_tet, 13750ef72598Sjeremylt cmode=libceed.USE_POINTER) 13760ef72598Sjeremylt strides = np.array([1, q_tet, q_tet], dtype="int32") 13770ef72598Sjeremylt rui_tet = ceed.StridedElemRestriction(nelem_tet, q_tet, 1, nqpts_tet, 13780ef72598Sjeremylt strides) 13790ef72598Sjeremylt 13800ef72598Sjeremylt # Bases 138180a9ef05SNatalie Beams qref = np.empty(dim * q_tet, dtype=ceed.scalar_type()) 138280a9ef05SNatalie Beams qweight = np.empty(q_tet, dtype=ceed.scalar_type()) 138380a9ef05SNatalie Beams interp, grad = bm.buildmats(qref, qweight, libceed.scalar_types[ 138480a9ef05SNatalie Beams libceed.lib.CEED_SCALAR_TYPE]) 13850ef72598Sjeremylt 13860ef72598Sjeremylt bx_tet = ceed.BasisH1(libceed.TRIANGLE, dim, p_tet, q_hex, interp, grad, qref, 13870ef72598Sjeremylt qweight) 13880ef72598Sjeremylt bu_tet = ceed.BasisH1(libceed.TRIANGLE, 1, p_tet, q_hex, interp, grad, qref, 13890ef72598Sjeremylt qweight) 13900ef72598Sjeremylt 13910ef72598Sjeremylt # QFunctions 13920ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 13930ef72598Sjeremylt qfs = load_qfs_so() 13940ef72598Sjeremylt 13950ef72598Sjeremylt qf_setup_tet = ceed.QFunction(1, qfs.setup_mass_2d, 13960ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 13970ef72598Sjeremylt qf_setup_tet.add_input("weights", 1, libceed.EVAL_WEIGHT) 13980ef72598Sjeremylt qf_setup_tet.add_input("dx", dim * dim, libceed.EVAL_GRAD) 13990ef72598Sjeremylt qf_setup_tet.add_output("rho", 1, libceed.EVAL_NONE) 14000ef72598Sjeremylt 14010ef72598Sjeremylt qf_mass_tet = ceed.QFunction(1, qfs.apply_mass, 14020ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 14030ef72598Sjeremylt qf_mass_tet.add_input("rho", 1, libceed.EVAL_NONE) 14040ef72598Sjeremylt qf_mass_tet.add_input("u", 1, libceed.EVAL_INTERP) 14050ef72598Sjeremylt qf_mass_tet.add_output("v", 1, libceed.EVAL_INTERP) 14060ef72598Sjeremylt 14070ef72598Sjeremylt # Operators 14080ef72598Sjeremylt op_setup_tet = ceed.Operator(qf_setup_tet) 14090ef72598Sjeremylt op_setup_tet.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_tet, 14100ef72598Sjeremylt libceed.VECTOR_NONE) 14110ef72598Sjeremylt op_setup_tet.set_field("dx", rx_tet, bx_tet, libceed.VECTOR_ACTIVE) 14120ef72598Sjeremylt op_setup_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, 14130ef72598Sjeremylt qdata_tet) 14140ef72598Sjeremylt 14150ef72598Sjeremylt op_mass_tet = ceed.Operator(qf_mass_tet) 14160ef72598Sjeremylt op_mass_tet.set_field("rho", rui_tet, libceed.BASIS_COLLOCATED, qdata_tet) 14170ef72598Sjeremylt op_mass_tet.set_field("u", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 14180ef72598Sjeremylt op_mass_tet.set_field("v", ru_tet, bu_tet, libceed.VECTOR_ACTIVE) 14190ef72598Sjeremylt 14200ef72598Sjeremylt # ------------------------- Hex Elements ------------------------- 14210ef72598Sjeremylt 14220ef72598Sjeremylt # Restrictions 14230ef72598Sjeremylt indx_hex = np.zeros(nelem_hex * p_hex * p_hex, dtype="int32") 14240ef72598Sjeremylt for i in range(nelem_hex): 14250ef72598Sjeremylt col = i % nx_hex 14260ef72598Sjeremylt row = i // nx_hex 14270ef72598Sjeremylt offset = (nx_tet * 2 + 1) * (ny_tet * 2) * (1 + row) + col * 2 14280ef72598Sjeremylt 14290ef72598Sjeremylt for j in range(p_hex): 14300ef72598Sjeremylt for k in range(p_hex): 14310ef72598Sjeremylt indx_hex[p_hex * (p_hex * i + k) + j] = offset + \ 14320ef72598Sjeremylt k * (nx_hex * 2 + 1) + j 14330ef72598Sjeremylt 14340ef72598Sjeremylt rx_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, dim, ndofs, 14350ef72598Sjeremylt dim * ndofs, indx_hex, 14360ef72598Sjeremylt cmode=libceed.USE_POINTER) 14370ef72598Sjeremylt 14380ef72598Sjeremylt ru_hex = ceed.ElemRestriction(nelem_hex, p_hex * p_hex, 1, 1, ndofs, 14390ef72598Sjeremylt indx_hex, cmode=libceed.USE_POINTER) 14400ef72598Sjeremylt strides = np.array([1, q_hex * q_hex, q_hex * q_hex], dtype="int32") 14410ef72598Sjeremylt rui_hex = ceed.StridedElemRestriction(nelem_hex, q_hex * q_hex, 1, 14420ef72598Sjeremylt nqpts_hex, strides) 14430ef72598Sjeremylt 14440ef72598Sjeremylt # Bases 14450ef72598Sjeremylt bx_hex = ceed.BasisTensorH1Lagrange(dim, dim, p_hex, q_hex, libceed.GAUSS) 14460ef72598Sjeremylt bu_hex = ceed.BasisTensorH1Lagrange(dim, 1, p_hex, q_hex, libceed.GAUSS) 14470ef72598Sjeremylt 14480ef72598Sjeremylt # QFunctions 14490ef72598Sjeremylt qf_setup_hex = ceed.QFunction(1, qfs.setup_mass_2d, 14500ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass_2d")) 14510ef72598Sjeremylt qf_setup_hex.add_input("weights", 1, libceed.EVAL_WEIGHT) 14520ef72598Sjeremylt qf_setup_hex.add_input("dx", dim * dim, libceed.EVAL_GRAD) 14530ef72598Sjeremylt qf_setup_hex.add_output("rho", 1, libceed.EVAL_NONE) 14540ef72598Sjeremylt 14550ef72598Sjeremylt qf_mass_hex = ceed.QFunction(1, qfs.apply_mass, 14560ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass")) 14570ef72598Sjeremylt qf_mass_hex.add_input("rho", 1, libceed.EVAL_NONE) 14580ef72598Sjeremylt qf_mass_hex.add_input("u", 1, libceed.EVAL_INTERP) 14590ef72598Sjeremylt qf_mass_hex.add_output("v", 1, libceed.EVAL_INTERP) 14600ef72598Sjeremylt 14610ef72598Sjeremylt # Operators 14620ef72598Sjeremylt op_setup_hex = ceed.Operator(qf_setup_tet) 14630ef72598Sjeremylt op_setup_hex.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx_hex, 14640ef72598Sjeremylt libceed.VECTOR_NONE) 14650ef72598Sjeremylt op_setup_hex.set_field("dx", rx_hex, bx_hex, libceed.VECTOR_ACTIVE) 14660ef72598Sjeremylt op_setup_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, 14670ef72598Sjeremylt qdata_hex) 14680ef72598Sjeremylt 14690ef72598Sjeremylt op_mass_hex = ceed.Operator(qf_mass_hex) 14700ef72598Sjeremylt op_mass_hex.set_field("rho", rui_hex, libceed.BASIS_COLLOCATED, qdata_hex) 14710ef72598Sjeremylt op_mass_hex.set_field("u", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 14720ef72598Sjeremylt op_mass_hex.set_field("v", ru_hex, bu_hex, libceed.VECTOR_ACTIVE) 14730ef72598Sjeremylt 14740ef72598Sjeremylt # ------------------------- Composite Operators ------------------------- 14750ef72598Sjeremylt 14760ef72598Sjeremylt # Setup 14770ef72598Sjeremylt op_setup = ceed.CompositeOperator() 14780ef72598Sjeremylt op_setup.add_sub(op_setup_tet) 14790ef72598Sjeremylt op_setup.add_sub(op_setup_hex) 14800ef72598Sjeremylt op_setup.apply(x, libceed.VECTOR_NONE) 14810ef72598Sjeremylt 14820ef72598Sjeremylt # Apply mass matrix 14830ef72598Sjeremylt op_mass = ceed.CompositeOperator() 14840ef72598Sjeremylt op_mass.add_sub(op_mass_tet) 14850ef72598Sjeremylt op_mass.add_sub(op_mass_hex) 14860ef72598Sjeremylt u.set_value(1.) 14870ef72598Sjeremylt op_mass.apply(u, v) 14880ef72598Sjeremylt 14890ef72598Sjeremylt # Check 14900ef72598Sjeremylt with v.array_read() as v_array: 14910ef72598Sjeremylt total = 0.0 14920ef72598Sjeremylt for i in range(ndofs): 14930ef72598Sjeremylt total = total + v_array[i] 149480a9ef05SNatalie Beams assert abs(total - 1.0) < 10. * TOL 14950ef72598Sjeremylt 14960ef72598Sjeremylt # ApplyAdd mass matrix 14970ef72598Sjeremylt v.set_value(1.) 14980ef72598Sjeremylt op_mass.apply_add(u, v) 14990ef72598Sjeremylt 15000ef72598Sjeremylt # Check 15010ef72598Sjeremylt with v.array_read() as v_array: 15020ef72598Sjeremylt total = -ndofs 15030ef72598Sjeremylt for i in range(ndofs): 15040ef72598Sjeremylt total = total + v_array[i] 150580a9ef05SNatalie Beams assert abs(total - 1.0) < 10. * TOL 15060ef72598Sjeremylt 15070ef72598Sjeremylt# ------------------------------------------------------------------------------- 15080ef72598Sjeremylt# Test assembly of mass matrix operator diagonal 15090ef72598Sjeremylt# ------------------------------------------------------------------------------- 15100ef72598Sjeremylt 15110ef72598Sjeremylt 15120ef72598Sjeremyltdef test_533(ceed_resource): 15130ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 15140ef72598Sjeremylt 15150ef72598Sjeremylt nelem = 6 15160ef72598Sjeremylt p = 3 15170ef72598Sjeremylt q = 4 15180ef72598Sjeremylt dim = 2 15190ef72598Sjeremylt nx = 3 15200ef72598Sjeremylt ny = 2 15210ef72598Sjeremylt ndofs = (nx * 2 + 1) * (ny * 2 + 1) 15220ef72598Sjeremylt nqpts = nelem * q * q 15230ef72598Sjeremylt 15240ef72598Sjeremylt # Vectors 15250ef72598Sjeremylt x = ceed.Vector(dim * ndofs) 15260ef72598Sjeremylt x_array = np.zeros(dim * ndofs) 15270ef72598Sjeremylt for i in range(nx * 2 + 1): 15280ef72598Sjeremylt for j in range(ny * 2 + 1): 15290ef72598Sjeremylt x_array[i + j * (nx * 2 + 1) + 0 * ndofs] = i / (2 * nx) 15300ef72598Sjeremylt x_array[i + j * (nx * 2 + 1) + 1 * ndofs] = j / (2 * ny) 15310ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 15320ef72598Sjeremylt 15330ef72598Sjeremylt qdata = ceed.Vector(nqpts) 15340ef72598Sjeremylt u = ceed.Vector(ndofs) 15350ef72598Sjeremylt v = ceed.Vector(ndofs) 15360ef72598Sjeremylt 15370ef72598Sjeremylt # Restrictions 15380ef72598Sjeremylt indx = np.zeros(nelem * p * p, dtype="int32") 15390ef72598Sjeremylt for i in range(nelem): 15400ef72598Sjeremylt col = i % nx 15410ef72598Sjeremylt row = i // nx 15420ef72598Sjeremylt offset = col * (p - 1) + row * (nx * 2 + 1) * (p - 1) 15430ef72598Sjeremylt for j in range(p): 15440ef72598Sjeremylt for k in range(p): 15450ef72598Sjeremylt indx[p * (p * i + k) + j] = offset + k * (nx * 2 + 1) + j 15460ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, p * p, dim, ndofs, dim * ndofs, 15470ef72598Sjeremylt indx, cmode=libceed.USE_POINTER) 15480ef72598Sjeremylt 15490ef72598Sjeremylt ru = ceed.ElemRestriction(nelem, p * p, 1, 1, ndofs, indx, 15500ef72598Sjeremylt cmode=libceed.USE_POINTER) 15510ef72598Sjeremylt strides = np.array([1, q * q, q * q], dtype="int32") 15520ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q * q, 1, nqpts, strides) 15530ef72598Sjeremylt 15540ef72598Sjeremylt # Bases 15550ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(dim, dim, p, q, libceed.GAUSS) 15560ef72598Sjeremylt bu = ceed.BasisTensorH1Lagrange(dim, 1, p, q, libceed.GAUSS) 15570ef72598Sjeremylt 15580ef72598Sjeremylt # QFunctions 15590ef72598Sjeremylt qf_setup = ceed.QFunctionByName("Mass2DBuild") 15600ef72598Sjeremylt 15610ef72598Sjeremylt# ------------------------------------------------------------------------------- 15620ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 15630ef72598Sjeremylt# multigrid level, tensor basis and interpolation basis generation 15640ef72598Sjeremylt# ------------------------------------------------------------------------------- 15650ef72598Sjeremylt 15660ef72598Sjeremylt 15670ef72598Sjeremyltdef test_550(ceed_resource): 15680ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 15690ef72598Sjeremylt 15700ef72598Sjeremylt nelem = 15 15710ef72598Sjeremylt p_coarse = 3 15720ef72598Sjeremylt p_fine = 5 15730ef72598Sjeremylt q = 8 15740ef72598Sjeremylt ncomp = 2 15750ef72598Sjeremylt nx = nelem + 1 15760ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 15770ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 15780ef72598Sjeremylt 15790ef72598Sjeremylt # Vectors 15800ef72598Sjeremylt x = ceed.Vector(nx) 158180a9ef05SNatalie Beams x_array = np.zeros(nx, dtype=ceed.scalar_type()) 15820ef72598Sjeremylt for i in range(nx): 15830ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 15840ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 15850ef72598Sjeremylt 15860ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 15870ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 15880ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 15890ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 15900ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 15910ef72598Sjeremylt 15920ef72598Sjeremylt # Restrictions 15930ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 15940ef72598Sjeremylt for i in range(nx): 15950ef72598Sjeremylt indx[2 * i + 0] = i 15960ef72598Sjeremylt indx[2 * i + 1] = i + 1 15970ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 15980ef72598Sjeremylt cmode=libceed.USE_POINTER) 15990ef72598Sjeremylt 16000ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 16010ef72598Sjeremylt for i in range(nelem): 16020ef72598Sjeremylt for j in range(p_coarse): 16030ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 16040ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 16050ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 16060ef72598Sjeremylt cmode=libceed.USE_POINTER) 16070ef72598Sjeremylt 16080ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 16090ef72598Sjeremylt for i in range(nelem): 16100ef72598Sjeremylt for j in range(p_fine): 16110ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 16120ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 16130ef72598Sjeremylt ncomp * nu_fine, indu_fine, 16140ef72598Sjeremylt cmode=libceed.USE_POINTER) 16150ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 16160ef72598Sjeremylt 16170ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 16180ef72598Sjeremylt 16190ef72598Sjeremylt # Bases 16200ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 16210ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 16220ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 16230ef72598Sjeremylt 16240ef72598Sjeremylt # QFunctions 16250ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 16260ef72598Sjeremylt qfs = load_qfs_so() 16270ef72598Sjeremylt 16280ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 16290ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 16300ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 16310ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 16320ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 16330ef72598Sjeremylt 16340ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass_two, 16350ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass_two")) 16360ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 16370ef72598Sjeremylt qf_mass.add_input("u", ncomp, libceed.EVAL_INTERP) 16380ef72598Sjeremylt qf_mass.add_output("v", ncomp, libceed.EVAL_INTERP) 16390ef72598Sjeremylt 16400ef72598Sjeremylt # Operators 16410ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 16420ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 16430ef72598Sjeremylt libceed.VECTOR_NONE) 16440ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 16450ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 16460ef72598Sjeremylt libceed.VECTOR_ACTIVE) 16470ef72598Sjeremylt 16480ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 16490ef72598Sjeremylt op_mass_fine.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 16500ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 16510ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 16520ef72598Sjeremylt 16530ef72598Sjeremylt # Setup 16540ef72598Sjeremylt op_setup.apply(x, qdata) 16550ef72598Sjeremylt 16560ef72598Sjeremylt # Create multigrid level 16570ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 16580ef72598Sjeremylt p_mult_fine.set_value(1.0) 16590ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create(p_mult_fine, 16600ef72598Sjeremylt ru_coarse, 16610ef72598Sjeremylt bu_coarse) 16620ef72598Sjeremylt 16630ef72598Sjeremylt # Apply coarse mass matrix 16640ef72598Sjeremylt u_coarse.set_value(1.0) 16650ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 16660ef72598Sjeremylt 16670ef72598Sjeremylt # Check 16680ef72598Sjeremylt with v_coarse.array_read() as v_array: 16690ef72598Sjeremylt total = 0.0 16700ef72598Sjeremylt for i in range(nu_coarse * ncomp): 16710ef72598Sjeremylt total = total + v_array[i] 167280a9ef05SNatalie Beams assert abs(total - 2.0) < 10. * TOL 16730ef72598Sjeremylt 16740ef72598Sjeremylt # Prolong coarse u 16750ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 16760ef72598Sjeremylt 16770ef72598Sjeremylt # Apply mass matrix 16780ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 16790ef72598Sjeremylt 16800ef72598Sjeremylt # Check 16810ef72598Sjeremylt with v_fine.array_read() as v_array: 16820ef72598Sjeremylt total = 0.0 16830ef72598Sjeremylt for i in range(nu_fine * ncomp): 16840ef72598Sjeremylt total = total + v_array[i] 168580a9ef05SNatalie Beams assert abs(total - 2.0) < 10. * TOL 16860ef72598Sjeremylt 16870ef72598Sjeremylt # Restrict state to coarse grid 16880ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 16890ef72598Sjeremylt 16900ef72598Sjeremylt # Check 16910ef72598Sjeremylt with v_coarse.array_read() as v_array: 16920ef72598Sjeremylt total = 0.0 16930ef72598Sjeremylt for i in range(nu_coarse * ncomp): 16940ef72598Sjeremylt total = total + v_array[i] 169580a9ef05SNatalie Beams assert abs(total - 2.0) < 10. * TOL 16960ef72598Sjeremylt 16970ef72598Sjeremylt# ------------------------------------------------------------------------------- 16980ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 16990ef72598Sjeremylt# multigrid level, tensor basis 17000ef72598Sjeremylt# ------------------------------------------------------------------------------- 17010ef72598Sjeremylt 17020ef72598Sjeremylt 17030ef72598Sjeremyltdef test_552(ceed_resource): 17040ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 17050ef72598Sjeremylt 17060ef72598Sjeremylt nelem = 15 17070ef72598Sjeremylt p_coarse = 3 17080ef72598Sjeremylt p_fine = 5 17090ef72598Sjeremylt q = 8 17100ef72598Sjeremylt ncomp = 2 17110ef72598Sjeremylt nx = nelem + 1 17120ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 17130ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 17140ef72598Sjeremylt 17150ef72598Sjeremylt # Vectors 17160ef72598Sjeremylt x = ceed.Vector(nx) 171780a9ef05SNatalie Beams x_array = np.zeros(nx, dtype=ceed.scalar_type()) 17180ef72598Sjeremylt for i in range(nx): 17190ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 17200ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 17210ef72598Sjeremylt 17220ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 17230ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 17240ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 17250ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 17260ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 17270ef72598Sjeremylt 17280ef72598Sjeremylt # Restrictions 17290ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 17300ef72598Sjeremylt for i in range(nx): 17310ef72598Sjeremylt indx[2 * i + 0] = i 17320ef72598Sjeremylt indx[2 * i + 1] = i + 1 17330ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 17340ef72598Sjeremylt cmode=libceed.USE_POINTER) 17350ef72598Sjeremylt 17360ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 17370ef72598Sjeremylt for i in range(nelem): 17380ef72598Sjeremylt for j in range(p_coarse): 17390ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 17400ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 17410ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 17420ef72598Sjeremylt cmode=libceed.USE_POINTER) 17430ef72598Sjeremylt 17440ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 17450ef72598Sjeremylt for i in range(nelem): 17460ef72598Sjeremylt for j in range(p_fine): 17470ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 17480ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 17490ef72598Sjeremylt ncomp * nu_fine, indu_fine, 17500ef72598Sjeremylt cmode=libceed.USE_POINTER) 17510ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 17520ef72598Sjeremylt 17530ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 17540ef72598Sjeremylt 17550ef72598Sjeremylt # Bases 17560ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 17570ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 17580ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 17590ef72598Sjeremylt 17600ef72598Sjeremylt # QFunctions 17610ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 17620ef72598Sjeremylt qfs = load_qfs_so() 17630ef72598Sjeremylt 17640ef72598Sjeremylt qf_setup = ceed.QFunction(1, qfs.setup_mass, 17650ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:setup_mass")) 17660ef72598Sjeremylt qf_setup.add_input("weights", 1, libceed.EVAL_WEIGHT) 17670ef72598Sjeremylt qf_setup.add_input("dx", 1, libceed.EVAL_GRAD) 17680ef72598Sjeremylt qf_setup.add_output("rho", 1, libceed.EVAL_NONE) 17690ef72598Sjeremylt 17700ef72598Sjeremylt qf_mass = ceed.QFunction(1, qfs.apply_mass_two, 17710ef72598Sjeremylt os.path.join(file_dir, "test-qfunctions.h:apply_mass_two")) 17720ef72598Sjeremylt qf_mass.add_input("rho", 1, libceed.EVAL_NONE) 17730ef72598Sjeremylt qf_mass.add_input("u", ncomp, libceed.EVAL_INTERP) 17740ef72598Sjeremylt qf_mass.add_output("v", ncomp, libceed.EVAL_INTERP) 17750ef72598Sjeremylt 17760ef72598Sjeremylt # Operators 17770ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 17780ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 17790ef72598Sjeremylt libceed.VECTOR_NONE) 17800ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 17810ef72598Sjeremylt op_setup.set_field("rho", rui, libceed.BASIS_COLLOCATED, 17820ef72598Sjeremylt libceed.VECTOR_ACTIVE) 17830ef72598Sjeremylt 17840ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 17850ef72598Sjeremylt op_mass_fine.set_field("rho", rui, libceed.BASIS_COLLOCATED, qdata) 17860ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 17870ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 17880ef72598Sjeremylt 17890ef72598Sjeremylt # Setup 17900ef72598Sjeremylt op_setup.apply(x, qdata) 17910ef72598Sjeremylt 17920ef72598Sjeremylt # Create multigrid level 17930ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 17940ef72598Sjeremylt p_mult_fine.set_value(1.0) 17950ef72598Sjeremylt b_c_to_f = ceed.BasisTensorH1Lagrange( 17960ef72598Sjeremylt 1, ncomp, p_coarse, p_fine, libceed.GAUSS_LOBATTO) 179766ce82e0Sjeremylt interp_C_to_F = b_c_to_f.get_interp_1d() 17980ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create_tensor_h1(p_mult_fine, 17990ef72598Sjeremylt ru_coarse, bu_coarse, interp_C_to_F) 18000ef72598Sjeremylt 18010ef72598Sjeremylt # Apply coarse mass matrix 18020ef72598Sjeremylt u_coarse.set_value(1.0) 18030ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 18040ef72598Sjeremylt 18050ef72598Sjeremylt # Check 18060ef72598Sjeremylt with v_coarse.array_read() as v_array: 18070ef72598Sjeremylt total = 0.0 18080ef72598Sjeremylt for i in range(nu_coarse * ncomp): 18090ef72598Sjeremylt total = total + v_array[i] 181080a9ef05SNatalie Beams assert abs(total - 2.0) < TOL 18110ef72598Sjeremylt 18120ef72598Sjeremylt # Prolong coarse u 18130ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 18140ef72598Sjeremylt 18150ef72598Sjeremylt # Apply mass matrix 18160ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 18170ef72598Sjeremylt 18180ef72598Sjeremylt # Check 18190ef72598Sjeremylt with v_fine.array_read() as v_array: 18200ef72598Sjeremylt total = 0.0 18210ef72598Sjeremylt for i in range(nu_fine * ncomp): 18220ef72598Sjeremylt total = total + v_array[i] 182380a9ef05SNatalie Beams assert abs(total - 2.0) < TOL 18240ef72598Sjeremylt 18250ef72598Sjeremylt # Restrict state to coarse grid 18260ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 18270ef72598Sjeremylt 18280ef72598Sjeremylt # Check 18290ef72598Sjeremylt with v_coarse.array_read() as v_array: 18300ef72598Sjeremylt total = 0.0 18310ef72598Sjeremylt for i in range(nu_coarse * ncomp): 18320ef72598Sjeremylt total = total + v_array[i] 183380a9ef05SNatalie Beams assert abs(total - 2.0) < TOL 18340ef72598Sjeremylt 18350ef72598Sjeremylt# ------------------------------------------------------------------------------- 18360ef72598Sjeremylt# Test creation, action, and destruction for mass matrix operator with 18370ef72598Sjeremylt# multigrid level, non-tensor basis 18380ef72598Sjeremylt# ------------------------------------------------------------------------------- 18390ef72598Sjeremylt 18400ef72598Sjeremylt 18410ef72598Sjeremyltdef test_553(ceed_resource): 18420ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 18430ef72598Sjeremylt 18440ef72598Sjeremylt nelem = 15 18450ef72598Sjeremylt p_coarse = 3 18460ef72598Sjeremylt p_fine = 5 18470ef72598Sjeremylt q = 8 18480ef72598Sjeremylt ncomp = 1 18490ef72598Sjeremylt nx = nelem + 1 18500ef72598Sjeremylt nu_coarse = nelem * (p_coarse - 1) + 1 18510ef72598Sjeremylt nu_fine = nelem * (p_fine - 1) + 1 18520ef72598Sjeremylt 18530ef72598Sjeremylt # Vectors 18540ef72598Sjeremylt x = ceed.Vector(nx) 185580a9ef05SNatalie Beams x_array = np.zeros(nx, dtype=ceed.scalar_type()) 18560ef72598Sjeremylt for i in range(nx): 18570ef72598Sjeremylt x_array[i] = i / (nx - 1.0) 18580ef72598Sjeremylt x.set_array(x_array, cmode=libceed.USE_POINTER) 18590ef72598Sjeremylt 18600ef72598Sjeremylt qdata = ceed.Vector(nelem * q) 18610ef72598Sjeremylt u_coarse = ceed.Vector(ncomp * nu_coarse) 18620ef72598Sjeremylt v_coarse = ceed.Vector(ncomp * nu_coarse) 18630ef72598Sjeremylt u_fine = ceed.Vector(ncomp * nu_fine) 18640ef72598Sjeremylt v_fine = ceed.Vector(ncomp * nu_fine) 18650ef72598Sjeremylt 18660ef72598Sjeremylt # Restrictions 18670ef72598Sjeremylt indx = np.zeros(nx * 2, dtype="int32") 18680ef72598Sjeremylt for i in range(nx): 18690ef72598Sjeremylt indx[2 * i + 0] = i 18700ef72598Sjeremylt indx[2 * i + 1] = i + 1 18710ef72598Sjeremylt rx = ceed.ElemRestriction(nelem, 2, 1, 1, nx, indx, 18720ef72598Sjeremylt cmode=libceed.USE_POINTER) 18730ef72598Sjeremylt 18740ef72598Sjeremylt indu_coarse = np.zeros(nelem * p_coarse, dtype="int32") 18750ef72598Sjeremylt for i in range(nelem): 18760ef72598Sjeremylt for j in range(p_coarse): 18770ef72598Sjeremylt indu_coarse[p_coarse * i + j] = i * (p_coarse - 1) + j 18780ef72598Sjeremylt ru_coarse = ceed.ElemRestriction(nelem, p_coarse, ncomp, nu_coarse, 18790ef72598Sjeremylt ncomp * nu_coarse, indu_coarse, 18800ef72598Sjeremylt cmode=libceed.USE_POINTER) 18810ef72598Sjeremylt 18820ef72598Sjeremylt indu_fine = np.zeros(nelem * p_fine, dtype="int32") 18830ef72598Sjeremylt for i in range(nelem): 18840ef72598Sjeremylt for j in range(p_fine): 18850ef72598Sjeremylt indu_fine[p_fine * i + j] = i * (p_fine - 1) + j 18860ef72598Sjeremylt ru_fine = ceed.ElemRestriction(nelem, p_fine, ncomp, nu_fine, 18870ef72598Sjeremylt ncomp * nu_fine, indu_fine, 18880ef72598Sjeremylt cmode=libceed.USE_POINTER) 18890ef72598Sjeremylt strides = np.array([1, q, q], dtype="int32") 18900ef72598Sjeremylt 18910ef72598Sjeremylt rui = ceed.StridedElemRestriction(nelem, q, 1, q * nelem, strides) 18920ef72598Sjeremylt 18930ef72598Sjeremylt # Bases 18940ef72598Sjeremylt bx = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS) 18950ef72598Sjeremylt bu_coarse = ceed.BasisTensorH1Lagrange(1, ncomp, p_coarse, q, libceed.GAUSS) 18960ef72598Sjeremylt bu_fine = ceed.BasisTensorH1Lagrange(1, ncomp, p_fine, q, libceed.GAUSS) 18970ef72598Sjeremylt 18980ef72598Sjeremylt # QFunctions 18990ef72598Sjeremylt file_dir = os.path.dirname(os.path.abspath(__file__)) 19000ef72598Sjeremylt qfs = load_qfs_so() 19010ef72598Sjeremylt 19020ef72598Sjeremylt qf_setup = ceed.QFunctionByName("Mass1DBuild") 19030ef72598Sjeremylt qf_mass = ceed.QFunctionByName("MassApply") 19040ef72598Sjeremylt 19050ef72598Sjeremylt # Operators 19060ef72598Sjeremylt op_setup = ceed.Operator(qf_setup) 19070ef72598Sjeremylt op_setup.set_field("weights", libceed.ELEMRESTRICTION_NONE, bx, 19080ef72598Sjeremylt libceed.VECTOR_NONE) 19090ef72598Sjeremylt op_setup.set_field("dx", rx, bx, libceed.VECTOR_ACTIVE) 19100ef72598Sjeremylt op_setup.set_field("qdata", rui, libceed.BASIS_COLLOCATED, 19110ef72598Sjeremylt libceed.VECTOR_ACTIVE) 19120ef72598Sjeremylt 19130ef72598Sjeremylt op_mass_fine = ceed.Operator(qf_mass) 19140ef72598Sjeremylt op_mass_fine.set_field("qdata", rui, libceed.BASIS_COLLOCATED, qdata) 19150ef72598Sjeremylt op_mass_fine.set_field("u", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 19160ef72598Sjeremylt op_mass_fine.set_field("v", ru_fine, bu_fine, libceed.VECTOR_ACTIVE) 19170ef72598Sjeremylt 19180ef72598Sjeremylt # Setup 19190ef72598Sjeremylt op_setup.apply(x, qdata) 19200ef72598Sjeremylt 19210ef72598Sjeremylt # Create multigrid level 19220ef72598Sjeremylt p_mult_fine = ceed.Vector(ncomp * nu_fine) 19230ef72598Sjeremylt p_mult_fine.set_value(1.0) 19240ef72598Sjeremylt b_c_to_f = ceed.BasisTensorH1Lagrange( 19250ef72598Sjeremylt 1, ncomp, p_coarse, p_fine, libceed.GAUSS_LOBATTO) 192666ce82e0Sjeremylt interp_C_to_F = b_c_to_f.get_interp_1d() 19270ef72598Sjeremylt [op_mass_coarse, op_prolong, op_restrict] = op_mass_fine.multigrid_create_h1(p_mult_fine, 19280ef72598Sjeremylt ru_coarse, bu_coarse, interp_C_to_F) 19290ef72598Sjeremylt 19300ef72598Sjeremylt # Apply coarse mass matrix 19310ef72598Sjeremylt u_coarse.set_value(1.0) 19320ef72598Sjeremylt op_mass_coarse.apply(u_coarse, v_coarse) 19330ef72598Sjeremylt 19340ef72598Sjeremylt # Check 19350ef72598Sjeremylt with v_coarse.array_read() as v_array: 19360ef72598Sjeremylt total = 0.0 19370ef72598Sjeremylt for i in range(nu_coarse * ncomp): 19380ef72598Sjeremylt total = total + v_array[i] 193980a9ef05SNatalie Beams assert abs(total - 1.0) < TOL 19400ef72598Sjeremylt 19410ef72598Sjeremylt # Prolong coarse u 19420ef72598Sjeremylt op_prolong.apply(u_coarse, u_fine) 19430ef72598Sjeremylt 19440ef72598Sjeremylt # Apply mass matrix 19450ef72598Sjeremylt op_mass_fine.apply(u_fine, v_fine) 19460ef72598Sjeremylt 19470ef72598Sjeremylt # Check 19480ef72598Sjeremylt with v_fine.array_read() as v_array: 19490ef72598Sjeremylt total = 0.0 19500ef72598Sjeremylt for i in range(nu_fine * ncomp): 19510ef72598Sjeremylt total = total + v_array[i] 195280a9ef05SNatalie Beams assert abs(total - 1.0) < TOL 19530ef72598Sjeremylt 19540ef72598Sjeremylt # Restrict state to coarse grid 19550ef72598Sjeremylt op_restrict.apply(v_fine, v_coarse) 19560ef72598Sjeremylt 19570ef72598Sjeremylt # Check 19580ef72598Sjeremylt with v_coarse.array_read() as v_array: 19590ef72598Sjeremylt total = 0.0 19600ef72598Sjeremylt for i in range(nu_coarse * ncomp): 19610ef72598Sjeremylt total = total + v_array[i] 196280a9ef05SNatalie Beams assert abs(total - 1.0) < TOL 19630ef72598Sjeremylt 19640ef72598Sjeremylt# ------------------------------------------------------------------------------- 1965