1*9ba83ac0SJeremy L Thompson# Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors 23d8e8822SJeremy L Thompson# All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 30ef72598Sjeremylt# 43d8e8822SJeremy L Thompson# SPDX-License-Identifier: BSD-2-Clause 50ef72598Sjeremylt# 63d8e8822SJeremy L Thompson# This file is part of CEED: http://github.com/ceed 70ef72598Sjeremylt 80ef72598Sjeremylt# @file 90ef72598Sjeremylt# Test Ceed ElemRestriction functionality 100ef72598Sjeremylt 110ef72598Sjeremyltimport os 120ef72598Sjeremyltimport libceed 130ef72598Sjeremyltimport numpy as np 140ef72598Sjeremyltimport check 150ef72598Sjeremylt 160ef72598Sjeremylt# ------------------------------------------------------------------------------- 170ef72598Sjeremylt# Test creation, use, and destruction of an element restriction 180ef72598Sjeremylt# ------------------------------------------------------------------------------- 190ef72598Sjeremylt 200ef72598Sjeremylt 210ef72598Sjeremyltdef test_200(ceed_resource): 220ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 230ef72598Sjeremylt 24c3a5a609SJeremy L Thompson num_elem = 3 250ef72598Sjeremylt 26c3a5a609SJeremy L Thompson x = ceed.Vector(num_elem + 1) 2780a9ef05SNatalie Beams a = np.arange(10, 10 + num_elem + 1, dtype=ceed.scalar_type()) 280ef72598Sjeremylt x.set_array(a, cmode=libceed.USE_POINTER) 290ef72598Sjeremylt 30c3a5a609SJeremy L Thompson ind = np.zeros(2 * num_elem, dtype="int32") 31c3a5a609SJeremy L Thompson for i in range(num_elem): 320ef72598Sjeremylt ind[2 * i + 0] = i 330ef72598Sjeremylt ind[2 * i + 1] = i + 1 34c3a5a609SJeremy L Thompson r = ceed.ElemRestriction(num_elem, 2, 1, 1, num_elem + 1, ind, 350ef72598Sjeremylt cmode=libceed.USE_POINTER) 360ef72598Sjeremylt 37c3a5a609SJeremy L Thompson y = ceed.Vector(2 * num_elem) 380ef72598Sjeremylt y.set_value(0) 390ef72598Sjeremylt 400ef72598Sjeremylt r.apply(x, y) 410ef72598Sjeremylt 420ef72598Sjeremylt with y.array_read() as y_array: 43c3a5a609SJeremy L Thompson for i in range(2 * num_elem): 440ef72598Sjeremylt assert 10 + (i + 1) // 2 == y_array[i] 450ef72598Sjeremylt 460ef72598Sjeremylt# ------------------------------------------------------------------------------- 470ef72598Sjeremylt# Test creation, use, and destruction of a strided element restriction 480ef72598Sjeremylt# ------------------------------------------------------------------------------- 490ef72598Sjeremylt 500ef72598Sjeremylt 510ef72598Sjeremyltdef test_201(ceed_resource): 520ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 530ef72598Sjeremylt 54c3a5a609SJeremy L Thompson num_elem = 3 550ef72598Sjeremylt 56c3a5a609SJeremy L Thompson x = ceed.Vector(2 * num_elem) 5780a9ef05SNatalie Beams a = np.arange(10, 10 + 2 * num_elem, dtype=ceed.scalar_type()) 580ef72598Sjeremylt x.set_array(a, cmode=libceed.USE_POINTER) 590ef72598Sjeremylt 600ef72598Sjeremylt strides = np.array([1, 2, 2], dtype="int32") 61c3a5a609SJeremy L Thompson r = ceed.StridedElemRestriction(num_elem, 2, 1, 2 * num_elem, strides) 620ef72598Sjeremylt 63c3a5a609SJeremy L Thompson y = ceed.Vector(2 * num_elem) 640ef72598Sjeremylt y.set_value(0) 650ef72598Sjeremylt 660ef72598Sjeremylt r.apply(x, y) 670ef72598Sjeremylt 680ef72598Sjeremylt with y.array_read() as y_array: 69c3a5a609SJeremy L Thompson for i in range(2 * num_elem): 700ef72598Sjeremylt assert 10 + i == y_array[i] 710ef72598Sjeremylt 720ef72598Sjeremylt# ------------------------------------------------------------------------------- 730ef72598Sjeremylt# Test creation and destruction of a blocked element restriction 740ef72598Sjeremylt# ------------------------------------------------------------------------------- 750ef72598Sjeremylt 760ef72598Sjeremylt 770ef72598Sjeremyltdef test_202(ceed_resource, capsys): 780ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 790ef72598Sjeremylt 80c3a5a609SJeremy L Thompson num_elem = 8 81c3a5a609SJeremy L Thompson elem_size = 2 82c3a5a609SJeremy L Thompson num_blk = 2 83c3a5a609SJeremy L Thompson blk_size = 5 840ef72598Sjeremylt 85c3a5a609SJeremy L Thompson x = ceed.Vector(num_elem + 1) 8680a9ef05SNatalie Beams a = np.arange(10, 10 + num_elem + 1, dtype=ceed.scalar_type()) 87c3a5a609SJeremy L Thompson x.set_array(a, cmode=libceed.COPY_VALUES) 880ef72598Sjeremylt 89c3a5a609SJeremy L Thompson ind = np.zeros(2 * num_elem, dtype="int32") 90c3a5a609SJeremy L Thompson for i in range(num_elem): 910ef72598Sjeremylt ind[2 * i + 0] = i 920ef72598Sjeremylt ind[2 * i + 1] = i + 1 93c3a5a609SJeremy L Thompson r = ceed.BlockedElemRestriction(num_elem, elem_size, blk_size, 1, 1, 94c3a5a609SJeremy L Thompson num_elem + 1, ind, cmode=libceed.COPY_VALUES) 950ef72598Sjeremylt 96c3a5a609SJeremy L Thompson y = ceed.Vector(num_blk * blk_size * elem_size) 970ef72598Sjeremylt y.set_value(0) 980ef72598Sjeremylt 99c3a5a609SJeremy L Thompson # NoTranspose 1000ef72598Sjeremylt r.apply(x, y) 10156c48462SJeremy L Thompson layout = r.get_e_layout() 102c3a5a609SJeremy L Thompson with y.array_read() as y_array: 103c3a5a609SJeremy L Thompson for i in range(elem_size): 104c3a5a609SJeremy L Thompson for j in range(1): 105c3a5a609SJeremy L Thompson for k in range(num_elem): 106c3a5a609SJeremy L Thompson block = int(k / blk_size) 107c3a5a609SJeremy L Thompson elem = k % blk_size 108c3a5a609SJeremy L Thompson indx = (i * blk_size + elem) * \ 109c3a5a609SJeremy L Thompson layout[0] + j * blk_size * layout[1] + \ 110c3a5a609SJeremy L Thompson block * blk_size * layout[2] 111c3a5a609SJeremy L Thompson assert y_array[indx] == a[ind[k * elem_size + i]] 1120ef72598Sjeremylt 1130ef72598Sjeremylt x.set_value(0) 1140ef72598Sjeremylt r.T.apply(y, x) 115c3a5a609SJeremy L Thompson with x.array_read() as x_array: 116c3a5a609SJeremy L Thompson for i in range(num_elem + 1): 117c3a5a609SJeremy L Thompson assert x_array[i] == (10 + i) * (2.0 if i > 118c3a5a609SJeremy L Thompson 0 and i < num_elem else 1.0) 1190ef72598Sjeremylt 1200ef72598Sjeremylt# ------------------------------------------------------------------------------- 1210ef72598Sjeremylt# Test creation, use, and destruction of a blocked element restriction 1220ef72598Sjeremylt# ------------------------------------------------------------------------------- 1230ef72598Sjeremylt 1240ef72598Sjeremylt 125c3a5a609SJeremy L Thompsondef test_208(ceed_resource): 1260ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1270ef72598Sjeremylt 128c3a5a609SJeremy L Thompson num_elem = 8 129c3a5a609SJeremy L Thompson elem_size = 2 130c3a5a609SJeremy L Thompson num_blk = 2 131c3a5a609SJeremy L Thompson blk_size = 5 1320ef72598Sjeremylt 133c3a5a609SJeremy L Thompson x = ceed.Vector(num_elem + 1) 13480a9ef05SNatalie Beams a = np.arange(10, 10 + num_elem + 1, dtype=ceed.scalar_type()) 135c3a5a609SJeremy L Thompson x.set_array(a, cmode=libceed.COPY_VALUES) 1360ef72598Sjeremylt 137c3a5a609SJeremy L Thompson ind = np.zeros(2 * num_elem, dtype="int32") 138c3a5a609SJeremy L Thompson for i in range(num_elem): 1390ef72598Sjeremylt ind[2 * i + 0] = i 1400ef72598Sjeremylt ind[2 * i + 1] = i + 1 141c3a5a609SJeremy L Thompson r = ceed.BlockedElemRestriction(num_elem, elem_size, blk_size, 1, 1, 142c3a5a609SJeremy L Thompson num_elem + 1, ind, cmode=libceed.COPY_VALUES) 1430ef72598Sjeremylt 144c3a5a609SJeremy L Thompson y = ceed.Vector(blk_size * elem_size) 1450ef72598Sjeremylt y.set_value(0) 1460ef72598Sjeremylt 147c3a5a609SJeremy L Thompson # NoTranspose 1480ef72598Sjeremylt r.apply_block(1, x, y) 14956c48462SJeremy L Thompson layout = r.get_e_layout() 150c3a5a609SJeremy L Thompson with y.array_read() as y_array: 151c3a5a609SJeremy L Thompson for i in range(elem_size): 152c3a5a609SJeremy L Thompson for j in range(1): 153c3a5a609SJeremy L Thompson for k in range(blk_size, num_elem): 154c3a5a609SJeremy L Thompson block = int(k / blk_size) 155c3a5a609SJeremy L Thompson elem = k % blk_size 156c3a5a609SJeremy L Thompson indx = (i * blk_size + elem) * layout[0] + j * blk_size * \ 157c3a5a609SJeremy L Thompson layout[1] + block * blk_size * \ 158c3a5a609SJeremy L Thompson layout[2] - blk_size * elem_size 159c3a5a609SJeremy L Thompson assert y_array[indx] == a[ind[k * elem_size + i]] 1600ef72598Sjeremylt 1610ef72598Sjeremylt x.set_value(0) 1620ef72598Sjeremylt r.T.apply_block(1, y, x) 163c3a5a609SJeremy L Thompson with x.array_read() as x_array: 164c3a5a609SJeremy L Thompson for i in range(blk_size, num_elem + 1): 165c3a5a609SJeremy L Thompson assert x_array[i] == (10 + i) * (2.0 if i > 166c3a5a609SJeremy L Thompson blk_size and i < num_elem else 1.0) 1670ef72598Sjeremylt 1680ef72598Sjeremylt# ------------------------------------------------------------------------------- 1690ef72598Sjeremylt# Test getting the multiplicity of the indices in an element restriction 1700ef72598Sjeremylt# ------------------------------------------------------------------------------- 1710ef72598Sjeremylt 1720ef72598Sjeremylt 1730ef72598Sjeremyltdef test_209(ceed_resource): 1740ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1750ef72598Sjeremylt 176c3a5a609SJeremy L Thompson num_elem = 3 1770ef72598Sjeremylt 178c3a5a609SJeremy L Thompson ind = np.zeros(4 * num_elem, dtype="int32") 179c3a5a609SJeremy L Thompson for i in range(num_elem): 1800ef72598Sjeremylt ind[4 * i + 0] = i * 3 + 0 1810ef72598Sjeremylt ind[4 * i + 1] = i * 3 + 1 1820ef72598Sjeremylt ind[4 * i + 2] = i * 3 + 2 1830ef72598Sjeremylt ind[4 * i + 3] = i * 3 + 3 184c3a5a609SJeremy L Thompson r = ceed.ElemRestriction(num_elem, 4, 1, 1, 3 * num_elem + 1, ind, 1850ef72598Sjeremylt cmode=libceed.USE_POINTER) 1860ef72598Sjeremylt 1870ef72598Sjeremylt mult = r.get_multiplicity() 1880ef72598Sjeremylt 1890ef72598Sjeremylt with mult.array_read() as mult_array: 190c3a5a609SJeremy L Thompson for i in range(3 * num_elem + 1): 191c3a5a609SJeremy L Thompson val = 1 + (1 if (i > 0 and i < 3 * num_elem and i % 3 == 0) else 0) 1920ef72598Sjeremylt assert val == mult_array[i] 1930ef72598Sjeremylt 1940ef72598Sjeremylt# ------------------------------------------------------------------------------- 1950ef72598Sjeremylt# Test creation and view of an element restriction 1960ef72598Sjeremylt# ------------------------------------------------------------------------------- 1970ef72598Sjeremylt 1980ef72598Sjeremylt 1990ef72598Sjeremyltdef test_210(ceed_resource, capsys): 2000ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 2010ef72598Sjeremylt 202c3a5a609SJeremy L Thompson num_elem = 3 2030ef72598Sjeremylt 204c3a5a609SJeremy L Thompson ind = np.zeros(2 * num_elem, dtype="int32") 205c3a5a609SJeremy L Thompson for i in range(num_elem): 2060ef72598Sjeremylt ind[2 * i + 0] = i + 0 2070ef72598Sjeremylt ind[2 * i + 1] = i + 1 208c3a5a609SJeremy L Thompson r = ceed.ElemRestriction(num_elem, 2, 1, 1, num_elem + 1, ind, 2090ef72598Sjeremylt cmode=libceed.USE_POINTER) 2100ef72598Sjeremylt 2110ef72598Sjeremylt print(r) 2120ef72598Sjeremylt 2130ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 2140ef72598Sjeremylt assert not stderr 2150ef72598Sjeremylt assert stdout == ref_stdout 2160ef72598Sjeremylt 2170ef72598Sjeremylt# ------------------------------------------------------------------------------- 2180ef72598Sjeremylt# Test creation and view of a strided element restriction 2190ef72598Sjeremylt# ------------------------------------------------------------------------------- 2200ef72598Sjeremylt 2210ef72598Sjeremylt 2220ef72598Sjeremyltdef test_211(ceed_resource, capsys): 2230ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 2240ef72598Sjeremylt 225c3a5a609SJeremy L Thompson num_elem = 3 2260ef72598Sjeremylt 2270ef72598Sjeremylt strides = np.array([1, 2, 2], dtype="int32") 228e7f679fcSJeremy L Thompson r = ceed.StridedElemRestriction(num_elem, 2, 1, num_elem * 2, strides) 2290ef72598Sjeremylt 2300ef72598Sjeremylt print(r) 2310ef72598Sjeremylt 2320ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 2330ef72598Sjeremylt assert not stderr 2340ef72598Sjeremylt assert stdout == ref_stdout 2350ef72598Sjeremylt 2360ef72598Sjeremylt# ------------------------------------------------------------------------------- 2370ef72598Sjeremylt# Test creation and view of a blocked strided element restriction 2380ef72598Sjeremylt# ------------------------------------------------------------------------------- 2390ef72598Sjeremylt 2400ef72598Sjeremylt 2410ef72598Sjeremyltdef test_212(ceed_resource, capsys): 2420ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 2430ef72598Sjeremylt 244c3a5a609SJeremy L Thompson num_elem = 3 2450ef72598Sjeremylt 2460ef72598Sjeremylt strides = np.array([1, 2, 2], dtype="int32") 247c3a5a609SJeremy L Thompson r = ceed.BlockedStridedElemRestriction( 248e7f679fcSJeremy L Thompson num_elem, 2, 2, 1, num_elem * 2, strides) 2490ef72598Sjeremylt 2500ef72598Sjeremylt print(r) 2510ef72598Sjeremylt 2520ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 2530ef72598Sjeremylt assert not stderr 2540ef72598Sjeremylt assert stdout == ref_stdout 2550ef72598Sjeremylt 2560ef72598Sjeremylt# ------------------------------------------------------------------------------- 257709403c1SSebastian Grimberg# Test creation, use, and destruction of an oriented element restriction 258709403c1SSebastian Grimberg# ------------------------------------------------------------------------------- 259709403c1SSebastian Grimberg 260709403c1SSebastian Grimberg 261709403c1SSebastian Grimbergdef test_213(ceed_resource): 262709403c1SSebastian Grimberg ceed = libceed.Ceed(ceed_resource) 263709403c1SSebastian Grimberg 264709403c1SSebastian Grimberg num_elem = 3 265709403c1SSebastian Grimberg 266709403c1SSebastian Grimberg x = ceed.Vector(num_elem + 1) 267709403c1SSebastian Grimberg a = np.arange(10, 10 + num_elem + 1, dtype=ceed.scalar_type()) 268709403c1SSebastian Grimberg x.set_array(a, cmode=libceed.USE_POINTER) 269709403c1SSebastian Grimberg 270709403c1SSebastian Grimberg ind = np.zeros(2 * num_elem, dtype="int32") 271709403c1SSebastian Grimberg orients = np.zeros(2 * num_elem, dtype="bool") 272709403c1SSebastian Grimberg for i in range(num_elem): 273709403c1SSebastian Grimberg ind[2 * i + 0] = i 274709403c1SSebastian Grimberg ind[2 * i + 1] = i + 1 275709403c1SSebastian Grimberg # flip the dofs on element 1, 3, ... 276709403c1SSebastian Grimberg orients[2 * i + 0] = (i % 2) > 0 277709403c1SSebastian Grimberg orients[2 * i + 1] = (i % 2) > 0 278709403c1SSebastian Grimberg r = ceed.OrientedElemRestriction( 279709403c1SSebastian Grimberg num_elem, 280709403c1SSebastian Grimberg 2, 281709403c1SSebastian Grimberg 1, 282709403c1SSebastian Grimberg 1, 283709403c1SSebastian Grimberg num_elem + 1, 284709403c1SSebastian Grimberg ind, 285709403c1SSebastian Grimberg orients, 286709403c1SSebastian Grimberg cmode=libceed.USE_POINTER) 287709403c1SSebastian Grimberg 288709403c1SSebastian Grimberg y = ceed.Vector(2 * num_elem) 289709403c1SSebastian Grimberg y.set_value(0) 290709403c1SSebastian Grimberg 291709403c1SSebastian Grimberg r.apply(x, y) 292709403c1SSebastian Grimberg 293709403c1SSebastian Grimberg with y.array_read() as y_array: 294709403c1SSebastian Grimberg for i in range(num_elem): 295709403c1SSebastian Grimberg for j in range(2): 296709403c1SSebastian Grimberg k = j + 2 * i 297709403c1SSebastian Grimberg assert 10 + (k + 1) // 2 == y_array[k] * pow(-1, i % 2) 298709403c1SSebastian Grimberg 299709403c1SSebastian Grimberg# ------------------------------------------------------------------------------- 300709403c1SSebastian Grimberg# Test creation, use, and destruction of a curl-oriented element restriction 301709403c1SSebastian Grimberg# ------------------------------------------------------------------------------- 302709403c1SSebastian Grimberg 303709403c1SSebastian Grimberg 304709403c1SSebastian Grimbergdef test_214(ceed_resource): 305709403c1SSebastian Grimberg ceed = libceed.Ceed(ceed_resource) 306709403c1SSebastian Grimberg 307709403c1SSebastian Grimberg num_elem = 3 308709403c1SSebastian Grimberg 309709403c1SSebastian Grimberg x = ceed.Vector(num_elem + 1) 310709403c1SSebastian Grimberg a = np.arange(10, 10 + num_elem + 1, dtype=ceed.scalar_type()) 311709403c1SSebastian Grimberg x.set_array(a, cmode=libceed.USE_POINTER) 312709403c1SSebastian Grimberg 313709403c1SSebastian Grimberg ind = np.zeros(2 * num_elem, dtype="int32") 314709403c1SSebastian Grimberg curl_orients = np.zeros(3 * 2 * num_elem, dtype="int8") 315709403c1SSebastian Grimberg for i in range(num_elem): 316709403c1SSebastian Grimberg ind[2 * i + 0] = i 317709403c1SSebastian Grimberg ind[2 * i + 1] = i + 1 318709403c1SSebastian Grimberg curl_orients[3 * 2 * i] = curl_orients[3 * 2 * (i + 1) - 1] = 0 319709403c1SSebastian Grimberg if i % 2 > 0: 320709403c1SSebastian Grimberg # T = [0 -1] 321709403c1SSebastian Grimberg # [-1 0] 322709403c1SSebastian Grimberg curl_orients[3 * 2 * i + 1] = 0 323709403c1SSebastian Grimberg curl_orients[3 * 2 * i + 2] = -1 324709403c1SSebastian Grimberg curl_orients[3 * 2 * i + 3] = -1 325709403c1SSebastian Grimberg curl_orients[3 * 2 * i + 4] = 0 326709403c1SSebastian Grimberg else: 327709403c1SSebastian Grimberg # T = I 328709403c1SSebastian Grimberg curl_orients[3 * 2 * i + 1] = 1 329709403c1SSebastian Grimberg curl_orients[3 * 2 * i + 2] = 0 330709403c1SSebastian Grimberg curl_orients[3 * 2 * i + 3] = 0 331709403c1SSebastian Grimberg curl_orients[3 * 2 * i + 4] = 1 332709403c1SSebastian Grimberg r = ceed.CurlOrientedElemRestriction( 333709403c1SSebastian Grimberg num_elem, 334709403c1SSebastian Grimberg 2, 335709403c1SSebastian Grimberg 1, 336709403c1SSebastian Grimberg 1, 337709403c1SSebastian Grimberg num_elem + 1, 338709403c1SSebastian Grimberg ind, 339709403c1SSebastian Grimberg curl_orients, 340709403c1SSebastian Grimberg cmode=libceed.USE_POINTER) 341709403c1SSebastian Grimberg 342709403c1SSebastian Grimberg y = ceed.Vector(2 * num_elem) 343709403c1SSebastian Grimberg y.set_value(0) 344709403c1SSebastian Grimberg 345709403c1SSebastian Grimberg r.apply(x, y) 346709403c1SSebastian Grimberg 347709403c1SSebastian Grimberg with y.array_read() as y_array: 348709403c1SSebastian Grimberg for i in range(num_elem): 349709403c1SSebastian Grimberg for j in range(2): 350709403c1SSebastian Grimberg k = j + 2 * i 351709403c1SSebastian Grimberg if i % 2 > 0: 352709403c1SSebastian Grimberg assert j != 0 or 10 + i + 1 == -y_array[k] 353709403c1SSebastian Grimberg assert j != 1 or 10 + i == -y_array[k] 354709403c1SSebastian Grimberg else: 355709403c1SSebastian Grimberg assert 10 + (k + 1) // 2 == y_array[k] 356709403c1SSebastian Grimberg 357709403c1SSebastian Grimberg# ------------------------------------------------------------------------------- 358