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,
270 RaviartThomas,
271 NedelecFirstKind,
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 variant: ciarlet::lagrange::Variant,
295 dtype: DType,
296 ) -> *mut ElementFamilyT {
297 let family = element_family_t_create();
298 let family_inner = unsafe { element_family_t_unwrap(family).unwrap() };
299
300 *family_inner = match dtype {
301 DType::F32 => Box::new(ciarlet::LagrangeElementFamily::<f32>::new(
302 degree, continuity, variant,
303 )),
304 DType::F64 => Box::new(ciarlet::LagrangeElementFamily::<f64>::new(
305 degree, continuity, variant,
306 )),
307 DType::C32 => Box::new(ciarlet::LagrangeElementFamily::<c32>::new(
308 degree, continuity, variant,
309 )),
310 DType::C64 => Box::new(ciarlet::LagrangeElementFamily::<c64>::new(
311 degree, continuity, variant,
312 )),
313 _ => panic!("Unsupported dtype"),
314 };
315
316 family
317 }
318
319 #[unsafe(no_mangle)]
320 pub extern "C" fn create_raviart_thomas_family(
321 degree: usize,
322 continuity: Continuity,
323 dtype: DType,
324 ) -> *mut ElementFamilyT {
325 let family = element_family_t_create();
326 let family_inner = unsafe { element_family_t_unwrap(family).unwrap() };
327
328 *family_inner = match dtype {
329 DType::F32 => Box::new(ciarlet::RaviartThomasElementFamily::<f32>::new(
330 degree, continuity,
331 )),
332 DType::F64 => Box::new(ciarlet::RaviartThomasElementFamily::<f64>::new(
333 degree, continuity,
334 )),
335 DType::C32 => Box::new(ciarlet::RaviartThomasElementFamily::<c32>::new(
336 degree, continuity,
337 )),
338 DType::C64 => Box::new(ciarlet::RaviartThomasElementFamily::<c64>::new(
339 degree, continuity,
340 )),
341 _ => panic!("Unsupported dtype"),
342 };
343
344 family
345 }
346
347 #[unsafe(no_mangle)]
348 pub extern "C" fn create_nedelec_family(
349 degree: usize,
350 continuity: Continuity,
351 dtype: DType,
352 ) -> *mut ElementFamilyT {
353 let family = element_family_t_create();
354 let family_inner = unsafe { element_family_t_unwrap(family).unwrap() };
355
356 *family_inner = match dtype {
357 DType::F32 => Box::new(ciarlet::NedelecFirstKindElementFamily::<f32>::new(
358 degree, continuity,
359 )),
360 DType::F64 => Box::new(ciarlet::NedelecFirstKindElementFamily::<f64>::new(
361 degree, continuity,
362 )),
363 DType::C32 => Box::new(ciarlet::NedelecFirstKindElementFamily::<c32>::new(
364 degree, continuity,
365 )),
366 DType::C64 => Box::new(ciarlet::NedelecFirstKindElementFamily::<c64>::new(
367 degree, continuity,
368 )),
369 _ => panic!("Unsupported dtype"),
370 };
371
372 family
373 }
374
375 #[concretise_types(
376 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
377 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
378 field(arg = 0, name = "element_family", wrapper = "ElementFamilyT", replace_with = [
379 "ciarlet::LagrangeElementFamily<{{dtype}}, {{geo_dtype}}>",
380 "ciarlet::RaviartThomasElementFamily<{{dtype}}, {{geo_dtype}}>",
381 "ciarlet::NedelecFirstKindElementFamily<{{dtype}}, {{geo_dtype}}>"
382 ])
383 )]
384 pub fn element_family_create_element<F: ElementFamily<CellType = ReferenceCellType>>(
385 family: &F,
386 cell: ReferenceCellType,
387 ) -> *mut CiarletElementT {
388 let ciarlet_element = ciarlet_element_t_create();
389 let inner = unsafe { ciarlet_element_t_unwrap(ciarlet_element).unwrap() };
390
391 *inner = Box::new(family.element(cell));
392
393 ciarlet_element
394 }
395
396 #[concretise_types(
397 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
398 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
399 field(arg = 0, name = "element_family", wrapper = "ElementFamilyT", replace_with = [
400 "ciarlet::LagrangeElementFamily<{{dtype}}, {{geo_dtype}}>",
401 "ciarlet::RaviartThomasElementFamily<{{dtype}}, {{geo_dtype}}>",
402 "ciarlet::NedelecFirstKindElementFamily<{{dtype}}, {{geo_dtype}}>"
403 ])
404 )]
405 pub fn element_family_dtype<
406 T: RlstScalar + DTypeIdentifier,
407 F: ElementFamily<CellType = ReferenceCellType, T = T>,
408 >(
409 _elem: &F,
410 ) -> DType {
411 <T as DTypeIdentifier>::dtype()
412 }
413
414 #[concretise_types(
415 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
416 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
417 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
418 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
419 )]
420 pub fn ciarlet_element_dtype<T: RlstScalar + DTypeIdentifier, E: FiniteElement<T = T>>(
421 _elem: &E,
422 ) -> DType {
423 <T as DTypeIdentifier>::dtype()
424 }
425
426 #[concretise_types(
427 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
428 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
429 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
430 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
431 )]
432 pub fn ciarlet_element_geo_dtype<
433 T: RlstScalar + DTypeIdentifier,
434 M: Map,
435 TGeo: RlstScalar + DTypeIdentifier,
436 >(
437 _elem: &CiarletElement<T, M, TGeo>,
438 ) -> DType {
439 <TGeo as DTypeIdentifier>::dtype()
440 }
441
442 #[concretise_types(
443 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
444 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
445 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
446 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
447 )]
448 pub fn ciarlet_element_tabulate_array_shape<E: FiniteElement>(
449 element: &E,
450 nderivs: usize,
451 npoints: usize,
452 shape: *mut usize,
453 ) {
454 for (i, j) in element
455 .tabulate_array_shape(nderivs, npoints)
456 .iter()
457 .enumerate()
458 {
459 unsafe {
460 *shape.add(i) = *j;
461 }
462 }
463 }
464
465 pub unsafe fn ciarlet_element_tabulate<
466 E: FiniteElement<CellType = ReferenceCellType>,
467 TGeo: RlstScalar,
468 >(
469 element: &E,
470 points: *const TGeo,
471 npoints: usize,
472 nderivs: usize,
473 data: *mut c_void,
474 ) {
475 let tdim = reference_cell::dim(element.cell_type());
476 let data = data as *mut E::T;
477 let points = SliceArray::<TGeo, 2>::from_shape(
478 unsafe { from_raw_parts(points, npoints * tdim) },
479 [tdim, npoints],
480 );
481 let shape = element.tabulate_array_shape(nderivs, npoints);
482 let mut data = SliceArrayMut::<E::T, 4>::from_shape(
483 unsafe { from_raw_parts_mut(data, shape[0] * shape[1] * shape[2] * shape[3]) },
484 shape,
485 );
486 element.tabulate(&points, nderivs, &mut data);
487 }
488
489 #[concretise_types(
490 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
491 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
492 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
493 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"]),
494 )]
495 pub unsafe fn ciarlet_element_tabulate_f32<E: FiniteElement<CellType = ReferenceCellType>>(
496 element: &E,
497 points: *const f32,
498 npoints: usize,
499 nderivs: usize,
500 data: *mut c_void,
501 ) {
502 unsafe {
503 ciarlet_element_tabulate(element, points, npoints, nderivs, data);
504 }
505 }
506
507 #[concretise_types(
508 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
509 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
510 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
511 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"]),
512 )]
513 pub unsafe fn ciarlet_element_tabulate_f64<E: FiniteElement<CellType = ReferenceCellType>>(
514 element: &E,
515 points: *const f64,
516 npoints: usize,
517 nderivs: usize,
518 data: *mut c_void,
519 ) {
520 unsafe {
521 ciarlet_element_tabulate(element, points, npoints, nderivs, data);
522 }
523 }
524
525 #[concretise_types(
526 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
527 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
528 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
529 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
530 )]
531 pub fn ciarlet_element_value_size<E: FiniteElement>(element: &E) -> usize {
532 element.value_size()
533 }
534
535 #[concretise_types(
536 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
537 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
538 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
539 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
540 )]
541 pub fn ciarlet_element_value_rank<E: FiniteElement>(element: &E) -> usize {
542 element.value_shape().len()
543 }
544
545 #[concretise_types(
546 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
547 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
548 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
549 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
550 )]
551 pub fn ciarlet_element_value_shape<E: FiniteElement>(element: &E, shape: *mut usize) {
552 for (i, j) in element.value_shape().iter().enumerate() {
553 unsafe {
554 *shape.add(i) = *j;
555 }
556 }
557 }
558
559 #[concretise_types(
560 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
561 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
562 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
563 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
564 )]
565 pub fn ciarlet_element_physical_value_size<E: MappedFiniteElement>(
566 element: &E,
567 gdim: usize,
568 ) -> usize {
569 element.physical_value_size(gdim)
570 }
571
572 #[concretise_types(
573 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
574 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
575 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
576 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
577 )]
578 pub fn ciarlet_element_physical_value_rank<E: MappedFiniteElement>(
579 element: &E,
580 gdim: usize,
581 ) -> usize {
582 element.physical_value_shape(gdim).len()
583 }
584
585 #[concretise_types(
586 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
587 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
588 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
589 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
590 )]
591 pub fn ciarlet_element_physical_value_shape<E: MappedFiniteElement>(
592 element: &E,
593 gdim: usize,
594 shape: *mut usize,
595 ) {
596 for (i, j) in element.physical_value_shape(gdim).iter().enumerate() {
597 unsafe {
598 *shape.add(i) = *j;
599 }
600 }
601 }
602
603 #[allow(clippy::too_many_arguments)]
604 pub unsafe fn ciarlet_element_push_forward<
605 E: MappedFiniteElement<CellType = ReferenceCellType>,
606 TGeo: RlstScalar,
607 >(
608 element: &E,
609 npoints: usize,
610 nfunctions: usize,
611 gdim: usize,
612 reference_values: *const TGeo,
613 nderivs: usize,
614 j: *const TGeo,
615 jdet: *const TGeo,
616 jinv: *const TGeo,
617 physical_values: *mut c_void,
618 ) {
619 let tdim = reference_cell::dim(element.cell_type());
620 let deriv_size = element.tabulate_array_shape(nderivs, npoints)[0];
621 let pvs = element.physical_value_size(gdim);
622 let vs = element.value_size();
623 let reference_values = SliceArray::<E::T, 4>::from_shape(
624 unsafe {
625 from_raw_parts(
626 reference_values as *const E::T,
627 deriv_size * npoints * nfunctions * vs,
628 )
629 },
630 [deriv_size, npoints, nfunctions, vs],
631 );
632 let j = SliceArray::<TGeo, 3>::from_shape(
633 unsafe { from_raw_parts(j, npoints * gdim * tdim) },
634 [npoints, gdim, tdim],
635 );
636 let jdet = unsafe { from_raw_parts(jdet, npoints) };
637 let jinv = SliceArray::<TGeo, 3>::from_shape(
638 unsafe { from_raw_parts(jinv, npoints * tdim * gdim) },
639 [npoints, tdim, gdim],
640 );
641 let mut physical_values = SliceArrayMut::<E::T, 4>::from_shape(
642 unsafe {
643 from_raw_parts_mut(
644 physical_values as *mut E::T,
645 deriv_size * npoints * nfunctions * pvs,
646 )
647 },
648 [deriv_size, npoints, nfunctions, pvs],
649 );
650 element.push_forward(
651 &reference_values,
652 nderivs,
653 &j,
654 jdet,
655 &jinv,
656 &mut physical_values,
657 );
658 }
659
660 #[allow(clippy::too_many_arguments)]
661 #[concretise_types(
662 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
663 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
664 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
665 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
666 )]
667 pub unsafe fn ciarlet_element_push_forward_f32<
668 E: MappedFiniteElement<CellType = ReferenceCellType>,
669 >(
670 element: &E,
671 npoints: usize,
672 nfunctions: usize,
673 gdim: usize,
674 reference_values: *const f32,
675 nderivs: usize,
676 j: *const f32,
677 jdet: *const f32,
678 jinv: *const f32,
679 physical_values: *mut c_void,
680 ) {
681 unsafe {
682 ciarlet_element_push_forward(
683 element,
684 npoints,
685 nfunctions,
686 gdim,
687 reference_values,
688 nderivs,
689 j,
690 jdet,
691 jinv,
692 physical_values,
693 );
694 }
695 }
696
697 #[allow(clippy::too_many_arguments)]
698 #[concretise_types(
699 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
700 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
701 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
702 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
703 )]
704 pub unsafe fn ciarlet_element_push_forward_f64<
705 E: MappedFiniteElement<CellType = ReferenceCellType>,
706 >(
707 element: &E,
708 npoints: usize,
709 nfunctions: usize,
710 gdim: usize,
711 reference_values: *const f64,
712 nderivs: usize,
713 j: *const f64,
714 jdet: *const f64,
715 jinv: *const f64,
716 physical_values: *mut c_void,
717 ) {
718 unsafe {
719 ciarlet_element_push_forward(
720 element,
721 npoints,
722 nfunctions,
723 gdim,
724 reference_values,
725 nderivs,
726 j,
727 jdet,
728 jinv,
729 physical_values,
730 );
731 }
732 }
733
734 #[allow(clippy::too_many_arguments)]
735 pub unsafe fn ciarlet_element_pull_back<
736 E: MappedFiniteElement<CellType = ReferenceCellType>,
737 TGeo: RlstScalar,
738 >(
739 element: &E,
740 npoints: usize,
741 nfunctions: usize,
742 gdim: usize,
743 physical_values: *const TGeo,
744 nderivs: usize,
745 j: *const TGeo,
746 jdet: *const TGeo,
747 jinv: *const TGeo,
748 reference_values: *mut c_void,
749 ) {
750 let tdim = reference_cell::dim(element.cell_type());
751 let deriv_size = element.tabulate_array_shape(nderivs, npoints)[0];
752 let pvs = element.physical_value_size(gdim);
753 let vs = element.value_size();
754 let physical_values = SliceArray::<E::T, 4>::from_shape(
755 unsafe {
756 from_raw_parts(
757 physical_values as *const E::T,
758 deriv_size * npoints * nfunctions * pvs,
759 )
760 },
761 [deriv_size, npoints, nfunctions, pvs],
762 );
763 let j = SliceArray::<TGeo, 3>::from_shape(
764 unsafe { from_raw_parts(j, npoints * gdim * tdim) },
765 [npoints, gdim, tdim],
766 );
767 let jdet = unsafe { from_raw_parts(jdet, npoints) };
768 let jinv = SliceArray::<TGeo, 3>::from_shape(
769 unsafe { from_raw_parts(jinv, npoints * tdim * gdim) },
770 [npoints, tdim, gdim],
771 );
772 let mut reference_values = SliceArrayMut::<E::T, 4>::from_shape(
773 unsafe {
774 from_raw_parts_mut(
775 reference_values as *mut E::T,
776 deriv_size * npoints * nfunctions * vs,
777 )
778 },
779 [deriv_size, npoints, nfunctions, vs],
780 );
781 element.pull_back(
782 &physical_values,
783 nderivs,
784 &j,
785 jdet,
786 &jinv,
787 &mut reference_values,
788 );
789 }
790
791 #[allow(clippy::too_many_arguments)]
792 #[concretise_types(
793 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
794 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
795 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
796 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
797 )]
798 pub unsafe fn ciarlet_element_pull_back_f32<
799 E: MappedFiniteElement<CellType = ReferenceCellType>,
800 >(
801 element: &E,
802 npoints: usize,
803 nfunctions: usize,
804 gdim: usize,
805 physical_values: *const f32,
806 nderivs: usize,
807 j: *const f32,
808 jdet: *const f32,
809 jinv: *const f32,
810 reference_values: *mut c_void,
811 ) {
812 unsafe {
813 ciarlet_element_pull_back(
814 element,
815 npoints,
816 nfunctions,
817 gdim,
818 physical_values,
819 nderivs,
820 j,
821 jdet,
822 jinv,
823 reference_values,
824 );
825 }
826 }
827
828 #[allow(clippy::too_many_arguments)]
829 #[concretise_types(
830 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
831 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
832 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
833 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
834 )]
835 pub fn ciarlet_element_pull_back_f64<E: MappedFiniteElement<CellType = ReferenceCellType>>(
836 element: &E,
837 npoints: usize,
838 nfunctions: usize,
839 gdim: usize,
840 physical_values: *const f64,
841 nderivs: usize,
842 j: *const f64,
843 jdet: *const f64,
844 jinv: *const f64,
845 reference_values: *mut c_void,
846 ) {
847 unsafe {
848 ciarlet_element_pull_back(
849 element,
850 npoints,
851 nfunctions,
852 gdim,
853 physical_values,
854 nderivs,
855 j,
856 jdet,
857 jinv,
858 reference_values,
859 );
860 }
861 }
862
863 #[concretise_types(
864 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
865 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
866 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
867 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
868 )]
869 pub fn ciarlet_element_degree<
870 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
871 M: Map,
872 TGeo: RlstScalar + DTypeIdentifier,
873 >(
874 element: &CiarletElement<T, M, TGeo>,
875 ) -> usize {
876 element.degree()
877 }
878
879 #[concretise_types(
880 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
881 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
882 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
883 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
884 )]
885 pub fn ciarlet_element_embedded_superdegree<E: MappedFiniteElement>(element: &E) -> usize {
886 element.lagrange_superdegree()
887 }
888
889 #[concretise_types(
890 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
891 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
892 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
893 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
894 )]
895 pub fn ciarlet_element_dim<E: FiniteElement>(element: &E) -> usize {
896 element.dim()
897 }
898
899 #[concretise_types(
900 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
901 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
902 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
903 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
904 )]
905 pub fn ciarlet_element_continuity<
906 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
907 M: Map,
908 TGeo: RlstScalar + DTypeIdentifier,
909 >(
910 element: &CiarletElement<T, M, TGeo>,
911 ) -> Continuity {
912 element.continuity()
913 }
914
915 #[concretise_types(
916 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
917 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
918 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
919 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
920 )]
921 pub fn ciarlet_element_cell_type<E: FiniteElement<CellType = ReferenceCellType>>(
922 element: &E,
923 ) -> ReferenceCellType {
924 element.cell_type()
925 }
926
927 #[concretise_types(
928 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
929 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
930 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
931 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
932 )]
933 pub fn ciarlet_element_entity_dofs_size<E: FiniteElement>(
934 element: &E,
935 entity_dim: usize,
936 entity_index: usize,
937 ) -> usize {
938 element.entity_dofs(entity_dim, entity_index).unwrap().len()
939 }
940
941 #[concretise_types(
942 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
943 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
944 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
945 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
946 )]
947 pub fn ciarlet_element_entity_dofs<E: FiniteElement>(
948 element: &E,
949 entity_dim: usize,
950 entity_index: usize,
951 entity_dofs: *mut usize,
952 ) {
953 for (i, dof) in element
954 .entity_dofs(entity_dim, entity_index)
955 .unwrap()
956 .iter()
957 .enumerate()
958 {
959 unsafe {
960 *entity_dofs.add(i) = *dof;
961 }
962 }
963 }
964
965 #[concretise_types(
966 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
967 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
968 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
969 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
970 )]
971 pub fn ciarlet_element_entity_closure_dofs_size<
972 T: RlstScalar + DTypeIdentifier,
973 M: Map,
974 TGeo: RlstScalar + DTypeIdentifier,
975 >(
976 element: &CiarletElement<T, M, TGeo>,
977 entity_dim: usize,
978 entity_index: usize,
979 ) -> usize {
980 element
981 .entity_closure_dofs(entity_dim, entity_index)
982 .unwrap()
983 .len()
984 }
985
986 #[concretise_types(
987 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
988 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
989 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
990 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
991 )]
992 pub fn ciarlet_element_entity_closure_dofs<
993 T: RlstScalar + DTypeIdentifier,
994 M: Map,
995 TGeo: RlstScalar + DTypeIdentifier,
996 >(
997 element: &CiarletElement<T, M, TGeo>,
998 entity_dim: usize,
999 entity_index: usize,
1000 entity_closure_dofs: *mut usize,
1001 ) {
1002 for (i, dof) in element
1003 .entity_closure_dofs(entity_dim, entity_index)
1004 .unwrap()
1005 .iter()
1006 .enumerate()
1007 {
1008 unsafe {
1009 *entity_closure_dofs.add(i) = *dof;
1010 }
1011 }
1012 }
1013
1014 #[concretise_types(
1015 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1016 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1017 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1018 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1019 )]
1020 pub fn ciarlet_element_interpolation_npoints<
1021 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1022 M: Map,
1023 TGeo: RlstScalar + DTypeIdentifier,
1024 >(
1025 element: &CiarletElement<T, M, TGeo>,
1026 entity_dim: usize,
1027 entity_index: usize,
1028 ) -> usize {
1029 element.interpolation_points()[entity_dim][entity_index].shape()[1]
1030 }
1031
1032 #[concretise_types(
1033 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1034 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1035 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1036 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1037 )]
1038 pub fn ciarlet_element_interpolation_ndofs<
1039 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1040 M: Map,
1041 TGeo: RlstScalar + DTypeIdentifier,
1042 >(
1043 element: &CiarletElement<T, M, TGeo>,
1044 entity_dim: usize,
1045 entity_index: usize,
1046 ) -> usize {
1047 element.interpolation_weights()[entity_dim][entity_index].shape()[0]
1048 }
1049
1050 #[concretise_types(
1051 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1052 gen_type(name = "geo_dtype", replace_with = ["f32", "f64"]),
1053 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1054 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1055 )]
1056 pub fn ciarlet_element_interpolation_points<
1057 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1058 TGeo: RlstScalar + DTypeIdentifier + Getrf + Getri,
1059 M: Map,
1060 >(
1061 element: &CiarletElement<T, M, TGeo>,
1062 entity_dim: usize,
1063 entity_index: usize,
1064 points: *mut c_void,
1065 ) {
1066 let points = points as *mut TGeo;
1067 for (i, j) in element.interpolation_points()[entity_dim][entity_index]
1068 .data()
1069 .unwrap()
1070 .iter()
1071 .enumerate()
1072 {
1073 unsafe {
1074 *points.add(i) = *j;
1075 }
1076 }
1077 }
1078
1079 #[concretise_types(
1080 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1081 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1082 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1083 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1084 )]
1085 pub fn ciarlet_element_interpolation_weights<
1086 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1087 M: Map,
1088 TGeo: RlstScalar + DTypeIdentifier,
1089 >(
1090 element: &CiarletElement<T, M, TGeo>,
1091 entity_dim: usize,
1092 entity_index: usize,
1093 weights: *mut c_void,
1094 ) {
1095 let weights = weights as *mut T;
1096 for (i, j) in element.interpolation_weights()[entity_dim][entity_index]
1097 .data()
1098 .unwrap()
1099 .iter()
1100 .enumerate()
1101 {
1102 unsafe {
1103 *weights.add(i) = *j;
1104 }
1105 }
1106 }
1107
1108 #[concretise_types(
1109 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1110 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1111 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1112 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1113 )]
1114 pub unsafe fn ciarlet_element_apply_dof_permutations_usize<
1115 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1116 M: Map,
1117 TGeo: RlstScalar + DTypeIdentifier,
1118 >(
1119 element: &CiarletElement<T, M, TGeo>,
1120 data: *mut usize,
1121 data_size: usize,
1122 orientation: i32,
1123 ) {
1124 unsafe {
1125 element.apply_dof_permutations(from_raw_parts_mut(data, data_size), orientation);
1126 }
1127 }
1128
1129 #[concretise_types(
1130 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1131 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1132 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1133 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1134 )]
1135 pub unsafe fn ciarlet_element_apply_dof_permutations<
1136 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1137 M: Map,
1138 TGeo: RlstScalar + DTypeIdentifier,
1139 >(
1140 element: &CiarletElement<T, M, TGeo>,
1141 data: *mut c_void,
1142 data_size: usize,
1143 orientation: i32,
1144 ) {
1145 unsafe {
1146 element
1147 .apply_dof_permutations(from_raw_parts_mut(data as *mut T, data_size), orientation);
1148 }
1149 }
1150
1151 #[concretise_types(
1152 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1153 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1154 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1155 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1156 )]
1157 pub unsafe fn ciarlet_element_apply_dof_transformations<
1158 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1159 M: Map,
1160 TGeo: RlstScalar + DTypeIdentifier,
1161 >(
1162 element: &CiarletElement<T, M, TGeo>,
1163 data: *mut c_void,
1164 data_size: usize,
1165 orientation: i32,
1166 ) {
1167 unsafe {
1168 element.apply_dof_transformations(
1169 from_raw_parts_mut(data as *mut T, data_size),
1170 orientation,
1171 );
1172 }
1173 }
1174
1175 #[concretise_types(
1176 gen_type(name = "dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1177 gen_type(name = "geo_dtype", replace_with = ["f32", "f64", "c32", "c64"]),
1178 gen_type(name = "maptype", replace_with = ["IdentityMap", "CovariantPiolaMap", "ContravariantPiolaMap"]),
1179 field(arg = 0, name = "element", wrapper = "CiarletElementT", replace_with = ["CiarletElement<{{dtype}}, {{maptype}}, {{geo_dtype}}>"])
1180 )]
1181 pub unsafe fn ciarlet_element_apply_dof_permutations_and_transformations<
1182 T: RlstScalar + DTypeIdentifier + Getrf + Getri,
1183 M: Map,
1184 TGeo: RlstScalar + DTypeIdentifier,
1185 >(
1186 element: &CiarletElement<T, M, TGeo>,
1187 data: *mut c_void,
1188 data_size: usize,
1189 orientation: i32,
1190 ) {
1191 unsafe {
1192 element.apply_dof_permutations_and_transformations(
1193 from_raw_parts_mut(data as *mut T, data_size),
1194 orientation,
1195 );
1196 }
1197 }
1198}