56 template<
typename real_t,
int dim>
class Swapping{
62 size_t NElements = _mesh->get_number_elements();
66 for(
size_t i=0;i<NElements;i++){
67 const int *n=_mesh->get_element(i);
73 _mesh->get_coords(n[1]),
74 _mesh->get_coords(n[2]));
77 _mesh->get_coords(n[1]),
78 _mesh->get_coords(n[2]),
79 _mesh->get_coords(n[3]));
87 newElements.resize(nthreads);
88 newBoundaries.resize(nthreads);
89 threadIdx.resize(nthreads);
90 splitCnt.resize(nthreads);
93 for(
int i=0; i<3; ++i){
100 for(
int i=0; i<3; ++i)
101 ind_set_size[i].resize(max_colour, 0);
102 ind_sets.resize(nthreads, std::vector< std::vector<index_t> >(max_colour));
103 range_indexer.resize(nthreads, std::vector< std::pair<size_t,size_t> >(max_colour, std::pair<size_t,size_t>(0,0)));
113 if(node_colour!=NULL)
114 delete[] node_colour;
116 for(
int i=0; i<3; ++i){
117 if(worklist[i] != NULL)
118 delete[] worklist[i];
124 void swap(real_t quality_tolerance){
126 swap2d(quality_tolerance);
128 swap3d(quality_tolerance);
134 void swap2d(real_t quality_tolerance){
135 size_t NNodes = _mesh->get_number_nodes();
136 size_t NElements = _mesh->get_number_elements();
138 min_Q = quality_tolerance;
140 if(nnodes_reserve<NNodes){
141 nnodes_reserve = NNodes;
143 GlobalActiveSet.resize(NNodes);
145 for(
int i=0; i<3; ++i){
146 if(worklist[i] != NULL)
147 delete[] worklist[i];
148 worklist[i] =
new index_t[NNodes];
151 if(node_colour!=NULL)
152 delete[] node_colour;
154 node_colour =
new int[NNodes];
156 quality.resize(NElements, 0.0);
157 marked_edges.resize(NNodes);
165 std::vector<index_t> forbiddenColours(max_colour, std::numeric_limits<index_t>::max());
167 #pragma omp single nowait
168 memset(node_colour, 0, NNodes*
sizeof(
int));
170 #pragma omp single nowait
172 for(
int i=0; i<max_colour; ++i)
173 ind_set_size[0][i] = 0;
174 GlobalActiveSet_size[0] = 0;
179 #pragma omp for schedule(guided)
180 for(
size_t i=0; i<NElements; ++i){
181 const int *n=_mesh->get_element(i);
183 const real_t *x0 = _mesh->get_coords(n[0]);
184 const real_t *
x1 = _mesh->get_coords(n[1]);
185 const real_t *
x2 = _mesh->get_coords(n[2]);
187 quality[i] =
property->lipnikov(x0, x1, x2,
188 _mesh->get_metric(n[0]),
189 _mesh->get_metric(n[1]),
190 _mesh->get_metric(n[2]));
192 if(quality[i]<min_Q){
196 def_ops->propagate_swapping(edge0.edge.first, edge0.edge.second, tid);
197 def_ops->propagate_swapping(edge1.edge.first, edge1.edge.second, tid);
198 def_ops->propagate_swapping(edge2.edge.first, edge2.edge.second, tid);
205 #pragma omp for schedule(guided)
206 for(
int vtid=0; vtid<defOp_scaling_factor*nthreads; ++vtid){
207 for(
int i=0; i<nthreads; ++i){
208 def_ops->commit_swapping_propagation(marked_edges, i, vtid);
221 #pragma omp single nowait
223 for(
int i=0; i<3; ++i)
224 worklist_size[i] = 0;
226 int next_rnd = (rnd+1)%3;
227 for(
int i=0; i<max_colour; ++i)
228 ind_set_size[next_rnd][i] = 0;
229 GlobalActiveSet_size[next_rnd] = 0;
233 std::vector<index_t> local_coloured;
234 #pragma omp for schedule(guided) nowait
235 for(
size_t i=0; i<NNodes; ++i){
236 if(marked_edges[i].size()>0){
243 for(
typename std::vector<index_t>::const_iterator jt=_mesh->NNList[i].begin(); jt!=_mesh->NNList[i].end(); ++jt){
244 if(marked_edges[*jt].size()>0){
245 forbiddenColours[node_colour[*jt]] = (
index_t) i;
248 for(
size_t j=0; j<forbiddenColours.size(); ++j){
249 if(forbiddenColours[j] != (
index_t) i){
250 node_colour[i] = (int) j;
256 local_coloured.push_back(i);
260 if(local_coloured.size()>0){
263 memcpy(&GlobalActiveSet[pos], &local_coloured[0], local_coloured.size() *
sizeof(
index_t));
267 if(GlobalActiveSet_size[rnd]>0){
269 for(
int set_no=0; set_no<max_colour; ++set_no){
270 ind_sets[tid][set_no].clear();
271 range_indexer[tid][set_no].first = std::numeric_limits<size_t>::infinity();
272 range_indexer[tid][set_no].second = std::numeric_limits<size_t>::infinity();
275 std::vector<index_t> conflicts;
277 #pragma omp for schedule(guided) nowait
278 for(
size_t i=0; i<GlobalActiveSet_size[rnd]; ++i){
279 bool defective =
false;
280 index_t n = GlobalActiveSet[i];
281 for(
typename std::vector<index_t>::const_iterator jt=_mesh->NNList[n].begin(); jt!=_mesh->NNList[n].end(); ++jt){
282 if(marked_edges[*jt].size()>0){
283 if(node_colour[n] == node_colour[*jt]){
295 conflicts.push_back(n);
297 for(
typename std::vector<index_t>::const_iterator jt=_mesh->NNList[n].begin(); jt!=_mesh->NNList[n].end(); ++jt){
298 if(marked_edges[*jt].size()>0){
299 int c = node_colour[*jt];
300 forbiddenColours[c] = n;
304 for(
size_t j=0; j<forbiddenColours.size(); j++){
305 if(forbiddenColours[j] != n){
306 node_colour[n] = (int) j;
311 ind_sets[tid][node_colour[n]].push_back(n);
318 memcpy(&worklist[0][pos], &conflicts[0], conflicts.size() *
sizeof(
index_t));
325 while(worklist_size[wl]){
326 #pragma omp for schedule(guided) nowait
327 for(
size_t item=0; item<worklist_size[wl]; ++item){
328 index_t n = worklist[wl][item];
329 bool defective =
false;
330 for(
typename std::vector<index_t>::const_iterator jt=_mesh->NNList[n].begin(); jt!=_mesh->NNList[n].end(); ++jt){
331 if(marked_edges[*jt].size()>0){
332 if(node_colour[n] == node_colour[*jt]){
344 conflicts.push_back(n);
346 for(
typename std::vector<index_t>::const_iterator jt=_mesh->NNList[n].begin(); jt!=_mesh->NNList[n].end(); ++jt){
347 if(marked_edges[*jt].size()>0){
348 int c = node_colour[*jt];
349 forbiddenColours[c] = n;
353 for(
size_t j=0; j<forbiddenColours.size(); j++){
354 if(forbiddenColours[j] != n){
360 ind_sets[tid][node_colour[n]].push_back(n);
369 memcpy(&worklist[wl][pos], &conflicts[0], conflicts.size() *
sizeof(
index_t));
376 worklist_size[(wl+1)%3] = 0;
380 for(
int set_no=0; set_no<max_colour; ++set_no){
381 if(ind_sets[tid][set_no].size()>0){
383 range_indexer[tid][set_no].second = range_indexer[tid][set_no].first + ind_sets[tid][set_no].size();
389 for(
int set_no=0; set_no<max_colour; ++set_no){
390 if(ind_set_size[rnd][set_no] == 0)
394 std::vector<range_element> range;
395 for(
int t=0; t<nthreads; ++t){
396 if(range_indexer[t][set_no].first != range_indexer[t][set_no].second)
401 #pragma omp for schedule(guided)
402 for(
size_t idx=0; idx<ind_set_size[rnd][set_no]; ++idx){
405 std::vector<range_element>::iterator ele = std::lower_bound(range.begin(), range.end(),
407 assert(ele != range.end());
408 assert(idx >= range_indexer[ele->second][set_no].first && idx < range_indexer[ele->second][set_no].second);
409 i = ind_sets[ele->second][set_no][idx - range_indexer[ele->second][set_no].first];
413 if(node_colour[i] != set_no)
417 std::set<index_t> modified_elements;
418 std::set<index_t> marked_edges_new;
420 for(
typename std::set<index_t>::const_iterator vid=marked_edges[i].begin(); vid!=marked_edges[i].end(); ++vid){
425 for(
typename std::set<index_t>::const_iterator it=modified_elements.begin(); it!=modified_elements.end(); ++it){
426 if(_mesh->NEList[j].find(*it) != _mesh->NEList[j].end()){
432 marked_edges_new.insert(j);
437 swap_kernel2d(edge, modified_elements, tid);
440 if(edge.edge.first != i){
444 if((node_colour[k] == node_colour[l]) && (node_colour[k] >= 0))
445 def_ops->reset_colour(l, tid);
451 for(
size_t ee=0; ee<4; ++ee)
452 def_ops->propagate_swapping(lateralEdges[ee].edge.first, lateralEdges[ee].edge.second, tid);
456 marked_edges[i].swap(marked_edges_new);
460 #pragma omp for schedule(guided)
461 for(
int vtid=0; vtid<defOp_scaling_factor*nthreads; ++vtid){
462 for(
int i=0; i<nthreads; ++i){
463 def_ops->commit_remNN(i, vtid);
464 def_ops->commit_addNN(i, vtid);
465 def_ops->commit_remNE(i, vtid);
466 def_ops->commit_addNE(i, vtid);
467 def_ops->commit_swapping_propagation(marked_edges, i, vtid);
468 def_ops->commit_colour_reset(node_colour, i, vtid);
473 }
while(GlobalActiveSet_size[rnd]>0);
477 void swap3d(real_t Q_min){
479 size_t NElements = _mesh->get_number_elements();
480 std::vector<real_t> quality(NElements, -1);
483 #pragma omp for schedule(static)
484 for(
int i=0;i<(int)NElements;i++){
485 const int *n=_mesh->get_element(i);
491 const real_t *x0 = _mesh->get_coords(n[0]);
492 const real_t *x1 = _mesh->get_coords(n[1]);
493 const real_t *x2 = _mesh->get_coords(n[2]);
494 const real_t *
x3 = _mesh->get_coords(n[3]);
496 quality[i] =
property->lipnikov(x0, x1, x2, x3,
497 _mesh->get_metric(n[0]),
498 _mesh->get_metric(n[1]),
499 _mesh->get_metric(n[2]),
500 _mesh->get_metric(n[3]));
504 std::map<int, std::deque<int> > partialEEList;
505 for(
size_t i=0;i<NElements;i++){
507 const int *n=_mesh->get_element(i);
512 if(quality[i]<Q_min){
513 bool is_halo =
false;
514 for(
int j=0; j<nloc; ++j){
515 if(_mesh->is_halo_node(n[j])){
523 partialEEList[i].resize(4);
524 std::fill(partialEEList[i].begin(), partialEEList[i].end(), -1);
526 for(
size_t j=0;j<4;j++){
527 std::set<index_t> intersection12;
528 set_intersection(_mesh->NEList[n[(j+1)%4]].begin(), _mesh->NEList[n[(j+1)%4]].end(),
529 _mesh->NEList[n[(j+2)%4]].begin(), _mesh->NEList[n[(j+2)%4]].end(),
530 inserter(intersection12, intersection12.begin()));
532 std::set<index_t> EE;
533 set_intersection(intersection12.begin(),intersection12.end(),
534 _mesh->NEList[n[(j+3)%4]].begin(), _mesh->NEList[n[(j+3)%4]].end(),
535 inserter(EE, EE.begin()));
537 for(
typename std::set<index_t>::const_iterator it=EE.begin();it!=EE.end();++it){
539 partialEEList[i][j] = *it;
547 if(partialEEList.empty())
551 std::map<int , std::set<int> > graph;
552 for(std::map<
int, std::deque<int> >::const_iterator it=partialEEList.begin();it!=partialEEList.end();++it){
553 for(std::deque<int>::const_iterator jt=it->second.begin();jt!=it->second.end();++jt){
554 graph[*jt].insert(it->first);
555 graph[it->first].insert(*jt);
559 std::deque<int> renumber(graph.size());
560 std::map<int, int> irenumber;
563 for(std::map<
int , std::set<int> >::const_iterator it=graph.begin();it!=graph.end();++it){
565 renumber[loc] = it->first;
566 irenumber[it->first] = loc;
570 std::vector< std::vector<index_t> > NNList(graph.size());
571 for(std::map<
int , std::set<int> >::const_iterator it=graph.begin();it!=graph.end();++it){
572 for(std::set<int>::const_iterator jt=it->second.begin();jt!=it->second.end();++jt){
573 NNList[irenumber[it->first]].push_back(irenumber[*jt]);
576 std::vector<char> colour(graph.size());
581 int max_colour=colour[0];
582 for(
size_t i=1;i<graph.size();i++)
583 max_colour = std::max(max_colour, (
int)colour[i]);
586 for(
int c=0;c<max_colour;c++){
587 for(
size_t i=0;i<graph.size();i++){
588 int eid0 = renumber[i];
590 if(colour[i]==c && (partialEEList.count(eid0)>0)){
593 const int *n=_mesh->get_element(eid0);
597 assert(partialEEList[eid0].size()==4);
601 for(
int j=0;j<4;j++){
602 int eid1 = partialEEList[eid0][j];
606 const int *m=_mesh->get_element(eid1);
616 std::set<int> ele0_set;
618 ele0_set.insert(n[j]);
620 for(
int j=0;j<4;j++){
621 int eid1 = partialEEList[eid0][j];
625 std::vector<int> hull(5, -1);
648 const int *m=_mesh->get_element(eid1);
652 if(ele0_set.count(m[k])==0){
659 real_t q0 =
property->lipnikov(_mesh->get_coords(hull[0]),
660 _mesh->get_coords(hull[1]),
661 _mesh->get_coords(hull[4]),
662 _mesh->get_coords(hull[3]),
663 _mesh->get_metric(hull[0]),
664 _mesh->get_metric(hull[1]),
665 _mesh->get_metric(hull[4]),
666 _mesh->get_metric(hull[3]));
669 real_t q1 =
property->lipnikov(_mesh->get_coords(hull[1]),
670 _mesh->get_coords(hull[2]),
671 _mesh->get_coords(hull[4]),
672 _mesh->get_coords(hull[3]),
673 _mesh->get_metric(hull[1]),
674 _mesh->get_metric(hull[2]),
675 _mesh->get_metric(hull[4]),
676 _mesh->get_metric(hull[3]));
679 real_t q2 =
property->lipnikov(_mesh->get_coords(hull[2]),
680 _mesh->get_coords(hull[0]),
681 _mesh->get_coords(hull[4]),
682 _mesh->get_coords(hull[3]),
683 _mesh->get_metric(hull[2]),
684 _mesh->get_metric(hull[0]),
685 _mesh->get_metric(hull[4]),
686 _mesh->get_metric(hull[3]));
688 if(std::min(quality[eid0],quality[eid1]) < std::min(q0, std::min(q1, q2))){
690 int eid0_b0, eid0_b1, eid0_b2, eid1_b0, eid1_b1, eid1_b2;
691 for(
int face=0; face<nloc; ++face){
692 if(n[face] == hull[0])
693 eid0_b0 = _mesh->boundary[eid0*nloc+face];
694 else if(n[face] == hull[1])
695 eid0_b1 = _mesh->boundary[eid0*nloc+face];
696 else if(n[face] == hull[2])
697 eid0_b2 = _mesh->boundary[eid0*nloc+face];
699 if(m[face] == hull[0])
700 eid1_b0 = _mesh->boundary[eid1*nloc+face];
701 else if(m[face] == hull[1])
702 eid1_b1 = _mesh->boundary[eid1*nloc+face];
703 else if(m[face] == hull[2])
704 eid1_b2 = _mesh->boundary[eid1*nloc+face];
707 _mesh->erase_element(eid0);
708 _mesh->erase_element(eid1);
710 int e0[] = {hull[0], hull[1], hull[4], hull[3]};
711 int b0[] = {0, 0, eid0_b2, eid1_b2};
712 int eid0 = _mesh->append_element(e0, b0);
713 quality.push_back(q0);
715 int e1[] = {hull[1], hull[2], hull[4], hull[3]};
716 int b1[] = {0, 0, eid0_b0, eid1_b0};
717 int eid1 = _mesh->append_element(e1, b1);
718 quality.push_back(q1);
720 int e2[] = {hull[2], hull[0], hull[4], hull[3]};
721 int b2[] = {0, 0, eid0_b1, eid1_b1};
722 int eid2 = _mesh->append_element(e2, b2);
723 quality.push_back(q2);
725 _mesh->NNList[hull[3]].push_back(hull[4]);
726 _mesh->NNList[hull[4]].push_back(hull[3]);
727 _mesh->NEList[hull[0]].insert(eid0);
728 _mesh->NEList[hull[0]].insert(eid2);
729 _mesh->NEList[hull[1]].insert(eid0);
730 _mesh->NEList[hull[1]].insert(eid1);
731 _mesh->NEList[hull[2]].insert(eid1);
732 _mesh->NEList[hull[2]].insert(eid2);
733 _mesh->NEList[hull[3]].insert(eid0);
734 _mesh->NEList[hull[3]].insert(eid1);
735 _mesh->NEList[hull[3]].insert(eid2);
736 _mesh->NEList[hull[4]].insert(eid0);
737 _mesh->NEList[hull[4]].insert(eid1);
738 _mesh->NEList[hull[4]].insert(eid2);
748 for(
int c=0;c<max_colour;c++){
749 for(
size_t i=0;i<graph.size();i++){
750 int eid0 = renumber[i];
752 if(colour[i]==c && (partialEEList.count(eid0)>0)){
755 const int *n=_mesh->get_element(eid0);
759 bool toxic=
false, swapped=
false;
760 for(
int k=0;(k<3)&&(!toxic)&&(!swapped);k++){
761 for(
int l=k+1;l<4;l++){
764 std::set<index_t> neigh_elements;
765 set_intersection(_mesh->NEList[n[k]].begin(), _mesh->NEList[n[k]].end(),
766 _mesh->NEList[n[l]].begin(), _mesh->NEList[n[l]].end(),
767 inserter(neigh_elements, neigh_elements.begin()));
769 double min_quality = quality[eid0];
770 std::vector<index_t> constrained_edges_unsorted;
771 std::map<int, std::map<index_t, int> >
b;
772 std::vector<int> element_order, e_to_eid;
774 for(
typename std::set<index_t>::const_iterator it=neigh_elements.begin();it!=neigh_elements.end();++it){
775 min_quality = std::min(min_quality, quality[*it]);
777 const int *m=_mesh->get_element(*it);
783 e_to_eid.push_back(*it);
785 for(
int j=0;j<4;j++){
786 if((m[j]!=n[k])&&(m[j]!=n[l])){
787 constrained_edges_unsorted.push_back(m[j]);
788 }
else if(m[j] == n[k]){
789 b[*it][n[k]] = _mesh->boundary[nloc*(*it)+j];
791 b[*it][n[l]] = _mesh->boundary[nloc*(*it)+j];
799 size_t nelements = neigh_elements.size();
800 assert(nelements*2==constrained_edges_unsorted.size());
801 assert(b.size() == nelements);
804 std::vector<index_t> constrained_edges;
805 std::vector<bool> sorted(nelements,
false);
806 constrained_edges.push_back(constrained_edges_unsorted[0]);
807 constrained_edges.push_back(constrained_edges_unsorted[1]);
808 element_order.push_back(e_to_eid[0]);
809 for(
size_t j=1;j<nelements;j++){
810 for(
size_t e=1;e<nelements;e++){
813 if(*constrained_edges.rbegin()==constrained_edges_unsorted[e*2]){
814 constrained_edges.push_back(constrained_edges_unsorted[e*2]);
815 constrained_edges.push_back(constrained_edges_unsorted[e*2+1]);
816 element_order.push_back(e_to_eid[e]);
819 }
else if(*constrained_edges.rbegin()==constrained_edges_unsorted[e*2+1]){
820 constrained_edges.push_back(constrained_edges_unsorted[e*2+1]);
821 constrained_edges.push_back(constrained_edges_unsorted[e*2]);
822 element_order.push_back(e_to_eid[e]);
829 if(*constrained_edges.begin() != *constrained_edges.rbegin()){
833 assert(element_order.size() == nelements);
835 std::vector< std::vector<index_t> > new_elements;
836 std::vector< std::vector<int> > new_boundaries;
839 new_elements.resize(1);
840 new_boundaries.resize(1);
842 new_elements[0].push_back(constrained_edges[0]);
843 new_elements[0].push_back(constrained_edges[2]);
844 new_elements[0].push_back(constrained_edges[4]);
845 new_elements[0].push_back(n[l]);
846 new_boundaries[0].push_back(b[element_order[1]][n[k]]);
847 new_boundaries[0].push_back(b[element_order[2]][n[k]]);
848 new_boundaries[0].push_back(b[element_order[0]][n[k]]);
849 new_boundaries[0].push_back(0);
851 new_elements[0].push_back(constrained_edges[2]);
852 new_elements[0].push_back(constrained_edges[0]);
853 new_elements[0].push_back(constrained_edges[4]);
854 new_elements[0].push_back(n[k]);
855 new_boundaries[0].push_back(b[element_order[2]][n[l]]);
856 new_boundaries[0].push_back(b[element_order[1]][n[l]]);
857 new_boundaries[0].push_back(b[element_order[0]][n[l]]);
858 new_boundaries[0].push_back(0);
859 }
else if(nelements==4){
861 new_elements.resize(2);
862 new_boundaries.resize(2);
865 new_elements[0].push_back(constrained_edges[0]);
866 new_elements[0].push_back(constrained_edges[2]);
867 new_elements[0].push_back(constrained_edges[6]);
868 new_elements[0].push_back(n[l]);
869 new_boundaries[0].push_back(0);
870 new_boundaries[0].push_back(b[element_order[3]][n[k]]);
871 new_boundaries[0].push_back(b[element_order[0]][n[k]]);
872 new_boundaries[0].push_back(0);
874 new_elements[0].push_back(constrained_edges[2]);
875 new_elements[0].push_back(constrained_edges[4]);
876 new_elements[0].push_back(constrained_edges[6]);
877 new_elements[0].push_back(n[l]);
878 new_boundaries[0].push_back(b[element_order[2]][n[k]]);
879 new_boundaries[0].push_back(0);
880 new_boundaries[0].push_back(b[element_order[1]][n[k]]);
881 new_boundaries[0].push_back(0);
883 new_elements[0].push_back(constrained_edges[2]);
884 new_elements[0].push_back(constrained_edges[0]);
885 new_elements[0].push_back(constrained_edges[6]);
886 new_elements[0].push_back(n[k]);
887 new_boundaries[0].push_back(b[element_order[3]][n[l]]);
888 new_boundaries[0].push_back(0);
889 new_boundaries[0].push_back(b[element_order[0]][n[l]]);
890 new_boundaries[0].push_back(0);
892 new_elements[0].push_back(constrained_edges[4]);
893 new_elements[0].push_back(constrained_edges[2]);
894 new_elements[0].push_back(constrained_edges[6]);
895 new_elements[0].push_back(n[k]);
896 new_boundaries[0].push_back(0);
897 new_boundaries[0].push_back(b[element_order[2]][n[l]]);
898 new_boundaries[0].push_back(b[element_order[1]][n[l]]);
899 new_boundaries[0].push_back(0);
902 new_elements[1].push_back(constrained_edges[0]);
903 new_elements[1].push_back(constrained_edges[2]);
904 new_elements[1].push_back(constrained_edges[4]);
905 new_elements[1].push_back(n[l]);
906 new_boundaries[1].push_back(b[element_order[1]][n[k]]);
907 new_boundaries[1].push_back(0);
908 new_boundaries[1].push_back(b[element_order[0]][n[k]]);
909 new_boundaries[1].push_back(0);
911 new_elements[1].push_back(constrained_edges[0]);
912 new_elements[1].push_back(constrained_edges[4]);
913 new_elements[1].push_back(constrained_edges[6]);
914 new_elements[1].push_back(n[l]);
915 new_boundaries[1].push_back(b[element_order[2]][n[k]]);
916 new_boundaries[1].push_back(b[element_order[3]][n[k]]);
917 new_boundaries[1].push_back(0);
918 new_boundaries[1].push_back(0);
920 new_elements[1].push_back(constrained_edges[0]);
921 new_elements[1].push_back(constrained_edges[4]);
922 new_elements[1].push_back(constrained_edges[2]);
923 new_elements[1].push_back(n[k]);
924 new_boundaries[1].push_back(b[element_order[1]][n[l]]);
925 new_boundaries[1].push_back(b[element_order[0]][n[l]]);
926 new_boundaries[1].push_back(0);
927 new_boundaries[1].push_back(0);
929 new_elements[1].push_back(constrained_edges[0]);
930 new_elements[1].push_back(constrained_edges[6]);
931 new_elements[1].push_back(constrained_edges[4]);
932 new_elements[1].push_back(n[k]);
933 new_boundaries[1].push_back(b[element_order[2]][n[l]]);
934 new_boundaries[1].push_back(0);
935 new_boundaries[1].push_back(b[element_order[3]][n[l]]);
936 new_boundaries[1].push_back(0);
937 }
else if(nelements==5){
939 new_elements.resize(5);
940 new_boundaries.resize(5);
943 new_elements[0].push_back(constrained_edges[0]);
944 new_elements[0].push_back(constrained_edges[2]);
945 new_elements[0].push_back(constrained_edges[4]);
946 new_elements[0].push_back(n[l]);
947 new_boundaries[0].push_back(b[element_order[1]][n[k]]);
948 new_boundaries[0].push_back(0);
949 new_boundaries[0].push_back(b[element_order[0]][n[k]]);
950 new_boundaries[0].push_back(0);
952 new_elements[0].push_back(constrained_edges[4]);
953 new_elements[0].push_back(constrained_edges[6]);
954 new_elements[0].push_back(constrained_edges[0]);
955 new_elements[0].push_back(n[l]);
956 new_boundaries[0].push_back(0);
957 new_boundaries[0].push_back(0);
958 new_boundaries[0].push_back(b[element_order[2]][n[k]]);
959 new_boundaries[0].push_back(0);
961 new_elements[0].push_back(constrained_edges[6]);
962 new_elements[0].push_back(constrained_edges[8]);
963 new_elements[0].push_back(constrained_edges[0]);
964 new_elements[0].push_back(n[l]);
965 new_boundaries[0].push_back(b[element_order[4]][n[k]]);
966 new_boundaries[0].push_back(0);
967 new_boundaries[0].push_back(b[element_order[3]][n[k]]);
968 new_boundaries[0].push_back(0);
970 new_elements[0].push_back(constrained_edges[2]);
971 new_elements[0].push_back(constrained_edges[0]);
972 new_elements[0].push_back(constrained_edges[4]);
973 new_elements[0].push_back(n[k]);
974 new_boundaries[0].push_back(0);
975 new_boundaries[0].push_back(b[element_order[1]][n[l]]);
976 new_boundaries[0].push_back(b[element_order[0]][n[l]]);
977 new_boundaries[0].push_back(0);
979 new_elements[0].push_back(constrained_edges[6]);
980 new_elements[0].push_back(constrained_edges[4]);
981 new_elements[0].push_back(constrained_edges[0]);
982 new_elements[0].push_back(n[k]);
983 new_boundaries[0].push_back(0);
984 new_boundaries[0].push_back(0);
985 new_boundaries[0].push_back(b[element_order[2]][n[l]]);
986 new_boundaries[0].push_back(0);
988 new_elements[0].push_back(constrained_edges[8]);
989 new_elements[0].push_back(constrained_edges[6]);
990 new_elements[0].push_back(constrained_edges[0]);
991 new_elements[0].push_back(n[k]);
992 new_boundaries[0].push_back(0);
993 new_boundaries[0].push_back(b[element_order[4]][n[l]]);
994 new_boundaries[0].push_back(b[element_order[3]][n[l]]);
995 new_boundaries[0].push_back(0);
998 new_elements[1].push_back(constrained_edges[0]);
999 new_elements[1].push_back(constrained_edges[2]);
1000 new_elements[1].push_back(constrained_edges[8]);
1001 new_elements[1].push_back(n[l]);
1002 new_boundaries[1].push_back(0);
1003 new_boundaries[1].push_back(b[element_order[4]][n[k]]);
1004 new_boundaries[1].push_back(b[element_order[0]][n[k]]);
1005 new_boundaries[1].push_back(0);
1007 new_elements[1].push_back(constrained_edges[2]);
1008 new_elements[1].push_back(constrained_edges[6]);
1009 new_elements[1].push_back(constrained_edges[8]);
1010 new_elements[1].push_back(n[l]);
1011 new_boundaries[1].push_back(b[element_order[3]][n[k]]);
1012 new_boundaries[1].push_back(0);
1013 new_boundaries[1].push_back(0);
1014 new_boundaries[1].push_back(0);
1016 new_elements[1].push_back(constrained_edges[2]);
1017 new_elements[1].push_back(constrained_edges[4]);
1018 new_elements[1].push_back(constrained_edges[6]);
1019 new_elements[1].push_back(n[l]);
1020 new_boundaries[1].push_back(b[element_order[2]][n[k]]);
1021 new_boundaries[1].push_back(0);
1022 new_boundaries[1].push_back(b[element_order[1]][n[k]]);
1023 new_boundaries[1].push_back(0);
1025 new_elements[1].push_back(constrained_edges[0]);
1026 new_elements[1].push_back(constrained_edges[8]);
1027 new_elements[1].push_back(constrained_edges[2]);
1028 new_elements[1].push_back(n[k]);
1029 new_boundaries[1].push_back(0);
1030 new_boundaries[1].push_back(b[element_order[0]][n[l]]);
1031 new_boundaries[1].push_back(b[element_order[4]][n[l]]);
1032 new_boundaries[1].push_back(0);
1034 new_elements[1].push_back(constrained_edges[2]);
1035 new_elements[1].push_back(constrained_edges[8]);
1036 new_elements[1].push_back(constrained_edges[6]);
1037 new_elements[1].push_back(n[k]);
1038 new_boundaries[1].push_back(b[element_order[3]][n[l]]);
1039 new_boundaries[1].push_back(0);
1040 new_boundaries[1].push_back(0);
1041 new_boundaries[1].push_back(0);
1043 new_elements[1].push_back(constrained_edges[2]);
1044 new_elements[1].push_back(constrained_edges[6]);
1045 new_elements[1].push_back(constrained_edges[4]);
1046 new_elements[1].push_back(n[k]);
1047 new_boundaries[1].push_back(b[element_order[2]][n[l]]);
1048 new_boundaries[1].push_back(b[element_order[1]][n[l]]);
1049 new_boundaries[1].push_back(0);
1050 new_boundaries[1].push_back(0);
1053 new_elements[2].push_back(constrained_edges[4]);
1054 new_elements[2].push_back(constrained_edges[0]);
1055 new_elements[2].push_back(constrained_edges[2]);
1056 new_elements[2].push_back(n[l]);
1057 new_boundaries[2].push_back(b[element_order[0]][n[k]]);
1058 new_boundaries[2].push_back(b[element_order[1]][n[k]]);
1059 new_boundaries[2].push_back(0);
1060 new_boundaries[2].push_back(0);
1062 new_elements[2].push_back(constrained_edges[4]);
1063 new_elements[2].push_back(constrained_edges[8]);
1064 new_elements[2].push_back(constrained_edges[0]);
1065 new_elements[2].push_back(n[l]);
1066 new_boundaries[2].push_back(b[element_order[4]][n[k]]);
1067 new_boundaries[2].push_back(0);
1068 new_boundaries[2].push_back(0);
1069 new_boundaries[2].push_back(0);
1071 new_elements[2].push_back(constrained_edges[4]);
1072 new_elements[2].push_back(constrained_edges[6]);
1073 new_elements[2].push_back(constrained_edges[8]);
1074 new_elements[2].push_back(n[l]);
1075 new_boundaries[2].push_back(b[element_order[3]][n[k]]);
1076 new_boundaries[2].push_back(0);
1077 new_boundaries[2].push_back(b[element_order[2]][n[k]]);
1078 new_boundaries[2].push_back(0);
1080 new_elements[2].push_back(constrained_edges[4]);
1081 new_elements[2].push_back(constrained_edges[2]);
1082 new_elements[2].push_back(constrained_edges[0]);
1083 new_elements[2].push_back(n[k]);
1084 new_boundaries[2].push_back(b[element_order[0]][n[l]]);
1085 new_boundaries[2].push_back(0);
1086 new_boundaries[2].push_back(b[element_order[1]][n[l]]);
1087 new_boundaries[2].push_back(0);
1089 new_elements[2].push_back(constrained_edges[4]);
1090 new_elements[2].push_back(constrained_edges[0]);
1091 new_elements[2].push_back(constrained_edges[8]);
1092 new_elements[2].push_back(n[k]);
1093 new_boundaries[2].push_back(b[element_order[4]][n[l]]);
1094 new_boundaries[2].push_back(0);
1095 new_boundaries[2].push_back(0);
1096 new_boundaries[2].push_back(0);
1098 new_elements[2].push_back(constrained_edges[4]);
1099 new_elements[2].push_back(constrained_edges[8]);
1100 new_elements[2].push_back(constrained_edges[6]);
1101 new_elements[2].push_back(n[k]);
1102 new_boundaries[2].push_back(b[element_order[3]][n[l]]);
1103 new_boundaries[2].push_back(b[element_order[2]][n[l]]);
1104 new_boundaries[2].push_back(0);
1105 new_boundaries[2].push_back(0);
1108 new_elements[3].push_back(constrained_edges[6]);
1109 new_elements[3].push_back(constrained_edges[2]);
1110 new_elements[3].push_back(constrained_edges[4]);
1111 new_elements[3].push_back(n[l]);
1112 new_boundaries[3].push_back(b[element_order[1]][n[k]]);
1113 new_boundaries[3].push_back(b[element_order[2]][n[k]]);
1114 new_boundaries[3].push_back(0);
1115 new_boundaries[3].push_back(0);
1117 new_elements[3].push_back(constrained_edges[6]);
1118 new_elements[3].push_back(constrained_edges[0]);
1119 new_elements[3].push_back(constrained_edges[2]);
1120 new_elements[3].push_back(n[l]);
1121 new_boundaries[3].push_back(b[element_order[0]][n[k]]);
1122 new_boundaries[3].push_back(0);
1123 new_boundaries[3].push_back(0);
1124 new_boundaries[3].push_back(0);
1126 new_elements[3].push_back(constrained_edges[6]);
1127 new_elements[3].push_back(constrained_edges[8]);
1128 new_elements[3].push_back(constrained_edges[0]);
1129 new_elements[3].push_back(n[l]);
1130 new_boundaries[3].push_back(b[element_order[4]][n[k]]);
1131 new_boundaries[3].push_back(0);
1132 new_boundaries[3].push_back(b[element_order[3]][n[k]]);
1133 new_boundaries[3].push_back(0);
1135 new_elements[3].push_back(constrained_edges[6]);
1136 new_elements[3].push_back(constrained_edges[4]);
1137 new_elements[3].push_back(constrained_edges[2]);
1138 new_elements[3].push_back(n[k]);
1139 new_boundaries[3].push_back(b[element_order[1]][n[l]]);
1140 new_boundaries[3].push_back(0);
1141 new_boundaries[3].push_back(b[element_order[2]][n[l]]);
1142 new_boundaries[3].push_back(0);
1144 new_elements[3].push_back(constrained_edges[6]);
1145 new_elements[3].push_back(constrained_edges[2]);
1146 new_elements[3].push_back(constrained_edges[0]);
1147 new_elements[3].push_back(n[k]);
1148 new_boundaries[3].push_back(b[element_order[0]][n[l]]);
1149 new_boundaries[3].push_back(0);
1150 new_boundaries[3].push_back(0);
1151 new_boundaries[3].push_back(0);
1153 new_elements[3].push_back(constrained_edges[6]);
1154 new_elements[3].push_back(constrained_edges[0]);
1155 new_elements[3].push_back(constrained_edges[8]);
1156 new_elements[3].push_back(n[k]);
1157 new_boundaries[3].push_back(b[element_order[4]][n[l]]);
1158 new_boundaries[3].push_back(b[element_order[3]][n[l]]);
1159 new_boundaries[3].push_back(0);
1160 new_boundaries[3].push_back(0);
1163 new_elements[4].push_back(constrained_edges[8]);
1164 new_elements[4].push_back(constrained_edges[0]);
1165 new_elements[4].push_back(constrained_edges[2]);
1166 new_elements[4].push_back(n[l]);
1167 new_boundaries[4].push_back(b[element_order[0]][n[k]]);
1168 new_boundaries[4].push_back(0);
1169 new_boundaries[4].push_back(b[element_order[4]][n[k]]);
1170 new_boundaries[4].push_back(0);
1172 new_elements[4].push_back(constrained_edges[8]);
1173 new_elements[4].push_back(constrained_edges[2]);
1174 new_elements[4].push_back(constrained_edges[4]);
1175 new_elements[4].push_back(n[l]);
1176 new_boundaries[4].push_back(b[element_order[1]][n[k]]);
1177 new_boundaries[4].push_back(0);
1178 new_boundaries[4].push_back(0);
1179 new_boundaries[4].push_back(0);
1181 new_elements[4].push_back(constrained_edges[8]);
1182 new_elements[4].push_back(constrained_edges[4]);
1183 new_elements[4].push_back(constrained_edges[6]);
1184 new_elements[4].push_back(n[l]);
1185 new_boundaries[4].push_back(b[element_order[2]][n[k]]);
1186 new_boundaries[4].push_back(b[element_order[3]][n[k]]);
1187 new_boundaries[4].push_back(0);
1188 new_boundaries[4].push_back(0);
1190 new_elements[4].push_back(constrained_edges[8]);
1191 new_elements[4].push_back(constrained_edges[2]);
1192 new_elements[4].push_back(constrained_edges[0]);
1193 new_elements[4].push_back(n[k]);
1194 new_boundaries[4].push_back(b[element_order[0]][n[l]]);
1195 new_boundaries[4].push_back(b[element_order[4]][n[l]]);
1196 new_boundaries[4].push_back(0);
1197 new_boundaries[4].push_back(0);
1199 new_elements[4].push_back(constrained_edges[8]);
1200 new_elements[4].push_back(constrained_edges[4]);
1201 new_elements[4].push_back(constrained_edges[2]);
1202 new_elements[4].push_back(n[k]);
1203 new_boundaries[4].push_back(b[element_order[1]][n[l]]);
1204 new_boundaries[4].push_back(0);
1205 new_boundaries[4].push_back(0);
1206 new_boundaries[4].push_back(0);
1208 new_elements[4].push_back(constrained_edges[8]);
1209 new_elements[4].push_back(constrained_edges[6]);
1210 new_elements[4].push_back(constrained_edges[4]);
1211 new_elements[4].push_back(n[k]);
1212 new_boundaries[4].push_back(b[element_order[2]][n[l]]);
1213 new_boundaries[4].push_back(0);
1214 new_boundaries[4].push_back(b[element_order[3]][n[l]]);
1215 new_boundaries[4].push_back(0);
1216 }
else if(nelements==6){
1218 new_elements.resize(1);
1219 new_boundaries.resize(1);
1221 new_elements[0].push_back(constrained_edges[0]);
1222 new_elements[0].push_back(constrained_edges[2]);
1223 new_elements[0].push_back(constrained_edges[10]);
1224 new_elements[0].push_back(n[l]);
1225 new_boundaries[0].push_back(0);
1226 new_boundaries[0].push_back(b[element_order[5]][n[k]]);
1227 new_boundaries[0].push_back(b[element_order[0]][n[k]]);
1228 new_boundaries[0].push_back(0);
1230 new_elements[0].push_back(constrained_edges[4]);
1231 new_elements[0].push_back(constrained_edges[6]);
1232 new_elements[0].push_back(constrained_edges[8]);
1233 new_elements[0].push_back(n[l]);
1234 new_boundaries[0].push_back(b[element_order[3]][n[k]]);
1235 new_boundaries[0].push_back(0);
1236 new_boundaries[0].push_back(b[element_order[2]][n[k]]);
1237 new_boundaries[0].push_back(0);
1239 new_elements[0].push_back(constrained_edges[2]);
1240 new_elements[0].push_back(constrained_edges[4]);
1241 new_elements[0].push_back(constrained_edges[10]);
1242 new_elements[0].push_back(n[l]);
1243 new_boundaries[0].push_back(0);
1244 new_boundaries[0].push_back(0);
1245 new_boundaries[0].push_back(b[element_order[1]][n[k]]);
1246 new_boundaries[0].push_back(0);
1248 new_elements[0].push_back(constrained_edges[10]);
1249 new_elements[0].push_back(constrained_edges[4]);
1250 new_elements[0].push_back(constrained_edges[8]);
1251 new_elements[0].push_back(n[l]);
1252 new_boundaries[0].push_back(0);
1253 new_boundaries[0].push_back(b[element_order[4]][n[k]]);
1254 new_boundaries[0].push_back(0);
1255 new_boundaries[0].push_back(0);
1257 new_elements[0].push_back(constrained_edges[2]);
1258 new_elements[0].push_back(constrained_edges[0]);
1259 new_elements[0].push_back(constrained_edges[10]);
1260 new_elements[0].push_back(n[k]);
1261 new_boundaries[0].push_back(b[element_order[5]][n[l]]);
1262 new_boundaries[0].push_back(0);
1263 new_boundaries[0].push_back(b[element_order[0]][n[l]]);
1264 new_boundaries[0].push_back(0);
1266 new_elements[0].push_back(constrained_edges[6]);
1267 new_elements[0].push_back(constrained_edges[4]);
1268 new_elements[0].push_back(constrained_edges[8]);
1269 new_elements[0].push_back(n[k]);
1270 new_boundaries[0].push_back(0);
1271 new_boundaries[0].push_back(b[element_order[3]][n[l]]);
1272 new_boundaries[0].push_back(b[element_order[2]][n[l]]);
1273 new_boundaries[0].push_back(0);
1275 new_elements[0].push_back(constrained_edges[4]);
1276 new_elements[0].push_back(constrained_edges[2]);
1277 new_elements[0].push_back(constrained_edges[10]);
1278 new_elements[0].push_back(n[k]);
1279 new_boundaries[0].push_back(0);
1280 new_boundaries[0].push_back(0);
1281 new_boundaries[0].push_back(b[element_order[1]][n[l]]);
1282 new_boundaries[0].push_back(0);
1284 new_elements[0].push_back(constrained_edges[4]);
1285 new_elements[0].push_back(constrained_edges[10]);
1286 new_elements[0].push_back(constrained_edges[8]);
1287 new_elements[0].push_back(n[k]);
1288 new_boundaries[0].push_back(b[element_order[4]][n[l]]);
1289 new_boundaries[0].push_back(0);
1290 new_boundaries[0].push_back(0);
1291 new_boundaries[0].push_back(0);
1296 nelements = new_elements[0].size()/4;
1299 std::vector<double> new_min_quality(new_elements.size());
1300 std::vector< std::vector<double> > newq(new_elements.size());
1302 for(
int invert=0;invert<2;invert++){
1304 for(
size_t option=0;option<new_elements.size();option++){
1305 newq[option].resize(nelements);
1306 for(
size_t j=0;j<nelements;j++){
1307 newq[option][j] =
property->lipnikov(_mesh->get_coords(new_elements[option][j*4+0]),
1308 _mesh->get_coords(new_elements[option][j*4+1]),
1309 _mesh->get_coords(new_elements[option][j*4+2]),
1310 _mesh->get_coords(new_elements[option][j*4+3]),
1311 _mesh->get_metric(new_elements[option][j*4+0]),
1312 _mesh->get_metric(new_elements[option][j*4+1]),
1313 _mesh->get_metric(new_elements[option][j*4+2]),
1314 _mesh->get_metric(new_elements[option][j*4+3]));
1317 new_min_quality[option] = newq[option][0];
1318 for(
size_t j=0;j<nelements;j++)
1319 new_min_quality[option] = std::min(newq[option][j], new_min_quality[option]);
1323 for(
size_t option=1;option<new_elements.size();option++){
1324 if(new_min_quality[option]>new_min_quality[best_option]){
1325 best_option = option;
1329 if(new_min_quality[best_option] < 0.0){
1331 std::vector< std::vector<index_t> >::iterator it, bit;
1332 for(it=new_elements.begin(), bit=new_boundaries.begin(); it!=new_elements.end(); ++it, ++bit){
1333 for(
size_t j=0;j<nelements;j++){
1334 index_t stash_id = (*it)[j*4];
1335 (*it)[j*4] = (*it)[j*4+1];
1336 (*it)[j*4+1] = stash_id;
1337 int stash_b = (*bit)[j*4];
1338 (*bit)[j*4] = (*bit)[j*4+1];
1339 (*bit)[j*4+1] = stash_b;
1348 if(new_min_quality[best_option] <= min_quality)
1352 std::vector<index_t>::iterator vit = std::find(_mesh->NNList[n[k]].begin(), _mesh->NNList[n[k]].end(), n[l]);
1353 assert(vit != _mesh->NNList[n[k]].end());
1354 _mesh->NNList[n[k]].erase(vit);
1355 vit = std::find(_mesh->NNList[n[l]].begin(), _mesh->NNList[n[l]].end(), n[k]);
1356 assert(vit != _mesh->NNList[n[l]].end());
1357 _mesh->NNList[n[l]].erase(vit);
1360 for(
typename std::set<index_t>::const_iterator it=neigh_elements.begin();it!=neigh_elements.end();++it)
1361 _mesh->erase_element(*it);
1364 for(
size_t j=0;j<nelements;j++){
1365 int eid = _mesh->append_element(&(new_elements[best_option][j*4]), &(new_boundaries[best_option][j*4]));
1366 quality.push_back(newq[best_option][j]);
1368 for(
int p=0; p<nloc; ++p){
1369 index_t v1 = new_elements[best_option][j*4+p];
1370 _mesh->NEList[v1].insert(eid);
1372 for(
int q=p+1; q<nloc; ++q){
1373 index_t v2 = new_elements[best_option][j*4+q];
1374 std::vector<index_t>::iterator vit = std::find(_mesh->NNList[v1].begin(), _mesh->NNList[v1].end(), v2);
1375 if(vit == _mesh->NNList[v1].end()){
1376 _mesh->NNList[v1].push_back(v2);
1377 _mesh->NNList[v2].push_back(v1);
1394 void swap_kernel2d(
Edge<index_t>& edge, std::set<index_t>& modified_elements,
size_t tid){
1398 if(_mesh->is_halo_node(i)&& _mesh->is_halo_node(j))
1405 std::set<index_t>::const_iterator it=_mesh->NEList[i].begin();
1406 while(loc<2 && it!=_mesh->NEList[i].end()){
1407 if(_mesh->NEList[j].find(*it)!=_mesh->NEList[j].end()){
1408 intersection[loc++] = *it;
1418 index_t eid0 = intersection[0];
1419 index_t eid1 = intersection[1];
1421 const index_t *n = _mesh->get_element(eid0);
1423 for(
size_t k=0;k<3;k++){
1424 if((n[k]!=i) && (n[k]!=j)){
1429 assert(n[n_off]>=0);
1431 const index_t *m = _mesh->get_element(eid1);
1433 for(
size_t k=0;k<3;k++){
1434 if((m[k]!=i) && (m[k]!=j)){
1439 assert(m[m_off]>=0);
1441 assert(n[(n_off+2)%3]==m[(m_off+1)%3] && n[(n_off+1)%3]==m[(m_off+2)%3]);
1446 if(_mesh->is_halo_node(k)&& _mesh->is_halo_node(l))
1449 int n_swap[] = {n[n_off], m[m_off], n[(n_off+2)%3]};
1450 int m_swap[] = {n[n_off], n[(n_off+1)%3], m[m_off]};
1452 real_t q0 =
property->lipnikov(_mesh->get_coords(n_swap[0]),
1453 _mesh->get_coords(n_swap[1]),
1454 _mesh->get_coords(n_swap[2]),
1455 _mesh->get_metric(n_swap[0]),
1456 _mesh->get_metric(n_swap[1]),
1457 _mesh->get_metric(n_swap[2]));
1458 real_t q1 =
property->lipnikov(_mesh->get_coords(m_swap[0]),
1459 _mesh->get_coords(m_swap[1]),
1460 _mesh->get_coords(m_swap[2]),
1461 _mesh->get_metric(m_swap[0]),
1462 _mesh->get_metric(m_swap[1]),
1463 _mesh->get_metric(m_swap[2]));
1464 real_t worst_q = std::min(quality[eid0], quality[eid1]);
1465 real_t new_worst_q = std::min(q0, q1);
1467 if(new_worst_q>worst_q){
1473 typename std::vector<index_t>::iterator it;
1474 it = std::find(_mesh->NNList[i].begin(), _mesh->NNList[i].end(), j);
1475 assert(it != _mesh->NNList[i].end());
1476 _mesh->NNList[i].erase(it);
1477 def_ops->remNN(j, i, tid);
1478 def_ops->addNN(k, l, tid);
1479 def_ops->addNN(l, k, tid);
1482 def_ops->remNE(n_swap[2], eid1, tid);
1483 def_ops->remNE(m_swap[1], eid0, tid);
1484 def_ops->addNE(n_swap[0], eid1, tid);
1485 def_ops->addNE(n_swap[1], eid0, tid);
1488 const int *bn = &_mesh->boundary[eid0*nloc];
1489 const int *bm = &_mesh->boundary[eid1*nloc];
1490 const int bn_swap[] = {bm[(m_off+2)%3], bn[(n_off+1)%3], 0};
1491 const int bm_swap[] = {bm[(m_off+1)%3], 0, bn[(n_off+2)%3]};
1493 for(
size_t cnt=0;cnt<nloc;cnt++){
1494 _mesh->_ENList[eid0*nloc+cnt] = n_swap[cnt];
1495 _mesh->_ENList[eid1*nloc+cnt] = m_swap[cnt];
1496 _mesh->boundary[eid0*nloc+cnt] = bn_swap[cnt];
1497 _mesh->boundary[eid1*nloc+cnt] = bm_swap[cnt];
1500 edge.edge.first = std::min(k, l);
1501 edge.edge.second = std::max(k, l);
1502 modified_elements.insert(eid0);
1503 modified_elements.insert(eid1);
1509 inline void append_element(
const index_t *elem,
const int *
boundary,
const size_t tid){
1510 for(
size_t i=0; i<nloc; ++i){
1511 newElements[tid].push_back(elem[i]);
1512 newBoundaries[tid].push_back(boundary[i]);
1516 inline void replace_element(
const index_t eid,
const index_t *n,
const int *boundary){
1517 for(
size_t i=0;i<nloc;i++){
1518 _mesh->_ENList[eid*nloc+i]=n[i];
1519 _mesh->boundary[eid*nloc+i]=boundary[i];
1526 size_t nnodes_reserve;
1530 static const int max_colour = (dim==2?16:64);
1531 std::vector<index_t> GlobalActiveSet;
1532 size_t GlobalActiveSet_size[3];
1533 std::vector<size_t> ind_set_size[3];
1534 std::vector< std::vector< std::vector<index_t> > > ind_sets;
1535 std::vector< std::vector< std::pair<size_t,size_t> > > range_indexer;
1539 size_t worklist_size[3];
1541 static const size_t ndims=dim;
1542 static const size_t nloc=dim+1;
1543 static const size_t msize=(dim==2?3:6);
1546 static const int defOp_scaling_factor = 32;
1548 std::vector< std::vector<index_t> > newElements;
1549 std::vector< std::vector<int> > newBoundaries;
1550 std::vector<size_t> threadIdx, splitCnt;
1552 std::vector< std::set<index_t> > marked_edges;
1553 std::vector<real_t> quality;
Swapping(Mesh< real_t > &mesh)
Default constructor.
Calculates a number of element properties.
Performs edge/face swapping.
bool pragmatic_range_element_comparator(range_element p1, range_element p2)
void swap(real_t quality_tolerance)
~Swapping()
Default destructor.
bool pragmatic_range_element_finder(range_element p1, range_element p2)
static void greedy(size_t NNodes, const std::vector< std::vector< index_t > > &NNList, std::vector< char > &colour)
int pragmatic_thread_id()
size_t pragmatic_omp_atomic_capture(size_t *shared, size_t inc)
std::pair< std::pair< size_t, size_t >, int > range_element