1#[cfg(feature = "serde")]
4use crate::traits::ConvertToSerializable;
5use crate::traits::Topology;
6use itertools::izip;
7use ndelement::{orientation::compute_orientation, reference_cell, types::ReferenceCellType};
8use rlst::{DynArray, rlst_dynamic_array};
9use std::collections::HashMap;
10use std::iter::Copied;
11
12#[derive(Debug)]
14pub struct SingleTypeTopology {
15 dim: usize,
16 pub(crate) ids: Vec<Option<Vec<usize>>>,
17 pub(crate) ids_to_indices: Vec<HashMap<usize, usize>>,
18 entity_types: Vec<ReferenceCellType>,
19 entity_counts: Vec<usize>,
20 pub(crate) downward_connectivity: Vec<Vec<DynArray<usize, 2>>>,
21 pub(crate) upward_connectivity: Vec<Vec<Vec<Vec<usize>>>>,
22 pub(crate) orientation: Vec<Vec<i32>>,
23}
24
25#[cfg(feature = "serde")]
26#[derive(serde::Serialize, Debug, serde::Deserialize)]
27pub struct SerializableTopology {
29 dim: usize,
30 ids: Vec<Option<Vec<usize>>>,
31 ids_to_indices: Vec<HashMap<usize, usize>>,
32 entity_types: Vec<ReferenceCellType>,
33 entity_counts: Vec<usize>,
34 downward_connectivity: Vec<Vec<(Vec<usize>, [usize; 2])>>,
35 upward_connectivity: Vec<Vec<Vec<Vec<usize>>>>,
36 orientation: Vec<Vec<i32>>,
37}
38
39#[cfg(feature = "serde")]
40impl ConvertToSerializable for SingleTypeTopology {
41 type SerializableType = SerializableTopology;
42 fn to_serializable(&self) -> SerializableTopology {
43 SerializableTopology {
44 dim: self.dim,
45 ids: self.ids.clone(),
46 ids_to_indices: self.ids_to_indices.clone(),
47 entity_types: self.entity_types.clone(),
48 entity_counts: self.entity_counts.clone(),
49 downward_connectivity: self
50 .downward_connectivity
51 .iter()
52 .map(|a| {
53 a.iter()
54 .map(|b| (b.data().unwrap().to_vec(), b.shape()))
55 .collect::<Vec<_>>()
56 })
57 .collect::<Vec<_>>(),
58 upward_connectivity: self.upward_connectivity.clone(),
59 orientation: self.orientation.clone(),
60 }
61 }
62 fn from_serializable(s: SerializableTopology) -> Self {
63 Self {
64 dim: s.dim,
65 ids: s.ids,
66 ids_to_indices: s.ids_to_indices,
67 entity_types: s.entity_types,
68 entity_counts: s.entity_counts,
69 downward_connectivity: s
70 .downward_connectivity
71 .iter()
72 .map(|a| {
73 a.iter()
74 .map(|(data, shape)| {
75 let mut c = DynArray::<usize, 2>::from_shape(*shape);
76 c.data_mut().unwrap().copy_from_slice(data);
77 c
78 })
79 .collect::<Vec<_>>()
80 })
81 .collect::<Vec<_>>(),
82 upward_connectivity: s.upward_connectivity,
83 orientation: s.orientation,
84 }
85 }
86}
87
88impl SingleTypeTopology {
89 pub fn new(
91 cells: &[usize],
92 cell_type: ReferenceCellType,
93 vertex_ids: Option<Vec<usize>>,
94 cell_ids: Option<Vec<usize>>,
95 ) -> Self {
96 let size = reference_cell::entity_counts(cell_type)[0];
97 let ncells = cells.len() / size;
98 let dim = reference_cell::dim(cell_type);
99
100 let ref_conn = reference_cell::connectivity(cell_type);
107
108 let etypes = reference_cell::entity_types(cell_type);
112
113 for t in &etypes {
117 for i in t {
118 if *i != t[0] {
119 panic!("Unsupported cell type for SingleTypeTopology: {cell_type:?}");
120 }
121 }
122 }
123
124 let entity_types = etypes
126 .iter()
127 .filter(|i| !i.is_empty())
128 .map(|i| i[0])
129 .collect::<Vec<_>>();
130
131 let mut entities = Vec::<HashMap<Vec<usize>, usize>>::new();
136 if dim > 0 {
137 for _ in 0..dim - 1 {
138 entities.push(HashMap::new());
139 }
140 }
141 let mut entity_counter = vec![0; entities.len()];
144
145 for cell_index in 0..ncells {
147 let cell = &cells[cell_index * size..(cell_index + 1) * size];
149 for (entity_dim, (e_i, rc_i)) in izip!(
155 entities.iter_mut(),
156 ref_conn.iter().take(dim).skip(1),
158 )
159 .enumerate()
160 {
161 for c_ij in rc_i {
165 let mut entity = c_ij[0].iter().map(|i| cell[*i]).collect::<Vec<_>>();
169 entity.sort();
172 e_i.entry(entity).or_insert_with(|| {
174 let old = entity_counter[entity_dim];
175 entity_counter[entity_dim] += 1;
176 old
177 });
178 }
179 }
180 }
181 let mut entity_counts = vec![0; dim + 1];
183 entity_counts[0] = cells.iter().max().unwrap() + 1;
187 entity_counts[dim] = ncells;
188 for d in 1..dim {
189 entity_counts[d] = entities[d - 1].len();
193 }
194
195 let mut downward_connectivity = entity_counts
204 .iter()
205 .enumerate()
206 .map(|(i, j)| {
209 ref_conn[i][0]
213 .iter()
215 .take(i + 1)
219 .map(|r| rlst_dynamic_array!(usize, [r.len(), *j]))
224 .collect::<Vec<_>>()
225 })
226 .collect::<Vec<_>>();
227
228 let mut upward_connectivity = entity_counts
233 .iter()
234 .take(dim)
235 .enumerate()
236 .map(|(i, j)| vec![vec![vec![]; *j]; dim - i])
237 .collect::<Vec<Vec<Vec<Vec<usize>>>>>();
238
239 for (d, dc) in downward_connectivity.iter_mut().enumerate() {
241 for (i, mut j) in dc[d].col_iter_mut().enumerate() {
242 j[[0]] = i;
245 }
246 }
247
248 for (i, mut dc_d0i) in downward_connectivity[dim][0].col_iter_mut().enumerate() {
251 for (dc_d0ij, c_j) in izip!(dc_d0i.iter_mut(), &cells[i * size..(i + 1) * size]) {
252 *dc_d0ij = *c_j;
253 if dim > 0 {
255 upward_connectivity[0][dim - 1][*c_j].push(i);
256 }
257 }
258 }
259
260 for (i, (es_i, dc_i)) in izip!(
262 entities.iter(),
263 downward_connectivity.iter_mut().take(dim).skip(1)
264 )
265 .enumerate()
266 {
267 for es_ij in es_i.iter() {
268 let entity_vertices = es_ij.0;
269 let entity_index = es_ij.1;
270 let mut dc_i0j = dc_i[0].r_mut().slice::<1>(1, *entity_index);
271 for (vertex, dc_i0jk) in izip!(entity_vertices.iter(), dc_i0j.iter_mut()) {
272 *dc_i0jk = *vertex;
273 if !upward_connectivity[0][i][*vertex].contains(entity_index) {
274 upward_connectivity[0][i][*vertex].push(*entity_index);
275 }
276 }
277 }
278 }
279
280 if dim > 0 {
282 let mut cell_entities = ref_conn
287 .iter()
288 .skip(1)
289 .map(|i| vec![0; i.len()])
290 .collect::<Vec<_>>();
291 for cell_index in 0..ncells {
293 cell_entities[dim - 1][0] = cell_index;
297 let cell = &cells[cell_index * size..(cell_index + 1) * size];
299 for (e_i, ce_i, rc_i) in izip!(
303 entities.iter(),
304 cell_entities.iter_mut(),
305 ref_conn.iter().skip(1),
306 ) {
307 for (ce_ij, rc_ij) in izip!(ce_i.iter_mut(), rc_i) {
311 let mut entity = rc_ij[0].iter().map(|i| cell[*i]).collect::<Vec<_>>();
313 entity.sort();
314 *ce_ij = *e_i.get(&entity).unwrap();
315 }
316 }
317 for (i, (dc_i, rc_i, ce_i)) in izip!(
331 downward_connectivity.iter_mut().skip(2),
332 ref_conn.iter().skip(2),
333 cell_entities.iter().skip(1)
334 )
335 .enumerate()
336 {
337 for (ce_ij, rc_ij) in izip!(ce_i, rc_i) {
340 for (k, (dc_ik, rc_ijk, ce_k)) in izip!(
349 dc_i.iter_mut().take(i + 2).skip(1),
350 rc_ij.iter().take(i + 2).skip(1),
351 &cell_entities
352 )
353 .enumerate()
354 {
355 for (l, rc_ijkl) in rc_ijk.iter().enumerate() {
359 dc_ik[[l, *ce_ij]] = ce_k[*rc_ijkl];
360 if !upward_connectivity[k + 1][i - k][ce_k[*rc_ijkl]]
366 .contains(ce_ij)
367 {
368 upward_connectivity[k + 1][i - k][ce_k[*rc_ijkl]].push(*ce_ij);
369 }
370 }
371 }
372 }
373 }
374 }
375 }
376
377 let mut ids = vec![vertex_ids];
378 for _ in 1..dim {
379 ids.push(None);
380 }
381 ids.push(cell_ids);
382
383 let ids_to_indices = ids
384 .iter()
385 .map(|ids_option| {
386 let mut ie = HashMap::new();
387 if let Some(ids) = ids_option {
388 for (i, j) in ids.iter().enumerate() {
389 ie.insert(*j, i);
390 }
391 }
392 ie
393 })
394 .collect::<Vec<_>>();
395
396 let mut orientation = vec![];
397
398 for d in 1..dim + 1 {
399 let dc = &downward_connectivity[d][0];
400 orientation.push(
401 (0..dc.shape()[1])
402 .map(|i| {
403 compute_orientation(
404 entity_types[d],
405 &dc.data().unwrap()[i * dc.shape()[0]..(i + 1) * dc.shape()[0]],
406 )
407 })
408 .collect::<Vec<_>>(),
409 );
410 }
411
412 Self {
413 dim,
414 ids,
415 ids_to_indices,
416 entity_types,
417 entity_counts,
418 downward_connectivity,
419 upward_connectivity,
420 orientation,
421 }
422 }
423 pub fn dim(&self) -> usize {
425 self.dim
426 }
427 pub fn entity_types(&self) -> &[ReferenceCellType] {
429 &self.entity_types
430 }
431 pub fn entity_counts(&self) -> &[usize] {
433 &self.entity_counts
434 }
435 pub fn entity_count(&self, entity_type: ReferenceCellType) -> usize {
437 if !self.entity_types.contains(&entity_type) {
438 0
439 } else {
440 self.entity_counts[reference_cell::dim(entity_type)]
441 }
442 }
443 pub fn downward_connectivity(&self) -> &[Vec<DynArray<usize, 2>>] {
445 &self.downward_connectivity
446 }
447 pub fn upward_connectivity(&self) -> &[Vec<Vec<Vec<usize>>>] {
449 &self.upward_connectivity
450 }
451 pub fn cell_entity_index(
453 &self,
454 cell_index: usize,
455 entity_dim: usize,
456 entity_index: usize,
457 ) -> usize {
458 self.downward_connectivity[self.dim][entity_dim][[entity_index, cell_index]]
459 }
460 pub fn entity_id(&self, entity_dim: usize, entity_index: usize) -> Option<usize> {
462 self.ids[entity_dim].as_ref().map(|a| a[entity_index])
463 }
464}
465
466#[derive(Debug)]
468pub struct SingleTypeEntityTopology<'a> {
469 topology: &'a SingleTypeTopology,
470 entity_index: usize,
471 dim: usize,
472}
473
474impl<'t> SingleTypeEntityTopology<'t> {
475 pub fn new(
477 topology: &'t SingleTypeTopology,
478 entity_type: ReferenceCellType,
479 entity_index: usize,
480 ) -> Self {
481 Self {
482 topology,
483 entity_index,
484 dim: reference_cell::dim(entity_type),
485 }
486 }
487}
488impl Topology for SingleTypeEntityTopology<'_> {
489 type EntityDescriptor = ReferenceCellType;
490 type EntityIndexIter<'a>
491 = Copied<std::slice::Iter<'a, usize>>
492 where
493 Self: 'a;
494
495 type ConnectedEntityIndexIter<'a>
496 = Copied<std::slice::Iter<'a, usize>>
497 where
498 Self: 'a;
499
500 fn connected_entity_iter(
501 &self,
502 entity_type: ReferenceCellType,
503 ) -> Copied<std::slice::Iter<'_, usize>> {
504 let dim = reference_cell::dim(entity_type);
505 if entity_type == self.topology.entity_types()[dim] {
506 self.topology.upward_connectivity[self.dim][dim - self.dim - 1][self.entity_index]
507 .iter()
508 .copied()
509 } else {
510 [].iter().copied()
511 }
512 }
513
514 fn sub_entity_iter(
515 &self,
516 entity_type: ReferenceCellType,
517 ) -> Copied<std::slice::Iter<'_, usize>> {
518 let dim = reference_cell::dim(entity_type);
519 if entity_type == self.topology.entity_types()[dim] {
520 let rows = self.topology.downward_connectivity[self.dim][dim].shape()[0];
521 self.topology.downward_connectivity[self.dim][dim]
522 .data()
523 .unwrap()[rows * self.entity_index..rows * (self.entity_index + 1)]
524 .iter()
525 .copied()
526 } else {
527 [].iter().copied()
528 }
529 }
530
531 fn sub_entity(&self, entity_type: ReferenceCellType, index: usize) -> usize {
532 let dim = reference_cell::dim(entity_type);
533 if entity_type != self.topology.entity_types()[dim] {
534 panic!("Invalid entity type");
535 }
536 self.topology.downward_connectivity[self.dim][dim][[index, self.entity_index]]
537 }
538
539 fn orientation(&self) -> i32 {
540 if self.dim == 0 {
541 0
542 } else {
543 self.topology.orientation[self.dim - 1][self.entity_index]
544 }
545 }
546}
547
548#[cfg(test)]
549mod test {
550 use super::*;
551
552 fn example_topology_point() -> SingleTypeTopology {
553 SingleTypeTopology::new(&[0, 1], ReferenceCellType::Point, None, None)
555 }
556
557 fn example_topology_interval() -> SingleTypeTopology {
558 SingleTypeTopology::new(&[0, 1, 1, 2], ReferenceCellType::Interval, None, None)
560 }
561
562 fn example_topology_triangle() -> SingleTypeTopology {
563 SingleTypeTopology::new(&[0, 1, 2, 2, 1, 3], ReferenceCellType::Triangle, None, None)
565 }
566
567 fn example_topology_tetrahedron() -> SingleTypeTopology {
568 SingleTypeTopology::new(
570 &[0, 1, 2, 3, 4, 0, 2, 3],
571 ReferenceCellType::Tetrahedron,
572 None,
573 None,
574 )
575 }
576
577 #[test]
578 #[should_panic]
579 fn test_prism() {
580 let _ = SingleTypeTopology::new(&[0, 1, 2, 3, 4, 5], ReferenceCellType::Prism, None, None);
581 }
582 #[test]
583 #[should_panic]
584 fn test_pyramid() {
585 let _ = SingleTypeTopology::new(&[0, 1, 2, 3, 4], ReferenceCellType::Pyramid, None, None);
586 }
587
588 #[test]
589 fn test_sub_entities_point() {
590 let t = example_topology_point();
592 let cell0 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 0);
593 assert_eq!(cell0.sub_entity(ReferenceCellType::Point, 0), 0);
594 let cell1 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 1);
595 assert_eq!(cell1.sub_entity(ReferenceCellType::Point, 0), 1);
596 }
597
598 #[test]
599 fn test_sub_entities_interval() {
600 let t = example_topology_interval();
602 let cell0 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 0);
603 assert_eq!(cell0.sub_entity(ReferenceCellType::Point, 0), 0);
604 assert_eq!(cell0.sub_entity(ReferenceCellType::Point, 1), 1);
605 assert_eq!(cell0.sub_entity(ReferenceCellType::Interval, 0), 0);
606 let cell1 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 1);
607 assert_eq!(cell1.sub_entity(ReferenceCellType::Point, 0), 1);
608 assert_eq!(cell1.sub_entity(ReferenceCellType::Point, 1), 2);
609 assert_eq!(cell1.sub_entity(ReferenceCellType::Interval, 0), 1);
610
611 let vertex0 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 0);
612 assert_eq!(vertex0.sub_entity(ReferenceCellType::Point, 0), 0);
613 let vertex1 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 1);
614 assert_eq!(vertex1.sub_entity(ReferenceCellType::Point, 0), 1);
615 let vertex2 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 2);
616 assert_eq!(vertex2.sub_entity(ReferenceCellType::Point, 0), 2);
617 }
618
619 #[test]
620 fn test_sub_entities_triangle() {
621 let t = example_topology_triangle();
623 let cell0 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Triangle, 0);
624 assert_eq!(cell0.sub_entity(ReferenceCellType::Point, 0), 0);
625 assert_eq!(cell0.sub_entity(ReferenceCellType::Point, 1), 1);
626 assert_eq!(cell0.sub_entity(ReferenceCellType::Point, 2), 2);
627 assert_eq!(cell0.sub_entity(ReferenceCellType::Interval, 0), 0);
628 assert_eq!(cell0.sub_entity(ReferenceCellType::Interval, 1), 1);
629 assert_eq!(cell0.sub_entity(ReferenceCellType::Interval, 2), 2);
630 assert_eq!(cell0.sub_entity(ReferenceCellType::Triangle, 0), 0);
631 let cell1 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Triangle, 1);
632 assert_eq!(cell1.sub_entity(ReferenceCellType::Point, 0), 2);
633 assert_eq!(cell1.sub_entity(ReferenceCellType::Point, 1), 1);
634 assert_eq!(cell1.sub_entity(ReferenceCellType::Point, 2), 3);
635 assert_eq!(cell1.sub_entity(ReferenceCellType::Interval, 0), 3);
636 assert_eq!(cell1.sub_entity(ReferenceCellType::Interval, 1), 4);
637 assert_eq!(cell1.sub_entity(ReferenceCellType::Interval, 2), 0);
638 assert_eq!(cell1.sub_entity(ReferenceCellType::Triangle, 0), 1);
639
640 let edge0 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 0);
641 assert_eq!(edge0.sub_entity(ReferenceCellType::Point, 0), 1);
642 assert_eq!(edge0.sub_entity(ReferenceCellType::Point, 1), 2);
643 assert_eq!(edge0.sub_entity(ReferenceCellType::Interval, 0), 0);
644 let edge1 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 1);
645 assert_eq!(edge1.sub_entity(ReferenceCellType::Point, 0), 0);
646 assert_eq!(edge1.sub_entity(ReferenceCellType::Point, 1), 2);
647 assert_eq!(edge1.sub_entity(ReferenceCellType::Interval, 0), 1);
648 let edge2 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 2);
649 assert_eq!(edge2.sub_entity(ReferenceCellType::Point, 0), 0);
650 assert_eq!(edge2.sub_entity(ReferenceCellType::Point, 1), 1);
651 assert_eq!(edge2.sub_entity(ReferenceCellType::Interval, 0), 2);
652 let edge3 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 3);
653 assert_eq!(edge3.sub_entity(ReferenceCellType::Point, 0), 1);
654 assert_eq!(edge3.sub_entity(ReferenceCellType::Point, 1), 3);
655 assert_eq!(edge3.sub_entity(ReferenceCellType::Interval, 0), 3);
656 let edge4 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 4);
657 assert_eq!(edge4.sub_entity(ReferenceCellType::Point, 0), 2);
658 assert_eq!(edge4.sub_entity(ReferenceCellType::Point, 1), 3);
659 assert_eq!(edge4.sub_entity(ReferenceCellType::Interval, 0), 4);
660
661 let vertex0 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 0);
662 assert_eq!(vertex0.sub_entity(ReferenceCellType::Point, 0), 0);
663 let vertex1 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 1);
664 assert_eq!(vertex1.sub_entity(ReferenceCellType::Point, 0), 1);
665 let vertex2 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 2);
666 assert_eq!(vertex2.sub_entity(ReferenceCellType::Point, 0), 2);
667 let vertex3 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 3);
668 assert_eq!(vertex3.sub_entity(ReferenceCellType::Point, 0), 3);
669 }
670
671 #[test]
672 fn test_sub_entities_tetrahedron() {
673 let t = example_topology_tetrahedron();
675 let cell0 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Tetrahedron, 0);
676 assert_eq!(cell0.sub_entity(ReferenceCellType::Point, 0), 0);
677 assert_eq!(cell0.sub_entity(ReferenceCellType::Point, 1), 1);
678 assert_eq!(cell0.sub_entity(ReferenceCellType::Point, 2), 2);
679 assert_eq!(cell0.sub_entity(ReferenceCellType::Point, 3), 3);
680 assert_eq!(cell0.sub_entity(ReferenceCellType::Interval, 0), 0);
681 assert_eq!(cell0.sub_entity(ReferenceCellType::Interval, 1), 1);
682 assert_eq!(cell0.sub_entity(ReferenceCellType::Interval, 2), 2);
683 assert_eq!(cell0.sub_entity(ReferenceCellType::Interval, 3), 3);
684 assert_eq!(cell0.sub_entity(ReferenceCellType::Interval, 4), 4);
685 assert_eq!(cell0.sub_entity(ReferenceCellType::Interval, 5), 5);
686 assert_eq!(cell0.sub_entity(ReferenceCellType::Triangle, 0), 0);
687 assert_eq!(cell0.sub_entity(ReferenceCellType::Triangle, 1), 1);
688 assert_eq!(cell0.sub_entity(ReferenceCellType::Triangle, 2), 2);
689 assert_eq!(cell0.sub_entity(ReferenceCellType::Triangle, 3), 3);
690 assert_eq!(cell0.sub_entity(ReferenceCellType::Tetrahedron, 0), 0);
691 let cell1 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Tetrahedron, 1);
692 assert_eq!(cell1.sub_entity(ReferenceCellType::Point, 0), 4);
693 assert_eq!(cell1.sub_entity(ReferenceCellType::Point, 1), 0);
694 assert_eq!(cell1.sub_entity(ReferenceCellType::Point, 2), 2);
695 assert_eq!(cell1.sub_entity(ReferenceCellType::Point, 3), 3);
696 assert_eq!(cell1.sub_entity(ReferenceCellType::Interval, 0), 0);
697 assert_eq!(cell1.sub_entity(ReferenceCellType::Interval, 1), 3);
698 assert_eq!(cell1.sub_entity(ReferenceCellType::Interval, 2), 4);
699 assert_eq!(cell1.sub_entity(ReferenceCellType::Interval, 3), 6);
700 assert_eq!(cell1.sub_entity(ReferenceCellType::Interval, 4), 7);
701 assert_eq!(cell1.sub_entity(ReferenceCellType::Interval, 5), 8);
702 assert_eq!(cell1.sub_entity(ReferenceCellType::Triangle, 0), 1);
703 assert_eq!(cell1.sub_entity(ReferenceCellType::Triangle, 1), 4);
704 assert_eq!(cell1.sub_entity(ReferenceCellType::Triangle, 2), 5);
705 assert_eq!(cell1.sub_entity(ReferenceCellType::Triangle, 3), 6);
706 assert_eq!(cell1.sub_entity(ReferenceCellType::Tetrahedron, 0), 1);
707
708 let face0 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Triangle, 0);
709 assert_eq!(face0.sub_entity(ReferenceCellType::Point, 0), 1);
710 assert_eq!(face0.sub_entity(ReferenceCellType::Point, 1), 2);
711 assert_eq!(face0.sub_entity(ReferenceCellType::Point, 2), 3);
712 assert_eq!(face0.sub_entity(ReferenceCellType::Interval, 0), 0);
713 assert_eq!(face0.sub_entity(ReferenceCellType::Interval, 1), 1);
714 assert_eq!(face0.sub_entity(ReferenceCellType::Interval, 2), 2);
715 assert_eq!(face0.sub_entity(ReferenceCellType::Triangle, 0), 0);
716 let face1 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Triangle, 1);
717 assert_eq!(face1.sub_entity(ReferenceCellType::Point, 0), 0);
718 assert_eq!(face1.sub_entity(ReferenceCellType::Point, 1), 2);
719 assert_eq!(face1.sub_entity(ReferenceCellType::Point, 2), 3);
720 assert_eq!(face1.sub_entity(ReferenceCellType::Interval, 0), 0);
721 assert_eq!(face1.sub_entity(ReferenceCellType::Interval, 1), 3);
722 assert_eq!(face1.sub_entity(ReferenceCellType::Interval, 2), 4);
723 assert_eq!(face1.sub_entity(ReferenceCellType::Triangle, 0), 1);
724 let face2 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Triangle, 2);
725 assert_eq!(face2.sub_entity(ReferenceCellType::Point, 0), 0);
726 assert_eq!(face2.sub_entity(ReferenceCellType::Point, 1), 1);
727 assert_eq!(face2.sub_entity(ReferenceCellType::Point, 2), 3);
728 assert_eq!(face2.sub_entity(ReferenceCellType::Interval, 0), 1);
729 assert_eq!(face2.sub_entity(ReferenceCellType::Interval, 1), 3);
730 assert_eq!(face2.sub_entity(ReferenceCellType::Interval, 2), 5);
731 assert_eq!(face2.sub_entity(ReferenceCellType::Triangle, 0), 2);
732 let face3 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Triangle, 3);
733 assert_eq!(face3.sub_entity(ReferenceCellType::Point, 0), 0);
734 assert_eq!(face3.sub_entity(ReferenceCellType::Point, 1), 1);
735 assert_eq!(face3.sub_entity(ReferenceCellType::Point, 2), 2);
736 assert_eq!(face3.sub_entity(ReferenceCellType::Interval, 0), 2);
737 assert_eq!(face3.sub_entity(ReferenceCellType::Interval, 1), 4);
738 assert_eq!(face3.sub_entity(ReferenceCellType::Interval, 2), 5);
739 assert_eq!(face3.sub_entity(ReferenceCellType::Triangle, 0), 3);
740 let face4 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Triangle, 4);
741 assert_eq!(face4.sub_entity(ReferenceCellType::Point, 0), 2);
742 assert_eq!(face4.sub_entity(ReferenceCellType::Point, 1), 3);
743 assert_eq!(face4.sub_entity(ReferenceCellType::Point, 2), 4);
744 assert_eq!(face4.sub_entity(ReferenceCellType::Interval, 0), 0);
745 assert_eq!(face4.sub_entity(ReferenceCellType::Interval, 1), 6);
746 assert_eq!(face4.sub_entity(ReferenceCellType::Interval, 2), 7);
747 assert_eq!(face4.sub_entity(ReferenceCellType::Triangle, 0), 4);
748 let face5 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Triangle, 5);
749 assert_eq!(face5.sub_entity(ReferenceCellType::Point, 0), 0);
750 assert_eq!(face5.sub_entity(ReferenceCellType::Point, 1), 3);
751 assert_eq!(face5.sub_entity(ReferenceCellType::Point, 2), 4);
752 assert_eq!(face5.sub_entity(ReferenceCellType::Interval, 0), 3);
753 assert_eq!(face5.sub_entity(ReferenceCellType::Interval, 1), 6);
754 assert_eq!(face5.sub_entity(ReferenceCellType::Interval, 2), 8);
755 assert_eq!(face5.sub_entity(ReferenceCellType::Triangle, 0), 5);
756 let face6 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Triangle, 6);
757 assert_eq!(face6.sub_entity(ReferenceCellType::Point, 0), 0);
758 assert_eq!(face6.sub_entity(ReferenceCellType::Point, 1), 2);
759 assert_eq!(face6.sub_entity(ReferenceCellType::Point, 2), 4);
760 assert_eq!(face6.sub_entity(ReferenceCellType::Interval, 0), 4);
761 assert_eq!(face6.sub_entity(ReferenceCellType::Interval, 1), 7);
762 assert_eq!(face6.sub_entity(ReferenceCellType::Interval, 2), 8);
763 assert_eq!(face6.sub_entity(ReferenceCellType::Triangle, 0), 6);
764
765 let edge0 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 0);
766 assert_eq!(edge0.sub_entity(ReferenceCellType::Point, 0), 2);
767 assert_eq!(edge0.sub_entity(ReferenceCellType::Point, 1), 3);
768 assert_eq!(edge0.sub_entity(ReferenceCellType::Interval, 0), 0);
769 let edge1 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 1);
770 assert_eq!(edge1.sub_entity(ReferenceCellType::Point, 0), 1);
771 assert_eq!(edge1.sub_entity(ReferenceCellType::Point, 1), 3);
772 assert_eq!(edge1.sub_entity(ReferenceCellType::Interval, 0), 1);
773 let edge2 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 2);
774 assert_eq!(edge2.sub_entity(ReferenceCellType::Point, 0), 1);
775 assert_eq!(edge2.sub_entity(ReferenceCellType::Point, 1), 2);
776 assert_eq!(edge2.sub_entity(ReferenceCellType::Interval, 0), 2);
777 let edge3 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 3);
778 assert_eq!(edge3.sub_entity(ReferenceCellType::Point, 0), 0);
779 assert_eq!(edge3.sub_entity(ReferenceCellType::Point, 1), 3);
780 assert_eq!(edge3.sub_entity(ReferenceCellType::Interval, 0), 3);
781 let edge4 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 4);
782 assert_eq!(edge4.sub_entity(ReferenceCellType::Point, 0), 0);
783 assert_eq!(edge4.sub_entity(ReferenceCellType::Point, 1), 2);
784 assert_eq!(edge4.sub_entity(ReferenceCellType::Interval, 0), 4);
785 let edge5 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 5);
786 assert_eq!(edge5.sub_entity(ReferenceCellType::Point, 0), 0);
787 assert_eq!(edge5.sub_entity(ReferenceCellType::Point, 1), 1);
788 assert_eq!(edge5.sub_entity(ReferenceCellType::Interval, 0), 5);
789 let edge6 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 6);
790 assert_eq!(edge6.sub_entity(ReferenceCellType::Point, 0), 3);
791 assert_eq!(edge6.sub_entity(ReferenceCellType::Point, 1), 4);
792 assert_eq!(edge6.sub_entity(ReferenceCellType::Interval, 0), 6);
793 let edge7 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 7);
794 assert_eq!(edge7.sub_entity(ReferenceCellType::Point, 0), 2);
795 assert_eq!(edge7.sub_entity(ReferenceCellType::Point, 1), 4);
796 assert_eq!(edge7.sub_entity(ReferenceCellType::Interval, 0), 7);
797 let edge8 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Interval, 8);
798 assert_eq!(edge8.sub_entity(ReferenceCellType::Point, 0), 0);
799 assert_eq!(edge8.sub_entity(ReferenceCellType::Point, 1), 4);
800 assert_eq!(edge8.sub_entity(ReferenceCellType::Interval, 0), 8);
801
802 let vertex0 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 0);
803 assert_eq!(vertex0.sub_entity(ReferenceCellType::Point, 0), 0);
804 let vertex1 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 1);
805 assert_eq!(vertex1.sub_entity(ReferenceCellType::Point, 0), 1);
806 let vertex2 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 2);
807 assert_eq!(vertex2.sub_entity(ReferenceCellType::Point, 0), 2);
808 let vertex3 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 3);
809 assert_eq!(vertex3.sub_entity(ReferenceCellType::Point, 0), 3);
810 let vertex4 = SingleTypeEntityTopology::new(&t, ReferenceCellType::Point, 4);
811 assert_eq!(vertex4.sub_entity(ReferenceCellType::Point, 0), 4);
812 }
813
814 macro_rules! make_tests {
815 ($cellname:ident) => {
816 paste::item! {
817 #[test]
818 fn [< test_up_and_down_ $cellname >]() {
819 let t = [< example_topology_ $cellname >]();
821
822 for (i, dc_i) in t.downward_connectivity.iter().enumerate() {
823 for (j, dc_ij) in dc_i.iter().enumerate() {
824 if i != j {
825 let uc_ji = &t.upward_connectivity[j][i - j - 1];
826 for (c, col) in dc_ij.col_iter().enumerate() {
827 for value in col.iter_ref() {
828 assert!(uc_ji[*value].contains(&c));
829 }
830 }
831 for (k, uc_jik) in uc_ji.iter().enumerate() {
832 for value in uc_jik {
833 assert!(dc_ij.r().slice::<1>(1, *value).iter_ref()
834 .position(|&i| i == k).is_some());
835 }
836 }
837 }
838 }
839 }
840 }
841 #[test]
842 fn [< test_sub_entity_iter_ $cellname >]() {
843 let t = [< example_topology_ $cellname >]();
845 for cell_type in t.entity_types() {
846 for index in 0..t.entity_count(*cell_type) {
847 let cell = SingleTypeEntityTopology::new(&t, *cell_type, index);
848 for dim in 0..reference_cell::dim(*cell_type) + 1 {
849 let sub_entity_type = t.entity_types()[dim];
850 for (i, j) in cell.sub_entity_iter(sub_entity_type).enumerate() {
851 assert_eq!(j, cell.sub_entity(sub_entity_type, i));
852 }
853 }
854 }
855 }
856 }
857 }
858 };
859 }
860
861 make_tests!(point);
862 make_tests!(interval);
863 make_tests!(triangle);
864 make_tests!(tetrahedron);
865
866 #[test]
867 fn test_orientation_triangle() {
868 let t =
869 SingleTypeTopology::new(&[0, 1, 2, 0, 2, 1], ReferenceCellType::Triangle, None, None);
870 assert_ne!(t.orientation[1][0], t.orientation[1][1]);
871 }
872
873 #[test]
874 fn test_orientation_quadrilateral() {
875 let t = SingleTypeTopology::new(
876 &[0, 1, 2, 3, 0, 3, 1, 2],
877 ReferenceCellType::Quadrilateral,
878 None,
879 None,
880 );
881 assert_ne!(t.orientation[1][0], t.orientation[1][1]);
882 }
883}