1#![allow(missing_docs)]
3#![allow(clippy::missing_safety_doc)]
4
5pub mod reference_cell {
6 use crate::{orientation, reference_cell, types::ReferenceCellType};
7 use rlst::RlstScalar;
8 use std::slice::from_raw_parts;
9
10 #[unsafe(no_mangle)]
11 pub unsafe extern "C" fn dim(cell: ReferenceCellType) -> usize {
12 reference_cell::dim(cell)
13 }
14 #[unsafe(no_mangle)]
15 pub unsafe extern "C" fn is_simplex(cell: ReferenceCellType) -> bool {
16 reference_cell::is_simplex(cell)
17 }
18 unsafe fn vertices<T: RlstScalar>(cell: ReferenceCellType, vs: *mut T) {
19 let mut i = 0;
20 for v in reference_cell::vertices::<T>(cell) {
21 for c in v {
22 unsafe {
23 *vs.add(i) = c;
24 }
25 i += 1;
26 }
27 }
28 }
29 #[unsafe(no_mangle)]
30 pub unsafe extern "C" fn vertices_f32(cell: ReferenceCellType, vs: *mut f32) {
31 unsafe {
32 vertices(cell, vs);
33 }
34 }
35 #[unsafe(no_mangle)]
36 pub unsafe extern "C" fn vertices_f64(cell: ReferenceCellType, vs: *mut f64) {
37 unsafe {
38 vertices(cell, vs);
39 }
40 }
41 unsafe fn midpoint<T: RlstScalar>(cell: ReferenceCellType, pt: *mut T) {
42 for (i, c) in reference_cell::midpoint(cell).iter().enumerate() {
43 unsafe {
44 *pt.add(i) = *c;
45 }
46 }
47 }
48 #[unsafe(no_mangle)]
49 pub unsafe extern "C" fn midpoint_f32(cell: ReferenceCellType, pt: *mut f32) {
50 unsafe {
51 midpoint(cell, pt);
52 }
53 }
54 #[unsafe(no_mangle)]
55 pub unsafe extern "C" fn midpoint_f64(cell: ReferenceCellType, pt: *mut f64) {
56 unsafe {
57 midpoint(cell, pt);
58 }
59 }
60 #[unsafe(no_mangle)]
61 pub unsafe extern "C" fn edges(cell: ReferenceCellType, es: *mut usize) {
62 let mut i = 0;
63 for e in reference_cell::edges(cell) {
64 for v in e {
65 unsafe {
66 *es.add(i) = v;
67 }
68 i += 1
69 }
70 }
71 }
72 #[unsafe(no_mangle)]
73 pub unsafe extern "C" fn faces(cell: ReferenceCellType, es: *mut usize) {
74 let mut i = 0;
75 for e in reference_cell::faces(cell) {
76 for v in e {
77 unsafe {
78 *es.add(i) = v;
79 }
80 i += 1
81 }
82 }
83 }
84 #[unsafe(no_mangle)]
85 pub unsafe extern "C" fn volumes(cell: ReferenceCellType, es: *mut usize) {
86 let mut i = 0;
87 for e in reference_cell::volumes(cell) {
88 for v in e {
89 unsafe {
90 *es.add(i) = v;
91 }
92 i += 1
93 }
94 }
95 }
96 #[unsafe(no_mangle)]
97 pub unsafe extern "C" fn entity_types(cell: ReferenceCellType, et: *mut u8) {
98 let mut i = 0;
99 for es in reference_cell::entity_types(cell) {
100 for e in es {
101 unsafe {
102 *et.add(i) = e as u8;
103 }
104 i += 1
105 }
106 }
107 }
108 #[unsafe(no_mangle)]
109 pub unsafe extern "C" fn entity_counts(cell: ReferenceCellType, ec: *mut usize) {
110 for (i, e) in reference_cell::entity_counts(cell).iter().enumerate() {
111 unsafe {
112 *ec.add(i) = *e;
113 }
114 }
115 }
116 #[unsafe(no_mangle)]
117 pub unsafe extern "C" fn connectivity_size(
118 cell: ReferenceCellType,
119 dim0: usize,
120 index0: usize,
121 dim1: usize,
122 ) -> usize {
123 reference_cell::connectivity(cell)[dim0][index0][dim1].len()
124 }
125 #[unsafe(no_mangle)]
126 pub unsafe extern "C" fn connectivity(
127 cell: ReferenceCellType,
128 dim0: usize,
129 index0: usize,
130 dim1: usize,
131 c: *mut usize,
132 ) {
133 for (i, j) in reference_cell::connectivity(cell)[dim0][index0][dim1]
134 .iter()
135 .enumerate()
136 {
137 unsafe {
138 *c.add(i) = *j;
139 }
140 }
141 }
142 #[unsafe(no_mangle)]
143 pub unsafe extern "C" fn compute_orientation(
144 cell: ReferenceCellType,
145 vertices: *const usize,
146 ) -> i32 {
147 let vertices = unsafe { from_raw_parts(vertices, reference_cell::entity_counts(cell)[0]) };
148 orientation::compute_orientation(cell, vertices)
149 }
150}
151
152pub mod quadrature {
153 use crate::{quadrature, types::ReferenceCellType};
154
155 #[unsafe(no_mangle)]
156 pub unsafe extern "C" fn gauss_jacobi_quadrature_npoints(
157 cell: ReferenceCellType,
158 m: usize,
159 ) -> usize {
160 quadrature::gauss_jacobi_npoints(cell, m)
161 }
162 #[unsafe(no_mangle)]
163 pub unsafe extern "C" fn make_gauss_jacobi_quadrature(
164 cell: ReferenceCellType,
165 m: usize,
166 pts: *mut f64,
167 wts: *mut f64,
168 ) {
169 let rule = quadrature::gauss_jacobi_rule(cell, m).unwrap();
170 for (i, p) in rule.points.iter().enumerate() {
171 unsafe {
172 *pts.add(i) = *p;
173 }
174 }
175 for (i, w) in rule.weights.iter().enumerate() {
176 unsafe {
177 *wts.add(i) = *w;
178 }
179 }
180 }
181}
182
183pub mod polynomials {
184 use crate::{polynomials, reference_cell, types::ReferenceCellType};
185 use rlst::{RlstScalar, SliceArray, SliceArrayMut};
186 use std::slice::{from_raw_parts, from_raw_parts_mut};
187
188 #[unsafe(no_mangle)]
189 pub unsafe extern "C" fn legendre_polynomials_shape(
190 cell: ReferenceCellType,
191 npts: usize,
192 degree: usize,
193 derivatives: usize,
194 shape: *mut usize,
195 ) {
196 unsafe {
197 *shape.add(0) = polynomials::derivative_count(cell, derivatives);
198 *shape.add(1) = polynomials::polynomial_count(cell, degree);
199 *shape.add(2) = npts;
200 }
201 }
202 unsafe fn tabulate_legendre_polynomials<T: RlstScalar, TGeo: RlstScalar>(
203 cell: ReferenceCellType,
204 points: *const TGeo,
205 npts: usize,
206 degree: usize,
207 derivatives: usize,
208 data: *mut T,
209 ) {
210 let tdim = reference_cell::dim(cell);
211 let points = SliceArray::<TGeo, 2>::from_shape(
212 unsafe { from_raw_parts(points, npts * tdim) },
213 [tdim, npts],
214 );
215 let npoly = polynomials::polynomial_count(cell, degree);
216 let nderiv = polynomials::derivative_count(cell, derivatives);
217 let mut data = SliceArrayMut::<T, 3>::from_shape(
218 unsafe { from_raw_parts_mut(data, npts * npoly * nderiv) },
219 [nderiv, npoly, npts],
220 );
221 polynomials::tabulate_legendre_polynomials(cell, &points, degree, derivatives, &mut data);
222 }
223 #[unsafe(no_mangle)]
224 pub unsafe extern "C" fn tabulate_legendre_polynomials_f32(
225 cell: ReferenceCellType,
226 points: *const f32,
227 npts: usize,
228 degree: usize,
229 derivatives: usize,
230 data: *mut f32,
231 ) {
232 unsafe {
233 tabulate_legendre_polynomials(cell, points, npts, degree, derivatives, data);
234 }
235 }
236 #[unsafe(no_mangle)]
237 pub unsafe extern "C" fn tabulate_legendre_polynomials_f64(
238 cell: ReferenceCellType,
239 points: *const f64,
240 npts: usize,
241 degree: usize,
242 derivatives: usize,
243 data: *mut f64,
244 ) {
245 unsafe {
246 tabulate_legendre_polynomials(cell, points, npts, degree, derivatives, data);
247 }
248 }
249}
250
251pub mod ciarlet {
252 use crate::{
253 ciarlet,
254 ciarlet::CiarletElement,
255 map::{ContravariantPiolaMap, CovariantPiolaMap, IdentityMap},
256 reference_cell,
257 traits::{ElementFamily, FiniteElement, Map, MappedFiniteElement},
258 types::{Continuity, ReferenceCellType},
259 };
260 use c_api_tools::{DType, DTypeIdentifier, cfuncs, concretise_types};
261 use rlst::dense::linalg::lapack::interface::{getrf::Getrf, getri::Getri};
262 use rlst::{RlstScalar, SliceArray, SliceArrayMut, c32, c64};
263 use std::ffi::c_void;
264 use std::slice::{from_raw_parts, from_raw_parts_mut};
265
266 #[derive(Debug, PartialEq, Clone, Copy)]
267 #[repr(u8)]
268 pub enum ElementType {
269 Lagrange = 0,
270 RaviartThomas = 1,
271 NedelecFirstKind = 2,
272 }
273
274 #[cfuncs(name = "ciarlet_element_t", create, free, unwrap)]
275 pub struct CiarletElementT;
276
277 #[cfuncs(name = "element_family_t", create, free, unwrap)]
278 pub struct ElementFamilyT;
279
280 #[concretise_types(
281 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
282 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
283 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
284 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
285 )]
286 pub fn element_value_size<E: FiniteElement>(element: &E) -> usize {
287 element.value_size()
288 }
289
290 #[unsafe(no_mangle)]
291 pub extern "C" fn create_lagrange_family(
292 degree: usize,
293 continuity: Continuity,
294 dtype: DType,
295 ) -> *mut ElementFamilyT {
296 let family = element_family_t_create();
297 let family_inner = unsafe { element_family_t_unwrap(family).unwrap() };
298
299 *family_inner = match dtype {
300 DType::F32 => Box::new(ciarlet::LagrangeElementFamily::<f32>::new(
301 degree, continuity,
302 )),
303 DType::F64 => Box::new(ciarlet::LagrangeElementFamily::<f64>::new(
304 degree, continuity,
305 )),
306 DType::C32 => Box::new(ciarlet::LagrangeElementFamily::<c32>::new(
307 degree, continuity,
308 )),
309 DType::C64 => Box::new(ciarlet::LagrangeElementFamily::<c64>::new(
310 degree, continuity,
311 )),
312 _ => panic!("Unsupported dtype"),
313 };
314
315 family
316 }
317
318 #[unsafe(no_mangle)]
319 pub extern "C" fn create_raviart_thomas_family(
320 degree: usize,
321 continuity: Continuity,
322 dtype: DType,
323 ) -> *mut ElementFamilyT {
324 let family = element_family_t_create();
325 let family_inner = unsafe { element_family_t_unwrap(family).unwrap() };
326
327 *family_inner = match dtype {
328 DType::F32 => Box::new(ciarlet::RaviartThomasElementFamily::<f32>::new(
329 degree, continuity,
330 )),
331 DType::F64 => Box::new(ciarlet::RaviartThomasElementFamily::<f64>::new(
332 degree, continuity,
333 )),
334 DType::C32 => Box::new(ciarlet::RaviartThomasElementFamily::<c32>::new(
335 degree, continuity,
336 )),
337 DType::C64 => Box::new(ciarlet::RaviartThomasElementFamily::<c64>::new(
338 degree, continuity,
339 )),
340 _ => panic!("Unsupported dtype"),
341 };
342
343 family
344 }
345
346 #[unsafe(no_mangle)]
347 pub extern "C" fn create_nedelec_family(
348 degree: usize,
349 continuity: Continuity,
350 dtype: DType,
351 ) -> *mut ElementFamilyT {
352 let family = element_family_t_create();
353 let family_inner = unsafe { element_family_t_unwrap(family).unwrap() };
354
355 *family_inner = match dtype {
356 DType::F32 => Box::new(ciarlet::NedelecFirstKindElementFamily::<f32>::new(
357 degree, continuity,
358 )),
359 DType::F64 => Box::new(ciarlet::NedelecFirstKindElementFamily::<f64>::new(
360 degree, continuity,
361 )),
362 DType::C32 => Box::new(ciarlet::NedelecFirstKindElementFamily::<c32>::new(
363 degree, continuity,
364 )),
365 DType::C64 => Box::new(ciarlet::NedelecFirstKindElementFamily::<c64>::new(
366 degree, continuity,
367 )),
368 _ => panic!("Unsupported dtype"),
369 };
370
371 family
372 }
373
374 #[concretise_types(
375 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
376 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
377 field(arg = 0, name = "element_family", wrapper = "ElementFamilyT", replace_with = [
378 "ciarlet::LagrangeElementFamily<{{dtype}}, {{geo_dtype}}>",
379 "ciarlet::RaviartThomasElementFamily<{{dtype}}, {{geo_dtype}}>",
380 "ciarlet::NedelecFirstKindElementFamily<{{dtype}}, {{geo_dtype}}>"
381 ])
382 )]
383 pub fn element_family_create_element<F: ElementFamily<CellType = ReferenceCellType>>(
384 family: &F,
385 cell: ReferenceCellType,
386 ) -> *mut CiarletElementT {
387 let ciarlet_element = ciarlet_element_t_create();
388 let inner = unsafe { ciarlet_element_t_unwrap(ciarlet_element).unwrap() };
389
390 *inner = Box::new(family.element(cell));
391
392 ciarlet_element
393 }
394
395 #[concretise_types(
396 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
397 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
398 field(arg = 0, name = "element_family", wrapper = "ElementFamilyT", replace_with = [
399 "ciarlet::LagrangeElementFamily<{{dtype}}, {{geo_dtype}}>",
400 "ciarlet::RaviartThomasElementFamily<{{dtype}}, {{geo_dtype}}>",
401 "ciarlet::NedelecFirstKindElementFamily<{{dtype}}, {{geo_dtype}}>"
402 ])
403 )]
404 pub fn element_family_dtype<
405 T: RlstScalar + DTypeIdentifier,
406 F: ElementFamily<CellType = ReferenceCellType, T = T>,
407 >(
408 _elem: &F,
409 ) -> DType {
410 <T as DTypeIdentifier>::dtype()
411 }
412
413 #[concretise_types(
414 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
415 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
416 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
417 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
418 )]
419 pub fn ciarlet_element_dtype<T: RlstScalar + DTypeIdentifier, E: FiniteElement<T = T>>(
420 _elem: &E,
421 ) -> DType {
422 <T as DTypeIdentifier>::dtype()
423 }
424
425 #[concretise_types(
426 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
427 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
428 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
429 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
430 )]
431 pub fn ciarlet_element_geo_dtype<
432 T: RlstScalar + DTypeIdentifier,
433 M: Map,
434 TGeo: RlstScalar + DTypeIdentifier,
435 >(
436 _elem: &CiarletElement<T, M, TGeo>,
437 ) -> DType {
438 <TGeo as DTypeIdentifier>::dtype()
439 }
440
441 #[concretise_types(
442 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
443 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
444 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
445 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
446 )]
447 pub fn ciarlet_element_tabulate_array_shape<E: FiniteElement>(
448 element: &E,
449 nderivs: usize,
450 npoints: usize,
451 shape: *mut usize,
452 ) {
453 for (i, j) in element
454 .tabulate_array_shape(nderivs, npoints)
455 .iter()
456 .enumerate()
457 {
458 unsafe {
459 *shape.add(i) = *j;
460 }
461 }
462 }
463
464 pub unsafe fn ciarlet_element_tabulate<
465 E: FiniteElement<CellType = ReferenceCellType>,
466 TGeo: RlstScalar,
467 >(
468 element: &E,
469 points: *const TGeo,
470 npoints: usize,
471 nderivs: usize,
472 data: *mut c_void,
473 ) {
474 let tdim = reference_cell::dim(element.cell_type());
475 let data = data as *mut E::T;
476 let points = SliceArray::<TGeo, 2>::from_shape(
477 unsafe { from_raw_parts(points, npoints * tdim) },
478 [tdim, npoints],
479 );
480 let shape = element.tabulate_array_shape(nderivs, npoints);
481 let mut data = SliceArrayMut::<E::T, 4>::from_shape(
482 unsafe { from_raw_parts_mut(data, shape[0] * shape[1] * shape[2] * shape[3]) },
483 shape,
484 );
485 element.tabulate(&points, nderivs, &mut data);
486 }
487
488 #[concretise_types(
489 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
490 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
491 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
492 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"]),
493 )]
494 pub unsafe fn ciarlet_element_tabulate_f32<E: FiniteElement<CellType = ReferenceCellType>>(
495 element: &E,
496 points: *const f32,
497 npoints: usize,
498 nderivs: usize,
499 data: *mut c_void,
500 ) {
501 unsafe {
502 ciarlet_element_tabulate(element, points, npoints, nderivs, data);
503 }
504 }
505
506 #[concretise_types(
507 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
508 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
509 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
510 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"]),
511 )]
512 pub unsafe fn ciarlet_element_tabulate_f64<E: FiniteElement<CellType = ReferenceCellType>>(
513 element: &E,
514 points: *const f64,
515 npoints: usize,
516 nderivs: usize,
517 data: *mut c_void,
518 ) {
519 unsafe {
520 ciarlet_element_tabulate(element, points, npoints, nderivs, data);
521 }
522 }
523
524 #[concretise_types(
525 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
526 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
527 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
528 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
529 )]
530 pub fn ciarlet_element_value_size<E: FiniteElement>(element: &E) -> usize {
531 element.value_size()
532 }
533
534 #[concretise_types(
535 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
536 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
537 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
538 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
539 )]
540 pub fn ciarlet_element_value_rank<E: FiniteElement>(element: &E) -> usize {
541 element.value_shape().len()
542 }
543
544 #[concretise_types(
545 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
546 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
547 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
548 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
549 )]
550 pub fn ciarlet_element_value_shape<E: FiniteElement>(element: &E, shape: *mut usize) {
551 for (i, j) in element.value_shape().iter().enumerate() {
552 unsafe {
553 *shape.add(i) = *j;
554 }
555 }
556 }
557
558 #[concretise_types(
559 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
560 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
561 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
562 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
563 )]
564 pub fn ciarlet_element_physical_value_size<E: MappedFiniteElement>(
565 element: &E,
566 gdim: usize,
567 ) -> usize {
568 element.physical_value_size(gdim)
569 }
570
571 #[concretise_types(
572 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
573 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
574 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
575 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
576 )]
577 pub fn ciarlet_element_physical_value_rank<E: MappedFiniteElement>(
578 element: &E,
579 gdim: usize,
580 ) -> usize {
581 element.physical_value_shape(gdim).len()
582 }
583
584 #[concretise_types(
585 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
586 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
587 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
588 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
589 )]
590 pub fn ciarlet_element_physical_value_shape<E: MappedFiniteElement>(
591 element: &E,
592 gdim: usize,
593 shape: *mut usize,
594 ) {
595 for (i, j) in element.physical_value_shape(gdim).iter().enumerate() {
596 unsafe {
597 *shape.add(i) = *j;
598 }
599 }
600 }
601
602 #[allow(clippy::too_many_arguments)]
603 pub unsafe fn ciarlet_element_push_forward<
604 E: MappedFiniteElement<CellType = ReferenceCellType>,
605 TGeo: RlstScalar,
606 >(
607 element: &E,
608 npoints: usize,
609 nfunctions: usize,
610 gdim: usize,
611 reference_values: *const TGeo,
612 nderivs: usize,
613 j: *const TGeo,
614 jdet: *const TGeo,
615 jinv: *const TGeo,
616 physical_values: *mut c_void,
617 ) {
618 let tdim = reference_cell::dim(element.cell_type());
619 let deriv_size = element.tabulate_array_shape(nderivs, npoints)[0];
620 let pvs = element.physical_value_size(gdim);
621 let vs = element.value_size();
622 let reference_values = SliceArray::<E::T, 4>::from_shape(
623 unsafe {
624 from_raw_parts(
625 reference_values as *const E::T,
626 deriv_size * npoints * nfunctions * vs,
627 )
628 },
629 [deriv_size, npoints, nfunctions, vs],
630 );
631 let j = SliceArray::<TGeo, 3>::from_shape(
632 unsafe { from_raw_parts(j, npoints * gdim * tdim) },
633 [npoints, gdim, tdim],
634 );
635 let jdet = unsafe { from_raw_parts(jdet, npoints) };
636 let jinv = SliceArray::<TGeo, 3>::from_shape(
637 unsafe { from_raw_parts(jinv, npoints * tdim * gdim) },
638 [npoints, tdim, gdim],
639 );
640 let mut physical_values = SliceArrayMut::<E::T, 4>::from_shape(
641 unsafe {
642 from_raw_parts_mut(
643 physical_values as *mut E::T,
644 deriv_size * npoints * nfunctions * pvs,
645 )
646 },
647 [deriv_size, npoints, nfunctions, pvs],
648 );
649 element.push_forward(
650 &reference_values,
651 nderivs,
652 &j,
653 jdet,
654 &jinv,
655 &mut physical_values,
656 );
657 }
658
659 #[allow(clippy::too_many_arguments)]
660 #[concretise_types(
661 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
662 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
663 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
664 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
665 )]
666 pub unsafe fn ciarlet_element_push_forward_f32<
667 E: MappedFiniteElement<CellType = ReferenceCellType>,
668 >(
669 element: &E,
670 npoints: usize,
671 nfunctions: usize,
672 gdim: usize,
673 reference_values: *const f32,
674 nderivs: usize,
675 j: *const f32,
676 jdet: *const f32,
677 jinv: *const f32,
678 physical_values: *mut c_void,
679 ) {
680 unsafe {
681 ciarlet_element_push_forward(
682 element,
683 npoints,
684 nfunctions,
685 gdim,
686 reference_values,
687 nderivs,
688 j,
689 jdet,
690 jinv,
691 physical_values,
692 );
693 }
694 }
695
696 #[allow(clippy::too_many_arguments)]
697 #[concretise_types(
698 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
699 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
700 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
701 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
702 )]
703 pub unsafe fn ciarlet_element_push_forward_f64<
704 E: MappedFiniteElement<CellType = ReferenceCellType>,
705 >(
706 element: &E,
707 npoints: usize,
708 nfunctions: usize,
709 gdim: usize,
710 reference_values: *const f64,
711 nderivs: usize,
712 j: *const f64,
713 jdet: *const f64,
714 jinv: *const f64,
715 physical_values: *mut c_void,
716 ) {
717 unsafe {
718 ciarlet_element_push_forward(
719 element,
720 npoints,
721 nfunctions,
722 gdim,
723 reference_values,
724 nderivs,
725 j,
726 jdet,
727 jinv,
728 physical_values,
729 );
730 }
731 }
732
733 #[allow(clippy::too_many_arguments)]
734 pub unsafe fn ciarlet_element_pull_back<
735 E: MappedFiniteElement<CellType = ReferenceCellType>,
736 TGeo: RlstScalar,
737 >(
738 element: &E,
739 npoints: usize,
740 nfunctions: usize,
741 gdim: usize,
742 physical_values: *const TGeo,
743 nderivs: usize,
744 j: *const TGeo,
745 jdet: *const TGeo,
746 jinv: *const TGeo,
747 reference_values: *mut c_void,
748 ) {
749 let tdim = reference_cell::dim(element.cell_type());
750 let deriv_size = element.tabulate_array_shape(nderivs, npoints)[0];
751 let pvs = element.physical_value_size(gdim);
752 let vs = element.value_size();
753 let physical_values = SliceArray::<E::T, 4>::from_shape(
754 unsafe {
755 from_raw_parts(
756 physical_values as *const E::T,
757 deriv_size * npoints * nfunctions * pvs,
758 )
759 },
760 [deriv_size, npoints, nfunctions, pvs],
761 );
762 let j = SliceArray::<TGeo, 3>::from_shape(
763 unsafe { from_raw_parts(j, npoints * gdim * tdim) },
764 [npoints, gdim, tdim],
765 );
766 let jdet = unsafe { from_raw_parts(jdet, npoints) };
767 let jinv = SliceArray::<TGeo, 3>::from_shape(
768 unsafe { from_raw_parts(jinv, npoints * tdim * gdim) },
769 [npoints, tdim, gdim],
770 );
771 let mut reference_values = SliceArrayMut::<E::T, 4>::from_shape(
772 unsafe {
773 from_raw_parts_mut(
774 reference_values as *mut E::T,
775 deriv_size * npoints * nfunctions * vs,
776 )
777 },
778 [deriv_size, npoints, nfunctions, vs],
779 );
780 element.pull_back(
781 &physical_values,
782 nderivs,
783 &j,
784 jdet,
785 &jinv,
786 &mut reference_values,
787 );
788 }
789
790 #[allow(clippy::too_many_arguments)]
791 #[concretise_types(
792 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
793 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
794 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
795 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
796 )]
797 pub unsafe fn ciarlet_element_pull_back_f32<
798 E: MappedFiniteElement<CellType = ReferenceCellType>,
799 >(
800 element: &E,
801 npoints: usize,
802 nfunctions: usize,
803 gdim: usize,
804 physical_values: *const f32,
805 nderivs: usize,
806 j: *const f32,
807 jdet: *const f32,
808 jinv: *const f32,
809 reference_values: *mut c_void,
810 ) {
811 unsafe {
812 ciarlet_element_pull_back(
813 element,
814 npoints,
815 nfunctions,
816 gdim,
817 physical_values,
818 nderivs,
819 j,
820 jdet,
821 jinv,
822 reference_values,
823 );
824 }
825 }
826
827 #[allow(clippy::too_many_arguments)]
828 #[concretise_types(
829 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
830 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
831 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
832 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
833 )]
834 pub fn ciarlet_element_pull_back_f64<E: MappedFiniteElement<CellType = ReferenceCellType>>(
835 element: &E,
836 npoints: usize,
837 nfunctions: usize,
838 gdim: usize,
839 physical_values: *const f64,
840 nderivs: usize,
841 j: *const f64,
842 jdet: *const f64,
843 jinv: *const f64,
844 reference_values: *mut c_void,
845 ) {
846 unsafe {
847 ciarlet_element_pull_back(
848 element,
849 npoints,
850 nfunctions,
851 gdim,
852 physical_values,
853 nderivs,
854 j,
855 jdet,
856 jinv,
857 reference_values,
858 );
859 }
860 }
861
862 #[concretise_types(
863 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
864 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
865 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
866 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
867 )]
868 pub fn ciarlet_element_degree<
869 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
870 M: Map,
871 TGeo: RlstScalar + DTypeIdentifier,
872 >(
873 element: &CiarletElement<T, M, TGeo>,
874 ) -> usize {
875 element.degree()
876 }
877
878 #[concretise_types(
879 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
880 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
881 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
882 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
883 )]
884 pub fn ciarlet_element_embedded_superdegree<E: MappedFiniteElement>(element: &E) -> usize {
885 element.lagrange_superdegree()
886 }
887
888 #[concretise_types(
889 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
890 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
891 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
892 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
893 )]
894 pub fn ciarlet_element_dim<E: FiniteElement>(element: &E) -> usize {
895 element.dim()
896 }
897
898 #[concretise_types(
899 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
900 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
901 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
902 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
903 )]
904 pub fn ciarlet_element_continuity<
905 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
906 M: Map,
907 TGeo: RlstScalar + DTypeIdentifier,
908 >(
909 element: &CiarletElement<T, M, TGeo>,
910 ) -> Continuity {
911 element.continuity()
912 }
913
914 #[concretise_types(
915 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
916 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
917 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
918 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
919 )]
920 pub fn ciarlet_element_cell_type<E: FiniteElement<CellType = ReferenceCellType>>(
921 element: &E,
922 ) -> ReferenceCellType {
923 element.cell_type()
924 }
925
926 #[concretise_types(
927 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
928 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
929 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
930 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
931 )]
932 pub fn ciarlet_element_entity_dofs_size<E: FiniteElement>(
933 element: &E,
934 entity_dim: usize,
935 entity_index: usize,
936 ) -> usize {
937 element.entity_dofs(entity_dim, entity_index).unwrap().len()
938 }
939
940 #[concretise_types(
941 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
942 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
943 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
944 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
945 )]
946 pub fn ciarlet_element_entity_dofs<E: FiniteElement>(
947 element: &E,
948 entity_dim: usize,
949 entity_index: usize,
950 entity_dofs: *mut usize,
951 ) {
952 for (i, dof) in element
953 .entity_dofs(entity_dim, entity_index)
954 .unwrap()
955 .iter()
956 .enumerate()
957 {
958 unsafe {
959 *entity_dofs.add(i) = *dof;
960 }
961 }
962 }
963
964 #[concretise_types(
965 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
966 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
967 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
968 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
969 )]
970 pub fn ciarlet_element_entity_closure_dofs_size<
971 T: RlstScalar + DTypeIdentifier,
972 M: Map,
973 TGeo: RlstScalar + DTypeIdentifier,
974 >(
975 element: &CiarletElement<T, M, TGeo>,
976 entity_dim: usize,
977 entity_index: usize,
978 ) -> usize {
979 element
980 .entity_closure_dofs(entity_dim, entity_index)
981 .unwrap()
982 .len()
983 }
984
985 #[concretise_types(
986 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
987 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
988 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
989 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
990 )]
991 pub fn ciarlet_element_entity_closure_dofs<
992 T: RlstScalar + DTypeIdentifier,
993 M: Map,
994 TGeo: RlstScalar + DTypeIdentifier,
995 >(
996 element: &CiarletElement<T, M, TGeo>,
997 entity_dim: usize,
998 entity_index: usize,
999 entity_closure_dofs: *mut usize,
1000 ) {
1001 for (i, dof) in element
1002 .entity_closure_dofs(entity_dim, entity_index)
1003 .unwrap()
1004 .iter()
1005 .enumerate()
1006 {
1007 unsafe {
1008 *entity_closure_dofs.add(i) = *dof;
1009 }
1010 }
1011 }
1012
1013 #[concretise_types(
1014 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1015 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1016 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1017 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1018 )]
1019 pub fn ciarlet_element_interpolation_npoints<
1020 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1021 M: Map,
1022 TGeo: RlstScalar + DTypeIdentifier,
1023 >(
1024 element: &CiarletElement<T, M, TGeo>,
1025 entity_dim: usize,
1026 entity_index: usize,
1027 ) -> usize {
1028 element.interpolation_points()[entity_dim][entity_index].shape()[1]
1029 }
1030
1031 #[concretise_types(
1032 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1033 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1034 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1035 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1036 )]
1037 pub fn ciarlet_element_interpolation_ndofs<
1038 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1039 M: Map,
1040 TGeo: RlstScalar + DTypeIdentifier,
1041 >(
1042 element: &CiarletElement<T, M, TGeo>,
1043 entity_dim: usize,
1044 entity_index: usize,
1045 ) -> usize {
1046 element.interpolation_weights()[entity_dim][entity_index].shape()[0]
1047 }
1048
1049 #[concretise_types(
1050 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1051 gen_type(name = "geo_dtype", replace_with = ["f32", "f64"]),
1052 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1053 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1054 )]
1055 pub fn ciarlet_element_interpolation_points<
1056 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1057 TGeo: RlstScalar + DTypeIdentifier + Getrf + Getri,
1058 M: Map,
1059 >(
1060 element: &CiarletElement<T, M, TGeo>,
1061 entity_dim: usize,
1062 entity_index: usize,
1063 points: *mut c_void,
1064 ) {
1065 let points = points as *mut TGeo;
1066 for (i, j) in element.interpolation_points()[entity_dim][entity_index]
1067 .data()
1068 .unwrap()
1069 .iter()
1070 .enumerate()
1071 {
1072 unsafe {
1073 *points.add(i) = *j;
1074 }
1075 }
1076 }
1077
1078 #[concretise_types(
1079 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1080 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1081 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1082 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1083 )]
1084 pub fn ciarlet_element_interpolation_weights<
1085 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1086 M: Map,
1087 TGeo: RlstScalar + DTypeIdentifier,
1088 >(
1089 element: &CiarletElement<T, M, TGeo>,
1090 entity_dim: usize,
1091 entity_index: usize,
1092 weights: *mut c_void,
1093 ) {
1094 let weights = weights as *mut T;
1095 for (i, j) in element.interpolation_weights()[entity_dim][entity_index]
1096 .data()
1097 .unwrap()
1098 .iter()
1099 .enumerate()
1100 {
1101 unsafe {
1102 *weights.add(i) = *j;
1103 }
1104 }
1105 }
1106
1107 #[concretise_types(
1108 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1109 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1110 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1111 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1112 )]
1113 pub unsafe fn ciarlet_element_apply_dof_permutations_usize<
1114 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1115 M: Map,
1116 TGeo: RlstScalar + DTypeIdentifier,
1117 >(
1118 element: &CiarletElement<T, M, TGeo>,
1119 data: *mut usize,
1120 data_size: usize,
1121 orientation: i32,
1122 ) {
1123 unsafe {
1124 element.apply_dof_permutations(from_raw_parts_mut(data, data_size), orientation);
1125 }
1126 }
1127
1128 #[concretise_types(
1129 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1130 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1131 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1132 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1133 )]
1134 pub unsafe fn ciarlet_element_apply_dof_permutations<
1135 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1136 M: Map,
1137 TGeo: RlstScalar + DTypeIdentifier,
1138 >(
1139 element: &CiarletElement<T, M, TGeo>,
1140 data: *mut c_void,
1141 data_size: usize,
1142 orientation: i32,
1143 ) {
1144 unsafe {
1145 element
1146 .apply_dof_permutations(from_raw_parts_mut(data as *mut T, data_size), orientation);
1147 }
1148 }
1149
1150 #[concretise_types(
1151 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1152 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1153 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1154 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1155 )]
1156 pub unsafe fn ciarlet_element_apply_dof_transformations<
1157 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1158 M: Map,
1159 TGeo: RlstScalar + DTypeIdentifier,
1160 >(
1161 element: &CiarletElement<T, M, TGeo>,
1162 data: *mut c_void,
1163 data_size: usize,
1164 orientation: i32,
1165 ) {
1166 unsafe {
1167 element.apply_dof_transformations(
1168 from_raw_parts_mut(data as *mut T, data_size),
1169 orientation,
1170 );
1171 }
1172 }
1173
1174 #[concretise_types(
1175 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1176 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1177 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1178 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1179 )]
1180 pub unsafe fn ciarlet_element_apply_dof_permutations_and_transformations<
1181 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1182 M: Map,
1183 TGeo: RlstScalar + DTypeIdentifier,
1184 >(
1185 element: &CiarletElement<T, M, TGeo>,
1186 data: *mut c_void,
1187 data_size: usize,
1188 orientation: i32,
1189 ) {
1190 unsafe {
1191 element.apply_dof_permutations_and_transformations(
1192 from_raw_parts_mut(data as *mut T, data_size),
1193 orientation,
1194 );
1195 }
1196 }
1197}