Skip to content

Commit f237a56

Browse files
committed
tests - add sequential composite operator test
1 parent 936936b commit f237a56

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

tests/t599-operator.c

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/// @file
2+
/// Test creation, action, and destruction for mass matrix operator at points using sequential composite operator
3+
/// \test Test creation, action, and destruction for mass matrix operator at points using sequential composite operator
4+
#include "t599-operator.h"
5+
6+
#include <ceed.h>
7+
#include <math.h>
8+
#include <stdio.h>
9+
10+
int main(int argc, char **argv) {
11+
Ceed ceed;
12+
CeedInt num_elem_1d = 3, num_elem = num_elem_1d * num_elem_1d, dim = 2, p = 3, q = 5;
13+
CeedInt num_nodes = (num_elem_1d * (p - 1) + 1) * (num_elem_1d * (p - 1) + 1), num_points_per_elem = 4, num_points = num_elem * num_points_per_elem;
14+
CeedVector x_points, u, v, u_points;
15+
CeedElemRestriction elem_restriction_x_points, elem_restriction_u_points, elem_restriction_u;
16+
CeedBasis basis_u;
17+
CeedQFunction qf_to_points, qf_from_points;
18+
CeedOperator op_to_points, op_from_points, op_mass;
19+
bool is_at_points;
20+
21+
CeedInit(argv[1], &ceed);
22+
23+
CeedVectorCreate(ceed, dim * num_points, &x_points);
24+
{
25+
CeedScalar x_array[dim * num_points];
26+
27+
for (CeedInt e = 0; e < num_elem; e++) {
28+
for (CeedInt d = 0; d < dim; d++) {
29+
x_array[num_points_per_elem * (e * dim + d) + 0] = 0.25;
30+
x_array[num_points_per_elem * (e * dim + d) + 1] = d == 0 ? -0.25 : 0.25;
31+
x_array[num_points_per_elem * (e * dim + d) + 2] = d == 0 ? 0.25 : -0.25;
32+
x_array[num_points_per_elem * (e * dim + d) + 3] = 0.25;
33+
}
34+
}
35+
CeedVectorSetArray(x_points, CEED_MEM_HOST, CEED_COPY_VALUES, x_array);
36+
}
37+
{
38+
CeedInt ind_x[num_elem + 1 + num_points];
39+
40+
for (CeedInt i = 0; i <= num_elem; i++) ind_x[i] = num_elem + 1 + i * num_points_per_elem;
41+
for (CeedInt i = 0; i < num_points; i++) ind_x[num_elem + 1 + i] = i;
42+
CeedElemRestrictionCreateAtPoints(ceed, num_elem, num_points, dim, num_points * dim, CEED_MEM_HOST, CEED_COPY_VALUES, ind_x,
43+
&elem_restriction_x_points);
44+
CeedElemRestrictionCreateAtPoints(ceed, num_elem, num_points, 1, num_points, CEED_MEM_HOST, CEED_COPY_VALUES, ind_x, &elem_restriction_u_points);
45+
CeedElemRestrictionCreateVector(elem_restriction_u_points, &u_points, NULL);
46+
CeedVectorSetValue(u_points, 0);
47+
}
48+
49+
{
50+
CeedInt ind_u[num_elem * p * p];
51+
52+
for (CeedInt e = 0; e < num_elem; e++) {
53+
CeedInt elem_xy[2] = {1, 1}, n_d[2] = {0, 0};
54+
55+
for (CeedInt d = 0; d < dim; d++) n_d[d] = num_elem_1d * (p - 1) + 1;
56+
{
57+
CeedInt r_e = e;
58+
59+
for (CeedInt d = 0; d < dim; d++) {
60+
elem_xy[d] = r_e % num_elem_1d;
61+
r_e /= num_elem_1d;
62+
}
63+
}
64+
CeedInt num_nodes_in_elem = p * p, *elem_nodes = ind_u + e * num_nodes_in_elem;
65+
66+
for (CeedInt n = 0; n < num_nodes_in_elem; n++) {
67+
CeedInt g_node = 0, g_node_stride = 1, r_node = n;
68+
69+
for (CeedInt d = 0; d < dim; d++) {
70+
g_node += (elem_xy[d] * (p - 1) + r_node % p) * g_node_stride;
71+
g_node_stride *= n_d[d];
72+
r_node /= p;
73+
}
74+
elem_nodes[n] = g_node;
75+
}
76+
}
77+
CeedElemRestrictionCreate(ceed, num_elem, p * p, 1, 1, num_nodes, CEED_MEM_HOST, CEED_COPY_VALUES, ind_u, &elem_restriction_u);
78+
}
79+
CeedBasisCreateTensorH1Lagrange(ceed, dim, 1, p, q, CEED_GAUSS, &basis_u);
80+
81+
CeedQFunctionCreateInterior(ceed, 1, mass, mass_loc, &qf_to_points);
82+
CeedQFunctionAddInput(qf_to_points, "u", 1, CEED_EVAL_INTERP);
83+
CeedQFunctionAddOutput(qf_to_points, "u_points", 1, CEED_EVAL_NONE);
84+
85+
CeedOperatorCreateAtPoints(ceed, qf_to_points, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_to_points);
86+
CeedOperatorSetField(op_to_points, "u", elem_restriction_u, basis_u, CEED_VECTOR_ACTIVE);
87+
CeedOperatorSetField(op_to_points, "u_points", elem_restriction_u_points, CEED_BASIS_NONE, u_points);
88+
CeedOperatorAtPointsSetPoints(op_to_points, elem_restriction_x_points, x_points);
89+
90+
CeedOperatorIsAtPoints(op_to_points, &is_at_points);
91+
if (!is_at_points) printf("Error: Operator should be at points\n");
92+
93+
CeedQFunctionCreateInterior(ceed, 1, mass, mass_loc, &qf_from_points);
94+
CeedQFunctionAddInput(qf_from_points, "u_points", 1, CEED_EVAL_NONE);
95+
CeedQFunctionAddOutput(qf_from_points, "v", 1, CEED_EVAL_INTERP);
96+
97+
CeedOperatorCreateAtPoints(ceed, qf_from_points, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_from_points);
98+
CeedOperatorSetField(op_from_points, "u_points", elem_restriction_u_points, CEED_BASIS_NONE, u_points);
99+
CeedOperatorSetField(op_from_points, "v", elem_restriction_u, basis_u, CEED_VECTOR_ACTIVE);
100+
CeedOperatorAtPointsSetPoints(op_from_points, elem_restriction_x_points, x_points);
101+
102+
CeedOperatorIsAtPoints(op_from_points, &is_at_points);
103+
if (!is_at_points) printf("Error: Operator should be at points\n");
104+
105+
CeedOperatorCreateComposite(ceed, &op_mass);
106+
CeedOperatorCompositeSetSequential(op_mass, true);
107+
CeedOperatorCompositeAddSub(op_mass, op_to_points);
108+
CeedOperatorCompositeAddSub(op_mass, op_from_points);
109+
110+
CeedVectorCreate(ceed, num_nodes, &u);
111+
CeedVectorSetValue(u, 1.0);
112+
CeedVectorCreate(ceed, num_nodes, &v);
113+
CeedOperatorApply(op_mass, u, v, CEED_REQUEST_IMMEDIATE);
114+
115+
{
116+
CeedScalar sum = 0.0;
117+
const CeedScalar *v_array;
118+
119+
CeedVectorGetArrayRead(v, CEED_MEM_HOST, &v_array);
120+
for (CeedInt i = 0; i < num_nodes; i++) sum += v_array[i];
121+
CeedVectorRestoreArrayRead(v, &v_array);
122+
// Summing 9 reference elements, each 2x2 => 36 sq units area
123+
if (fabs(sum - 4.0 * num_elem) > CEED_EPSILON * 5e3) {
124+
printf("Incorrect area computed, %g != %g (abs error %g)\n", sum, 4.0 * num_elem, fabs(sum - 4.0 * num_elem));
125+
}
126+
}
127+
128+
CeedVectorDestroy(&x_points);
129+
CeedVectorDestroy(&u_points);
130+
CeedVectorDestroy(&u);
131+
CeedVectorDestroy(&v);
132+
CeedElemRestrictionDestroy(&elem_restriction_x_points);
133+
CeedElemRestrictionDestroy(&elem_restriction_u_points);
134+
CeedElemRestrictionDestroy(&elem_restriction_u);
135+
CeedBasisDestroy(&basis_u);
136+
CeedQFunctionDestroy(&qf_to_points);
137+
CeedQFunctionDestroy(&qf_from_points);
138+
CeedOperatorDestroy(&op_to_points);
139+
CeedOperatorDestroy(&op_from_points);
140+
CeedOperatorDestroy(&op_mass);
141+
CeedDestroy(&ceed);
142+
return 0;
143+
}

tests/t599-operator.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
2+
// All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3+
//
4+
// SPDX-License-Identifier: BSD-2-Clause
5+
//
6+
// This file is part of CEED: http://github.com/ceed
7+
8+
#include <ceed/types.h>
9+
10+
CEED_QFUNCTION(mass)(void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
11+
const CeedScalar *u = in[0];
12+
CeedScalar *v = out[0];
13+
14+
for (CeedInt i = 0; i < Q; i++) v[i] = u[i];
15+
return 0;
16+
}

0 commit comments

Comments
 (0)