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