18c81f8b0SPeter Munch // --------------------------------------------------------------------- 28c81f8b0SPeter Munch // 38c81f8b0SPeter Munch // Copyright (C) 2023 by the deal.II authors 48c81f8b0SPeter Munch // 58c81f8b0SPeter Munch // This file is part of the deal.II library. 68c81f8b0SPeter Munch // 78c81f8b0SPeter Munch // The deal.II library is free software; you can use it, redistribute 88c81f8b0SPeter Munch // it, and/or modify it under the terms of the GNU Lesser General 98c81f8b0SPeter Munch // Public License as published by the Free Software Foundation; either 108c81f8b0SPeter Munch // version 2.1 of the License, or (at your option) any later version. 118c81f8b0SPeter Munch // The full text of the license can be found in the file LICENSE.md at 128c81f8b0SPeter Munch // the top level directory of deal.II. 138c81f8b0SPeter Munch // 148c81f8b0SPeter Munch // Authors: Peter Munch, Martin Kronbichler 158c81f8b0SPeter Munch // 168c81f8b0SPeter Munch // --------------------------------------------------------------------- 178c81f8b0SPeter Munch 18*c0b5abf0SJeremy L Thompson #include <ceed/types.h> 198c81f8b0SPeter Munch 208c81f8b0SPeter Munch 218c81f8b0SPeter Munch 228c81f8b0SPeter Munch /** 238c81f8b0SPeter Munch * Context passed to libCEED Q-function. 248c81f8b0SPeter Munch */ 258c81f8b0SPeter Munch struct BuildContext 268c81f8b0SPeter Munch { 278c81f8b0SPeter Munch CeedInt dim, space_dim; 288c81f8b0SPeter Munch }; 298c81f8b0SPeter Munch 308c81f8b0SPeter Munch 318c81f8b0SPeter Munch 328c81f8b0SPeter Munch /** 338c81f8b0SPeter Munch * libCEED Q-function for building quadrature data for a mass operator 348c81f8b0SPeter Munch */ 358c81f8b0SPeter Munch CEED_QFUNCTION(f_build_mass) 368c81f8b0SPeter Munch (void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) 378c81f8b0SPeter Munch { 388c81f8b0SPeter Munch BuildContext *bc = (BuildContext *)ctx; 398c81f8b0SPeter Munch const CeedScalar *J = in[0], *w = in[1]; 408c81f8b0SPeter Munch CeedScalar *qdata = out[0]; 418c81f8b0SPeter Munch 428c81f8b0SPeter Munch switch (bc->dim + 10 * bc->space_dim) 438c81f8b0SPeter Munch { 448c81f8b0SPeter Munch case 11: 458c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; ++i) 468c81f8b0SPeter Munch { 478c81f8b0SPeter Munch qdata[i] = J[i] * w[i]; 488c81f8b0SPeter Munch } 498c81f8b0SPeter Munch break; 508c81f8b0SPeter Munch case 22: 518c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; ++i) 528c81f8b0SPeter Munch { 538c81f8b0SPeter Munch qdata[i] = (J[i + Q * 0] * J[i + Q * 3] - J[i + Q * 1] * J[i + Q * 2]) * w[i]; 548c81f8b0SPeter Munch } 558c81f8b0SPeter Munch break; 568c81f8b0SPeter Munch case 33: 578c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; ++i) 588c81f8b0SPeter Munch { 598c81f8b0SPeter Munch qdata[i] = (J[i + Q * 0] * (J[i + Q * 4] * J[i + Q * 8] - J[i + Q * 5] * J[i + Q * 7]) - 608c81f8b0SPeter Munch J[i + Q * 1] * (J[i + Q * 3] * J[i + Q * 8] - J[i + Q * 5] * J[i + Q * 6]) + 618c81f8b0SPeter Munch J[i + Q * 2] * (J[i + Q * 3] * J[i + Q * 7] - J[i + Q * 4] * J[i + Q * 6])) * 628c81f8b0SPeter Munch w[i]; 638c81f8b0SPeter Munch } 648c81f8b0SPeter Munch break; 658c81f8b0SPeter Munch } 668c81f8b0SPeter Munch return 0; 678c81f8b0SPeter Munch } 688c81f8b0SPeter Munch 698c81f8b0SPeter Munch 708c81f8b0SPeter Munch 718c81f8b0SPeter Munch /** 728c81f8b0SPeter Munch * libCEED Q-function for applying a mass operator 738c81f8b0SPeter Munch */ 748c81f8b0SPeter Munch CEED_QFUNCTION(f_apply_mass) 758c81f8b0SPeter Munch (void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) 768c81f8b0SPeter Munch { 778c81f8b0SPeter Munch (void)ctx; 788c81f8b0SPeter Munch 798c81f8b0SPeter Munch const CeedScalar *u = in[0]; 808c81f8b0SPeter Munch const CeedScalar *JxW = in[1]; 818c81f8b0SPeter Munch CeedScalar *v = out[0]; 828c81f8b0SPeter Munch 838c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; ++i) 848c81f8b0SPeter Munch { 858c81f8b0SPeter Munch v[i] = JxW[i] * u[i]; 868c81f8b0SPeter Munch } 878c81f8b0SPeter Munch return 0; 888c81f8b0SPeter Munch } 898c81f8b0SPeter Munch 908c81f8b0SPeter Munch 918c81f8b0SPeter Munch 928c81f8b0SPeter Munch /** 938c81f8b0SPeter Munch * libCEED Q-function for applying a vector mass operator 948c81f8b0SPeter Munch */ 958c81f8b0SPeter Munch CEED_QFUNCTION(f_apply_mass_vec) 968c81f8b0SPeter Munch (void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) 978c81f8b0SPeter Munch { 988c81f8b0SPeter Munch BuildContext *bc = (BuildContext *)ctx; 998c81f8b0SPeter Munch 1008c81f8b0SPeter Munch const CeedScalar *u = in[0]; 1018c81f8b0SPeter Munch const CeedScalar *JxW = in[1]; 1028c81f8b0SPeter Munch CeedScalar *v = out[0]; 1038c81f8b0SPeter Munch 1048c81f8b0SPeter Munch switch (bc->dim + 10 * bc->space_dim) 1058c81f8b0SPeter Munch { 1068c81f8b0SPeter Munch case 11: 1078c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; ++i) 1088c81f8b0SPeter Munch { 1098c81f8b0SPeter Munch v[i + Q * 0] = JxW[i] * u[i + Q * 0]; 1108c81f8b0SPeter Munch } 1118c81f8b0SPeter Munch break; 1128c81f8b0SPeter Munch case 22: 1138c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; ++i) 1148c81f8b0SPeter Munch { 1158c81f8b0SPeter Munch v[i + Q * 0] = JxW[i] * u[i + Q * 0]; 1168c81f8b0SPeter Munch v[i + Q * 1] = JxW[i] * u[i + Q * 1]; 1178c81f8b0SPeter Munch } 1188c81f8b0SPeter Munch break; 1198c81f8b0SPeter Munch case 33: 1208c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; ++i) 1218c81f8b0SPeter Munch { 1228c81f8b0SPeter Munch v[i + Q * 0] = JxW[i] * u[i + Q * 0]; 1238c81f8b0SPeter Munch v[i + Q * 1] = JxW[i] * u[i + Q * 1]; 1248c81f8b0SPeter Munch v[i + Q * 2] = JxW[i] * u[i + Q * 2]; 1258c81f8b0SPeter Munch } 1268c81f8b0SPeter Munch break; 1278c81f8b0SPeter Munch } 1288c81f8b0SPeter Munch return 0; 1298c81f8b0SPeter Munch } 1308c81f8b0SPeter Munch 1318c81f8b0SPeter Munch 1328c81f8b0SPeter Munch 1338c81f8b0SPeter Munch /** 1348c81f8b0SPeter Munch * libCEED Q-function for building quadrature data for a Poisson operator 1358c81f8b0SPeter Munch */ 1368c81f8b0SPeter Munch CEED_QFUNCTION(f_build_poisson) 1378c81f8b0SPeter Munch (void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) 1388c81f8b0SPeter Munch { 1398c81f8b0SPeter Munch BuildContext *bc = (BuildContext *)ctx; 1408c81f8b0SPeter Munch const CeedScalar *J = in[0], *w = in[1]; 1418c81f8b0SPeter Munch CeedScalar *qdata = out[0]; 1428c81f8b0SPeter Munch 1438c81f8b0SPeter Munch switch (bc->dim + 10 * bc->space_dim) 1448c81f8b0SPeter Munch { 1458c81f8b0SPeter Munch case 11: 1468c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) 1478c81f8b0SPeter Munch { 1488c81f8b0SPeter Munch qdata[i] = w[i] / J[i]; 1498c81f8b0SPeter Munch } 1508c81f8b0SPeter Munch break; 1518c81f8b0SPeter Munch case 22: 1528c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) 1538c81f8b0SPeter Munch { 1548c81f8b0SPeter Munch const CeedScalar J11 = J[i + Q * 0]; 1558c81f8b0SPeter Munch const CeedScalar J21 = J[i + Q * 1]; 1568c81f8b0SPeter Munch const CeedScalar J12 = J[i + Q * 2]; 1578c81f8b0SPeter Munch const CeedScalar J22 = J[i + Q * 3]; 1588c81f8b0SPeter Munch const CeedScalar qw = w[i] / (J11 * J22 - J21 * J12); 1598c81f8b0SPeter Munch qdata[i + Q * 0] = qw * (J12 * J12 + J22 * J22); 1608c81f8b0SPeter Munch qdata[i + Q * 1] = qw * (J11 * J11 + J21 * J21); 1618c81f8b0SPeter Munch qdata[i + Q * 2] = -qw * (J11 * J12 + J21 * J22); 1628c81f8b0SPeter Munch } 1638c81f8b0SPeter Munch break; 1648c81f8b0SPeter Munch case 33: 1658c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) 1668c81f8b0SPeter Munch { 1678c81f8b0SPeter Munch const CeedScalar J11 = J[i + Q * 0]; 1688c81f8b0SPeter Munch const CeedScalar J21 = J[i + Q * 1]; 1698c81f8b0SPeter Munch const CeedScalar J31 = J[i + Q * 2]; 1708c81f8b0SPeter Munch const CeedScalar J12 = J[i + Q * 3]; 1718c81f8b0SPeter Munch const CeedScalar J22 = J[i + Q * 4]; 1728c81f8b0SPeter Munch const CeedScalar J32 = J[i + Q * 5]; 1738c81f8b0SPeter Munch const CeedScalar J13 = J[i + Q * 6]; 1748c81f8b0SPeter Munch const CeedScalar J23 = J[i + Q * 7]; 1758c81f8b0SPeter Munch const CeedScalar J33 = J[i + Q * 8]; 1768c81f8b0SPeter Munch const CeedScalar A11 = J22 * J33 - J23 * J32; 1778c81f8b0SPeter Munch const CeedScalar A12 = J13 * J32 - J12 * J33; 1788c81f8b0SPeter Munch const CeedScalar A13 = J12 * J23 - J13 * J22; 1798c81f8b0SPeter Munch const CeedScalar A21 = J23 * J31 - J21 * J33; 1808c81f8b0SPeter Munch const CeedScalar A22 = J11 * J33 - J13 * J31; 1818c81f8b0SPeter Munch const CeedScalar A23 = J13 * J21 - J11 * J23; 1828c81f8b0SPeter Munch const CeedScalar A31 = J21 * J32 - J22 * J31; 1838c81f8b0SPeter Munch const CeedScalar A32 = J12 * J31 - J11 * J32; 1848c81f8b0SPeter Munch const CeedScalar A33 = J11 * J22 - J12 * J21; 1858c81f8b0SPeter Munch const CeedScalar qw = w[i] / (J11 * A11 + J21 * A12 + J31 * A13); 1868c81f8b0SPeter Munch qdata[i + Q * 0] = qw * (A11 * A11 + A12 * A12 + A13 * A13); 1878c81f8b0SPeter Munch qdata[i + Q * 1] = qw * (A21 * A21 + A22 * A22 + A23 * A23); 1888c81f8b0SPeter Munch qdata[i + Q * 2] = qw * (A31 * A31 + A32 * A32 + A33 * A33); 1898c81f8b0SPeter Munch qdata[i + Q * 3] = qw * (A21 * A31 + A22 * A32 + A23 * A33); 1908c81f8b0SPeter Munch qdata[i + Q * 4] = qw * (A11 * A31 + A12 * A32 + A13 * A33); 1918c81f8b0SPeter Munch qdata[i + Q * 5] = qw * (A11 * A21 + A12 * A22 + A13 * A23); 1928c81f8b0SPeter Munch } 1938c81f8b0SPeter Munch break; 1948c81f8b0SPeter Munch } 1958c81f8b0SPeter Munch return 0; 1968c81f8b0SPeter Munch } 1978c81f8b0SPeter Munch 1988c81f8b0SPeter Munch 1998c81f8b0SPeter Munch 2008c81f8b0SPeter Munch /** 2018c81f8b0SPeter Munch * libCEED Q-function for applying a Poisson operator 2028c81f8b0SPeter Munch */ 2038c81f8b0SPeter Munch CEED_QFUNCTION(f_apply_poisson) 2048c81f8b0SPeter Munch (void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) 2058c81f8b0SPeter Munch { 2068c81f8b0SPeter Munch BuildContext *bc = (BuildContext *)ctx; 2078c81f8b0SPeter Munch const CeedScalar *ug = in[0], *qdata = in[1]; 2088c81f8b0SPeter Munch CeedScalar *vg = out[0]; 2098c81f8b0SPeter Munch 2108c81f8b0SPeter Munch switch (bc->dim) 2118c81f8b0SPeter Munch { 2128c81f8b0SPeter Munch case 1: 2138c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) 2148c81f8b0SPeter Munch { 2158c81f8b0SPeter Munch vg[i] = ug[i] * qdata[i]; 2168c81f8b0SPeter Munch } 2178c81f8b0SPeter Munch break; 2188c81f8b0SPeter Munch case 2: 2198c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) 2208c81f8b0SPeter Munch { 2218c81f8b0SPeter Munch const CeedScalar ug0 = ug[i + Q * 0]; 2228c81f8b0SPeter Munch const CeedScalar ug1 = ug[i + Q * 1]; 2238c81f8b0SPeter Munch vg[i + Q * 0] = qdata[i + Q * 0] * ug0 + qdata[i + Q * 2] * ug1; 2248c81f8b0SPeter Munch vg[i + Q * 1] = qdata[i + Q * 2] * ug0 + qdata[i + Q * 1] * ug1; 2258c81f8b0SPeter Munch } 2268c81f8b0SPeter Munch break; 2278c81f8b0SPeter Munch case 3: 2288c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) 2298c81f8b0SPeter Munch { 2308c81f8b0SPeter Munch const CeedScalar ug0 = ug[i + Q * 0]; 2318c81f8b0SPeter Munch const CeedScalar ug1 = ug[i + Q * 1]; 2328c81f8b0SPeter Munch const CeedScalar ug2 = ug[i + Q * 2]; 2338c81f8b0SPeter Munch vg[i + Q * 0] = qdata[i + Q * 0] * ug0 + qdata[i + Q * 5] * ug1 + qdata[i + Q * 4] * ug2; 2348c81f8b0SPeter Munch vg[i + Q * 1] = qdata[i + Q * 5] * ug0 + qdata[i + Q * 1] * ug1 + qdata[i + Q * 3] * ug2; 2358c81f8b0SPeter Munch vg[i + Q * 2] = qdata[i + Q * 4] * ug0 + qdata[i + Q * 3] * ug1 + qdata[i + Q * 2] * ug2; 2368c81f8b0SPeter Munch } 2378c81f8b0SPeter Munch break; 2388c81f8b0SPeter Munch } 2398c81f8b0SPeter Munch return 0; 2408c81f8b0SPeter Munch } 2418c81f8b0SPeter Munch 2428c81f8b0SPeter Munch 2438c81f8b0SPeter Munch 2448c81f8b0SPeter Munch /** 2458c81f8b0SPeter Munch *libCEED Q-function for applying a vector Poisson operator 2468c81f8b0SPeter Munch */ 2478c81f8b0SPeter Munch CEED_QFUNCTION(f_apply_poisson_vec) 2488c81f8b0SPeter Munch (void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) 2498c81f8b0SPeter Munch { 2508c81f8b0SPeter Munch BuildContext *bc = (BuildContext *)ctx; 2518c81f8b0SPeter Munch const CeedScalar *ug = in[0], *qdata = in[1]; 2528c81f8b0SPeter Munch CeedScalar *vg = out[0]; 2538c81f8b0SPeter Munch 2548c81f8b0SPeter Munch switch (bc->dim) 2558c81f8b0SPeter Munch { 2568c81f8b0SPeter Munch case 1: 2578c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) 2588c81f8b0SPeter Munch { 2598c81f8b0SPeter Munch vg[i] = ug[i] * qdata[i]; 2608c81f8b0SPeter Munch } 2618c81f8b0SPeter Munch break; 2628c81f8b0SPeter Munch case 2: 2638c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) 2648c81f8b0SPeter Munch { 2658c81f8b0SPeter Munch { 2668c81f8b0SPeter Munch const CeedScalar ug0 = ug[i + Q * 0 + Q * 2 * 0]; 2678c81f8b0SPeter Munch const CeedScalar ug1 = ug[i + Q * 1 + Q * 2 * 0]; 2688c81f8b0SPeter Munch vg[i + Q * 0 + Q * 2 * 0] = qdata[i + Q * 0] * ug0 + qdata[i + Q * 2] * ug1; 2698c81f8b0SPeter Munch vg[i + Q * 1 + Q * 2 * 0] = qdata[i + Q * 2] * ug0 + qdata[i + Q * 1] * ug1; 2708c81f8b0SPeter Munch } 2718c81f8b0SPeter Munch { 2728c81f8b0SPeter Munch const CeedScalar ug0 = ug[i + Q * 0 + Q * 2 * 1]; 2738c81f8b0SPeter Munch const CeedScalar ug1 = ug[i + Q * 1 + Q * 2 * 1]; 2748c81f8b0SPeter Munch vg[i + Q * 0 + Q * 2 * 1] = qdata[i + Q * 0] * ug0 + qdata[i + Q * 2] * ug1; 2758c81f8b0SPeter Munch vg[i + Q * 1 + Q * 2 * 1] = qdata[i + Q * 2] * ug0 + qdata[i + Q * 1] * ug1; 2768c81f8b0SPeter Munch } 2778c81f8b0SPeter Munch } 2788c81f8b0SPeter Munch break; 2798c81f8b0SPeter Munch case 3: 2808c81f8b0SPeter Munch CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) 2818c81f8b0SPeter Munch { 2828c81f8b0SPeter Munch { 2838c81f8b0SPeter Munch const CeedScalar ug0 = ug[i + Q * 0 + Q * 3 * 0]; 2848c81f8b0SPeter Munch const CeedScalar ug1 = ug[i + Q * 1 + Q * 3 * 0]; 2858c81f8b0SPeter Munch const CeedScalar ug2 = ug[i + Q * 2 + Q * 3 * 0]; 2868c81f8b0SPeter Munch vg[i + Q * 0 + Q * 3 * 0] = 2878c81f8b0SPeter Munch qdata[i + Q * 0] * ug0 + qdata[i + Q * 5] * ug1 + qdata[i + Q * 4] * ug2; 2888c81f8b0SPeter Munch vg[i + Q * 1 + Q * 3 * 0] = 2898c81f8b0SPeter Munch qdata[i + Q * 5] * ug0 + qdata[i + Q * 1] * ug1 + qdata[i + Q * 3] * ug2; 2908c81f8b0SPeter Munch vg[i + Q * 2 + Q * 3 * 0] = 2918c81f8b0SPeter Munch qdata[i + Q * 4] * ug0 + qdata[i + Q * 3] * ug1 + qdata[i + Q * 2] * ug2; 2928c81f8b0SPeter Munch } 2938c81f8b0SPeter Munch { 2948c81f8b0SPeter Munch const CeedScalar ug0 = ug[i + Q * 0 + Q * 3 * 1]; 2958c81f8b0SPeter Munch const CeedScalar ug1 = ug[i + Q * 1 + Q * 3 * 1]; 2968c81f8b0SPeter Munch const CeedScalar ug2 = ug[i + Q * 2 + Q * 3 * 1]; 2978c81f8b0SPeter Munch vg[i + Q * 0 + Q * 3 * 1] = 2988c81f8b0SPeter Munch qdata[i + Q * 0] * ug0 + qdata[i + Q * 5] * ug1 + qdata[i + Q * 4] * ug2; 2998c81f8b0SPeter Munch vg[i + Q * 1 + Q * 3 * 1] = 3008c81f8b0SPeter Munch qdata[i + Q * 5] * ug0 + qdata[i + Q * 1] * ug1 + qdata[i + Q * 3] * ug2; 3018c81f8b0SPeter Munch vg[i + Q * 2 + Q * 3 * 1] = 3028c81f8b0SPeter Munch qdata[i + Q * 4] * ug0 + qdata[i + Q * 3] * ug1 + qdata[i + Q * 2] * ug2; 3038c81f8b0SPeter Munch } 3048c81f8b0SPeter Munch { 3058c81f8b0SPeter Munch const CeedScalar ug0 = ug[i + Q * 0 + Q * 3 * 2]; 3068c81f8b0SPeter Munch const CeedScalar ug1 = ug[i + Q * 1 + Q * 3 * 2]; 3078c81f8b0SPeter Munch const CeedScalar ug2 = ug[i + Q * 2 + Q * 3 * 2]; 3088c81f8b0SPeter Munch vg[i + Q * 0 + Q * 3 * 2] = 3098c81f8b0SPeter Munch qdata[i + Q * 0] * ug0 + qdata[i + Q * 5] * ug1 + qdata[i + Q * 4] * ug2; 3108c81f8b0SPeter Munch vg[i + Q * 1 + Q * 3 * 2] = 3118c81f8b0SPeter Munch qdata[i + Q * 5] * ug0 + qdata[i + Q * 1] * ug1 + qdata[i + Q * 3] * ug2; 3128c81f8b0SPeter Munch vg[i + Q * 2 + Q * 3 * 2] = 3138c81f8b0SPeter Munch qdata[i + Q * 4] * ug0 + qdata[i + Q * 3] * ug1 + qdata[i + Q * 2] * ug2; 3148c81f8b0SPeter Munch } 3158c81f8b0SPeter Munch } 3168c81f8b0SPeter Munch break; 3178c81f8b0SPeter Munch } 3188c81f8b0SPeter Munch return 0; 3198c81f8b0SPeter Munch } 320