12 #ifndef _SF_CONTAINER_H
13 #define _SF_CONTAINER_H
59 return {arr[0], arr[1], arr[2]};
65 arr[0] = p.
x, arr[1] = p.
y, arr[2] = p.
z;
77 return a.
x*b.
x + a.
y*b.
y + a.
z*b.
z;
80 inline void outer_prod(
const Point & a,
const Point & b,
const double s,
double* buff,
const bool add =
false)
83 memset(buff, 0, 9*
sizeof(
double));
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;
103 double norm =
mag(vect);
104 return {vect.
x / norm, vect.
y / norm, vect.
z / norm};
109 return {a.
x - b.
x, a.
y - b.
y, a.
z - b.
z};
114 return {a.
x + b.
x, a.
y + b.
y, a.
z + b.
z};
119 return {a.
x * s, a.
y * s, a.
z * s};
124 return {s * a.
x, s * a.
y, s * a.
z};
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};
156 if ( !strcmp( eletype,
"Tt" ) ) {
158 }
else if ( !strcmp( eletype,
"Hx" ) ) {
160 }
else if ( !strcmp( eletype,
"Oc" ) ) {
162 }
else if ( !strcmp( eletype,
"Py" ) ) {
164 }
else if ( !strcmp( eletype,
"Pr" ) ) {
166 }
else if ( !strcmp( eletype,
"Qd" ) ) {
168 }
else if ( !strcmp( eletype,
"Tr" ) ) {
176 template<
class S,
class POINT>
inline
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]};
194 template<
class T>
class overlapping_layout;
195 template<
class T>
class non_overlapping_layout;
240 for(
size_t i=0; i<a.
size(); i++)
242 T aidx = a[i], bidx = b[i];
279 size_t lsize = idx.
size();
293 T val = it != _fwd.
end() ? it->second : T(-1);
295 while( (c < lsize) && (cc == idx[c]) )
315 size_t lsize = idx.
size();
329 T val = it != _bwd.
end() ? *it : T(-1);
331 while( (c < lsize) && (cc == idx[c]) )
348 return _fwd.
count(idx) == 1;
352 return _bwd.
count(idx) == 1;
379 template<
class T,
class S>
411 std::map< SF_nbr, vector<T> >
nbr;
431 if(
nbr.count(nbr_type) == 0)
434 return nbr[nbr_type];
451 typename std::map< SF_nbr, vector<T> >::iterator it =
nbr.find(nbr_type);
452 assert(it !=
nbr.end());
469 typename std::map< SF_nbr, vector<T> >::const_iterator it =
nbr.find(nbr_type);
470 assert(it !=
nbr.end());
487 for(
const T & c : this->con) g2l[c] = 0;
494 for(
auto it = g2l.
begin(); it != g2l.
end(); ++it, widx++) {
495 nod[widx] = it->first;
500 this->l_numpts = nod.
size();
514 for(T & c :
con) c = nod[c];
544 con.resize(0);
con.reallocate();
545 dsp.resize(0);
dsp.reallocate();
546 tag.resize(0);
tag.reallocate();
567 template<
class T,
class S>
592 template<
class T,
class S>
599 for(
size_t nidx=0; nidx < n2n_cnt.
size(); nidx++)
600 if(nmax < n2n_cnt[nidx]) nmax = n2n_cnt[nidx];
602 MPI_Allreduce(MPI_IN_PLACE, &nmax, 1, MPI_INT, MPI_MAX, mesh.
comm);
607 template<
class T,
class S>
610 const vector<T> & alg_nod = mesh.
pl.algebraic_nodes();
613 for(
const T & n : alg_nod) alg_mask[n] =
true;
633 scnt.assign(size, T()),
rcnt.assign(size, T()),
sdsp.assign(size+1, T()),
rdsp.assign(size+1, T());
640 for(
size_t i=0; i<
scnt.size(); i++)
643 for(
size_t i=0; i<
sdsp.size(); i++)
667 MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank);
672 MPI_Alltoall(
scnt.data(),
sizeof(T), MPI_BYTE,
rcnt.data(),
sizeof(T), MPI_BYTE, comm);
689 MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank);
694 for(
size_t i=0; i<dest.
size(); i++)
scnt[dest[i]] += cnt[i];
696 MPI_Alltoall(
scnt.data(),
sizeof(T), MPI_BYTE,
rcnt.data(),
sizeof(T), MPI_BYTE, comm);
713 size_t size =
rcnt.size();
716 for(
size_t i=0, widx=0; i<size; i++)
717 for(T j=0; j<
rcnt[i]; j++, widx++)
728 template<
class T,
class S>
742 template<
class T,
class S,
class V>
761 return lhs.
v1 < rhs.
v1;
763 return lhs.
v2 < rhs.
v2;
765 template<
class T,
class S>
769 return lhs.
v1 < rhs.
v1;
771 return lhs.
v2 < rhs.
v2;
778 return lhs.
v1 < rhs.
v1;
779 else if(lhs.
v2 != rhs.
v2)
780 return lhs.
v2 < rhs.
v2;
782 return lhs.
v3 < rhs.
v3;
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;
795 return lhs.
v4 < rhs.
v4;
809 return a.
v1 == b.
v1 && a.
v2 == b.
v2;
878 void sort_triple(
const T in1,
const T in2,
const T in3, T & out1, T & out2, T & out3)
880 bool t12 = in1 < in2;
881 bool t13 = in1 < in3;
882 bool t23 = in2 < in3;
888 out1=in1; out2=in2; out3=in3;
894 out1=in1; out2=in3; out3=in2;
898 out1=in3; out2=in1; out3=in2;
908 out1=in2; out2=in1; out3=in3;
912 out1=in2; out2=in3; out3=in1;
917 out1=in3; out2=in2; out3=in1;
opencarp::local_index_t mesh_int_t
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
#define SF_COMM
the default SlimFem MPI communicator
Sequential linear algebra kernels.
The vector class and related algorithms.
The class holds the communication graph for a MPI_Exchange() call.
vector< T > rcnt
Number of elements received from each rank.
vector< T > scnt
Number of elements sent to each rank.
void resize(size_t size)
Resize all vectors to size.
void configure(const vector< V > &dest, MPI_Comm comm)
Set up the communication graph.
void configure(const vector< V > &dest, const vector< T > &cnt, MPI_Comm comm)
Set up the communication graph.
vector< T > sdsp
Displacements w.r.t. scnt.
vector< T > rdsp
Displacements w.r.t. rcnt.
void source_ranks(vector< V > &source)
For every received data element, get the rank indices it was receive from.
void transpose()
transpose comm graph (receive becomes send, and vice versa)
void scale(V fac)
scale comm graph layout data
Index mapping class. This is a bijective mapping.
void assign(const vector< T > &a, const vector< T > &b)
Set up the index mapping between a and b.
const hashmap::unordered_map< T, T > & get_fwd_map() const
void backward_map(vector< T > &idx) const
Map a whole array of indices in b to indices in a.
hashmap::unordered_map< T, T > & get_bwd_map()
index_mapping(const vector< T > &a, const vector< T > &b)
Constructor that uses assign() to set up the index mapping.
size_t size() const
number of entries in bijective map
void forward_map(vector< T > &idx) const
Map a whole array of indices in a to indices in b.
hashmap::unordered_map< T, T > & get_fwd_map()
const hashmap::unordered_map< T, T > & get_bwd_map() const
T forward_map(T idx) const
Map one index from a to b.
bool in_a(const T idx)
return whether idx is in set A
bool in_b(const T idx)
return whether idx is in set B
T backward_map(T idx) const
Map one index from b to a.
index_mapping()
empty constructor.
The mesh storage class. It contains both element and vertex data.
void globalize(SF_nbr nbr_type)
Localize the connectivity data w.r.t. a given numbering.
void clear_data()
Clear the mesh data from memory.
overlapping_layout< T > pl
nodal parallel layout
size_t g_numpts
global number of points
meshdata()
construct empty mesh
vector< T > dsp
connectivity starting index of each element
vector< S > she
sheet direction
vector< S > fib
fiber direction
size_t l_numelem
local number of elements
vector< elem_t > type
element type
std::map< SF_nbr, vector< T > > nbr
container for different numberings
std::string name
the mesh name
void generate_par_layout()
Set up the parallel layout.
vector< T > & register_numbering(SF_nbr nbr_type)
Register a new numbering to the mesh and return the associated index vector.
vector< S > xyz
node cooridnates
const vector< T > & get_numbering(SF_nbr nbr_type) const
Get the vector defining a certain numbering.
size_t l_numpts
local number of points
size_t g_numelem
global number of elements
void localize(SF_nbr nbr_type)
Localize the connectivity data w.r.t. a given numbering.
MPI_Comm comm
the parallel mesh is defined on a MPI world
vector< T > & get_numbering(SF_nbr nbr_type)
Get the vector defining a certain numbering.
vector< T > tag
element tag
hashmap::unordered_set< int > extr_tag
the element tags based on which the mesh has been extracted
non_overlapping_layout< T > epl
element parallel layout
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.
void resize(size_t n)
Resize a vector.
void assign(InputIterator s, InputIterator e)
Assign a memory range.
iterator find(const K &key)
Search for key. Return iterator.
hm_int count(const K &key) const
Check if key exists.
void sort(Compare comp=Compare())
Sort data entries.
Dense matrix class and associated funcs.
Classes similar to unordered_set and unordered_map, but with better performance.
unsigned long int hm_uint
double mag(const Point &vect)
vector magnitude
void cnt_from_dsp(const vector< T > &dsp, vector< T > &cnt)
Compute counts from displacements.
Point arr_to_point(V *arr)
void dsp_from_cnt(const vector< T > &cnt, vector< T > &dsp)
Compute displacements from counts.
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)
dmat< S > operator-(const dmat< S > &a, const dmat< S > &b)
void interval(vector< T > &vec, size_t start, size_t end)
Create an integer interval between start and end.
void get_alg_mask(const meshdata< T, S > &mesh, vector< bool > &alg_mask)
double inner_prod(const Point &a, const Point &b)
void binary_sort_copy(vector< T > &_V, vector< S > &_W)
T sum(const vector< T > &vec)
Compute sum of a vector's entries.
void count(const vector< T > &data, vector< S > &cnt)
Count number of occurrences of indices.
void point_to_arr(Point &p, V *arr)
Point project(const Point &a, const Point &b)
project b onto a
void outer_prod(const Point &a, const Point &b, const double s, double *buff, const bool add=false)
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.
dmat< S > operator*(const dmat< S > &a, const dmat< S > &b)
Point normalize(const Point &vect)
void array_to_points(const vector< S > &arr, vector< POINT > &pts)
Point orthogonalize(const Point &a, const Point &b)
void global_to_local(const vector< T > &glob, vector< T > &data, bool sortedData, bool doWarn)
elem_t getElemTypeID(char *eletype)
Generate element type enum from string.
double distance(const Point &a, const Point &b)
dmat< S > operator+(const dmat< S > &a, const dmat< S > &b)
Point cross(const Point &a, const Point &b)
cross product
void nodal_connectivity_graph(const meshdata< T, S > &mesh, vector< T > &n2n_cnt, vector< T > &n2n_con)
Compute the node-to-node connectivity.
SF_nbr
Enumeration encoding the different supported numberings.
@ NBR_PETSC
PETSc numbering of nodes.
@ NBR_ELEM_REF
The element numbering of the reference mesh (the one stored on HD).
@ NBR_REF
The nodal numbering of the reference mesh (the one stored on HD).
@ NBR_SUBMESH
Submesh nodal numbering: The globally ascending sorted reference indices are reindexed.
@ NBR_ELEM_SUBMESH
Submesh element numbering: The globally ascending sorted reference indices are reindexed.
const hm_uint mkhash_init
hm_uint mkhash(hm_uint a, hm_uint b)
static hm_uint hash(SF::quadruple< T > a)
static bool cmp(SF::quadruple< T > a, SF::quadruple< T > b)
static bool cmp(SF::triple< T > a, SF::triple< T > b)
static hm_uint hash(SF::triple< T > a)
static hm_uint hash(SF::tuple< T > a)
static bool cmp(SF::tuple< T > a, SF::tuple< T > b)