24 #include "simplex_set.h"
25 #include "is_mesh_iterator.h"
27 #include "attribute_vector.h"
32 std::vector<NodeKey> nodeKeys;
33 std::vector<EdgeKey> edgeKeys;
34 std::vector<FaceKey> faceKeys;
35 std::vector<TetrahedronKey> tetrahedronKeys;
47 std::shared_ptr<Geometry> subdomain;
49 std::map<long,std::function<void(const GarbageCollectDeletions&)>> m_gc_listeners;
50 std::map<long,std::function<void(const TetrahedronKey& tid, unsigned int oldValue)>> m_set_label_listeners;
51 std::map<long,std::function<void(const NodeKey& nid_new, const NodeKey& nid1, const NodeKey& nid2)>> m_split_listeners;
52 std::map<long,std::function<void(const NodeKey& nid, const NodeKey& nid_removed, double weight)>> m_collapse_listeners;
54 unsigned int m_number_of_threads = std::thread::hardware_concurrency();
56 ISMesh(std::vector<vec3> & points, std::vector<int> & tets,
const std::vector<int>& tet_labels);
64 unsigned int get_no_nodes()
const;
66 unsigned int get_no_edges()
const;
68 unsigned int get_no_faces()
const;
70 unsigned int get_no_tets()
const;
72 unsigned int get_max_node_key()
const;
74 unsigned int get_max_edge_key()
const;
76 unsigned int get_max_face_key()
const;
78 unsigned int get_max_tet_key()
const;
80 std::shared_ptr<Geometry> get_subdomain();
82 void clear_subdomain();
84 void set_subdomain(std::shared_ptr<Geometry> subdomain);
86 unsigned int get_number_of_threads()
const;
88 void set_number_of_threads(
unsigned int m_number_of_threads);
94 std::vector<TetrahedronKey> find_par_tet(std::function<
bool(
Tetrahedron&)> include){
return find_par<TetrahedronKey,Tetrahedron>(include); }
95 std::vector<FaceKey> find_par_face(std::function<
bool(
Face&)> include){
return find_par<FaceKey,Face>(include); }
96 std::vector<EdgeKey> find_par_edge(std::function<
bool(
Edge&)> include){
return find_par<EdgeKey,Edge>(include); }
97 std::vector<NodeKey> find_par_node(std::function<
bool(
Node&)> include){
return find_par<NodeKey,Node>(include); }
99 template<
typename key_type,
typename value_type>
100 std::vector<key_type> find_par(std::function<
bool(value_type&)> include);
104 template<
typename value_type>
105 void for_each_par(std::function<
void(value_type&,
int)> fn);
108 template<
typename simplex_type,
typename return_type>
109 return_type map_reduce_par(std::function<return_type(simplex_type&)> map_fn, std::function<return_type(return_type,return_type)> reduce_fn, return_type default_value = {});
117 template<
typename value_type>
118 void for_each_par_sp(
double partitionsize,
int dimension, std::function<
void(value_type& node,
int threadid)> fn);
132 template<
typename key_type,
typename value_type>
137 edge_key(
int i,
int j) : k1(i), k2(j) {}
138 bool operator<(
const edge_key& k)
const
140 return k1 < k.k1 || (k1 == k.k1 && k2 < k.k2);
146 face_key(
int i,
int j,
int k) : k1(i), k2(j), k3(k){}
147 bool operator<(
const face_key& k)
const
150 if (k1 < k.k1)
return true;
151 if (k1 == k.k1 && k2 < k.k2)
return true;
152 if (k1 == k.k1 && k2 == k.k2 && k3 < k.k3)
return true;
157 template<
typename map_type,
typename mesh_type>
158 inline int create_edge(
int i,
int j, map_type& edge_map, mesh_type& mesh)
161 if (i <= j) { a = i; b = j; }
162 else { a = j; b = i; }
164 auto it = edge_map.find(key);
165 if (it == edge_map.end())
167 int n = mesh.insert_edge(i, j);
168 it = edge_map.insert(std::pair<edge_key,int>(key, n)).first;
173 template<
typename map_type,
typename mesh_type>
174 inline int create_face(
int i,
int j,
int k, map_type& face_map, mesh_type& mesh)
176 int a[3] = {i, j, k};
178 face_key key(a[0], a[1], a[2]);
179 auto it = face_map.find(key);
180 if (it == face_map.end())
182 int index = mesh.insert_face(i, j, k);
183 it = face_map.insert(std::pair<face_key,int>(key, index)).first;
188 bool create(
const std::vector<vec3>& points,
const std::vector<int>& tets);
192 void init_flags(
const std::vector<int>& tet_labels);
204 void update_flag(
const FaceKey & f);
206 void update_flag(
const EdgeKey & e);
210 bool crossing(
const NodeKey& n);
213 void update_flag(
const NodeKey & n);
242 template<
typename key_type>
248 nids +=
get(k).node_keys();
253 template<
typename key_type>
259 eids +=
get(k).edge_keys();
265 template<
typename key_type>
271 fids +=
get(k).face_keys();
276 template<
typename key_type>
282 tids +=
get(k).tet_keys();
337 bool excluded(
const FaceKey& f);
339 bool excluded(
const EdgeKey& e);
341 bool excluded(
const NodeKey& n);
387 void remove(
const NodeKey& nid);
389 void remove(
const EdgeKey& eid);
391 void remove(
const FaceKey& fid);
397 template<
typename child_key,
typename parent_key>
398 void connect(
const child_key& ck,
const parent_key& pk)
400 get(ck).add_co_face(pk);
401 get(pk).add_face(ck);
404 template<
typename child_key,
typename parent_key>
405 void disconnect(
const child_key& ck,
const parent_key& pk)
407 get(ck).remove_co_face(pk);
408 get(pk).remove_face(ck);
411 template<
typename child_key,
typename parent_key>
412 void swap(
const child_key& ck1,
const parent_key& pk1,
const child_key& ck2,
const parent_key& pk2)
414 if(!
get(pk1).get_boundary().contains(ck1))
416 assert(
get(pk1).get_boundary().contains(ck2));
417 assert(
get(pk2).get_boundary().contains(ck1));
419 disconnect(ck1, pk2);
420 disconnect(ck2, pk1);
425 assert(
get(pk1).get_boundary().contains(ck1));
426 assert(
get(pk2).get_boundary().contains(ck2));
428 disconnect(ck1, pk1);
429 disconnect(ck2, pk2);
435 template<
typename key_type>
436 key_type merge(
const key_type& key1,
const key_type& key2)
438 auto& simplex =
get(key2);
439 for(
auto k : simplex.get_co_boundary())
443 for(
auto k : simplex.get_boundary())
480 void update_collapse(
const NodeKey& nid,
const NodeKey& nid_removed,
double weight);
491 void garbage_collect();
493 virtual void scale(
const vec3& s);
495 void extract_surface_mesh(std::vector<vec3>& points, std::vector<int>& faces);
498 void extract_surface_mesh_debug(std::vector<vec3>& points, std::vector<int>& faces);
500 void extract_tet_mesh(std::vector<vec3>& points, std::vector<int>& tets, std::vector<int>& tet_labels);
502 void validity_check(
bool skip_boundary_check =
false);
509 bool remove_gc_listener(
long id);
511 long add_label_listener(std::function<
void(
const TetrahedronKey& tid,
unsigned int oldValue)> fn);
513 bool remove_label_listener(
long id);
515 long add_split_listener(std::function<
void(
const NodeKey& nid_new,
const NodeKey& nid1,
const NodeKey& nid2)> fn);
517 bool remove_split_listener(
long id);
519 long add_collapse_listener(std::function<
void(
const NodeKey& nid,
const NodeKey& nid_removed,
double weight)> fn);
521 bool remove_collapse_listener(
long id);
529 template<
typename key_type,
typename value_type>
533 for (
auto iter = begin;iter!=end;iter++){
539 template<
typename value_type>
540 inline void ISMesh::for_each_par(std::function<
void(value_type&,
int)> fn) {
541 using KeyType = decltype(std::declval<value_type>().key());
542 auto kernel = &get_kernel<KeyType, value_type>();
543 kernel->readonly =
true;
545 int thread_count = m_number_of_threads;
546 if (thread_count<=1){
547 for (
auto &n : *kernel){
551 std::vector<std::thread *> threads;
552 int chunk_size = (int) ceil(kernel->
capacity() / (float) (thread_count));
554 for (
int i = 0; i < thread_count; i++) {
555 threads.push_back(
new std::thread(run_for_each_par<KeyType, value_type>, fn, kernel, i * chunk_size, (1 + i) * chunk_size, i));
558 for (
int i = 0; i < thread_count; i++) {
563 kernel->readonly =
false;
566 template<
typename simplex_type,
typename return_type>
567 inline return_type ISMesh::map_reduce_par(std::function<return_type(simplex_type&)> map_fn, std::function<return_type(return_type,return_type)> reduce_fn, return_type default_value){
568 std::vector<return_type> res(m_number_of_threads, default_value);
569 for_each_par<simplex_type>([&](simplex_type& v,
int index){
570 auto value = map_fn(v);
571 res[index] = reduce_fn(res[index],value);
573 for (
int i=1;i<res.size();i++){
574 res[i] = reduce_fn(res[i-1], res[i]);
576 return res[res.size()-1];
579 template<
typename key_type,
typename value_type>
580 inline std::vector<key_type> ISMesh::find_par(std::function<
bool(value_type&)> include){
581 std::vector<std::vector<key_type>> res_array(m_number_of_threads, {});
582 for_each_par<value_type>([&](value_type &value,
int threadid){
585 res_array[threadid].push_back(value.key());
588 std::vector<key_type> res;
589 for (
auto & t:res_array){
590 res.insert(res.end(), t.begin(), t.end());
595 template<
typename value_type,
typename kernel_type,
typename key_type>
596 inline void run_for_each_par_sp(std::function<
void(value_type&,
int)> fn, kernel_type* kernel,
int threadid,
int actualthread, AttributeVector<key_type, int> *attributeVector){
597 for (
int i=0;i< attributeVector->size();i++){
599 int run_in_thread = (*attributeVector)[key];
600 if (run_in_thread == threadid){
601 fn(kernel->get(key), actualthread);
606 template<
typename value_type>
607 inline void ISMesh::for_each_par_sp(
double partitionsize,
int dimension, std::function<
void(value_type&,
int)> fn) {
608 using KeyType = decltype(std::declval<value_type>().key());
609 using KernelType = kernel<KeyType, value_type>;
610 auto kernel = &get_kernel<KeyType, value_type>();
611 kernel->readonly =
true;
613 if (m_number_of_threads <=1){
614 for (
auto &n : *kernel){
618 AttributeVector<KeyType, int> attributeVector(kernel->capacity(), -1);
619 for_each_par<value_type>([&](value_type& n,
int t){
620 double p = n.get_center()[dimension];
621 double concur_partitionsize = partitionsize * m_number_of_threads * 2;
623 p += concur_partitionsize * (int) (ceil(-p / concur_partitionsize));
625 p = fmod(p, concur_partitionsize);
626 int run_in_thread = std::min((
int) floor(p / partitionsize), ((
int) m_number_of_threads * 2) - 1);
627 attributeVector[n.key()] = run_in_thread;
630 std::vector<std::thread*> threads;
631 for (
int i=0;i< m_number_of_threads;i++){
632 threads.push_back(
new std::thread(run_for_each_par_sp<value_type, KernelType, KeyType>, fn, kernel, i*2,i, &attributeVector));
634 for (
int i=0;i< m_number_of_threads;i++){
637 for (
int i=0;i< m_number_of_threads;i++){
639 threads[i] =
new std::thread(run_for_each_par_sp<value_type, KernelType, KeyType>, fn, kernel, 1+i*2,i, &attributeVector);
641 for (
int i=0;i< m_number_of_threads;i++){
646 kernel->readonly =
false;
650 inline kernel<NodeKey,Node>& ISMesh::get_kernel(){
651 return m_node_kernel;
655 inline kernel<EdgeKey,Edge>& ISMesh::get_kernel(){
656 return m_edge_kernel;
660 inline kernel<FaceKey,Face>& ISMesh::get_kernel(){
661 return m_face_kernel;
665 inline kernel<TetrahedronKey,Tetrahedron>& ISMesh::get_kernel(){
666 return m_tetrahedron_kernel;
TetrahedronKey insert_tetrahedron(FaceKey face1, FaceKey face2, FaceKey face3, FaceKey face4)
Definition: is_mesh.cpp:634
Definition: geometry.h:24
TetrahedronKey get_tet(const TetrahedronKey &tid, const FaceKey &fid)
Definition: is_mesh.cpp:498
Definition: is_mesh_iterator.h:60
A 3D double vector.
Definition: Vec3d.h:26
size_t capacity() const
Definition: kernel.h:159
void collapse(const EdgeKey &eid, const NodeKey &nid, double weight=0.5)
Definition: is_mesh.cpp:776
Definition: tetrahedron.h:27
Definition: is_mesh_iterator.h:49
Definition: is_mesh_iterator.h:29
bool is_inverted(const TetrahedronKey &tid)
Definition: is_mesh.cpp:566
FaceKey insert_face(EdgeKey edge1, EdgeKey edge2, EdgeKey edge3)
Definition: is_mesh.cpp:622
NodeKey get_node(const EdgeKey &eid1, const EdgeKey &eid2)
Definition: is_mesh.cpp:433
iterator find_valid_iterator(key_type k)
Definition: kernel.h:274
NodeKey insert_node(const vec3 &p)
Definition: is_mesh.cpp:606
FaceKey get_face(const NodeKey &nid1, const NodeKey &nid2, const NodeKey &nid3)
Definition: is_mesh.cpp:475
std::vector< vec3 > get_pos(const SimplexSet< NodeKey > &nids)
Definition: is_mesh.cpp:509
EdgeKey insert_edge(NodeKey node1, NodeKey node2)
Definition: is_mesh.cpp:611
vec3 get_barycenter(const SimplexSet< NodeKey > &nids, bool interface=false)
Definition: is_mesh.cpp:1338
EdgeKey get_edge(const NodeKey &nid1, const NodeKey &nid2)
Definition: is_mesh.cpp:453
Definition: is_mesh_iterator.h:39