ceed-basis.c (efdfdf6d1fcc8ba9a50fc4afdeed4a17ffbbdc85) ceed-basis.c (c4e3f59b2ea5a0c95cc0118aa5026c447cce3092)
1// Copyright (c) 2017-2022, 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-impl.h>

--- 329 unchanged lines hidden (view full) ---

338 @ref Backend
339**/
340int CeedBasisReference(CeedBasis basis) {
341 basis->ref_count++;
342 return CEED_ERROR_SUCCESS;
343}
344
345/**
1// Copyright (c) 2017-2022, 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-impl.h>

--- 329 unchanged lines hidden (view full) ---

338 @ref Backend
339**/
340int CeedBasisReference(CeedBasis basis) {
341 basis->ref_count++;
342 return CEED_ERROR_SUCCESS;
343}
344
345/**
346 @brief Get number of Q-vector components for given CeedBasis
347
348 @param[in] basis CeedBasis
349 @param[in] eval_mode \ref CEED_EVAL_INTERP to use interpolated values,
350 \ref CEED_EVAL_GRAD to use gradients,
351 \ref CEED_EVAL_DIV to use divergence,
352 \ref CEED_EVAL_CURL to use curl.
353 @param[out] q_comp Variable to store number of Q-vector components of basis
354
355 @return An error code: 0 - success, otherwise - failure
356
357 @ref Backend
358**/
359int CeedBasisGetNumQuadratureComponents(CeedBasis basis, CeedEvalMode eval_mode, CeedInt *q_comp) {
360 switch (eval_mode) {
361 case CEED_EVAL_INTERP:
362 *q_comp = (basis->fe_space == CEED_FE_SPACE_H1) ? 1 : basis->dim;
363 break;
364 case CEED_EVAL_GRAD:
365 *q_comp = basis->dim;
366 break;
367 case CEED_EVAL_DIV:
368 *q_comp = 1;
369 break;
370 case CEED_EVAL_CURL:
371 *q_comp = (basis->dim < 3) ? 1 : basis->dim;
372 break;
373 case CEED_EVAL_NONE:
374 case CEED_EVAL_WEIGHT:
375 *q_comp = 0;
376 break;
377 }
378 return CEED_ERROR_SUCCESS;
379}
380
381/**
346 @brief Estimate number of FLOPs required to apply CeedBasis in t_mode and eval_mode
347
348 @param[in] basis Basis to estimate FLOPs for
349 @param[in] t_mode Apply basis or transpose
350 @param[in] eval_mode Basis evaluation mode
351 @param[out] flops Address of variable to hold FLOPs estimate
352
353 @ref Backend

--- 36 unchanged lines hidden (view full) ---

390 return CeedError(basis->ceed, CEED_ERROR_INCOMPATIBLE, "Tensor CEED_EVAL_CURL not supported");
391 break;
392 // LCOV_EXCL_STOP
393 case CEED_EVAL_WEIGHT:
394 *flops = dim * CeedIntPow(Q_1d, dim);
395 break;
396 }
397 } else {
382 @brief Estimate number of FLOPs required to apply CeedBasis in t_mode and eval_mode
383
384 @param[in] basis Basis to estimate FLOPs for
385 @param[in] t_mode Apply basis or transpose
386 @param[in] eval_mode Basis evaluation mode
387 @param[out] flops Address of variable to hold FLOPs estimate
388
389 @ref Backend

--- 36 unchanged lines hidden (view full) ---

426 return CeedError(basis->ceed, CEED_ERROR_INCOMPATIBLE, "Tensor CEED_EVAL_CURL not supported");
427 break;
428 // LCOV_EXCL_STOP
429 case CEED_EVAL_WEIGHT:
430 *flops = dim * CeedIntPow(Q_1d, dim);
431 break;
432 }
433 } else {
398 CeedInt dim, num_comp, num_nodes, num_qpts, Q_comp;
434 CeedInt dim, num_comp, q_comp, num_nodes, num_qpts;
399 CeedCall(CeedBasisGetDimension(basis, &dim));
400 CeedCall(CeedBasisGetNumComponents(basis, &num_comp));
435 CeedCall(CeedBasisGetDimension(basis, &dim));
436 CeedCall(CeedBasisGetNumComponents(basis, &num_comp));
437 CeedCall(CeedBasisGetNumQuadratureComponents(basis, eval_mode, &q_comp));
401 CeedCall(CeedBasisGetNumNodes(basis, &num_nodes));
402 CeedCall(CeedBasisGetNumQuadraturePoints(basis, &num_qpts));
438 CeedCall(CeedBasisGetNumNodes(basis, &num_nodes));
439 CeedCall(CeedBasisGetNumQuadraturePoints(basis, &num_qpts));
403 CeedCall(CeedBasisGetNumQuadratureComponents(basis, &Q_comp));
404 switch (eval_mode) {
405 case CEED_EVAL_NONE:
406 *flops = 0;
407 break;
408 case CEED_EVAL_INTERP:
440 switch (eval_mode) {
441 case CEED_EVAL_NONE:
442 *flops = 0;
443 break;
444 case CEED_EVAL_INTERP:
409 *flops = num_nodes * num_qpts * num_comp;
410 break;
411 case CEED_EVAL_GRAD:
445 case CEED_EVAL_GRAD:
412 *flops = num_nodes * num_qpts * num_comp * dim;
413 break;
414 case CEED_EVAL_DIV:
446 case CEED_EVAL_DIV:
415 *flops = num_nodes * num_qpts;
416 break;
417 case CEED_EVAL_CURL:
447 case CEED_EVAL_CURL:
418 *flops = num_nodes * num_qpts * dim;
448 *flops = num_nodes * num_qpts * num_comp * q_comp;
419 break;
420 case CEED_EVAL_WEIGHT:
421 *flops = 0;
422 break;
423 }
424 }
425
426 return CEED_ERROR_SUCCESS;
427}
428
429/**
449 break;
450 case CEED_EVAL_WEIGHT:
451 *flops = 0;
452 break;
453 }
454 }
455
456 return CEED_ERROR_SUCCESS;
457}
458
459/**
460 @brief Get CeedFESpace for a CeedBasis
461
462 @param[in] basis CeedBasis
463 @param[out] fe_space Variable to store CeedFESpace
464
465 @return An error code: 0 - success, otherwise - failure
466
467 @ref Backend
468**/
469int CeedBasisGetFESpace(CeedBasis basis, CeedFESpace *fe_space) {
470 *fe_space = basis->fe_space;
471 return CEED_ERROR_SUCCESS;
472}
473
474/**
430 @brief Get dimension for given CeedElemTopology
431
432 @param[in] topo CeedElemTopology
433 @param[out] dim Variable to store dimension of topology
434
435 @return An error code: 0 - success, otherwise - failure
436
437 @ref Backend

--- 127 unchanged lines hidden (view full) ---

565 @param[in] m Number of rows in A
566 @param[in] n Number of columns in A
567 @param[in] k Number of elementary reflectors in Q, k<m
568 @param[in] row Row stride in A
569 @param[in] col Col stride in A
570
571 @return An error code: 0 - success, otherwise - failure
572
475 @brief Get dimension for given CeedElemTopology
476
477 @param[in] topo CeedElemTopology
478 @param[out] dim Variable to store dimension of topology
479
480 @return An error code: 0 - success, otherwise - failure
481
482 @ref Backend

--- 127 unchanged lines hidden (view full) ---

610 @param[in] m Number of rows in A
611 @param[in] n Number of columns in A
612 @param[in] k Number of elementary reflectors in Q, k<m
613 @param[in] row Row stride in A
614 @param[in] col Col stride in A
615
616 @return An error code: 0 - success, otherwise - failure
617
573 @ref Developer
618 @ref Utility
574**/
575int CeedHouseholderApplyQ(CeedScalar *mat_A, const CeedScalar *mat_Q, const CeedScalar *tau, CeedTransposeMode t_mode, CeedInt m, CeedInt n,
576 CeedInt k, CeedInt row, CeedInt col) {
577 CeedScalar *v;
578 CeedCall(CeedMalloc(m, &v));
579 for (CeedInt ii = 0; ii < k; ii++) {
580 CeedInt i = t_mode == CEED_TRANSPOSE ? ii : k - 1 - ii;
581 for (CeedInt j = i + 1; j < m; j++) v[j] = mat_Q[j * k + i];

--- 314 unchanged lines hidden (view full) ---

896 (*basis)->tensor_basis = 1;
897 (*basis)->dim = dim;
898 (*basis)->topo = topo;
899 (*basis)->num_comp = num_comp;
900 (*basis)->P_1d = P_1d;
901 (*basis)->Q_1d = Q_1d;
902 (*basis)->P = CeedIntPow(P_1d, dim);
903 (*basis)->Q = CeedIntPow(Q_1d, dim);
619**/
620int CeedHouseholderApplyQ(CeedScalar *mat_A, const CeedScalar *mat_Q, const CeedScalar *tau, CeedTransposeMode t_mode, CeedInt m, CeedInt n,
621 CeedInt k, CeedInt row, CeedInt col) {
622 CeedScalar *v;
623 CeedCall(CeedMalloc(m, &v));
624 for (CeedInt ii = 0; ii < k; ii++) {
625 CeedInt i = t_mode == CEED_TRANSPOSE ? ii : k - 1 - ii;
626 for (CeedInt j = i + 1; j < m; j++) v[j] = mat_Q[j * k + i];

--- 314 unchanged lines hidden (view full) ---

941 (*basis)->tensor_basis = 1;
942 (*basis)->dim = dim;
943 (*basis)->topo = topo;
944 (*basis)->num_comp = num_comp;
945 (*basis)->P_1d = P_1d;
946 (*basis)->Q_1d = Q_1d;
947 (*basis)->P = CeedIntPow(P_1d, dim);
948 (*basis)->Q = CeedIntPow(Q_1d, dim);
904 (*basis)->Q_comp = 1;
905 (*basis)->basis_space = 1; // 1 for H^1 space
949 (*basis)->fe_space = CEED_FE_SPACE_H1;
906 CeedCall(CeedCalloc(Q_1d, &(*basis)->q_ref_1d));
907 CeedCall(CeedCalloc(Q_1d, &(*basis)->q_weight_1d));
908 if (q_ref_1d) memcpy((*basis)->q_ref_1d, q_ref_1d, Q_1d * sizeof(q_ref_1d[0]));
909 if (q_weight_1d) memcpy((*basis)->q_weight_1d, q_weight_1d, Q_1d * sizeof(q_weight_1d[0]));
910 CeedCall(CeedCalloc(Q_1d * P_1d, &(*basis)->interp_1d));
911 CeedCall(CeedCalloc(Q_1d * P_1d, &(*basis)->grad_1d));
912 if (interp_1d) memcpy((*basis)->interp_1d, interp_1d, Q_1d * P_1d * sizeof(interp_1d[0]));
913 if (grad_1d) memcpy((*basis)->grad_1d, grad_1d, Q_1d * P_1d * sizeof(grad_1d[0]));

--- 101 unchanged lines hidden (view full) ---

1015 @brief Create a non tensor-product basis for H^1 discretizations
1016
1017 @param[in] ceed Ceed object where the CeedBasis will be created
1018 @param[in] topo Topology of element, e.g. hypercube, simplex, ect
1019 @param[in] num_comp Number of field components (1 for scalar fields)
1020 @param[in] num_nodes Total number of nodes
1021 @param[in] num_qpts Total number of quadrature points
1022 @param[in] interp Row-major (num_qpts * num_nodes) matrix expressing the values of nodal basis functions at quadrature points
950 CeedCall(CeedCalloc(Q_1d, &(*basis)->q_ref_1d));
951 CeedCall(CeedCalloc(Q_1d, &(*basis)->q_weight_1d));
952 if (q_ref_1d) memcpy((*basis)->q_ref_1d, q_ref_1d, Q_1d * sizeof(q_ref_1d[0]));
953 if (q_weight_1d) memcpy((*basis)->q_weight_1d, q_weight_1d, Q_1d * sizeof(q_weight_1d[0]));
954 CeedCall(CeedCalloc(Q_1d * P_1d, &(*basis)->interp_1d));
955 CeedCall(CeedCalloc(Q_1d * P_1d, &(*basis)->grad_1d));
956 if (interp_1d) memcpy((*basis)->interp_1d, interp_1d, Q_1d * P_1d * sizeof(interp_1d[0]));
957 if (grad_1d) memcpy((*basis)->grad_1d, grad_1d, Q_1d * P_1d * sizeof(grad_1d[0]));

--- 101 unchanged lines hidden (view full) ---

1059 @brief Create a non tensor-product basis for H^1 discretizations
1060
1061 @param[in] ceed Ceed object where the CeedBasis will be created
1062 @param[in] topo Topology of element, e.g. hypercube, simplex, ect
1063 @param[in] num_comp Number of field components (1 for scalar fields)
1064 @param[in] num_nodes Total number of nodes
1065 @param[in] num_qpts Total number of quadrature points
1066 @param[in] interp Row-major (num_qpts * num_nodes) matrix expressing the values of nodal basis functions at quadrature points
1023 @param[in] grad Row-major (num_qpts * dim * num_nodes) matrix expressing derivatives of nodal basis functions at quadrature points
1067 @param[in] grad Row-major (dim * num_qpts * num_nodes) matrix expressing derivatives of nodal basis functions at quadrature points
1024 @param[in] q_ref Array of length num_qpts * dim holding the locations of quadrature points on the reference element
1025 @param[in] q_weight Array of length num_qpts holding the quadrature weights on the reference element
1026 @param[out] basis Address of the variable where the newly created CeedBasis will be stored.
1027
1028 @return An error code: 0 - success, otherwise - failure
1029
1030 @ref User
1031**/

--- 41 unchanged lines hidden (view full) ---

1073 CeedCall(CeedReference(ceed));
1074 (*basis)->ref_count = 1;
1075 (*basis)->tensor_basis = 0;
1076 (*basis)->dim = dim;
1077 (*basis)->topo = topo;
1078 (*basis)->num_comp = num_comp;
1079 (*basis)->P = P;
1080 (*basis)->Q = Q;
1068 @param[in] q_ref Array of length num_qpts * dim holding the locations of quadrature points on the reference element
1069 @param[in] q_weight Array of length num_qpts holding the quadrature weights on the reference element
1070 @param[out] basis Address of the variable where the newly created CeedBasis will be stored.
1071
1072 @return An error code: 0 - success, otherwise - failure
1073
1074 @ref User
1075**/

--- 41 unchanged lines hidden (view full) ---

1117 CeedCall(CeedReference(ceed));
1118 (*basis)->ref_count = 1;
1119 (*basis)->tensor_basis = 0;
1120 (*basis)->dim = dim;
1121 (*basis)->topo = topo;
1122 (*basis)->num_comp = num_comp;
1123 (*basis)->P = P;
1124 (*basis)->Q = Q;
1081 (*basis)->Q_comp = 1;
1082 (*basis)->basis_space = 1; // 1 for H^1 space
1125 (*basis)->fe_space = CEED_FE_SPACE_H1;
1083 CeedCall(CeedCalloc(Q * dim, &(*basis)->q_ref_1d));
1084 CeedCall(CeedCalloc(Q, &(*basis)->q_weight_1d));
1085 if (q_ref) memcpy((*basis)->q_ref_1d, q_ref, Q * dim * sizeof(q_ref[0]));
1086 if (q_weight) memcpy((*basis)->q_weight_1d, q_weight, Q * sizeof(q_weight[0]));
1087 CeedCall(CeedCalloc(Q * P, &(*basis)->interp));
1088 CeedCall(CeedCalloc(dim * Q * P, &(*basis)->grad));
1089 if (interp) memcpy((*basis)->interp, interp, Q * P * sizeof(interp[0]));
1090 if (grad) memcpy((*basis)->grad, grad, dim * Q * P * sizeof(grad[0]));

--- 4 unchanged lines hidden (view full) ---

1095/**
1096 @brief Create a non tensor-product basis for \f$H(\mathrm{div})\f$ discretizations
1097
1098 @param[in] ceed Ceed object where the CeedBasis will be created
1099 @param[in] topo Topology of element (`CEED_TOPOLOGY_QUAD`, `CEED_TOPOLOGY_PRISM`, etc.), dimension of which is used in some array sizes below
1100 @param[in] num_comp Number of components (usually 1 for vectors in H(div) bases)
1101 @param[in] num_nodes Total number of nodes (dofs per element)
1102 @param[in] num_qpts Total number of quadrature points
1126 CeedCall(CeedCalloc(Q * dim, &(*basis)->q_ref_1d));
1127 CeedCall(CeedCalloc(Q, &(*basis)->q_weight_1d));
1128 if (q_ref) memcpy((*basis)->q_ref_1d, q_ref, Q * dim * sizeof(q_ref[0]));
1129 if (q_weight) memcpy((*basis)->q_weight_1d, q_weight, Q * sizeof(q_weight[0]));
1130 CeedCall(CeedCalloc(Q * P, &(*basis)->interp));
1131 CeedCall(CeedCalloc(dim * Q * P, &(*basis)->grad));
1132 if (interp) memcpy((*basis)->interp, interp, Q * P * sizeof(interp[0]));
1133 if (grad) memcpy((*basis)->grad, grad, dim * Q * P * sizeof(grad[0]));

--- 4 unchanged lines hidden (view full) ---

1138/**
1139 @brief Create a non tensor-product basis for \f$H(\mathrm{div})\f$ discretizations
1140
1141 @param[in] ceed Ceed object where the CeedBasis will be created
1142 @param[in] topo Topology of element (`CEED_TOPOLOGY_QUAD`, `CEED_TOPOLOGY_PRISM`, etc.), dimension of which is used in some array sizes below
1143 @param[in] num_comp Number of components (usually 1 for vectors in H(div) bases)
1144 @param[in] num_nodes Total number of nodes (dofs per element)
1145 @param[in] num_qpts Total number of quadrature points
1103 @param[in] interp Row-major (dim*num_qpts * num_nodes) matrix expressing the values of nodal basis functions at quadrature points
1104 @param[in] div Row-major (num_qpts * num_nodes) matrix expressing divergence of nodal basis functions at quadrature points
1146 @param[in] interp Row-major (dim * num_qpts * num_nodes) matrix expressing the values of basis functions at quadrature points
1147 @param[in] div Row-major (num_qpts * num_nodes) matrix expressing divergence of basis functions at quadrature points
1105 @param[in] q_ref Array of length num_qpts * dim holding the locations of quadrature points on the reference element
1106 @param[in] q_weight Array of length num_qpts holding the quadrature weights on the reference element
1107 @param[out] basis Address of the variable where the newly created CeedBasis will be stored.
1108
1109 @return An error code: 0 - success, otherwise - failure
1110
1111 @ref User
1112**/
1113int CeedBasisCreateHdiv(Ceed ceed, CeedElemTopology topo, CeedInt num_comp, CeedInt num_nodes, CeedInt num_qpts, const CeedScalar *interp,
1114 const CeedScalar *div, const CeedScalar *q_ref, const CeedScalar *q_weight, CeedBasis *basis) {
1115 CeedInt Q = num_qpts, P = num_nodes, dim = 0;
1148 @param[in] q_ref Array of length num_qpts * dim holding the locations of quadrature points on the reference element
1149 @param[in] q_weight Array of length num_qpts holding the quadrature weights on the reference element
1150 @param[out] basis Address of the variable where the newly created CeedBasis will be stored.
1151
1152 @return An error code: 0 - success, otherwise - failure
1153
1154 @ref User
1155**/
1156int CeedBasisCreateHdiv(Ceed ceed, CeedElemTopology topo, CeedInt num_comp, CeedInt num_nodes, CeedInt num_qpts, const CeedScalar *interp,
1157 const CeedScalar *div, const CeedScalar *q_ref, const CeedScalar *q_weight, CeedBasis *basis) {
1158 CeedInt Q = num_qpts, P = num_nodes, dim = 0;
1116 CeedCall(CeedBasisGetTopologyDimension(topo, &dim));
1159
1117 if (!ceed->BasisCreateHdiv) {
1118 Ceed delegate;
1119 CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Basis"));
1120
1121 if (!delegate) {
1122 // LCOV_EXCL_START
1123 return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement BasisCreateHdiv");
1124 // LCOV_EXCL_STOP

--- 18 unchanged lines hidden (view full) ---

1143 if (num_qpts < 1) {
1144 // LCOV_EXCL_START
1145 return CeedError(ceed, CEED_ERROR_DIMENSION, "Basis must have at least 1 quadrature point");
1146 // LCOV_EXCL_STOP
1147 }
1148
1149 CeedCall(CeedCalloc(1, basis));
1150
1160 if (!ceed->BasisCreateHdiv) {
1161 Ceed delegate;
1162 CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Basis"));
1163
1164 if (!delegate) {
1165 // LCOV_EXCL_START
1166 return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement BasisCreateHdiv");
1167 // LCOV_EXCL_STOP

--- 18 unchanged lines hidden (view full) ---

1186 if (num_qpts < 1) {
1187 // LCOV_EXCL_START
1188 return CeedError(ceed, CEED_ERROR_DIMENSION, "Basis must have at least 1 quadrature point");
1189 // LCOV_EXCL_STOP
1190 }
1191
1192 CeedCall(CeedCalloc(1, basis));
1193
1194 CeedCall(CeedBasisGetTopologyDimension(topo, &dim));
1195
1151 (*basis)->ceed = ceed;
1152 CeedCall(CeedReference(ceed));
1153 (*basis)->ref_count = 1;
1154 (*basis)->tensor_basis = 0;
1155 (*basis)->dim = dim;
1156 (*basis)->topo = topo;
1157 (*basis)->num_comp = num_comp;
1158 (*basis)->P = P;
1159 (*basis)->Q = Q;
1196 (*basis)->ceed = ceed;
1197 CeedCall(CeedReference(ceed));
1198 (*basis)->ref_count = 1;
1199 (*basis)->tensor_basis = 0;
1200 (*basis)->dim = dim;
1201 (*basis)->topo = topo;
1202 (*basis)->num_comp = num_comp;
1203 (*basis)->P = P;
1204 (*basis)->Q = Q;
1160 (*basis)->Q_comp = dim;
1161 (*basis)->basis_space = 2; // 2 for H(div) space
1205 (*basis)->fe_space = CEED_FE_SPACE_HDIV;
1162 CeedCall(CeedMalloc(Q * dim, &(*basis)->q_ref_1d));
1163 CeedCall(CeedMalloc(Q, &(*basis)->q_weight_1d));
1164 if (q_ref) memcpy((*basis)->q_ref_1d, q_ref, Q * dim * sizeof(q_ref[0]));
1165 if (q_weight) memcpy((*basis)->q_weight_1d, q_weight, Q * sizeof(q_weight[0]));
1166 CeedCall(CeedMalloc(dim * Q * P, &(*basis)->interp));
1167 CeedCall(CeedMalloc(Q * P, &(*basis)->div));
1168 if (interp) memcpy((*basis)->interp, interp, dim * Q * P * sizeof(interp[0]));
1169 if (div) memcpy((*basis)->div, div, Q * P * sizeof(div[0]));
1170 CeedCall(ceed->BasisCreateHdiv(topo, dim, P, Q, interp, div, q_ref, q_weight, *basis));
1171 return CEED_ERROR_SUCCESS;
1172}
1173
1174/**
1206 CeedCall(CeedMalloc(Q * dim, &(*basis)->q_ref_1d));
1207 CeedCall(CeedMalloc(Q, &(*basis)->q_weight_1d));
1208 if (q_ref) memcpy((*basis)->q_ref_1d, q_ref, Q * dim * sizeof(q_ref[0]));
1209 if (q_weight) memcpy((*basis)->q_weight_1d, q_weight, Q * sizeof(q_weight[0]));
1210 CeedCall(CeedMalloc(dim * Q * P, &(*basis)->interp));
1211 CeedCall(CeedMalloc(Q * P, &(*basis)->div));
1212 if (interp) memcpy((*basis)->interp, interp, dim * Q * P * sizeof(interp[0]));
1213 if (div) memcpy((*basis)->div, div, Q * P * sizeof(div[0]));
1214 CeedCall(ceed->BasisCreateHdiv(topo, dim, P, Q, interp, div, q_ref, q_weight, *basis));
1215 return CEED_ERROR_SUCCESS;
1216}
1217
1218/**
1219 @brief Create a non tensor-product basis for H(curl) discretizations
1220
1221 @param[in] ceed Ceed object where the CeedBasis will be created
1222 @param[in] topo Topology of element (`CEED_TOPOLOGY_QUAD`, `CEED_TOPOLOGY_PRISM`, etc.), dimension of which is used in some array sizes below
1223 @param[in] num_comp Number of components (usually 1 for vectors in H(curl) bases)
1224 @param[in] num_nodes Total number of nodes (dofs per element)
1225 @param[in] num_qpts Total number of quadrature points
1226 @param[in] interp Row-major (dim * num_qpts * num_nodes) matrix expressing the values of basis functions at quadrature points
1227 @param[in] curl Row-major (curl_comp * num_qpts * num_nodes, curl_comp = 1 if dim < 3 else dim) matrix expressing curl of basis functions at
1228quadrature points
1229 @param[in] q_ref Array of length num_qpts * dim holding the locations of quadrature points on the reference element
1230 @param[in] q_weight Array of length num_qpts holding the quadrature weights on the reference element
1231 @param[out] basis Address of the variable where the newly created CeedBasis will be stored.
1232
1233 @return An error code: 0 - success, otherwise - failure
1234
1235 @ref User
1236**/
1237int CeedBasisCreateHcurl(Ceed ceed, CeedElemTopology topo, CeedInt num_comp, CeedInt num_nodes, CeedInt num_qpts, const CeedScalar *interp,
1238 const CeedScalar *curl, const CeedScalar *q_ref, const CeedScalar *q_weight, CeedBasis *basis) {
1239 CeedInt Q = num_qpts, P = num_nodes, dim = 0, curl_comp = 0;
1240
1241 if (!ceed->BasisCreateHdiv) {
1242 Ceed delegate;
1243 CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Basis"));
1244
1245 if (!delegate) {
1246 // LCOV_EXCL_START
1247 return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement BasisCreateHcurl");
1248 // LCOV_EXCL_STOP
1249 }
1250
1251 CeedCall(CeedBasisCreateHcurl(delegate, topo, num_comp, num_nodes, num_qpts, interp, curl, q_ref, q_weight, basis));
1252 return CEED_ERROR_SUCCESS;
1253 }
1254
1255 if (num_comp < 1) {
1256 // LCOV_EXCL_START
1257 return CeedError(ceed, CEED_ERROR_DIMENSION, "Basis must have at least 1 component");
1258 // LCOV_EXCL_STOP
1259 }
1260
1261 if (num_nodes < 1) {
1262 // LCOV_EXCL_START
1263 return CeedError(ceed, CEED_ERROR_DIMENSION, "Basis must have at least 1 node");
1264 // LCOV_EXCL_STOP
1265 }
1266
1267 if (num_qpts < 1) {
1268 // LCOV_EXCL_START
1269 return CeedError(ceed, CEED_ERROR_DIMENSION, "Basis must have at least 1 quadrature point");
1270 // LCOV_EXCL_STOP
1271 }
1272
1273 CeedCall(CeedCalloc(1, basis));
1274
1275 CeedCall(CeedBasisGetTopologyDimension(topo, &dim));
1276 curl_comp = (dim < 3) ? 1 : dim;
1277
1278 (*basis)->ceed = ceed;
1279 CeedCall(CeedReference(ceed));
1280 (*basis)->ref_count = 1;
1281 (*basis)->tensor_basis = 0;
1282 (*basis)->dim = dim;
1283 (*basis)->topo = topo;
1284 (*basis)->num_comp = num_comp;
1285 (*basis)->P = P;
1286 (*basis)->Q = Q;
1287 (*basis)->fe_space = CEED_FE_SPACE_HCURL;
1288 CeedCall(CeedMalloc(Q * dim, &(*basis)->q_ref_1d));
1289 CeedCall(CeedMalloc(Q, &(*basis)->q_weight_1d));
1290 if (q_ref) memcpy((*basis)->q_ref_1d, q_ref, Q * dim * sizeof(q_ref[0]));
1291 if (q_weight) memcpy((*basis)->q_weight_1d, q_weight, Q * sizeof(q_weight[0]));
1292 CeedCall(CeedMalloc(dim * Q * P, &(*basis)->interp));
1293 CeedCall(CeedMalloc(curl_comp * Q * P, &(*basis)->curl));
1294 if (interp) memcpy((*basis)->interp, interp, dim * Q * P * sizeof(interp[0]));
1295 if (curl) memcpy((*basis)->curl, curl, curl_comp * Q * P * sizeof(curl[0]));
1296 CeedCall(ceed->BasisCreateHcurl(topo, dim, P, Q, interp, curl, q_ref, q_weight, *basis));
1297 return CEED_ERROR_SUCCESS;
1298}
1299
1300/**
1175 @brief Create a CeedBasis for projection from the nodes of `basis_from` to the nodes of `basis_to`.
1176
1177 Only `CEED_EVAL_INTERP` and `CEED_EVAL_GRAD` will be valid for the new basis, `basis_project`.
1178 The interpolation is given by `interp_project = interp_to^+ * interp_from`, where the pesudoinverse `interp_to^+` is given by QR
1179factorization. The gradient is given by `grad_project = interp_to^+ * grad_from`. Note: `basis_from` and `basis_to` must have compatible quadrature
1180spaces.
1181 Note: `basis_project` will have the same number of components as `basis_from`, regardless of the number of components that `basis_to` has. If
1182`basis_from` has 3 components and `basis_to` has 5 components, then `basis_project` will have 3 components.

--- 74 unchanged lines hidden (view full) ---

1257 @param[in] basis CeedBasis to view
1258 @param[in] stream Stream to view to, e.g., stdout
1259
1260 @return An error code: 0 - success, otherwise - failure
1261
1262 @ref User
1263**/
1264int CeedBasisView(CeedBasis basis, FILE *stream) {
1301 @brief Create a CeedBasis for projection from the nodes of `basis_from` to the nodes of `basis_to`.
1302
1303 Only `CEED_EVAL_INTERP` and `CEED_EVAL_GRAD` will be valid for the new basis, `basis_project`.
1304 The interpolation is given by `interp_project = interp_to^+ * interp_from`, where the pesudoinverse `interp_to^+` is given by QR
1305factorization. The gradient is given by `grad_project = interp_to^+ * grad_from`. Note: `basis_from` and `basis_to` must have compatible quadrature
1306spaces.
1307 Note: `basis_project` will have the same number of components as `basis_from`, regardless of the number of components that `basis_to` has. If
1308`basis_from` has 3 components and `basis_to` has 5 components, then `basis_project` will have 3 components.

--- 74 unchanged lines hidden (view full) ---

1383 @param[in] basis CeedBasis to view
1384 @param[in] stream Stream to view to, e.g., stdout
1385
1386 @return An error code: 0 - success, otherwise - failure
1387
1388 @ref User
1389**/
1390int CeedBasisView(CeedBasis basis, FILE *stream) {
1265 CeedFESpace FE_space = basis->basis_space;
1266 CeedElemTopology topo = basis->topo;
1391 CeedElemTopology topo = basis->topo;
1392 CeedFESpace fe_space = basis->fe_space;
1393 CeedInt q_comp = 0;
1267
1268 // Print FE space and element topology of the basis
1269 if (basis->tensor_basis) {
1394
1395 // Print FE space and element topology of the basis
1396 if (basis->tensor_basis) {
1270 fprintf(stream, "CeedBasis (%s on a %s element): dim=%" CeedInt_FMT " P=%" CeedInt_FMT " Q=%" CeedInt_FMT "\n", CeedFESpaces[FE_space],
1397 fprintf(stream, "CeedBasis (%s on a %s element): dim=%" CeedInt_FMT " P=%" CeedInt_FMT " Q=%" CeedInt_FMT "\n", CeedFESpaces[fe_space],
1271 CeedElemTopologies[topo], basis->dim, basis->P_1d, basis->Q_1d);
1272 } else {
1398 CeedElemTopologies[topo], basis->dim, basis->P_1d, basis->Q_1d);
1399 } else {
1273 fprintf(stream, "CeedBasis (%s on a %s element): dim=%" CeedInt_FMT " P=%" CeedInt_FMT " Q=%" CeedInt_FMT "\n", CeedFESpaces[FE_space],
1400 fprintf(stream, "CeedBasis (%s on a %s element): dim=%" CeedInt_FMT " P=%" CeedInt_FMT " Q=%" CeedInt_FMT "\n", CeedFESpaces[fe_space],
1274 CeedElemTopologies[topo], basis->dim, basis->P, basis->Q);
1275 }
1276 // Print quadrature data, interpolation/gradient/divergence/curl of the basis
1277 if (basis->tensor_basis) { // tensor basis
1278 CeedCall(CeedScalarView("qref1d", "\t% 12.8f", 1, basis->Q_1d, basis->q_ref_1d, stream));
1279 CeedCall(CeedScalarView("qweight1d", "\t% 12.8f", 1, basis->Q_1d, basis->q_weight_1d, stream));
1280 CeedCall(CeedScalarView("interp1d", "\t% 12.8f", basis->Q_1d, basis->P_1d, basis->interp_1d, stream));
1281 CeedCall(CeedScalarView("grad1d", "\t% 12.8f", basis->Q_1d, basis->P_1d, basis->grad_1d, stream));
1282 } else { // non-tensor basis
1283 CeedCall(CeedScalarView("qref", "\t% 12.8f", 1, basis->Q * basis->dim, basis->q_ref_1d, stream));
1284 CeedCall(CeedScalarView("qweight", "\t% 12.8f", 1, basis->Q, basis->q_weight_1d, stream));
1401 CeedElemTopologies[topo], basis->dim, basis->P, basis->Q);
1402 }
1403 // Print quadrature data, interpolation/gradient/divergence/curl of the basis
1404 if (basis->tensor_basis) { // tensor basis
1405 CeedCall(CeedScalarView("qref1d", "\t% 12.8f", 1, basis->Q_1d, basis->q_ref_1d, stream));
1406 CeedCall(CeedScalarView("qweight1d", "\t% 12.8f", 1, basis->Q_1d, basis->q_weight_1d, stream));
1407 CeedCall(CeedScalarView("interp1d", "\t% 12.8f", basis->Q_1d, basis->P_1d, basis->interp_1d, stream));
1408 CeedCall(CeedScalarView("grad1d", "\t% 12.8f", basis->Q_1d, basis->P_1d, basis->grad_1d, stream));
1409 } else { // non-tensor basis
1410 CeedCall(CeedScalarView("qref", "\t% 12.8f", 1, basis->Q * basis->dim, basis->q_ref_1d, stream));
1411 CeedCall(CeedScalarView("qweight", "\t% 12.8f", 1, basis->Q, basis->q_weight_1d, stream));
1285 CeedCall(CeedScalarView("interp", "\t% 12.8f", basis->Q_comp * basis->Q, basis->P, basis->interp, stream));
1412 CeedCall(CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_INTERP, &q_comp));
1413 CeedCall(CeedScalarView("interp", "\t% 12.8f", q_comp * basis->Q, basis->P, basis->interp, stream));
1286 if (basis->grad) {
1414 if (basis->grad) {
1287 CeedCall(CeedScalarView("grad", "\t% 12.8f", basis->dim * basis->Q, basis->P, basis->grad, stream));
1415 CeedCall(CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_GRAD, &q_comp));
1416 CeedCall(CeedScalarView("grad", "\t% 12.8f", q_comp * basis->Q, basis->P, basis->grad, stream));
1288 }
1289 if (basis->div) {
1417 }
1418 if (basis->div) {
1290 CeedCall(CeedScalarView("div", "\t% 12.8f", basis->Q, basis->P, basis->div, stream));
1419 CeedCall(CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_DIV, &q_comp));
1420 CeedCall(CeedScalarView("div", "\t% 12.8f", q_comp * basis->Q, basis->P, basis->div, stream));
1291 }
1421 }
1422 if (basis->curl) {
1423 CeedCall(CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_CURL, &q_comp));
1424 CeedCall(CeedScalarView("curl", "\t% 12.8f", q_comp * basis->Q, basis->P, basis->curl, stream));
1425 }
1292 }
1293 return CEED_ERROR_SUCCESS;
1294}
1295
1296/**
1297 @brief Apply basis evaluation from nodes to quadrature points or vice versa
1298
1299 @param[in] basis CeedBasis to evaluate
1300 @param[in] num_elem The number of elements to apply the basis evaluation to;
1301 the backend will specify the ordering in CeedElemRestrictionCreateBlocked()
1302 @param[in] t_mode \ref CEED_NOTRANSPOSE to evaluate from nodes to quadrature points;
1303 \ref CEED_TRANSPOSE to apply the transpose, mapping from quadrature points to nodes
1304 @param[in] eval_mode \ref CEED_EVAL_NONE to use values directly,
1305 \ref CEED_EVAL_INTERP to use interpolated values,
1306 \ref CEED_EVAL_GRAD to use gradients,
1426 }
1427 return CEED_ERROR_SUCCESS;
1428}
1429
1430/**
1431 @brief Apply basis evaluation from nodes to quadrature points or vice versa
1432
1433 @param[in] basis CeedBasis to evaluate
1434 @param[in] num_elem The number of elements to apply the basis evaluation to;
1435 the backend will specify the ordering in CeedElemRestrictionCreateBlocked()
1436 @param[in] t_mode \ref CEED_NOTRANSPOSE to evaluate from nodes to quadrature points;
1437 \ref CEED_TRANSPOSE to apply the transpose, mapping from quadrature points to nodes
1438 @param[in] eval_mode \ref CEED_EVAL_NONE to use values directly,
1439 \ref CEED_EVAL_INTERP to use interpolated values,
1440 \ref CEED_EVAL_GRAD to use gradients,
1441 \ref CEED_EVAL_DIV to use divergence,
1442 \ref CEED_EVAL_CURL to use curl,
1307 \ref CEED_EVAL_WEIGHT to use quadrature weights.
1308 @param[in] u Input CeedVector
1309 @param[out] v Output CeedVector
1310
1311 @return An error code: 0 - success, otherwise - failure
1312
1313 @ref User
1314**/
1315int CeedBasisApply(CeedBasis basis, CeedInt num_elem, CeedTransposeMode t_mode, CeedEvalMode eval_mode, CeedVector u, CeedVector v) {
1316 CeedSize u_length = 0, v_length;
1443 \ref CEED_EVAL_WEIGHT to use quadrature weights.
1444 @param[in] u Input CeedVector
1445 @param[out] v Output CeedVector
1446
1447 @return An error code: 0 - success, otherwise - failure
1448
1449 @ref User
1450**/
1451int CeedBasisApply(CeedBasis basis, CeedInt num_elem, CeedTransposeMode t_mode, CeedEvalMode eval_mode, CeedVector u, CeedVector v) {
1452 CeedSize u_length = 0, v_length;
1317 CeedInt dim, num_comp, num_nodes, num_qpts;
1453 CeedInt dim, num_comp, q_comp, num_nodes, num_qpts;
1318 CeedCall(CeedBasisGetDimension(basis, &dim));
1319 CeedCall(CeedBasisGetNumComponents(basis, &num_comp));
1454 CeedCall(CeedBasisGetDimension(basis, &dim));
1455 CeedCall(CeedBasisGetNumComponents(basis, &num_comp));
1456 CeedCall(CeedBasisGetNumQuadratureComponents(basis, eval_mode, &q_comp));
1320 CeedCall(CeedBasisGetNumNodes(basis, &num_nodes));
1321 CeedCall(CeedBasisGetNumQuadraturePoints(basis, &num_qpts));
1322 CeedCall(CeedVectorGetLength(v, &v_length));
1323 if (u) {
1324 CeedCall(CeedVectorGetLength(u, &u_length));
1325 }
1326
1327 if (!basis->Apply) {

--- 10 unchanged lines hidden (view full) ---

1338 // LCOV_EXCL_STOP
1339 }
1340
1341 // Check vector lengths to prevent out of bounds issues
1342 bool bad_dims = false;
1343 switch (eval_mode) {
1344 case CEED_EVAL_NONE:
1345 case CEED_EVAL_INTERP:
1457 CeedCall(CeedBasisGetNumNodes(basis, &num_nodes));
1458 CeedCall(CeedBasisGetNumQuadraturePoints(basis, &num_qpts));
1459 CeedCall(CeedVectorGetLength(v, &v_length));
1460 if (u) {
1461 CeedCall(CeedVectorGetLength(u, &u_length));
1462 }
1463
1464 if (!basis->Apply) {

--- 10 unchanged lines hidden (view full) ---

1475 // LCOV_EXCL_STOP
1476 }
1477
1478 // Check vector lengths to prevent out of bounds issues
1479 bool bad_dims = false;
1480 switch (eval_mode) {
1481 case CEED_EVAL_NONE:
1482 case CEED_EVAL_INTERP:
1346 bad_dims = ((t_mode == CEED_TRANSPOSE && (u_length < num_elem * num_comp * num_qpts || v_length < num_elem * num_comp * num_nodes)) ||
1347 (t_mode == CEED_NOTRANSPOSE && (v_length < num_elem * num_qpts * num_comp || u_length < num_elem * num_comp * num_nodes)));
1348 break;
1349 case CEED_EVAL_GRAD:
1483 case CEED_EVAL_GRAD:
1350 bad_dims = ((t_mode == CEED_TRANSPOSE && (u_length < num_elem * num_comp * num_qpts * dim || v_length < num_elem * num_comp * num_nodes)) ||
1351 (t_mode == CEED_NOTRANSPOSE && (v_length < num_elem * num_qpts * num_comp * dim || u_length < num_elem * num_comp * num_nodes)));
1484 case CEED_EVAL_DIV:
1485 case CEED_EVAL_CURL:
1486 bad_dims = ((t_mode == CEED_TRANSPOSE && (u_length < num_elem * num_comp * num_qpts * q_comp || v_length < num_elem * num_comp * num_nodes)) ||
1487 (t_mode == CEED_NOTRANSPOSE && (v_length < num_elem * num_qpts * num_comp * q_comp || u_length < num_elem * num_comp * num_nodes)));
1352 break;
1353 case CEED_EVAL_WEIGHT:
1354 bad_dims = v_length < num_elem * num_qpts;
1355 break;
1488 break;
1489 case CEED_EVAL_WEIGHT:
1490 bad_dims = v_length < num_elem * num_qpts;
1491 break;
1356 // LCOV_EXCL_START
1357 case CEED_EVAL_DIV:
1358 bad_dims = ((t_mode == CEED_TRANSPOSE && (u_length < num_elem * num_comp * num_qpts || v_length < num_elem * num_comp * num_nodes)) ||
1359 (t_mode == CEED_NOTRANSPOSE && (v_length < num_elem * num_qpts * num_comp || u_length < num_elem * num_comp * num_nodes)));
1360 break;
1361 case CEED_EVAL_CURL:
1362 bad_dims = ((t_mode == CEED_TRANSPOSE && (u_length < num_elem * num_comp * num_qpts || v_length < num_elem * num_comp * num_nodes)) ||
1363 (t_mode == CEED_NOTRANSPOSE && (v_length < num_elem * num_qpts * num_comp || u_length < num_elem * num_comp * num_nodes)));
1364 break;
1365 // LCOV_EXCL_STOP
1366 }
1367 if (bad_dims) {
1368 // LCOV_EXCL_START
1369 return CeedError(basis->ceed, CEED_ERROR_DIMENSION, "Input/output vectors too short for basis and evaluation mode");
1370 // LCOV_EXCL_STOP
1371 }
1372
1373 CeedCall(basis->Apply(basis, num_elem, t_mode, eval_mode, u, v));

--- 41 unchanged lines hidden (view full) ---

1415 @ref Advanced
1416**/
1417int CeedBasisGetTopology(CeedBasis basis, CeedElemTopology *topo) {
1418 *topo = basis->topo;
1419 return CEED_ERROR_SUCCESS;
1420}
1421
1422/**
1492 }
1493 if (bad_dims) {
1494 // LCOV_EXCL_START
1495 return CeedError(basis->ceed, CEED_ERROR_DIMENSION, "Input/output vectors too short for basis and evaluation mode");
1496 // LCOV_EXCL_STOP
1497 }
1498
1499 CeedCall(basis->Apply(basis, num_elem, t_mode, eval_mode, u, v));

--- 41 unchanged lines hidden (view full) ---

1541 @ref Advanced
1542**/
1543int CeedBasisGetTopology(CeedBasis basis, CeedElemTopology *topo) {
1544 *topo = basis->topo;
1545 return CEED_ERROR_SUCCESS;
1546}
1547
1548/**
1423 @brief Get number of Q-vector components for given CeedBasis
1424
1425 @param[in] basis CeedBasis
1426 @param[out] Q_comp Variable to store number of Q-vector components of basis
1427
1428 @return An error code: 0 - success, otherwise - failure
1429
1430 @ref Advanced
1431**/
1432int CeedBasisGetNumQuadratureComponents(CeedBasis basis, CeedInt *Q_comp) {
1433 *Q_comp = basis->Q_comp;
1434 return CEED_ERROR_SUCCESS;
1435}
1436
1437/**
1438 @brief Get number of components for given CeedBasis
1439
1440 @param[in] basis CeedBasis
1441 @param[out] num_comp Variable to store number of components of basis
1442
1443 @return An error code: 0 - success, otherwise - failure
1444
1445 @ref Advanced

--- 233 unchanged lines hidden (view full) ---

1679 // LCOV_EXCL_STOP
1680 }
1681
1682 *div = basis->div;
1683 return CEED_ERROR_SUCCESS;
1684}
1685
1686/**
1549 @brief Get number of components for given CeedBasis
1550
1551 @param[in] basis CeedBasis
1552 @param[out] num_comp Variable to store number of components of basis
1553
1554 @return An error code: 0 - success, otherwise - failure
1555
1556 @ref Advanced

--- 233 unchanged lines hidden (view full) ---

1790 // LCOV_EXCL_STOP
1791 }
1792
1793 *div = basis->div;
1794 return CEED_ERROR_SUCCESS;
1795}
1796
1797/**
1798 @brief Get curl matrix of a CeedBasis
1799
1800 @param[in] basis CeedBasis
1801 @param[out] curl Variable to store curl matrix
1802
1803 @return An error code: 0 - success, otherwise - failure
1804
1805 @ref Advanced
1806**/
1807int CeedBasisGetCurl(CeedBasis basis, const CeedScalar **curl) {
1808 if (!basis->curl) {
1809 // LCOV_EXCL_START
1810 return CeedError(basis->ceed, CEED_ERROR_MINOR, "CeedBasis does not have curl matrix.");
1811 // LCOV_EXCL_STOP
1812 }
1813
1814 *curl = basis->curl;
1815 return CEED_ERROR_SUCCESS;
1816}
1817
1818/**
1687 @brief Destroy a CeedBasis
1688
1689 @param[in,out] basis CeedBasis to destroy
1690
1691 @return An error code: 0 - success, otherwise - failure
1692
1693 @ref User
1694**/
1695int CeedBasisDestroy(CeedBasis *basis) {
1696 if (!*basis || *basis == CEED_BASIS_COLLOCATED || --(*basis)->ref_count > 0) {
1697 *basis = NULL;
1698 return CEED_ERROR_SUCCESS;
1699 }
1700 if ((*basis)->Destroy) CeedCall((*basis)->Destroy(*basis));
1701 if ((*basis)->contract) CeedCall(CeedTensorContractDestroy(&(*basis)->contract));
1819 @brief Destroy a CeedBasis
1820
1821 @param[in,out] basis CeedBasis to destroy
1822
1823 @return An error code: 0 - success, otherwise - failure
1824
1825 @ref User
1826**/
1827int CeedBasisDestroy(CeedBasis *basis) {
1828 if (!*basis || *basis == CEED_BASIS_COLLOCATED || --(*basis)->ref_count > 0) {
1829 *basis = NULL;
1830 return CEED_ERROR_SUCCESS;
1831 }
1832 if ((*basis)->Destroy) CeedCall((*basis)->Destroy(*basis));
1833 if ((*basis)->contract) CeedCall(CeedTensorContractDestroy(&(*basis)->contract));
1834 CeedCall(CeedFree(&(*basis)->q_ref_1d));
1835 CeedCall(CeedFree(&(*basis)->q_weight_1d));
1702 CeedCall(CeedFree(&(*basis)->interp));
1703 CeedCall(CeedFree(&(*basis)->interp_1d));
1704 CeedCall(CeedFree(&(*basis)->grad));
1836 CeedCall(CeedFree(&(*basis)->interp));
1837 CeedCall(CeedFree(&(*basis)->interp_1d));
1838 CeedCall(CeedFree(&(*basis)->grad));
1705 CeedCall(CeedFree(&(*basis)->div));
1706 CeedCall(CeedFree(&(*basis)->grad_1d));
1839 CeedCall(CeedFree(&(*basis)->grad_1d));
1707 CeedCall(CeedFree(&(*basis)->q_ref_1d));
1708 CeedCall(CeedFree(&(*basis)->q_weight_1d));
1840 CeedCall(CeedFree(&(*basis)->div));
1841 CeedCall(CeedFree(&(*basis)->curl));
1709 CeedCall(CeedDestroy(&(*basis)->ceed));
1710 CeedCall(CeedFree(basis));
1711 return CEED_ERROR_SUCCESS;
1712}
1713
1714/**
1715 @brief Construct a Gauss-Legendre quadrature
1716

--- 120 unchanged lines hidden ---
1842 CeedCall(CeedDestroy(&(*basis)->ceed));
1843 CeedCall(CeedFree(basis));
1844 return CEED_ERROR_SUCCESS;
1845}
1846
1847/**
1848 @brief Construct a Gauss-Legendre quadrature
1849

--- 120 unchanged lines hidden ---