openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
SF_container.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) NumeriCor GmbH
2 // SPDX-License-Identifier: Apache-2.0
3 
12 #ifndef _SF_CONTAINER_H
13 #define _SF_CONTAINER_H
14 
15 #include <cstring>
16 #include <mpi.h>
17 #include <map>
18 #include <math.h>
19 #include <set>
20 
21 #include "dense_mat.hpp"
22 #include "SF_globals.h"
23 #include "SF_vector.h"
24 #include "SF_linalg_utils.h"
25 #include "hashmap.hpp"
26 
27 // This datatypes will be used in conjunction with mesh data. We might want to
28 // have increased / reduced precision when storing meshes, mesh related numberings, etc.
29 // Therefore, we will use (mesh_int_t,mesh_real_t) for data fields that scale with the mesh size,
30 // to be able to tweak the used datatype later. -Aurel
31 typedef opencarp::local_index_t mesh_int_t;
32 typedef float mesh_real_t;
33 
34 namespace SF {
35 
37 enum elem_t
38 {
39  Tetra = 0,
45  Tri,
46  Line
47 };
48 
50 struct Point {
51  double x;
52  double y;
53  double z;
54 };
55 
56 template<class V>
57 inline Point arr_to_point(V* arr)
58 {
59  return {arr[0], arr[1], arr[2]};
60 }
61 
62 template<class V>
63 inline void point_to_arr(Point & p, V* arr)
64 {
65  arr[0] = p.x, arr[1] = p.y, arr[2] = p.z;
66 }
67 
69 inline Point cross(const Point & a, const Point & b)
70 {
71  Point c = {a.y*b.z - b.y*a.z, b.x*a.z - a.x*b.z, a.x*b.y - a.y*b.x};
72  return c;
73 }
74 
75 inline double inner_prod(const Point & a, const Point & b)
76 {
77  return a.x*b.x + a.y*b.y + a.z*b.z;
78 }
79 
80 inline void outer_prod(const Point & a, const Point & b, const double s, double* buff, const bool add = false)
81 {
82  if(add == false)
83  memset(buff, 0, 9*sizeof(double));
84 
85  buff[0] += a.x*b.x*s, buff[1] += a.x*b.y*s, buff[2] += a.x*b.z*s;
86  buff[3] += a.y*b.x*s, buff[4] += a.y*b.y*s, buff[5] += a.y*b.z*s;
87  buff[6] += a.z*b.x*s, buff[7] += a.z*b.y*s, buff[8] += a.z*b.z*s;
88 }
89 
90 inline void outer_prod(const Point & a, const Point & b, double* buff)
91 {
92  outer_prod(a, b, 1.0, buff);
93 }
94 
96 inline double mag(const Point & vect)
97 {
98  return sqrt(inner_prod(vect, vect));
99 }
100 
101 inline Point normalize(const Point & vect)
102 {
103  double norm = mag(vect);
104  return {vect.x / norm, vect.y / norm, vect.z / norm};
105 }
106 
107 inline Point operator-(const Point & a, const Point & b)
108 {
109  return {a.x - b.x, a.y - b.y, a.z - b.z};
110 }
111 
112 inline Point operator+(const Point & a, const Point & b)
113 {
114  return {a.x + b.x, a.y + b.y, a.z + b.z};
115 }
116 
117 inline Point operator*(const Point & a, const double & s)
118 {
119  return {a.x * s, a.y * s, a.z * s};
120 }
121 
122 inline Point operator*(const double & s, const Point & a)
123 {
124  return {s * a.x, s * a.y, s * a.z};
125 }
126 
127 inline Point operator*(const dmat<double>& A, const Point& b)
128 {
129  return {A[0][0] * b.x + A[0][1] * b.y + A[0][2] * b.z,
130  A[1][0] * b.x + A[1][1] * b.y + A[1][2] * b.z,
131  A[2][0] * b.x + A[2][1] * b.y + A[2][2] * b.z};
132 }
133 
135 inline Point project(const Point & a, const Point & b)
136 {
137  return a * inner_prod(normalize(a), normalize(b));
138 }
139 
140 inline Point orthogonalize(const Point & a, const Point & b)
141 {
142  return a - project(a, b);
143 }
144 
145 
146 inline double distance(const Point & a, const Point & b)
147 {
148  return mag(a - b);
149 }
150 
152 inline elem_t getElemTypeID(char *eletype)
153 {
154  elem_t ret;
155 
156  if ( !strcmp( eletype, "Tt" ) ) {
157  ret = Tetra;
158  } else if ( !strcmp( eletype, "Hx" ) ) {
159  ret = Hexa;
160  } else if ( !strcmp( eletype, "Oc" ) ) {
161  ret = Octa;
162  } else if ( !strcmp( eletype, "Py" ) ) {
163  ret = Pyramid;
164  } else if ( !strcmp( eletype, "Pr" ) ) {
165  ret = Prism;
166  } else if ( !strcmp( eletype, "Qd" ) ) {
167  ret = Quad;
168  } else if ( !strcmp( eletype, "Tr" ) ) {
169  ret = Tri;
170  } else {
171  ret = Line;
172  }
173  return ret;
174 }
175 
176 template<class S, class POINT> inline
177 void array_to_points(const vector<S> & arr, vector<POINT> & pts)
178 {
179  pts.resize(arr.size() / 3);
180  for(size_t i=0; i<pts.size(); i++)
181  pts[i] = {arr[i*3+0], arr[i*3+1], arr[i*3+2]};
182 }
183 
185 typedef enum {
192 
193 // forward declaration of parallel layouts since they are used in mesh.
194 template<class T> class overlapping_layout;
195 template<class T> class non_overlapping_layout;
196 
203 template<class T>
205 {
206  private:
209 
210  public:
213  {}
214 
221  index_mapping(const vector<T> & a, const vector<T> & b)
222  {
223  this->assign(a, b);
224  }
225 
232  inline void assign(const vector<T> & a, const vector<T> & b)
233  {
234  // a 1:1 mapping between old and new indices is required
235  assert( a.size() == b.size() );
236 
237  _fwd.clear();
238  _bwd.clear();
239 
240  for(size_t i=0; i<a.size(); i++)
241  {
242  T aidx = a[i], bidx = b[i];
243  _fwd[aidx] = bidx;
244  _bwd[bidx] = aidx;
245  }
246  }
247 
249  inline T forward_map(T idx) const
250  {
251  typename hashmap::unordered_map<T, T>::const_iterator it = _fwd.find(idx);
252  if(it != _fwd.end())
253  return it->second;
254  else
255  return T(-1);
256  }
257 
259  inline T backward_map(T idx) const
260  {
261  typename hashmap::unordered_map<T, T>::const_iterator it = _bwd.find(idx);
262  if(it != _bwd.end())
263  return it->second;
264  else
265  return T(-1);
266  }
267 
268 
277  inline void forward_map(vector<T> & idx) const
278  {
279  size_t lsize = idx.size();
280  vector<T> perm(lsize);
281  interval(perm, 0, lsize);
282 
283  binary_sort_copy(idx, perm);
284 
285  size_t c = 0;
287 
288  while(c < lsize)
289  {
290  T cc = idx[c];
291  it = _fwd.find(cc);
292 
293  T val = it != _fwd.end() ? it->second : T(-1);
294 
295  while( (c < lsize) && (cc == idx[c]) )
296  {
297  idx[c] = val;
298  c++;
299  }
300  }
301 
302  binary_sort_copy(perm, idx);
303  }
304 
313  inline void backward_map(vector<T> & idx) const
314  {
315  size_t lsize = idx.size();
316  vector<T> perm(lsize);
317  interval(perm, 0, lsize);
318 
319  binary_sort_copy(idx, perm);
320 
321  size_t c = 0;
323 
324  while(c < lsize)
325  {
326  T cc = idx[c];
327  it = _bwd.find(cc);
328 
329  T val = it != _bwd.end() ? *it : T(-1);
330 
331  while( (c < lsize) && (cc == idx[c]) )
332  {
333  idx[c] = val;
334  c++;
335  }
336  }
337 
338  binary_sort_copy(perm, idx);
339  }
340 
342  size_t size() const
343  {
344  return _fwd.size();
345  }
347  bool in_a(const T idx) {
348  return _fwd.count(idx) == 1;
349  }
351  bool in_b(const T idx) {
352  return _bwd.count(idx) == 1;
353  }
354 
356  {
357  return _fwd;
358  }
359 
361  {
362  return _bwd;
363  }
364 
366  {
367  return _fwd;
368  }
369 
371  {
372  return _bwd;
373  }
374 };
375 
379 template<class T, class S>
380 class meshdata
381 {
382 public:
383  size_t g_numelem;
384  size_t l_numelem;
385  size_t g_numpts;
386  size_t l_numpts;
387 
389  MPI_Comm comm;
390 
392  std::string name;
393 
394  // element connectivity : the nodes forming the elements
398 
399  // element data
400  // one value per element
404  // multiple values per element
407 
410 
411  std::map< SF_nbr, vector<T> > nbr;
413 
416 
419  comm(SF_COMM), name("unnamed")
420  {}
421 
430  {
431  if(nbr.count(nbr_type) == 0)
432  nbr[nbr_type] = vector<T>();
433 
434  return nbr[nbr_type];
435  }
436 
449  inline vector<T> & get_numbering(SF_nbr nbr_type)
450  {
451  typename std::map< SF_nbr, vector<T> >::iterator it = nbr.find(nbr_type);
452  assert(it != nbr.end());
453  return it->second;
454  }
467  inline const vector<T> & get_numbering(SF_nbr nbr_type) const
468  {
469  typename std::map< SF_nbr, vector<T> >::const_iterator it = nbr.find(nbr_type);
470  assert(it != nbr.end());
471  return it->second;
472  }
473 
481  inline void localize(SF_nbr nbr_type)
482  {
483  // register numbering
484  vector<T> & nod = this->register_numbering(nbr_type);
485 
487  for(const T & c : this->con) g2l[c] = 0;
488  g2l.sort();
489 
490  // compute numbering
491  nod.resize(g2l.size());
492 
493  size_t widx = 0;
494  for(auto it = g2l.begin(); it != g2l.end(); ++it, widx++) {
495  nod[widx] = it->first;
496  it->second = widx;
497  }
498 
499  global_to_local(g2l, this->con, true);
500  this->l_numpts = nod.size();
501  }
502 
510  inline void globalize(SF_nbr nbr_type)
511  {
512  // register numbering
513  vector<T> & nod = this->get_numbering(nbr_type);
514  for(T & c : con) c = nod[c];
515  }
516 
517 
523  inline void generate_par_layout()
524  {
525  const vector<T> & rnod = this->get_numbering(NBR_REF);
526  const vector<T> & reidx = this->get_numbering(NBR_ELEM_REF);
527 
528  pl.assign(rnod, comm);
529  g_numpts = pl.num_global_idx();
530 
531  epl.assign(reidx, comm);
532  }
533 
537  inline void clear_data()
538  {
539  g_numelem = 0;
540  g_numpts = 0;
541  l_numelem = 0;
542  l_numpts = 0;
543 
544  con.resize(0); con.reallocate();
545  dsp.resize(0); dsp.reallocate();
546  tag.resize(0); tag.reallocate();
547  type.resize(0); type.reallocate();
548 
549  fib.resize(0); fib.reallocate();
550  she.resize(0); she.reallocate();
551  xyz.resize(0); xyz.reallocate();
552 
553  extr_tag.clear();
554  nbr.clear();
555  }
556 
557 
558 };
559 
567 template<class T, class S>
568 inline void nodal_connectivity_graph(const meshdata<T, S> & mesh,
569  vector<T> & n2n_cnt,
570  vector<T> & n2n_con)
571 {
572  vector<T> e2n_cnt, n2e_cnt, n2e_con;
573  const vector<T> & e2n_con = mesh.con;
574 
575  cnt_from_dsp(mesh.dsp, e2n_cnt);
576 
577  transpose_connectivity(e2n_cnt, e2n_con, n2e_cnt, n2e_con);
578  multiply_connectivities(n2e_cnt, n2e_con,
579  e2n_cnt, e2n_con,
580  n2n_cnt, n2n_con);
581 }
582 
592 template<class T, class S>
594 {
595  vector<T> n2n_cnt, n2n_con;
596  nodal_connectivity_graph(mesh, n2n_cnt, n2n_con);
597 
598  int nmax = 0;
599  for(size_t nidx=0; nidx < n2n_cnt.size(); nidx++)
600  if(nmax < n2n_cnt[nidx]) nmax = n2n_cnt[nidx];
601 
602  MPI_Allreduce(MPI_IN_PLACE, &nmax, 1, MPI_INT, MPI_MAX, mesh.comm);
603 
604  return nmax;
605 }
606 
607 template<class T, class S>
608 void get_alg_mask(const meshdata<T,S> & mesh, vector<bool> & alg_mask)
609 {
610  const vector<T> & alg_nod = mesh.pl.algebraic_nodes();
611 
612  alg_mask.assign(mesh.l_numpts, false);
613  for(const T & n : alg_nod) alg_mask[n] = true;
614 }
615 
616 
621 template<class T>
623 {
624  public:
629 
631  inline void resize(size_t size)
632  {
633  scnt.assign(size, T()), rcnt.assign(size, T()), sdsp.assign(size+1, T()), rdsp.assign(size+1, T());
634  }
635 
637  template<class V>
638  inline void scale(V fac)
639  {
640  for(size_t i=0; i<scnt.size(); i++)
641  scnt[i] *= fac, rcnt[i] *= fac;
642 
643  for(size_t i=0; i<sdsp.size(); i++)
644  sdsp[i] *= fac, rdsp[i] *= fac;
645  }
646 
648  inline void transpose()
649  {
650  vector<T> tcnt(scnt), tdsp(sdsp);
651  scnt = rcnt, sdsp = rdsp;
652  rcnt = tcnt, rdsp = tdsp;
653  }
654 
663  template<class V>
664  inline void configure(const vector<V> & dest, MPI_Comm comm)
665  {
666  int size, rank;
667  MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank);
668 
669  this->resize(size);
670 
671  count(dest, scnt);
672  MPI_Alltoall(scnt.data(), sizeof(T), MPI_BYTE, rcnt.data(), sizeof(T), MPI_BYTE, comm);
675  }
685  template<class V>
686  inline void configure(const vector<V> & dest, const vector<T> & cnt, MPI_Comm comm)
687  {
688  int size, rank;
689  MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank);
690 
691  this->resize(size);
692 
693  scnt.zero();
694  for(size_t i=0; i<dest.size(); i++) scnt[dest[i]] += cnt[i];
695 
696  MPI_Alltoall(scnt.data(), sizeof(T), MPI_BYTE, rcnt.data(), sizeof(T), MPI_BYTE, comm);
697 
700  }
710  template<class V>
711  inline void source_ranks(vector<V> & source)
712  {
713  size_t size = rcnt.size();
714  source.resize(sum(rcnt));
715 
716  for(size_t i=0, widx=0; i<size; i++)
717  for(T j=0; j<rcnt[i]; j++, widx++)
718  source[widx] = i;
719  }
720 };
721 
722 template<class T>
723 struct tuple {
724  T v1;
725  T v2;
726 };
727 
728 template<class T, class S>
730 {
731  T v1;
732  S v2;
733 };
734 
735 template<class T>
736 struct triple {
737  T v1;
738  T v2;
739  T v3;
740 };
741 
742 template<class T, class S, class V>
743 struct mixed_triple {
744  T v1;
745  S v2;
746  V v3;
747 };
748 
749 template<class T>
750 struct quadruple {
751  T v1;
752  T v2;
753  T v3;
754  T v4;
755 };
756 
757 template<class T>
758 bool operator<(const struct tuple<T> & lhs, const struct tuple<T> & rhs)
759 {
760  if(lhs.v1 != rhs.v1)
761  return lhs.v1 < rhs.v1;
762  else
763  return lhs.v2 < rhs.v2;
764 }
765 template<class T, class S>
766 bool operator<(const struct mixed_tuple<T, S> & lhs, const struct mixed_tuple<T, S> & rhs)
767 {
768  if(lhs.v1 != rhs.v1)
769  return lhs.v1 < rhs.v1;
770  else
771  return lhs.v2 < rhs.v2;
772 }
773 
774 template<class T>
775 bool operator<(const struct triple<T> & lhs, const struct triple<T> & rhs)
776 {
777  if(lhs.v1 != rhs.v1)
778  return lhs.v1 < rhs.v1;
779  else if(lhs.v2 != rhs.v2)
780  return lhs.v2 < rhs.v2;
781  else
782  return lhs.v3 < rhs.v3;
783 }
784 
785 template<class T>
786 bool operator<(const struct quadruple<T> & lhs, const struct quadruple<T> & rhs)
787 {
788  if(lhs.v1 != rhs.v1)
789  return lhs.v1 < rhs.v1;
790  else if(lhs.v2 != rhs.v2)
791  return lhs.v2 < rhs.v2;
792  else if(lhs.v3 != rhs.v3)
793  return lhs.v3 < rhs.v3;
794  else
795  return lhs.v4 < rhs.v4;
796 }
797 
798 // expand hashing for custom triple struct
799 
800 }
801 
802 namespace hashmap {
803 
804 template<typename T>
805 struct hash_ops< SF::tuple<T> >
806 {
807  static inline
809  return a.v1 == b.v1 && a.v2 == b.v2;
810  }
811 
812  static inline
817  return h;
818  }
819 };
820 
821 template<typename T>
822 struct hash_ops< SF::triple<T> >
823 {
824  static inline
826  return a.v1 == b.v1 && a.v2 == b.v2 && a.v3 == b.v3;
827  }
828 
829  static inline
831  hm_uint h = mkhash_init;
835  return h;
836  }
837 };
838 
839 template<typename T>
840 struct hash_ops< SF::quadruple<T> >
841 {
842  static inline
844  return a.v1 == b.v1 && a.v2 == b.v2 && a.v3 == b.v3 && a.v4 == b.v4;
845  }
846 
847  static inline
849  hm_uint h = mkhash_init;
854  return h;
855  }
856 };
857 }
858 
859 template<class T>
860 struct tri_sele {
861  T v1;
862  T v2;
863  T v3;
864  T eidx;
865 };
866 
867 template<class T>
868 struct quad_sele {
869  T v1;
870  T v2;
871  T v3;
872  T v4;
873  T eidx;
874 };
875 
877 template<class T>
878 void sort_triple(const T in1, const T in2, const T in3, T & out1, T & out2, T & out3)
879 {
880  bool t12 = in1 < in2;
881  bool t13 = in1 < in3;
882  bool t23 = in2 < in3;
883 
884  if(t12) {
885  //(123),(312),(132)
886  if(t23) {
887  //123
888  out1=in1; out2=in2; out3=in3;
889  }
890  else {
891  //(312),(132)
892  if(t13) {
893  //132
894  out1=in1; out2=in3; out3=in2;
895  }
896  else {
897  //312
898  out1=in3; out2=in1; out3=in2;
899  }
900  }
901  }
902  else {
903  //(213),(231),(321)
904  if(t23) {
905  //(213),(231)
906  if(t13) {
907  //213
908  out1=in2; out2=in1; out3=in3;
909  }
910  else {
911  //231
912  out1=in2; out2=in3; out3=in1;
913  }
914  }
915  else {
916  //321
917  out1=in3; out2=in2; out3=in1;
918  }
919  }
920 }
921 
922 #endif
opencarp::local_index_t mesh_int_t
Definition: SF_container.h:31
void sort_triple(const T in1, const T in2, const T in3, T &out1, T &out2, T &out3)
sort the "in" triple into the "out" triple
Definition: SF_container.h:878
float mesh_real_t
Definition: SF_container.h:32
#define SF_COMM
the default SlimFem MPI communicator
Definition: SF_globals.h:13
Sequential linear algebra kernels.
The vector class and related algorithms.
Definition: mesher.cc:230
The class holds the communication graph for a MPI_Exchange() call.
Definition: SF_container.h:623
vector< T > rcnt
Number of elements received from each rank.
Definition: SF_container.h:627
vector< T > scnt
Number of elements sent to each rank.
Definition: SF_container.h:625
void resize(size_t size)
Resize all vectors to size.
Definition: SF_container.h:631
void configure(const vector< V > &dest, MPI_Comm comm)
Set up the communication graph.
Definition: SF_container.h:664
void configure(const vector< V > &dest, const vector< T > &cnt, MPI_Comm comm)
Set up the communication graph.
Definition: SF_container.h:686
vector< T > sdsp
Displacements w.r.t. scnt.
Definition: SF_container.h:626
vector< T > rdsp
Displacements w.r.t. rcnt.
Definition: SF_container.h:628
void source_ranks(vector< V > &source)
For every received data element, get the rank indices it was receive from.
Definition: SF_container.h:711
void transpose()
transpose comm graph (receive becomes send, and vice versa)
Definition: SF_container.h:648
void scale(V fac)
scale comm graph layout data
Definition: SF_container.h:638
Index mapping class. This is a bijective mapping.
Definition: SF_container.h:205
void assign(const vector< T > &a, const vector< T > &b)
Set up the index mapping between a and b.
Definition: SF_container.h:232
const hashmap::unordered_map< T, T > & get_fwd_map() const
Definition: SF_container.h:355
void backward_map(vector< T > &idx) const
Map a whole array of indices in b to indices in a.
Definition: SF_container.h:313
hashmap::unordered_map< T, T > & get_bwd_map()
Definition: SF_container.h:370
index_mapping(const vector< T > &a, const vector< T > &b)
Constructor that uses assign() to set up the index mapping.
Definition: SF_container.h:221
size_t size() const
number of entries in bijective map
Definition: SF_container.h:342
void forward_map(vector< T > &idx) const
Map a whole array of indices in a to indices in b.
Definition: SF_container.h:277
hashmap::unordered_map< T, T > & get_fwd_map()
Definition: SF_container.h:365
const hashmap::unordered_map< T, T > & get_bwd_map() const
Definition: SF_container.h:360
T forward_map(T idx) const
Map one index from a to b.
Definition: SF_container.h:249
bool in_a(const T idx)
return whether idx is in set A
Definition: SF_container.h:347
bool in_b(const T idx)
return whether idx is in set B
Definition: SF_container.h:351
T backward_map(T idx) const
Map one index from b to a.
Definition: SF_container.h:259
index_mapping()
empty constructor.
Definition: SF_container.h:212
The mesh storage class. It contains both element and vertex data.
Definition: SF_container.h:381
void globalize(SF_nbr nbr_type)
Localize the connectivity data w.r.t. a given numbering.
Definition: SF_container.h:510
void clear_data()
Clear the mesh data from memory.
Definition: SF_container.h:537
overlapping_layout< T > pl
nodal parallel layout
Definition: SF_container.h:414
size_t g_numpts
global number of points
Definition: SF_container.h:385
meshdata()
construct empty mesh
Definition: SF_container.h:418
vector< T > dsp
connectivity starting index of each element
Definition: SF_container.h:401
vector< S > she
sheet direction
Definition: SF_container.h:406
vector< S > fib
fiber direction
Definition: SF_container.h:405
size_t l_numelem
local number of elements
Definition: SF_container.h:384
vector< elem_t > type
element type
Definition: SF_container.h:403
std::map< SF_nbr, vector< T > > nbr
container for different numberings
Definition: SF_container.h:411
std::string name
the mesh name
Definition: SF_container.h:392
void generate_par_layout()
Set up the parallel layout.
Definition: SF_container.h:523
vector< T > & register_numbering(SF_nbr nbr_type)
Register a new numbering to the mesh and return the associated index vector.
Definition: SF_container.h:429
vector< T > con
Definition: SF_container.h:397
vector< S > xyz
node cooridnates
Definition: SF_container.h:412
const vector< T > & get_numbering(SF_nbr nbr_type) const
Get the vector defining a certain numbering.
Definition: SF_container.h:467
size_t l_numpts
local number of points
Definition: SF_container.h:386
size_t g_numelem
global number of elements
Definition: SF_container.h:383
void localize(SF_nbr nbr_type)
Localize the connectivity data w.r.t. a given numbering.
Definition: SF_container.h:481
MPI_Comm comm
the parallel mesh is defined on a MPI world
Definition: SF_container.h:389
vector< T > & get_numbering(SF_nbr nbr_type)
Get the vector defining a certain numbering.
Definition: SF_container.h:449
vector< T > tag
element tag
Definition: SF_container.h:402
hashmap::unordered_set< int > extr_tag
the element tags based on which the mesh has been extracted
Definition: SF_container.h:409
non_overlapping_layout< T > epl
element parallel layout
Definition: SF_container.h:415
The parallel layout of non overlapping indices.
The overlapping_layout class contains the algorithms related to managing overlapping parallel index s...
void assign(const vector< T > &idx, MPI_Comm comm)
Initialization function.
size_t size() const
The current size of the vector.
Definition: SF_vector.h:89
void resize(size_t n)
Resize a vector.
Definition: SF_vector.h:194
void assign(InputIterator s, InputIterator e)
Assign a memory range.
Definition: SF_vector.h:146
void reallocate()
Definition: SF_vector.h:242
iterator find(const K &key)
Search for key. Return iterator.
Definition: hashmap.hpp:626
hm_int count(const K &key) const
Check if key exists.
Definition: hashmap.hpp:612
void sort(Compare comp=Compare())
Sort data entries.
Definition: hashmap.hpp:692
size_t size() const
Definition: hashmap.hpp:720
Dense matrix class and associated funcs.
Classes similar to unordered_set and unordered_map, but with better performance.
unsigned long int hm_uint
Definition: hashmap.hpp:28
Definition: dense_mat.hpp:19
double mag(const Point &vect)
vector magnitude
Definition: SF_container.h:96
void cnt_from_dsp(const vector< T > &dsp, vector< T > &cnt)
Compute counts from displacements.
Definition: SF_vector.h:304
Point arr_to_point(V *arr)
Definition: SF_container.h:57
void dsp_from_cnt(const vector< T > &cnt, vector< T > &dsp)
Compute displacements from counts.
Definition: SF_vector.h:295
void transpose_connectivity(const vector< T > &a_cnt, const vector< T > &a_con, vector< T > &b_cnt, vector< T > &b_con)
Transpose CRS matrix graph A into B.
bool operator<(const struct tuple< T > &lhs, const struct tuple< T > &rhs)
Definition: SF_container.h:758
dmat< S > operator-(const dmat< S > &a, const dmat< S > &b)
Definition: dense_mat.hpp:406
void interval(vector< T > &vec, size_t start, size_t end)
Create an integer interval between start and end.
Definition: SF_vector.h:335
void get_alg_mask(const meshdata< T, S > &mesh, vector< bool > &alg_mask)
Definition: SF_container.h:608
double inner_prod(const Point &a, const Point &b)
Definition: SF_container.h:75
void binary_sort_copy(vector< T > &_V, vector< S > &_W)
Definition: SF_sort.h:286
T sum(const vector< T > &vec)
Compute sum of a vector's entries.
Definition: SF_vector.h:325
void count(const vector< T > &data, vector< S > &cnt)
Count number of occurrences of indices.
Definition: SF_vector.h:317
void point_to_arr(Point &p, V *arr)
Definition: SF_container.h:63
Point project(const Point &a, const Point &b)
project b onto a
Definition: SF_container.h:135
void outer_prod(const Point &a, const Point &b, const double s, double *buff, const bool add=false)
Definition: SF_container.h:80
void multiply_connectivities(const vector< T > &a_cnt, const vector< T > &a_con, const vector< T > &b_cnt, const vector< T > &b_con, vector< T > &c_cnt, vector< T > &c_con)
int max_nodal_edgecount(const meshdata< T, S > &mesh)
Compute the maximum number of node-to-node edges for a mesh.
Definition: SF_container.h:593
dmat< S > operator*(const dmat< S > &a, const dmat< S > &b)
Definition: dense_mat.hpp:358
Point normalize(const Point &vect)
Definition: SF_container.h:101
void array_to_points(const vector< S > &arr, vector< POINT > &pts)
Definition: SF_container.h:177
Point orthogonalize(const Point &a, const Point &b)
Definition: SF_container.h:140
void global_to_local(const vector< T > &glob, vector< T > &data, bool sortedData, bool doWarn)
Definition: SF_sort.h:530
elem_t getElemTypeID(char *eletype)
Generate element type enum from string.
Definition: SF_container.h:152
double distance(const Point &a, const Point &b)
Definition: SF_container.h:146
dmat< S > operator+(const dmat< S > &a, const dmat< S > &b)
Definition: dense_mat.hpp:398
Point cross(const Point &a, const Point &b)
cross product
Definition: SF_container.h:69
elem_t
element type enum
Definition: SF_container.h:38
@ Line
Definition: SF_container.h:46
@ Tri
Definition: SF_container.h:45
@ Prism
Definition: SF_container.h:43
@ Pyramid
Definition: SF_container.h:42
@ Tetra
Definition: SF_container.h:39
@ Quad
Definition: SF_container.h:44
@ Octa
Definition: SF_container.h:41
@ Hexa
Definition: SF_container.h:40
void nodal_connectivity_graph(const meshdata< T, S > &mesh, vector< T > &n2n_cnt, vector< T > &n2n_con)
Compute the node-to-node connectivity.
Definition: SF_container.h:568
SF_nbr
Enumeration encoding the different supported numberings.
Definition: SF_container.h:185
@ NBR_PETSC
PETSc numbering of nodes.
Definition: SF_container.h:188
@ NBR_ELEM_REF
The element numbering of the reference mesh (the one stored on HD).
Definition: SF_container.h:189
@ NBR_REF
The nodal numbering of the reference mesh (the one stored on HD).
Definition: SF_container.h:186
@ NBR_SUBMESH
Submesh nodal numbering: The globally ascending sorted reference indices are reindexed.
Definition: SF_container.h:187
@ NBR_ELEM_SUBMESH
Submesh element numbering: The globally ascending sorted reference indices are reindexed.
Definition: SF_container.h:190
const hm_uint mkhash_init
Definition: hashmap.hpp:42
hm_uint mkhash(hm_uint a, hm_uint b)
Definition: hashmap.hpp:37
Point and vector struct.
Definition: SF_container.h:50
double y
Definition: SF_container.h:52
double z
Definition: SF_container.h:53
double x
Definition: SF_container.h:51
static hm_uint hash(SF::quadruple< T > a)
Definition: SF_container.h:848
static bool cmp(SF::quadruple< T > a, SF::quadruple< T > b)
Definition: SF_container.h:843
static bool cmp(SF::triple< T > a, SF::triple< T > b)
Definition: SF_container.h:825
static hm_uint hash(SF::triple< T > a)
Definition: SF_container.h:830
static hm_uint hash(SF::tuple< T > a)
Definition: SF_container.h:813
static bool cmp(SF::tuple< T > a, SF::tuple< T > b)
Definition: SF_container.h:808
Base hashing class.
Definition: hashmap.hpp:73