56 template<
typename real_t,
int dim>
class Refine{
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]), _mesh->get_coords(n[2]));
76 _mesh->get_coords(n[1]), _mesh->get_coords(n[2]), _mesh->get_coords(n[3]));
81 MPI_Comm comm = _mesh->get_mpi_comm();
88 newVertices.resize(nthreads);
89 newElements.resize(nthreads);
90 newBoundaries.resize(nthreads);
91 newCoords.resize(nthreads);
92 newMetric.resize(nthreads);
95 allNewVertices.resize(_mesh->_ENList.size());
97 threadIdx.resize(nthreads);
98 splitCnt.resize(nthreads);
102 cidRecv_additional.resize(nprocs);
103 cidSend_additional.resize(nprocs);
133 size_t origNElements = _mesh->get_number_elements();
134 size_t origNNodes = _mesh->get_number_nodes();
135 size_t edgeSplitCnt = 0;
139 #pragma omp single nowait
141 new_vertices_per_element.resize(nedge*origNElements);
142 std::fill(new_vertices_per_element.begin(), new_vertices_per_element.end(), -1);
153 size_t reserve_size = nedge*origNNodes/nthreads;
154 newVertices[tid].clear(); newVertices[tid].reserve(reserve_size);
155 newCoords[tid].clear(); newCoords[tid].reserve(ndims*reserve_size);
156 newMetric[tid].clear(); newMetric[tid].reserve(msize*reserve_size);
160 #pragma omp for schedule(guided) nowait
161 for(
size_t i=0;i<origNNodes;++i){
162 for(
size_t it=0;it<_mesh->NNList[i].size();++it){
163 index_t otherVertex = _mesh->NNList[i][it];
164 assert(otherVertex>=0);
170 if(_mesh->lnn2gnn[i] < _mesh->lnn2gnn[otherVertex]){
171 double length = _mesh->calc_edge_length(i, otherVertex);
174 refine_edge(i, otherVertex, tid);
181 assert(newVertices[tid].size()==splitCnt[tid]);
187 size_t reserve = 1.1*_mesh->NNodes;
188 if(_mesh->_coords.size()<reserve*ndims){
189 _mesh->_coords.resize(reserve*ndims);
190 _mesh->metric.resize(reserve*msize);
191 _mesh->NNList.resize(reserve);
192 _mesh->NEList.resize(reserve);
193 _mesh->node_owner.resize(reserve);
194 _mesh->lnn2gnn.resize(reserve);
196 edgeSplitCnt = _mesh->NNodes - origNNodes;
200 memcpy(&_mesh->_coords[ndims*threadIdx[tid]], &newCoords[tid][0], ndims*splitCnt[tid]*
sizeof(real_t));
201 memcpy(&_mesh->metric[msize*threadIdx[tid]], &newMetric[tid][0], msize*splitCnt[tid]*
sizeof(
double));
204 assert(newVertices[tid].size()==splitCnt[tid]);
205 for(
size_t i=0;i<splitCnt[tid];i++){
206 newVertices[tid][i].id = threadIdx[tid]+i;
210 memcpy(&allNewVertices[threadIdx[tid]-origNNodes], &newVertices[tid][0], newVertices[tid].size()*
sizeof(
DirectedEdge<index_t>));
215 #pragma omp for schedule(guided)
216 for(
size_t i=0; i<edgeSplitCnt; ++i){
217 index_t vid = allNewVertices[i].id;
218 index_t firstid = allNewVertices[i].edge.first;
219 index_t secondid = allNewVertices[i].edge.second;
222 std::set<index_t> intersection;
223 std::set_intersection(_mesh->NEList[firstid].begin(), _mesh->NEList[firstid].end(),
224 _mesh->NEList[secondid].begin(), _mesh->NEList[secondid].end(),
225 std::inserter(intersection, intersection.begin()));
227 for(
typename std::set<index_t>::const_iterator element=intersection.begin(); element!=intersection.end(); ++element){
229 size_t edgeOffset = edgeNumber(eid, firstid, secondid);
230 new_vertices_per_element[nedge*eid+edgeOffset] = vid;
238 _mesh->NNList[vid].push_back(firstid);
239 _mesh->NNList[vid].push_back(secondid);
241 def_ops->remNN(firstid, secondid, tid);
242 def_ops->addNN(firstid, vid, tid);
243 def_ops->remNN(secondid, firstid, tid);
244 def_ops->addNN(secondid, vid, tid);
249 _mesh->node_owner[vid] = 0;
250 _mesh->lnn2gnn[vid] = vid;
258 int owner0 = _mesh->node_owner[firstid];
259 int owner1 = _mesh->node_owner[secondid];
260 int owner = std::min(owner0, owner1);
261 _mesh->node_owner[vid] = owner;
263 if(_mesh->node_owner[vid] == rank)
264 _mesh->lnn2gnn[vid] = _mesh->gnn_offset+vid;
270 #pragma omp for schedule(guided)
271 for(
index_t eid=0; eid<origNElements; ++eid){
273 const index_t *n = _mesh->get_element(eid);
277 const index_t facets[4][3] = {{n[0], n[1], n[2]},
282 for(
int j=0; j<4; ++j){
284 const index_t *facet = facets[j];
285 std::set<index_t> intersection01, EE;
286 std::set_intersection(_mesh->NEList[facet[0]].begin(), _mesh->NEList[facet[0]].end(),
287 _mesh->NEList[facet[1]].begin(), _mesh->NEList[facet[1]].end(),
288 std::inserter(intersection01, intersection01.begin()));
289 std::set_intersection(_mesh->NEList[facet[2]].begin(), _mesh->NEList[facet[2]].end(),
290 intersection01.begin(), intersection01.end(),
291 std::inserter(EE, EE.begin()));
293 assert(EE.size() <= 2 );
294 assert(EE.count(eid) == 1);
298 if(eid == *EE.rbegin())
299 for(
size_t k=0; k<3; ++k)
300 if(new_vertices_per_element[nedge*eid+edgeNumber(eid, facet[k], facet[(k+1)%3])] != -1){
301 refine_facet(eid, facet, tid);
307 #pragma omp for schedule(guided)
308 for(
int vtid=0; vtid<defOp_scaling_factor*nthreads; ++vtid){
309 for(
int i=0; i<nthreads; ++i){
310 def_ops->commit_remNN(i, vtid);
311 def_ops->commit_addNN(i, vtid);
318 newElements[tid].clear(); newBoundaries[tid].clear();
319 newElements[tid].reserve(dim*dim*origNElements/nthreads);
320 newBoundaries[tid].reserve(dim*dim*origNElements/nthreads);
322 #pragma omp for schedule(guided) nowait
323 for(
size_t eid=0; eid<origNElements; ++eid){
325 const index_t *n = _mesh->get_element(eid);
329 for(
size_t j=0; j<nedge; ++j)
330 if(new_vertices_per_element[nedge*eid+j] != -1){
331 refine_element(eid, tid);
341 if(_mesh->_ENList.size()<_mesh->NElements*nloc){
342 _mesh->_ENList.resize(_mesh->NElements*nloc);
343 _mesh->boundary.resize(_mesh->NElements*nloc);
348 memcpy(&_mesh->_ENList[nloc*threadIdx[tid]], &newElements[tid][0], nloc*splitCnt[tid]*
sizeof(
index_t));
349 memcpy(&_mesh->boundary[nloc*threadIdx[tid]], &newBoundaries[tid][0], nloc*splitCnt[tid]*
sizeof(
int));
352 #pragma omp for schedule(guided)
353 for(
int vtid=0; vtid<defOp_scaling_factor*nthreads; ++vtid){
354 for(
int i=0; i<nthreads; ++i){
355 def_ops->commit_remNN(i, vtid);
356 def_ops->commit_addNN(i, vtid);
357 def_ops->commit_remNE(i, vtid);
358 def_ops->commit_addNE(i, vtid);
359 def_ops->commit_addNE_fix(threadIdx, i, vtid);
368 std::vector< std::set< DirectedEdge<index_t> > > recv_additional(nprocs), send_additional(nprocs);
370 for(
size_t i=0; i<edgeSplitCnt; ++i){
373 if(_mesh->node_owner[vert->id] != rank){
377 bool visible =
false;
378 for(
typename std::vector<index_t>::const_iterator neigh=_mesh->NNList[vert->id].begin(); neigh!=_mesh->NNList[vert->id].end(); ++neigh){
379 if(_mesh->is_owned_node(*neigh)){
381 DirectedEdge<index_t> gnn_edge(_mesh->lnn2gnn[vert->edge.first], _mesh->lnn2gnn[vert->edge.second], vert->id);
382 recv_additional[_mesh->node_owner[vert->id]].insert(gnn_edge);
389 if(_mesh->is_halo_node(vert->edge.first) && _mesh->is_halo_node(vert->edge.second)){
391 std::set<int> processes;
392 for(
typename std::vector<index_t>::const_iterator neigh=_mesh->NNList[vert->id].begin(); neigh!=_mesh->NNList[vert->id].end(); ++neigh)
393 processes.insert(_mesh->node_owner[*neigh]);
395 processes.erase(rank);
397 for(
typename std::set<int>::const_iterator proc=processes.begin(); proc!=processes.end(); ++proc){
398 DirectedEdge<index_t> gnn_edge(_mesh->lnn2gnn[vert->edge.first], _mesh->lnn2gnn[vert->edge.second], vert->id);
399 send_additional[*proc].insert(gnn_edge);
407 std::vector<size_t> recv_cnt(nprocs, 0), send_cnt(nprocs, 0);
409 for(
int i=0;i<nprocs;++i){
410 recv_cnt[i] = recv_additional[i].size();
411 for(
typename std::set<
DirectedEdge<index_t> >::const_iterator it=recv_additional[i].begin();it!=recv_additional[i].end();++it){
412 _mesh->recv[i].push_back(it->id);
413 _mesh->recv_halo.insert(it->id);
416 send_cnt[i] = send_additional[i].size();
417 for(
typename std::set<
DirectedEdge<index_t> >::const_iterator it=send_additional[i].begin();it!=send_additional[i].end();++it){
418 _mesh->send[i].push_back(it->id);
419 _mesh->send_halo.insert(it->id);
425 for(
int i=0;i<nprocs;++i){
426 recv_cnt[i] += cidRecv_additional[i].size();
427 for(
typename std::set<Wedge>::const_iterator it=cidRecv_additional[i].begin();it!=cidRecv_additional[i].end();++it){
428 _mesh->recv[i].push_back(it->cid);
429 _mesh->recv_halo.insert(it->cid);
432 send_cnt[i] += cidSend_additional[i].size();
433 for(
typename std::set<Wedge>::const_iterator it=cidSend_additional[i].begin();it!=cidSend_additional[i].end();++it){
434 _mesh->send[i].push_back(it->cid);
435 _mesh->send_halo.insert(it->cid);
441 _mesh->update_gappy_global_numbering(recv_cnt, send_cnt);
444 for(
int i=0;i<nprocs;++i){
445 for(
typename std::set<
DirectedEdge<index_t> >::const_iterator it=recv_additional[i].begin();it!=recv_additional[i].end();++it)
446 _mesh->recv_map[i][_mesh->lnn2gnn[it->id]] = it->id;
448 for(
typename std::set<
DirectedEdge<index_t> >::const_iterator it=send_additional[i].begin();it!=send_additional[i].end();++it)
449 _mesh->send_map[i][_mesh->lnn2gnn[it->id]] = it->id;
453 for(
typename std::set<Wedge>::const_iterator it=cidRecv_additional[i].begin();it!=cidRecv_additional[i].end();++it)
454 _mesh->recv_map[i][_mesh->lnn2gnn[it->cid]] = it->cid;
456 for(
typename std::set<Wedge>::const_iterator it=cidSend_additional[i].begin();it!=cidSend_additional[i].end();++it)
457 _mesh->send_map[i][_mesh->lnn2gnn[it->cid]] = it->cid;
459 cidRecv_additional[i].clear();
460 cidSend_additional[i].clear();
473 size_t NElements = _mesh->get_number_elements();
475 #pragma omp for schedule(guided)
476 for(
size_t i=0;i<NElements;i++){
477 index_t n0 = _mesh->_ENList[i*nloc];
481 index_t n1 = _mesh->_ENList[i*nloc + 1];
482 index_t n2 = _mesh->_ENList[i*nloc + 2];
484 const real_t *x0 = &_mesh->_coords[n0*ndims];
485 const real_t *
x1 = &_mesh->_coords[n1*ndims];
486 const real_t *
x2 = &_mesh->_coords[n2*ndims];
488 real_t av =
property->area(x0, x1, x2);
492 std::cerr<<
"ERROR: inverted element in refinement"<<std::endl
493 <<
"element = "<<n0<<
", "<<n1<<
", "<<n2<<std::endl;
505 if(_mesh->lnn2gnn[n0] > _mesh->lnn2gnn[n1]){
516 const real_t *x0 = _mesh->get_coords(n0);
517 const double *m0 = _mesh->get_metric(n0);
519 const real_t *
x1 = _mesh->get_coords(n1);
520 const double *m1 = _mesh->get_metric(n1);
522 real_t weight = 1.0/(1.0 + sqrt(property->template length<dim>(x0, x1, m0)/
523 property->template length<dim>(x0, x1, m1)));
526 for(
size_t i=0;i<ndims;i++){
527 x = x0[i]+weight*(x1[i] - x0[i]);
528 newCoords[tid].push_back(x);
532 for(
size_t i=0;i<msize;i++){
533 m = m0[i]+weight*(m1[i] - m0[i]);
534 newMetric[tid].push_back(m);
536 std::cerr<<
"ERROR: metric health is bad in "<<__FILE__<<std::endl
537 <<
"m0[i] = "<<m0[i]<<std::endl
538 <<
"m1[i] = "<<m1[i]<<std::endl
539 <<
"property->length(x0, x1, m0) = "<<
property->template length<dim>(x0,
x1, m0)<<std::endl
540 <<
"property->length(x0, x1, m1) = "<<property->template length<dim>(x0, x1, m1)<<std::endl
541 <<
"weight = "<<weight<<std::endl;
546 const index_t *n=_mesh->get_element(eid);
548 index_t newVertex[3] = {-1, -1, -1};
549 newVertex[0] = new_vertices_per_element[nedge*eid+edgeNumber(eid, facet[1], facet[2])];
550 newVertex[1] = new_vertices_per_element[nedge*eid+edgeNumber(eid, facet[0], facet[2])];
551 newVertex[2] = new_vertices_per_element[nedge*eid+edgeNumber(eid, facet[0], facet[1])];
554 for(
size_t i=0; i<3; ++i)
564 for(
int j=0; j<3; j++)
565 if(newVertex[j] >= 0){
566 def_ops->addNN(newVertex[j], facet[j], tid);
567 def_ops->addNN(facet[j], newVertex[j], tid);
573 for(
int j=0; j<3; j++){
574 if(newVertex[j] < 0){
575 def_ops->addNN(newVertex[(j+1)%3], newVertex[(j+2)%3], tid);
576 def_ops->addNN(newVertex[(j+2)%3], newVertex[(j+1)%3], tid);
578 real_t ldiag1 = _mesh->calc_edge_length(newVertex[(j+1)%3], facet[(j+1)%3]);
579 real_t ldiag2 = _mesh->calc_edge_length(newVertex[(j+2)%3], facet[(j+2)%3]);
580 const int offset = ldiag1 < ldiag2 ? (j+1)%3 : (j+2)%3;
582 def_ops->addNN(newVertex[offset], facet[offset], tid);
583 def_ops->addNN(facet[offset], newVertex[offset], tid);
591 for(
int j=0; j<3; j++){
592 def_ops->addNN(newVertex[j], newVertex[(j+1)%3], tid);
593 def_ops->addNN(newVertex[(j+1)%3], newVertex[j], tid);
601 #ifdef HAVE_BOOST_UNORDERED_MAP_HPP
602 typedef boost::unordered_map<index_t, int> boundary_t;
604 typedef std::map<index_t, int> boundary_t;
607 void refine_element(
size_t eid,
int tid){
615 const int *n=_mesh->get_element(eid);
618 index_t newVertex[3] = {-1, -1, -1};
619 newVertex[0] = new_vertices_per_element[nedge*eid];
620 newVertex[1] = new_vertices_per_element[nedge*eid+1];
621 newVertex[2] = new_vertices_per_element[nedge*eid+2];
624 for(
size_t i=0; i<3; ++i)
629 (this->*refineMode2D[refine_cnt-1])(newVertex, eid, tid);
638 const int *n=_mesh->get_element(eid);
641 std::vector< DirectedEdge<index_t> > splitEdges;
642 for(
int j=0, pos=0; j<4; j++)
643 for(
int k=j+1; k<4; k++){
644 index_t vertexID = new_vertices_per_element[nedge*eid+pos];
650 refine_cnt=splitEdges.size();
653 (this->*refineMode3D[refine_cnt-1])(splitEdges, eid, tid);
657 void refine2D_1(
const index_t *newVertex,
int eid,
int tid){
660 const int *n=_mesh->get_element(eid);
661 const int *
boundary=&(_mesh->boundary[eid*nloc]);
664 int rotated_boundary[3];
667 if(newVertex[j] >= 0){
668 vertexID = newVertex[j];
670 rotated_ele[0] = n[j];
671 rotated_ele[1] = n[(j+1)%3];
672 rotated_ele[2] = n[(j+2)%3];
674 rotated_boundary[0] = boundary[j];
675 rotated_boundary[1] = boundary[(j+1)%3];
676 rotated_boundary[2] = boundary[(j+2)%3];
680 assert(vertexID!=-1);
682 const index_t ele0[] = {rotated_ele[0], rotated_ele[1], vertexID};
683 const index_t ele1[] = {rotated_ele[0], vertexID, rotated_ele[2]};
685 const index_t ele0_boundary[] = {rotated_boundary[0], 0, rotated_boundary[2]};
686 const index_t ele1_boundary[] = {rotated_boundary[0], rotated_boundary[1], 0};
689 ele1ID = splitCnt[tid];
692 def_ops->addNN(vertexID, rotated_ele[0], tid);
694 def_ops->addNN(rotated_ele[0], vertexID, tid);
700 def_ops->addNE_fix(rotated_ele[0], ele1ID, tid);
703 def_ops->addNE(vertexID, eid, tid);
704 def_ops->addNE_fix(vertexID, ele1ID, tid);
707 def_ops->remNE(rotated_ele[2], eid, tid);
708 def_ops->addNE_fix(rotated_ele[2], ele1ID, tid);
710 assert(ele0[0]>=0 && ele0[1]>=0 && ele0[2]>=0);
711 assert(ele1[0]>=0 && ele1[1]>=0 && ele1[2]>=0);
713 replace_element(eid, ele0, ele0_boundary);
714 append_element(ele1, ele1_boundary, tid);
718 void refine2D_2(
const index_t *newVertex,
int eid,
int tid){
719 const int *n=_mesh->get_element(eid);
720 const int *boundary=&(_mesh->boundary[eid*nloc]);
723 int rotated_boundary[3];
725 for(
int j=0;j<3;j++){
726 if(newVertex[j] < 0){
727 vertexID[0] = newVertex[(j+1)%3];
728 vertexID[1] = newVertex[(j+2)%3];
730 rotated_ele[0] = n[j];
731 rotated_ele[1] = n[(j+1)%3];
732 rotated_ele[2] = n[(j+2)%3];
734 rotated_boundary[0] = boundary[j];
735 rotated_boundary[1] = boundary[(j+1)%3];
736 rotated_boundary[2] = boundary[(j+2)%3];
742 real_t ldiag0 = _mesh->calc_edge_length(rotated_ele[1], vertexID[0]);
743 real_t ldiag1 = _mesh->calc_edge_length(rotated_ele[2], vertexID[1]);
745 const int offset = ldiag0 < ldiag1 ? 0 : 1;
747 const index_t ele0[] = {rotated_ele[0], vertexID[1], vertexID[0]};
748 const index_t ele1[] = {vertexID[offset], rotated_ele[1], rotated_ele[2]};
749 const index_t ele2[] = {vertexID[0], vertexID[1], rotated_ele[offset+1]};
751 const index_t ele0_boundary[] = {0, rotated_boundary[1], rotated_boundary[2]};
752 const index_t ele1_boundary[] = {rotated_boundary[0], (offset==0)?rotated_boundary[1]:0, (offset==0)?0:rotated_boundary[2]};
753 const index_t ele2_boundary[] = {(offset==0)?rotated_boundary[2]:0, (offset==0)?0:rotated_boundary[1], 0};
756 ele0ID = splitCnt[tid];
761 def_ops->addNN(vertexID[0], vertexID[1], tid);
762 def_ops->addNN(vertexID[1], vertexID[0], tid);
765 def_ops->addNN(vertexID[offset], rotated_ele[offset+1], tid);
766 def_ops->addNN(rotated_ele[offset+1], vertexID[offset], tid);
770 def_ops->addNE_fix(rotated_ele[offset+1], ele2ID, tid);
773 def_ops->remNE(rotated_ele[0], eid, tid);
774 def_ops->addNE_fix(rotated_ele[0], ele0ID, tid);
777 def_ops->addNE(vertexID[offset], eid, tid);
778 def_ops->addNE_fix(vertexID[offset], ele0ID, tid);
779 def_ops->addNE_fix(vertexID[offset], ele2ID, tid);
783 def_ops->addNE_fix(vertexID[(offset+1)%2], ele0ID, tid);
784 def_ops->addNE_fix(vertexID[(offset+1)%2], ele2ID, tid);
786 assert(ele0[0]>=0 && ele0[1]>=0 && ele0[2]>=0);
787 assert(ele1[0]>=0 && ele1[1]>=0 && ele1[2]>=0);
788 assert(ele2[0]>=0 && ele2[1]>=0 && ele2[2]>=0);
790 replace_element(eid, ele1, ele1_boundary);
791 append_element(ele0, ele0_boundary, tid);
792 append_element(ele2, ele2_boundary, tid);
796 void refine2D_3(
const index_t *newVertex,
int eid,
int tid){
797 const int *n=_mesh->get_element(eid);
798 const int *boundary=&(_mesh->boundary[eid*nloc]);
800 const index_t ele0[] = {n[0], newVertex[2], newVertex[1]};
801 const index_t ele1[] = {n[1], newVertex[0], newVertex[2]};
802 const index_t ele2[] = {n[2], newVertex[1], newVertex[0]};
803 const index_t ele3[] = {newVertex[0], newVertex[1], newVertex[2]};
805 const int ele0_boundary[] = {0, boundary[1], boundary[2]};
806 const int ele1_boundary[] = {0, boundary[2], boundary[0]};
807 const int ele2_boundary[] = {0, boundary[0], boundary[1]};
808 const int ele3_boundary[] = {0, 0, 0};
810 index_t ele1ID, ele2ID, ele3ID;
811 ele1ID = splitCnt[tid];
816 def_ops->addNN(newVertex[0], newVertex[1], tid);
817 def_ops->addNN(newVertex[0], newVertex[2], tid);
818 def_ops->addNN(newVertex[1], newVertex[0], tid);
819 def_ops->addNN(newVertex[1], newVertex[2], tid);
820 def_ops->addNN(newVertex[2], newVertex[0], tid);
821 def_ops->addNN(newVertex[2], newVertex[1], tid);
824 def_ops->remNE(n[1], eid, tid);
825 def_ops->addNE_fix(n[1], ele1ID, tid);
826 def_ops->remNE(n[2], eid, tid);
827 def_ops->addNE_fix(n[2], ele2ID, tid);
829 def_ops->addNE_fix(newVertex[0], ele1ID, tid);
830 def_ops->addNE_fix(newVertex[0], ele2ID, tid);
831 def_ops->addNE_fix(newVertex[0], ele3ID, tid);
833 def_ops->addNE(newVertex[1], eid, tid);
834 def_ops->addNE_fix(newVertex[1], ele2ID, tid);
835 def_ops->addNE_fix(newVertex[1], ele3ID, tid);
837 def_ops->addNE(newVertex[2], eid, tid);
838 def_ops->addNE_fix(newVertex[2], ele1ID, tid);
839 def_ops->addNE_fix(newVertex[2], ele3ID, tid);
841 assert(ele0[0]>=0 && ele0[1]>=0 && ele0[2]>=0);
842 assert(ele1[0]>=0 && ele1[1]>=0 && ele1[2]>=0);
843 assert(ele2[0]>=0 && ele2[1]>=0 && ele2[2]>=0);
844 assert(ele3[0]>=0 && ele3[1]>=0 && ele3[2]>=0);
846 replace_element(eid, ele0, ele0_boundary);
847 append_element(ele1, ele1_boundary, tid);
848 append_element(ele2, ele2_boundary, tid);
849 append_element(ele3, ele3_boundary, tid);
854 const int *n=_mesh->get_element(eid);
855 const int *boundary=&(_mesh->boundary[eid*nloc]);
858 for(
int j=0; j<nloc; ++j)
859 b[n[j]] = boundary[j];
863 for(
int j=0, pos=0;j<4;j++)
864 if(!splitEdges[0].contains(n[j]))
868 const int ele0[] = {splitEdges[0].edge.first, splitEdges[0].id, oe[0], oe[1]};
869 const int ele1[] = {splitEdges[0].edge.second, splitEdges[0].id, oe[0], oe[1]};
871 const int ele0_boundary[] = {0, b[splitEdges[0].edge.second], b[oe[0]], b[oe[1]]};
872 const int ele1_boundary[] = {0, b[splitEdges[0].edge.first], b[oe[0]], b[oe[1]]};
875 ele1ID = splitCnt[tid];
881 def_ops->addNE_fix(oe[0], ele1ID, tid);
882 def_ops->addNE_fix(oe[1], ele1ID, tid);
885 def_ops->addNE(splitEdges[0].
id, eid, tid);
886 def_ops->addNE_fix(splitEdges[0].
id, ele1ID, tid);
889 def_ops->remNE(splitEdges[0].edge.second, eid, tid);
890 def_ops->addNE_fix(splitEdges[0].edge.second, ele1ID, tid);
892 replace_element(eid, ele0, ele0_boundary);
893 append_element(ele1, ele1_boundary, tid);
898 const int *n=_mesh->get_element(eid);
899 const int *boundary=&(_mesh->boundary[eid*nloc]);
902 for(
int j=0; j<nloc; ++j)
903 b[n[j]] = boundary[j];
911 int n0=splitEdges[0].connected(splitEdges[1]);
918 int n1 = (n0 == splitEdges[0].edge.first) ? splitEdges[0].edge.second : splitEdges[0].edge.first;
919 int n2 = (n0 == splitEdges[1].edge.first) ? splitEdges[1].edge.second : splitEdges[1].edge.first;
923 for(
int j=0; j<nloc; ++j)
924 if(n[j] != n0 && n[j] != n1 && n[j] != n2){
931 std::vector<index_t>::const_iterator p = std::find(_mesh->NNList[splitEdges[0].id].begin(),
932 _mesh->NNList[splitEdges[0].id].end(), n2);
933 if(p != _mesh->NNList[splitEdges[0].id].end()){
934 diagonal.edge.first = splitEdges[0].id;
935 diagonal.edge.second = n2;
936 offdiagonal.edge.first = splitEdges[1].id;
937 offdiagonal.edge.second = n1;
939 assert(std::find(_mesh->NNList[splitEdges[1].id].begin(),
940 _mesh->NNList[splitEdges[1].id].end(), n1) != _mesh->NNList[splitEdges[1].id].end());
941 diagonal.edge.first = splitEdges[1].id;
942 diagonal.edge.second = n1;
943 offdiagonal.edge.first = splitEdges[0].id;
944 offdiagonal.edge.second = n2;
947 const int ele0[] = {n0, splitEdges[0].id, splitEdges[1].id, n3};
948 const int ele1[] = {diagonal.edge.first, offdiagonal.edge.first, diagonal.edge.second, n3};
949 const int ele2[] = {diagonal.edge.first, diagonal.edge.second, offdiagonal.edge.second, n3};
951 const int ele0_boundary[] = {0, b[n1], b[n2], b[n3]};
952 const int ele1_boundary[] = {b[offdiagonal.edge.second], 0, 0, b[n3]};
953 const int ele2_boundary[] = {b[n0], b[diagonal.edge.second], 0, b[n3]};
956 ele1ID = splitCnt[tid];
959 def_ops->addNE(diagonal.edge.first, eid, tid);
960 def_ops->addNE_fix(diagonal.edge.first, ele1ID, tid);
961 def_ops->addNE_fix(diagonal.edge.first, ele2ID, tid);
963 def_ops->remNE(diagonal.edge.second, eid, tid);
964 def_ops->addNE_fix(diagonal.edge.second, ele1ID, tid);
965 def_ops->addNE_fix(diagonal.edge.second, ele2ID, tid);
967 def_ops->addNE(offdiagonal.edge.first, eid, tid);
968 def_ops->addNE_fix(offdiagonal.edge.first, ele1ID, tid);
970 def_ops->remNE(offdiagonal.edge.second, eid, tid);
971 def_ops->addNE_fix(offdiagonal.edge.second, ele2ID, tid);
973 def_ops->addNE_fix(n3, ele1ID, tid);
974 def_ops->addNE_fix(n3, ele2ID, tid);
976 replace_element(eid, ele0, ele0_boundary);
977 append_element(ele1, ele1_boundary, tid);
978 append_element(ele2, ele2_boundary, tid);
986 const int ele0[] = {splitEdges[0].edge.first, splitEdges[0].id, splitEdges[1].edge.first, splitEdges[1].id};
987 const int ele1[] = {splitEdges[0].edge.first, splitEdges[0].id, splitEdges[1].edge.second, splitEdges[1].id};
988 const int ele2[] = {splitEdges[0].edge.second, splitEdges[0].id, splitEdges[1].edge.first, splitEdges[1].id};
989 const int ele3[] = {splitEdges[0].edge.second, splitEdges[0].id, splitEdges[1].edge.second, splitEdges[1].id};
991 const int ele0_boundary[] = {0, b[splitEdges[0].edge.second], 0, b[splitEdges[1].edge.second]};
992 const int ele1_boundary[] = {0, b[splitEdges[0].edge.second], 0, b[splitEdges[1].edge.first]};
993 const int ele2_boundary[] = {0, b[splitEdges[0].edge.first], 0, b[splitEdges[1].edge.second]};
994 const int ele3_boundary[] = {0, b[splitEdges[0].edge.first], 0, b[splitEdges[1].edge.first]};
996 index_t ele1ID, ele2ID, ele3ID;
997 ele1ID = splitCnt[tid];
1001 def_ops->addNN(splitEdges[0].
id, splitEdges[1].
id, tid);
1002 def_ops->addNN(splitEdges[1].
id, splitEdges[0].
id, tid);
1004 def_ops->addNE(splitEdges[0].
id, eid, tid);
1005 def_ops->addNE_fix(splitEdges[0].
id, ele1ID, tid);
1006 def_ops->addNE_fix(splitEdges[0].
id, ele2ID, tid);
1007 def_ops->addNE_fix(splitEdges[0].
id, ele3ID, tid);
1009 def_ops->addNE(splitEdges[1].
id, eid, tid);
1010 def_ops->addNE_fix(splitEdges[1].
id, ele1ID, tid);
1011 def_ops->addNE_fix(splitEdges[1].
id, ele2ID, tid);
1012 def_ops->addNE_fix(splitEdges[1].
id, ele3ID, tid);
1014 def_ops->addNE_fix(splitEdges[0].edge.first, ele1ID, tid);
1016 def_ops->remNE(splitEdges[0].edge.second, eid, tid);
1017 def_ops->addNE_fix(splitEdges[0].edge.second, ele2ID, tid);
1018 def_ops->addNE_fix(splitEdges[0].edge.second, ele3ID, tid);
1020 def_ops->addNE_fix(splitEdges[1].edge.first, ele2ID, tid);
1022 def_ops->remNE(splitEdges[1].edge.second, eid, tid);
1023 def_ops->addNE_fix(splitEdges[1].edge.second, ele1ID, tid);
1024 def_ops->addNE_fix(splitEdges[1].edge.second, ele3ID, tid);
1026 replace_element(eid, ele0, ele0_boundary);
1027 append_element(ele1, ele1_boundary, tid);
1028 append_element(ele2, ele2_boundary, tid);
1029 append_element(ele3, ele3_boundary, tid);
1035 const int *n=_mesh->get_element(eid);
1036 const int *boundary=&(_mesh->boundary[eid*nloc]);
1039 for(
int j=0; j<nloc; ++j)
1040 b[n[j]] = boundary[j];
1053 std::set<index_t> shared;
1054 for(
int j=0;j<3;j++){
1055 for(
int k=j+1;k<3;k++){
1056 index_t nid = splitEdges[j].connected(splitEdges[k]);
1061 size_t nshared = shared.size();
1069 index_t m[] = {-1, -1, -1, -1, -1, -1, -1};
1071 m[0] = splitEdges[0].edge.first;
1072 m[1] = splitEdges[0].id;
1073 m[2] = splitEdges[0].edge.second;
1074 if(splitEdges[1].contains(m[2])){
1075 m[3] = splitEdges[1].id;
1076 if(splitEdges[1].edge.first!=m[2])
1077 m[4] = splitEdges[1].edge.first;
1079 m[4] = splitEdges[1].edge.second;
1080 m[5] = splitEdges[2].id;
1082 m[3] = splitEdges[2].id;
1083 if(splitEdges[2].edge.first!=m[2])
1084 m[4] = splitEdges[2].edge.first;
1086 m[4] = splitEdges[2].edge.second;
1087 m[5] = splitEdges[1].id;
1089 for(
int j=0;j<4;j++){
1090 if((n[j]!=m[0])&&(n[j]!=m[2])&&(n[j]!=m[4])){
1096 const int ele0[] = {m[0], m[1], m[5], m[6]};
1097 const int ele1[] = {m[1], m[2], m[3], m[6]};
1098 const int ele2[] = {m[5], m[3], m[4], m[6]};
1099 const int ele3[] = {m[1], m[3], m[5], m[6]};
1101 const int ele0_boundary[] = {0, b[m[2]], b[m[4]], b[m[6]]};
1102 const int ele1_boundary[] = {b[m[0]], 0, b[m[4]], b[m[6]]};
1103 const int ele2_boundary[] = {b[m[0]], b[m[2]], 0, b[m[6]]};
1104 const int ele3_boundary[] = {0, 0, 0, b[m[6]]};
1106 index_t ele1ID, ele2ID, ele3ID;
1107 ele1ID = splitCnt[tid];
1111 def_ops->addNE(m[1], eid, tid);
1112 def_ops->addNE_fix(m[1], ele1ID, tid);
1113 def_ops->addNE_fix(m[1], ele3ID, tid);
1115 def_ops->addNE(m[5], eid, tid);
1116 def_ops->addNE_fix(m[5], ele2ID, tid);
1117 def_ops->addNE_fix(m[5], ele3ID, tid);
1119 def_ops->addNE_fix(m[3], ele1ID, tid);
1120 def_ops->addNE_fix(m[3], ele2ID, tid);
1121 def_ops->addNE_fix(m[3], ele3ID, tid);
1123 def_ops->addNE_fix(m[6], ele1ID, tid);
1124 def_ops->addNE_fix(m[6], ele2ID, tid);
1125 def_ops->addNE_fix(m[6], ele3ID, tid);
1127 def_ops->remNE(m[2], eid, tid);
1128 def_ops->addNE_fix(m[2], ele1ID, tid);
1130 def_ops->remNE(m[4], eid, tid);
1131 def_ops->addNE_fix(m[4], ele2ID, tid);
1133 replace_element(eid, ele0, ele0_boundary);
1134 append_element(ele1, ele1_boundary, tid);
1135 append_element(ele2, ele2_boundary, tid);
1136 append_element(ele3, ele3_boundary, tid);
1138 }
else if(nshared==1){
1147 index_t top_vertex = *shared.begin();
1148 index_t bottom_triangle[3], top_triangle[3];
1149 for(
int j=0; j<3; ++j){
1150 if(splitEdges[j].edge.first != top_vertex){
1151 bottom_triangle[j] = splitEdges[j].edge.first;
1153 bottom_triangle[j] = splitEdges[j].edge.second;
1155 top_triangle[j] = splitEdges[j].id;
1159 int bwedge[] = {b[bottom_triangle[2]], b[bottom_triangle[0]], b[bottom_triangle[1]], 0, b[top_vertex]};
1160 refine_wedge(top_triangle, bottom_triangle, bwedge, NULL, eid, tid);
1162 const int ele0[] = {top_vertex, splitEdges[0].id, splitEdges[1].id, splitEdges[2].id};
1163 const int ele0_boundary[] = {0, b[bottom_triangle[0]], b[bottom_triangle[1]], b[bottom_triangle[2]]};
1165 def_ops->remNE(bottom_triangle[0], eid, tid);
1166 def_ops->remNE(bottom_triangle[1], eid, tid);
1167 def_ops->remNE(bottom_triangle[2], eid, tid);
1168 def_ops->addNE(splitEdges[0].
id, eid, tid);
1169 def_ops->addNE(splitEdges[1].
id, eid, tid);
1170 def_ops->addNE(splitEdges[2].
id, eid, tid);
1172 replace_element(eid, ele0, ele0_boundary);
1179 assert(shared.size() == 2);
1192 for(
int j=0; j<3; ++j){
1193 if(splitEdges[j].contains(*shared.begin()) && splitEdges[j].contains(*shared.rbegin())){
1194 middleZ = &splitEdges[j];
1196 if(splitEdges[(j+1)%3].contains(splitEdges[j].edge.first)){
1197 topZ = &splitEdges[(j+1)%3];
1198 bottomZ = &splitEdges[(j+2)%3];
1200 topZ = &splitEdges[(j+2)%3];
1201 bottomZ = &splitEdges[(j+1)%3];
1209 if(topZ->edge.first != middleZ->edge.first){
1210 topZ->edge.second = topZ->edge.first;
1211 topZ->edge.first = middleZ->edge.first;
1213 if(bottomZ->edge.second != middleZ->edge.second){
1214 bottomZ->edge.first = bottomZ->edge.second;
1215 bottomZ->edge.second = middleZ->edge.second;
1227 std::vector< DirectedEdge<index_t> > diagonals;
1228 for(std::vector<index_t>::const_iterator it=_mesh->NNList[middleZ->id].begin();
1229 it!=_mesh->NNList[middleZ->id].end(); ++it){
1230 if(*it == topZ->edge.second || *it == bottomZ->edge.first){
1235 switch(diagonals.size()){
1238 const int ele0[] = {middleZ->edge.first, topZ->id, bottomZ->id, bottomZ->edge.first};
1239 const int ele1[] = {middleZ->id, middleZ->edge.first, topZ->id, bottomZ->id};
1240 const int ele2[] = {topZ->id, topZ->edge.second, bottomZ->id, bottomZ->edge.first};
1241 const int ele3[] = {topZ->id, topZ->edge.second, bottomZ->edge.second, bottomZ->id};
1242 const int ele4[] = {middleZ->id, topZ->id, bottomZ->edge.second, bottomZ->id};
1244 const int ele0_boundary[] = {0, b[topZ->edge.second], b[middleZ->edge.second], 0};
1245 const int ele1_boundary[] = {0, 0, b[topZ->edge.second], b[bottomZ->edge.first]};
1246 const int ele2_boundary[] = {b[middleZ->edge.first], 0, b[middleZ->edge.second], 0};
1247 const int ele3_boundary[] = {b[middleZ->edge.first], 0, 0, b[bottomZ->edge.first]};
1248 const int ele4_boundary[] = {0, b[topZ->edge.second], 0, b[bottomZ->edge.first]};
1250 index_t ele1ID, ele2ID, ele3ID, ele4ID;
1251 ele1ID = splitCnt[tid];
1256 def_ops->addNN(topZ->id, bottomZ->id, tid);
1257 def_ops->addNN(bottomZ->id, topZ->id, tid);
1259 def_ops->addNE_fix(middleZ->edge.first, ele1ID, tid);
1261 def_ops->remNE(middleZ->edge.second, eid, tid);
1262 def_ops->addNE_fix(middleZ->edge.second, ele3ID, tid);
1263 def_ops->addNE_fix(middleZ->edge.second, ele4ID, tid);
1265 def_ops->remNE(topZ->edge.second, eid, tid);
1266 def_ops->addNE_fix(topZ->edge.second, ele2ID, tid);
1267 def_ops->addNE_fix(topZ->edge.second, ele3ID, tid);
1269 def_ops->addNE_fix(bottomZ->edge.first, ele2ID, tid);
1271 def_ops->addNE_fix(middleZ->id, ele1ID, tid);
1272 def_ops->addNE_fix(middleZ->id, ele4ID, tid);
1274 def_ops->addNE(topZ->id, eid, tid);
1275 def_ops->addNE_fix(topZ->id, ele1ID, tid);
1276 def_ops->addNE_fix(topZ->id, ele2ID, tid);
1277 def_ops->addNE_fix(topZ->id, ele3ID, tid);
1278 def_ops->addNE_fix(topZ->id, ele4ID, tid);
1280 def_ops->addNE(bottomZ->id, eid, tid);
1281 def_ops->addNE_fix(bottomZ->id, ele1ID, tid);
1282 def_ops->addNE_fix(bottomZ->id, ele2ID, tid);
1283 def_ops->addNE_fix(bottomZ->id, ele3ID, tid);
1284 def_ops->addNE_fix(bottomZ->id, ele4ID, tid);
1286 replace_element(eid, ele0, ele0_boundary);
1287 append_element(ele1, ele1_boundary, tid);
1288 append_element(ele2, ele2_boundary, tid);
1289 append_element(ele3, ele3_boundary, tid);
1290 append_element(ele4, ele4_boundary, tid);
1299 if(topZ->edge.second != diagonals[0].edge.second){
1300 assert(diagonals[0].edge.second == bottomZ->edge.first);
1306 index_t v = middleZ->edge.first;
1307 middleZ->edge.first = middleZ->edge.second;
1308 middleZ->edge.second = v;
1310 v = topZ->edge.first;
1311 topZ->edge.first = topZ->edge.second;
1312 topZ->edge.second = v;
1314 v = bottomZ->edge.first;
1315 bottomZ->edge.first = bottomZ->edge.second;
1316 bottomZ->edge.second = v;
1319 const int ele0[] = {middleZ->edge.first, topZ->id, bottomZ->id, bottomZ->edge.first};
1320 const int ele1[] = {middleZ->id, middleZ->edge.first, topZ->id, bottomZ->id};
1321 const int ele2[] = {topZ->id, topZ->edge.second, bottomZ->id, bottomZ->edge.first};
1322 const int ele3[] = {middleZ->id, topZ->id, topZ->edge.second, bottomZ->id};
1323 const int ele4[] = {middleZ->id, topZ->edge.second, middleZ->edge.second, bottomZ->id};
1325 const int ele0_boundary[] = {0, b[topZ->edge.second], b[middleZ->edge.second], 0};
1326 const int ele1_boundary[] = {0, 0, b[topZ->edge.second], b[bottomZ->edge.first]};
1327 const int ele2_boundary[] = {b[middleZ->edge.first], 0, b[middleZ->edge.second], 0};
1328 const int ele3_boundary[] = {0, 0, 0, b[bottomZ->edge.first]};
1329 const int ele4_boundary[] = {b[middleZ->edge.first], b[topZ->edge.second], 0, b[bottomZ->edge.first]};
1331 index_t ele1ID, ele2ID, ele3ID, ele4ID;
1332 ele1ID = splitCnt[tid];
1337 def_ops->addNN(topZ->id, bottomZ->id, tid);
1338 def_ops->addNN(bottomZ->id, topZ->id, tid);
1340 def_ops->addNE_fix(middleZ->edge.first, ele1ID, tid);
1342 def_ops->remNE(middleZ->edge.second, eid, tid);
1343 def_ops->addNE_fix(middleZ->edge.second, ele4ID, tid);
1345 def_ops->remNE(topZ->edge.second, eid, tid);
1346 def_ops->addNE_fix(topZ->edge.second, ele2ID, tid);
1347 def_ops->addNE_fix(topZ->edge.second, ele3ID, tid);
1348 def_ops->addNE_fix(topZ->edge.second, ele4ID, tid);
1350 def_ops->addNE_fix(bottomZ->edge.first, ele2ID, tid);
1352 def_ops->addNE_fix(middleZ->id, ele1ID, tid);
1353 def_ops->addNE_fix(middleZ->id, ele3ID, tid);
1354 def_ops->addNE_fix(middleZ->id, ele4ID, tid);
1356 def_ops->addNE(topZ->id, eid, tid);
1357 def_ops->addNE_fix(topZ->id, ele1ID, tid);
1358 def_ops->addNE_fix(topZ->id, ele2ID, tid);
1359 def_ops->addNE_fix(topZ->id, ele3ID, tid);
1361 def_ops->addNE(bottomZ->id, eid, tid);
1362 def_ops->addNE_fix(bottomZ->id, ele1ID, tid);
1363 def_ops->addNE_fix(bottomZ->id, ele2ID, tid);
1364 def_ops->addNE_fix(bottomZ->id, ele3ID, tid);
1365 def_ops->addNE_fix(bottomZ->id, ele4ID, tid);
1367 replace_element(eid, ele0, ele0_boundary);
1368 append_element(ele1, ele1_boundary, tid);
1369 append_element(ele2, ele2_boundary, tid);
1370 append_element(ele3, ele3_boundary, tid);
1371 append_element(ele4, ele4_boundary, tid);
1377 const int ele0[] = {middleZ->id, bottomZ->edge.first, middleZ->edge.first, topZ->id};
1378 const int ele1[] = {middleZ->id, bottomZ->edge.first, topZ->id, topZ->edge.second};
1379 const int ele2[] = {middleZ->id, bottomZ->id, bottomZ->edge.first, topZ->edge.second};
1380 const int ele3[] = {middleZ->id, middleZ->edge.second, bottomZ->id, topZ->edge.second};
1382 const int ele0_boundary[] = {b[middleZ->edge.second], b[bottomZ->edge.first], 0, b[topZ->edge.second]};
1383 const int ele1_boundary[] = {b[middleZ->edge.second], b[bottomZ->edge.first], 0, 0};
1384 const int ele2_boundary[] = {b[middleZ->edge.first], 0, 0, b[topZ->edge.second]};
1385 const int ele3_boundary[] = {b[middleZ->edge.first], 0, b[bottomZ->edge.first], b[topZ->edge.second]};
1387 index_t ele1ID, ele2ID, ele3ID;
1388 ele1ID = splitCnt[tid];
1392 def_ops->addNE(middleZ->id, eid, tid);
1393 def_ops->addNE_fix(middleZ->id, ele1ID, tid);
1394 def_ops->addNE_fix(middleZ->id, ele2ID, tid);
1395 def_ops->addNE_fix(middleZ->id, ele3ID, tid);
1397 def_ops->remNE(middleZ->edge.second, eid, tid);
1398 def_ops->addNE_fix(middleZ->edge.second, ele3ID, tid);
1400 def_ops->remNE(topZ->edge.second, eid, tid);
1401 def_ops->addNE_fix(topZ->edge.second, ele1ID, tid);
1402 def_ops->addNE_fix(topZ->edge.second, ele2ID, tid);
1403 def_ops->addNE_fix(topZ->edge.second, ele3ID, tid);
1405 def_ops->addNE_fix(bottomZ->edge.first, ele1ID, tid);
1406 def_ops->addNE_fix(bottomZ->edge.first, ele2ID, tid);
1408 def_ops->addNE(topZ->id, eid, tid);
1409 def_ops->addNE_fix(topZ->id, ele1ID, tid);
1411 def_ops->addNE_fix(bottomZ->id, ele2ID, tid);
1412 def_ops->addNE_fix(bottomZ->id, ele3ID, tid);
1414 replace_element(eid, ele0, ele0_boundary);
1415 append_element(ele1, ele1_boundary, tid);
1416 append_element(ele2, ele2_boundary, tid);
1417 append_element(ele3, ele3_boundary, tid);
1428 const int *n=_mesh->get_element(eid);
1429 const int *boundary=&(_mesh->boundary[eid*nloc]);
1432 for(
int j=0; j<nloc; ++j)
1433 b[n[j]] = boundary[j];
1442 std::set<index_t> shared;
1443 for(
int j=0; j<4; ++j){
1444 for(
int k=j+1; k<4; ++k){
1445 index_t nid = splitEdges[j].connected(splitEdges[k]);
1450 size_t nshared = shared.size();
1451 assert(nshared==3 || nshared==4);
1461 for(
int j=0; j<4; ++j)
1462 if(shared.count(splitEdges[j].edge.first)>0 && shared.count(splitEdges[j].edge.second)>0)
1463 p[pos++] = &splitEdges[j];
1465 p[3] = &splitEdges[j];
1474 if(p[3]->connected(*p[0]) >= 0){
1475 for(
int j=1; j<3; ++j){
1476 if(p[3]->connected(*p[j]) < 0){
1487 if(shared.count(p[3]->edge.first)==0){
1489 p[3]->edge.first = p[3]->edge.second;
1490 p[3]->edge.second = v;
1494 for(
int j=1; j<=2; ++j)
1495 if(p[j]->edge.first != p[3]->edge.first){
1496 assert(p[j]->edge.second == p[3]->edge.first);
1497 p[j]->edge.second = p[j]->edge.first;
1498 p[j]->edge.first = p[3]->edge.first;
1510 std::vector< DirectedEdge<index_t> > diagonals;
1511 for(std::vector<index_t>::const_iterator it=_mesh->NNList[p[3]->id].begin();
1512 it!=_mesh->NNList[p[3]->id].end(); ++it){
1513 if(*it == p[1]->edge.second || *it == p[2]->edge.second){
1518 switch(diagonals.size()){
1521 const int ele0[] = {p[0]->id, p[1]->edge.second, p[1]->id, p[3]->edge.second};
1522 const int ele1[] = {p[0]->id, p[1]->id, p[2]->id, p[3]->edge.second};
1523 const int ele2[] = {p[0]->id, p[2]->id, p[2]->edge.second, p[3]->edge.second};
1524 const int ele3[] = {p[1]->id, p[3]->id, p[2]->id, p[3]->edge.second};
1525 const int ele4[] = {p[1]->id, p[2]->id, p[3]->id, p[3]->edge.first};
1527 const int ele0_boundary[] = {b[p[2]->edge.second], 0, b[p[3]->edge.first], b[p[3]->edge.second]};
1528 const int ele1_boundary[] = {0, 0, 0, b[p[3]->edge.second]};
1529 const int ele2_boundary[] = {b[p[1]->edge.second], b[p[2]->edge.first], 0, b[p[3]->edge.second]};
1530 const int ele3_boundary[] = {b[p[1]->edge.second], 0, b[p[2]->edge.second], 0};
1531 const int ele4_boundary[] = {b[p[1]->edge.second], b[p[2]->edge.second], b[p[3]->edge.second], 0};
1533 index_t ele1ID, ele2ID, ele3ID, ele4ID;
1534 ele1ID = splitCnt[tid];
1539 def_ops->remNE(p[2]->edge.first, eid, tid);
1540 def_ops->addNE_fix(p[2]->edge.first, ele4ID, tid);
1542 def_ops->remNE(p[2]->edge.second, eid, tid);
1543 def_ops->addNE_fix(p[2]->edge.second, ele2ID, tid);
1545 def_ops->addNE_fix(p[3]->edge.second, ele1ID, tid);
1546 def_ops->addNE_fix(p[3]->edge.second, ele2ID, tid);
1547 def_ops->addNE_fix(p[3]->edge.second, ele3ID, tid);
1549 def_ops->addNE(p[0]->
id, eid, tid);
1550 def_ops->addNE_fix(p[0]->
id, ele1ID, tid);
1551 def_ops->addNE_fix(p[0]->
id, ele2ID, tid);
1553 def_ops->addNE(p[1]->
id, eid, tid);
1554 def_ops->addNE_fix(p[1]->
id, ele1ID, tid);
1555 def_ops->addNE_fix(p[1]->
id, ele3ID, tid);
1556 def_ops->addNE_fix(p[1]->
id, ele4ID, tid);
1558 def_ops->addNE_fix(p[2]->
id, ele1ID, tid);
1559 def_ops->addNE_fix(p[2]->
id, ele2ID, tid);
1560 def_ops->addNE_fix(p[2]->
id, ele3ID, tid);
1561 def_ops->addNE_fix(p[2]->
id, ele4ID, tid);
1563 def_ops->addNE_fix(p[3]->
id, ele3ID, tid);
1564 def_ops->addNE_fix(p[3]->
id, ele4ID, tid);
1566 replace_element(eid, ele0, ele0_boundary);
1567 append_element(ele1, ele1_boundary, tid);
1568 append_element(ele2, ele2_boundary, tid);
1569 append_element(ele3, ele3_boundary, tid);
1570 append_element(ele4, ele4_boundary, tid);
1579 if(p[2]->edge.second != diagonals[0].edge.second){
1584 assert(p[2]->edge.second == diagonals[0].edge.second);
1586 const int ele0[] = {p[0]->id, p[1]->edge.second, p[1]->id, p[3]->edge.second};
1587 const int ele1[] = {p[0]->id, p[3]->id, p[2]->edge.second, p[3]->edge.second};
1588 const int ele2[] = {p[0]->id, p[1]->id, p[3]->id, p[3]->edge.second};
1589 const int ele3[] = {p[0]->id, p[3]->id, p[2]->id, p[2]->edge.second};
1590 const int ele4[] = {p[0]->id, p[1]->id, p[2]->id, p[3]->id};
1591 const int ele5[] = {p[2]->id, p[3]->id, p[1]->id, p[3]->edge.first};
1593 const int ele0_boundary[] = {b[p[2]->edge.second], 0, b[p[1]->edge.first], b[p[3]->edge.second]};
1594 const int ele1_boundary[] = {b[p[1]->edge.second], b[p[3]->edge.first], 0, 0};
1595 const int ele2_boundary[] = {b[p[2]->edge.second], 0, 0, 0};
1596 const int ele3_boundary[] = {b[p[1]->edge.second], b[p[3]->edge.second], 0, 0};
1597 const int ele4_boundary[] = {0, 0, 0, b[p[3]->edge.second]};
1598 const int ele5_boundary[] = {b[p[2]->edge.second], b[p[3]->edge.second], b[p[1]->edge.second], 0};
1600 index_t ele1ID, ele2ID, ele3ID, ele4ID, ele5ID;
1601 ele1ID = splitCnt[tid];
1607 def_ops->addNN(p[0]->
id, p[3]->
id, tid);
1608 def_ops->addNN(p[3]->
id, p[0]->
id, tid);
1610 def_ops->remNE(p[2]->edge.first, eid, tid);
1611 def_ops->addNE_fix(p[2]->edge.first, ele5ID, tid);
1613 def_ops->remNE(p[2]->edge.second, eid, tid);
1614 def_ops->addNE_fix(p[2]->edge.second, ele1ID, tid);
1615 def_ops->addNE_fix(p[2]->edge.second, ele3ID, tid);
1617 def_ops->addNE_fix(p[3]->edge.second, ele1ID, tid);
1618 def_ops->addNE_fix(p[3]->edge.second, ele2ID, tid);
1620 def_ops->addNE(p[0]->
id, eid, tid);
1621 def_ops->addNE_fix(p[0]->
id, ele1ID, tid);
1622 def_ops->addNE_fix(p[0]->
id, ele2ID, tid);
1623 def_ops->addNE_fix(p[0]->
id, ele3ID, tid);
1624 def_ops->addNE_fix(p[0]->
id, ele4ID, tid);
1626 def_ops->addNE(p[1]->
id, eid, tid);
1627 def_ops->addNE_fix(p[1]->
id, ele2ID, tid);
1628 def_ops->addNE_fix(p[1]->
id, ele4ID, tid);
1629 def_ops->addNE_fix(p[1]->
id, ele5ID, tid);
1631 def_ops->addNE_fix(p[2]->
id, ele3ID, tid);
1632 def_ops->addNE_fix(p[2]->
id, ele4ID, tid);
1633 def_ops->addNE_fix(p[2]->
id, ele5ID, tid);
1635 def_ops->addNE_fix(p[3]->
id, ele1ID, tid);
1636 def_ops->addNE_fix(p[3]->
id, ele2ID, tid);
1637 def_ops->addNE_fix(p[3]->
id, ele3ID, tid);
1638 def_ops->addNE_fix(p[3]->
id, ele4ID, tid);
1639 def_ops->addNE_fix(p[3]->
id, ele5ID, tid);
1641 replace_element(eid, ele0, ele0_boundary);
1642 append_element(ele1, ele1_boundary, tid);
1643 append_element(ele2, ele2_boundary, tid);
1644 append_element(ele3, ele3_boundary, tid);
1645 append_element(ele4, ele4_boundary, tid);
1646 append_element(ele5, ele5_boundary, tid);
1652 const int ele0[] = {p[1]->edge.first, p[1]->id, p[2]->id, p[3]->id};
1653 const int ele1[] = {p[3]->id, p[1]->edge.second, p[0]->id, p[3]->edge.second};
1654 const int ele2[] = {p[3]->id, p[0]->id, p[2]->edge.second, p[3]->edge.second};
1655 const int ele3[] = {p[1]->id, p[1]->edge.second, p[0]->id, p[3]->id};
1656 const int ele4[] = {p[1]->id, p[0]->id, p[2]->id, p[3]->id};
1657 const int ele5[] = {p[2]->id, p[3]->id, p[0]->id, p[2]->edge.second};
1659 const int ele0_boundary[] = {0, b[p[1]->edge.second], b[p[2]->edge.second], b[p[3]->edge.second]};
1660 const int ele1_boundary[] = {b[p[3]->edge.first], 0, b[p[2]->edge.second], 0};
1661 const int ele2_boundary[] = {b[p[3]->edge.first], b[p[1]->edge.second], 0, 0};
1662 const int ele3_boundary[] = {0, 0, b[p[2]->edge.second], b[p[3]->edge.second]};
1663 const int ele4_boundary[] = {0, 0, 0, b[p[3]->edge.second]};
1664 const int ele5_boundary[] = {0, b[p[3]->edge.second], b[p[1]->edge.second], 0};
1666 index_t ele1ID, ele2ID, ele3ID, ele4ID, ele5ID;
1667 ele1ID = splitCnt[tid];
1673 def_ops->addNN(p[0]->
id, p[3]->
id, tid);
1674 def_ops->addNN(p[3]->
id, p[0]->
id, tid);
1677 def_ops->remNE(p[1]->edge.second, eid, tid);
1678 def_ops->addNE_fix(p[1]->edge.second, ele1ID, tid);
1679 def_ops->addNE_fix(p[1]->edge.second, ele3ID, tid);
1681 def_ops->remNE(p[2]->edge.second, eid, tid);
1682 def_ops->addNE_fix(p[2]->edge.second, ele2ID, tid);
1683 def_ops->addNE_fix(p[2]->edge.second, ele5ID, tid);
1685 def_ops->remNE(p[3]->edge.second, eid, tid);
1686 def_ops->addNE_fix(p[3]->edge.second, ele1ID, tid);
1687 def_ops->addNE_fix(p[3]->edge.second, ele2ID, tid);
1689 def_ops->addNE_fix(p[0]->
id, ele1ID, tid);
1690 def_ops->addNE_fix(p[0]->
id, ele2ID, tid);
1691 def_ops->addNE_fix(p[0]->
id, ele3ID, tid);
1692 def_ops->addNE_fix(p[0]->
id, ele4ID, tid);
1693 def_ops->addNE_fix(p[0]->
id, ele5ID, tid);
1695 def_ops->addNE(p[1]->
id, eid, tid);
1696 def_ops->addNE_fix(p[1]->
id, ele3ID, tid);
1697 def_ops->addNE_fix(p[1]->
id, ele4ID, tid);
1699 def_ops->addNE(p[2]->
id, eid, tid);
1700 def_ops->addNE_fix(p[2]->
id, ele4ID, tid);
1701 def_ops->addNE_fix(p[2]->
id, ele5ID, tid);
1703 def_ops->addNE(p[3]->
id, eid, tid);
1704 def_ops->addNE_fix(p[3]->
id, ele1ID, tid);
1705 def_ops->addNE_fix(p[3]->
id, ele2ID, tid);
1706 def_ops->addNE_fix(p[3]->
id, ele3ID, tid);
1707 def_ops->addNE_fix(p[3]->
id, ele4ID, tid);
1708 def_ops->addNE_fix(p[3]->
id, ele5ID, tid);
1710 replace_element(eid, ele0, ele0_boundary);
1711 append_element(ele1, ele1_boundary, tid);
1712 append_element(ele2, ele2_boundary, tid);
1713 append_element(ele3, ele3_boundary, tid);
1714 append_element(ele4, ele4_boundary, tid);
1715 append_element(ele5, ele5_boundary, tid);
1734 tl = &splitEdges[0];
1737 for(
int j=1; j<4; ++j){
1738 if(splitEdges[j].contains(tl->edge.first)){
1739 tr = &splitEdges[j];
1744 if(tr->edge.first != tl->edge.first){
1745 assert(tr->edge.second == tl->edge.first);
1746 tr->edge.second = tr->edge.first;
1747 tr->edge.first = tl->edge.first;
1751 for(
int j=1; j<4; ++j){
1752 if(splitEdges[j].contains(tl->edge.second)){
1753 bl = &splitEdges[j];
1758 if(bl->edge.second != tl->edge.second){
1759 assert(bl->edge.first == tl->edge.second);
1760 bl->edge.first = bl->edge.second;
1761 bl->edge.second = tl->edge.second;
1765 for(
int j=1; j<4; ++j){
1766 if(splitEdges[j].contains(bl->edge.first) && splitEdges[j].contains(tr->edge.second)){
1767 br = &splitEdges[j];
1772 if(br->edge.first != bl->edge.first){
1773 assert(br->edge.second == bl->edge.first);
1774 br->edge.second = br->edge.first;
1775 br->edge.first = bl->edge.first;
1778 assert(tr->edge.second == br->edge.second);
1782 std::vector<index_t>::const_iterator p;
1791 p = std::find(_mesh->NNList[tl->id].begin(), _mesh->NNList[tl->id].end(), tr->edge.second);
1792 if(p != _mesh->NNList[tl->id].end()){
1793 bw1.edge.first = tl->id;
1794 bw1.edge.second = tr->edge.second;
1796 bw1.edge.first = tr->id;
1797 bw1.edge.second = tl->edge.second;
1800 p = std::find(_mesh->NNList[bl->id].begin(), _mesh->NNList[bl->id].end(), br->edge.second);
1801 if(p != _mesh->NNList[bl->id].end()){
1802 bw2.edge.first = bl->id;
1803 bw2.edge.second = br->edge.second;
1805 bw2.edge.first = br->id;
1806 bw2.edge.second = bl->edge.second;
1809 p = std::find(_mesh->NNList[tl->id].begin(), _mesh->NNList[tl->id].end(), bl->edge.first);
1810 if(p != _mesh->NNList[tl->id].end()){
1811 tw1.edge.first = tl->id;
1812 tw1.edge.second = bl->edge.first;
1814 tw1.edge.first = bl->id;
1815 tw1.edge.second = tl->edge.first;
1818 p = std::find(_mesh->NNList[tr->id].begin(), _mesh->NNList[tr->id].end(), br->edge.first);
1819 if(p != _mesh->NNList[tr->id].end()){
1820 tw2.edge.first = tr->id;
1821 tw2.edge.second = br->edge.first;
1823 tw2.edge.first = br->id;
1824 tw2.edge.second = tr->edge.first;
1833 bool flex_bottom, flex_top;
1838 flex_bottom =
false;
1839 bw.edge.first = bw1.edge.first;
1840 bw.edge.second = bw2.edge.first;
1847 tw.edge.first = tw1.edge.first;
1848 tw.edge.second = tw2.edge.first;
1853 if(flex_top && !flex_bottom){
1855 diag.edge.first = bw.edge.first;
1856 diag.edge.second = bw.edge.second;
1857 }
else if(!flex_top && flex_bottom){
1859 diag.edge.first = tw.edge.first;
1860 diag.edge.second = tw.edge.second;
1862 if(flex_top && flex_bottom){
1864 real_t ldiag1 = _mesh->calc_edge_length(tl->id, br->id);
1865 real_t ldiag2 = _mesh->calc_edge_length(bl->id, tr->id);
1867 if(ldiag1 < ldiag2){
1868 diag.edge.first = tl->id;
1869 diag.edge.second = br->id;
1871 diag.edge.first = bl->id;
1872 diag.edge.second = tr->id;
1879 diag.edge.first = bw.edge.first;
1880 diag.edge.second = bw.edge.second;
1883 real_t ldiag1 = _mesh->calc_edge_length(tl->id, br->id);
1884 real_t ldiag2 = _mesh->calc_edge_length(bl->id, tr->id);
1886 if(ldiag1 < ldiag2){
1887 diag.edge.first = tl->id;
1888 diag.edge.second = br->id;
1890 diag.edge.first = bl->id;
1891 diag.edge.second = tr->id;
1897 def_ops->addNN(diag.edge.first, diag.edge.second, tid);
1898 def_ops->addNN(diag.edge.second, diag.edge.first, tid);
1907 top_triangle[0] = tr->id;
1908 top_triangle[1] = tr->edge.second;
1909 top_triangle[2] = br->id;
1910 bottom_triangle[0] = tl->id;
1911 bottom_triangle[1] = tl->edge.second;
1912 bottom_triangle[2] = bl->id;
1913 bwedge[0] = b[bl->edge.first];
1914 bwedge[1] = b[tl->edge.first];
1916 bwedge[3] = b[tl->edge.second];
1917 bwedge[4] = b[tr->edge.second];
1918 refine_wedge(top_triangle, bottom_triangle, bwedge, &diag, eid, tid);
1921 top_triangle[0] = tl->id;
1922 top_triangle[1] = tl->edge.first;
1923 top_triangle[2] = tr->id;
1924 bottom_triangle[0] = bl->id;
1925 bottom_triangle[1] = bl->edge.first;
1926 bottom_triangle[2] = br->id;
1927 bwedge[0] = b[tr->edge.second];
1928 bwedge[1] = b[tl->edge.second];
1930 bwedge[3] = b[bl->edge.first];
1931 bwedge[4] = b[tl->edge.first];
1933 index_t swap = diag.edge.first;
1934 diag.edge.first = diag.edge.second;
1935 diag.edge.second = swap;
1936 refine_wedge(top_triangle, bottom_triangle, bwedge, &diag, eid, tid);
1939 for(
size_t j=0; j<nloc; ++j)
1940 def_ops->remNE(n[j], eid, tid);
1941 _mesh->_ENList[eid*nloc] = -1;
1946 const int *n=_mesh->get_element(eid);
1947 const int *boundary=&(_mesh->boundary[eid*nloc]);
1950 for(
int j=0; j<nloc; ++j)
1951 b[n[j]] = boundary[j];
1954 int adj_cnt[] = {0, 0, 0, 0};
1955 for(
int j=0; j<nloc; ++j){
1956 for(
int k=0; k<5; ++k)
1957 if(splitEdges[k].contains(n[j]))
1965 for(
int j=0; j<nloc; ++j)
1971 for(
int k=0; k<5; ++k)
1972 if(!splitEdges[k].contains(ue[0]) && !splitEdges[k].contains(ue[1])){
1976 splitEdges[4] = splitEdges[k];
1977 splitEdges[k] = swap;
1979 oe = &splitEdges[4];
1985 tl = &splitEdges[0];
1989 index_t swap = tl->edge.second;
1990 tl->edge.second = tl->edge.first;
1991 tl->edge.first = swap;
1995 for(
int j=1; j<4; ++j){
1996 if(splitEdges[j].contains(tl->edge.first)){
1997 tr = &splitEdges[j];
2002 if(tr->edge.first != tl->edge.first){
2003 assert(tr->edge.second == tl->edge.first);
2004 tr->edge.second = tr->edge.first;
2005 tr->edge.first = tl->edge.first;
2009 for(
int j=1; j<4; ++j){
2010 if(splitEdges[j].contains(tl->edge.second)){
2011 bl = &splitEdges[j];
2016 if(bl->edge.second != tl->edge.second){
2017 assert(bl->edge.first == tl->edge.second);
2018 bl->edge.first = bl->edge.second;
2019 bl->edge.second = tl->edge.second;
2023 for(
int j=1; j<4; ++j){
2024 if(splitEdges[j].contains(bl->edge.first) && splitEdges[j].contains(tr->edge.second)){
2025 br = &splitEdges[j];
2030 if(br->edge.first != bl->edge.first){
2031 assert(br->edge.second == bl->edge.first);
2032 br->edge.second = br->edge.first;
2033 br->edge.first = bl->edge.first;
2036 assert(tr->edge.second == br->edge.second);
2043 std::vector<index_t>::const_iterator p;
2045 p = std::find(_mesh->NNList[tl->id].begin(), _mesh->NNList[tl->id].end(), bl->edge.first);
2046 if(p != _mesh->NNList[tl->id].end()){
2047 q1.edge.first = tl->id;
2048 q1.edge.second = bl->edge.first;
2050 q1.edge.first = bl->id;
2051 q1.edge.second = tl->edge.first;
2054 p = std::find(_mesh->NNList[tr->id].begin(), _mesh->NNList[tr->id].end(), br->edge.first);
2055 if(p != _mesh->NNList[tr->id].end()){
2056 q2.edge.first = tr->id;
2057 q2.edge.second = br->edge.first;
2059 q2.edge.first = br->id;
2060 q2.edge.second = tr->edge.first;
2064 if(q1.connected(q2) >= 0){
2067 real_t ldiag1 = _mesh->calc_edge_length(tl->id, br->id);
2068 real_t ldiag2 = _mesh->calc_edge_length(bl->id, tr->id);
2070 if(ldiag1 < ldiag2){
2071 diag.edge.first = br->id;
2072 diag.edge.second = tl->id;
2073 cross_diag.edge.first = tr->id;
2074 cross_diag.edge.second = bl->id;
2076 diag.edge.first = bl->id;
2077 diag.edge.second = tr->id;
2078 cross_diag.edge.first = tl->id;
2079 cross_diag.edge.second = br->id;
2083 if(q1.edge.first == bl->id){
2084 assert(q2.edge.first == tr->id);
2085 diag.edge.first = q1.edge.first;
2086 diag.edge.second = q2.edge.first;
2088 assert(q2.edge.first == br->id);
2089 diag.edge.first = q2.edge.first;
2090 diag.edge.second = q1.edge.first;
2092 assert((diag.edge.first==bl->id && diag.edge.second==tr->id)
2093 || (diag.edge.first==br->id && diag.edge.second==tl->id));
2095 cross_diag.edge.first = (diag.edge.second == tr->id ? tl->id : tr->id);
2096 cross_diag.edge.second = (diag.edge.first == br->id ? bl->id : br->id);
2097 assert((cross_diag.edge.first==tl->id && cross_diag.edge.second==br->id)
2098 || (cross_diag.edge.first==tr->id && cross_diag.edge.second==bl->id));
2101 index_t bottom_triangle[] = {br->id, br->edge.first, bl->id};
2102 index_t top_triangle[] = {tr->id, tr->edge.first, tl->id};
2103 int bwedge[] = {b[bl->edge.second], b[br->edge.second], 0, b[bl->edge.first], b[tl->edge.first]};
2104 refine_wedge(top_triangle, bottom_triangle, bwedge, &diag, eid, tid);
2106 const int ele0[] = {tl->edge.second, bl->id, tl->id, oe->id};
2107 const int ele1[] = {tr->edge.second, tr->id, br->id, oe->id};
2108 const int ele2[] = {diag.edge.first, cross_diag.edge.first, diag.edge.second, oe->id};
2109 const int ele3[] = {diag.edge.first, diag.edge.second, cross_diag.edge.second, oe->id};
2111 const int ele0_boundary[] = {0, b[bl->edge.first], b[tl->edge.first], b[tr->edge.second]};
2112 const int ele1_boundary[] = {0, b[tl->edge.first], b[bl->edge.first], b[tl->edge.second]};
2113 const int ele2_boundary[] = {b[bl->edge.first], 0, 0, 0};
2114 const int ele3_boundary[] = {0, b[tl->edge.first], 0, 0};
2116 index_t ele1ID, ele2ID, ele3ID;
2117 ele1ID = splitCnt[tid];
2121 def_ops->addNN(diag.edge.first, diag.edge.second, tid);
2122 def_ops->addNN(diag.edge.second, diag.edge.first, tid);
2124 def_ops->remNE(tr->edge.first, eid, tid);
2125 def_ops->remNE(br->edge.first, eid, tid);
2126 def_ops->remNE(tr->edge.second, eid, tid);
2128 def_ops->addNE(tl->id, eid, tid);
2129 def_ops->addNE(bl->id, eid, tid);
2130 def_ops->addNE(oe->id, eid, tid);
2132 def_ops->addNE_fix(tr->edge.second, ele1ID, tid);
2133 def_ops->addNE_fix(tr->id, ele1ID, tid);
2134 def_ops->addNE_fix(br->id, ele1ID, tid);
2135 def_ops->addNE_fix(oe->id, ele1ID, tid);
2137 def_ops->addNE_fix(diag.edge.first, ele2ID, tid);
2138 def_ops->addNE_fix(diag.edge.second, ele2ID, tid);
2139 def_ops->addNE_fix(cross_diag.edge.first, ele2ID, tid);
2140 def_ops->addNE_fix(oe->id, ele2ID, tid);
2142 def_ops->addNE_fix(diag.edge.first, ele3ID, tid);
2143 def_ops->addNE_fix(diag.edge.second, ele3ID, tid);
2144 def_ops->addNE_fix(cross_diag.edge.second, ele3ID, tid);
2145 def_ops->addNE_fix(oe->id, ele3ID, tid);
2147 replace_element(eid, ele0, ele0_boundary);
2148 append_element(ele1, ele1_boundary, tid);
2149 append_element(ele2, ele2_boundary, tid);
2150 append_element(ele3, ele3_boundary, tid);
2155 const int *n=_mesh->get_element(eid);
2156 const int *boundary=&(_mesh->boundary[eid*nloc]);
2159 for(
int j=0; j<nloc; ++j)
2160 b[n[j]] = boundary[j];
2169 real_t ldiag0 = _mesh->calc_edge_length(splitEdges[0].
id, splitEdges[5].
id);
2170 real_t ldiag1 = _mesh->calc_edge_length(splitEdges[1].
id, splitEdges[4].
id);
2171 real_t ldiag2 = _mesh->calc_edge_length(splitEdges[2].
id, splitEdges[3].
id);
2173 std::vector<index_t>
internal(2);
2174 std::vector<index_t> opposite(4);
2175 std::vector<int> bndr(4);
2176 if(ldiag0 < ldiag1 && ldiag0 < ldiag2){
2178 internal[0] = splitEdges[5].id;
2179 internal[1] = splitEdges[0].id;
2180 opposite[0] = splitEdges[3].id;
2181 opposite[1] = splitEdges[4].id;
2182 opposite[2] = splitEdges[2].id;
2183 opposite[3] = splitEdges[1].id;
2184 bndr[0] = boundary[0];
2185 bndr[1] = boundary[2];
2186 bndr[2] = boundary[1];
2187 bndr[3] = boundary[3];
2188 }
else if(ldiag1 < ldiag2){
2190 internal[0] = splitEdges[1].id;
2191 internal[1] = splitEdges[4].id;
2192 opposite[0] = splitEdges[0].id;
2193 opposite[1] = splitEdges[3].id;
2194 opposite[2] = splitEdges[5].id;
2195 opposite[3] = splitEdges[2].id;
2196 bndr[0] = boundary[3];
2197 bndr[1] = boundary[0];
2198 bndr[2] = boundary[1];
2199 bndr[3] = boundary[2];
2202 internal[0] = splitEdges[3].id;
2203 internal[1] = splitEdges[2].id;
2204 opposite[0] = splitEdges[4].id;
2205 opposite[1] = splitEdges[5].id;
2206 opposite[2] = splitEdges[1].id;
2207 opposite[3] = splitEdges[0].id;
2208 bndr[0] = boundary[0];
2209 bndr[1] = boundary[1];
2210 bndr[2] = boundary[3];
2211 bndr[3] = boundary[2];
2214 const int ele0[] = {n[0], splitEdges[0].id, splitEdges[1].id, splitEdges[2].id};
2215 const int ele1[] = {n[1], splitEdges[3].id, splitEdges[0].id, splitEdges[4].id};
2216 const int ele2[] = {n[2], splitEdges[1].id, splitEdges[3].id, splitEdges[5].id};
2217 const int ele3[] = {n[3], splitEdges[2].id, splitEdges[4].id, splitEdges[5].id};
2218 const int ele4[] = {
internal[0], opposite[0], opposite[1],
internal[1]};
2219 const int ele5[] = {
internal[0], opposite[1], opposite[2],
internal[1]};
2220 const int ele6[] = {
internal[0], opposite[2], opposite[3],
internal[1]};
2221 const int ele7[] = {
internal[0], opposite[3], opposite[0],
internal[1]};
2223 const int ele0_boundary[] = {0, boundary[1], boundary[2], boundary[3]};
2224 const int ele1_boundary[] = {0, boundary[2], boundary[0], boundary[3]};
2225 const int ele2_boundary[] = {0, boundary[0], boundary[1], boundary[3]};
2226 const int ele3_boundary[] = {0, boundary[0], boundary[1], boundary[2]};
2227 const int ele4_boundary[] = {0, 0, 0, bndr[0]};
2228 const int ele5_boundary[] = {bndr[1], 0, 0, 0};
2229 const int ele6_boundary[] = {0, 0, 0, bndr[2]};
2230 const int ele7_boundary[] = {bndr[3], 0, 0, 0};
2232 index_t ele1ID, ele2ID, ele3ID, ele4ID, ele5ID, ele6ID, ele7ID;
2233 ele1ID = splitCnt[tid];
2241 def_ops->addNN(
internal[0],
internal[1], tid);
2242 def_ops->addNN(
internal[1],
internal[0], tid);
2244 def_ops->remNE(n[1], eid, tid);
2245 def_ops->addNE_fix(n[1], ele1ID, tid);
2246 def_ops->remNE(n[2], eid, tid);
2247 def_ops->addNE_fix(n[2], ele2ID, tid);
2248 def_ops->remNE(n[3], eid, tid);
2249 def_ops->addNE_fix(n[3], ele3ID, tid);
2251 def_ops->addNE(splitEdges[0].
id, eid, tid);
2252 def_ops->addNE_fix(splitEdges[0].
id, ele1ID, tid);
2254 def_ops->addNE(splitEdges[1].
id, eid, tid);
2255 def_ops->addNE_fix(splitEdges[1].
id, ele2ID, tid);
2257 def_ops->addNE(splitEdges[2].
id, eid, tid);
2258 def_ops->addNE_fix(splitEdges[2].
id, ele3ID, tid);
2260 def_ops->addNE_fix(splitEdges[3].
id, ele1ID, tid);
2261 def_ops->addNE_fix(splitEdges[3].
id, ele2ID, tid);
2263 def_ops->addNE_fix(splitEdges[4].
id, ele1ID, tid);
2264 def_ops->addNE_fix(splitEdges[4].
id, ele3ID, tid);
2266 def_ops->addNE_fix(splitEdges[5].
id, ele2ID, tid);
2267 def_ops->addNE_fix(splitEdges[5].
id, ele3ID, tid);
2269 def_ops->addNE_fix(
internal[0], ele4ID, tid);
2270 def_ops->addNE_fix(
internal[0], ele5ID, tid);
2271 def_ops->addNE_fix(
internal[0], ele6ID, tid);
2272 def_ops->addNE_fix(
internal[0], ele7ID, tid);
2273 def_ops->addNE_fix(
internal[1], ele4ID, tid);
2274 def_ops->addNE_fix(
internal[1], ele5ID, tid);
2275 def_ops->addNE_fix(
internal[1], ele6ID, tid);
2276 def_ops->addNE_fix(
internal[1], ele7ID, tid);
2278 def_ops->addNE_fix(opposite[0], ele4ID, tid);
2279 def_ops->addNE_fix(opposite[1], ele4ID, tid);
2280 def_ops->addNE_fix(opposite[1], ele5ID, tid);
2281 def_ops->addNE_fix(opposite[2], ele5ID, tid);
2282 def_ops->addNE_fix(opposite[2], ele6ID, tid);
2283 def_ops->addNE_fix(opposite[3], ele6ID, tid);
2284 def_ops->addNE_fix(opposite[3], ele7ID, tid);
2285 def_ops->addNE_fix(opposite[0], ele7ID, tid);
2287 replace_element(eid, ele0, ele0_boundary);
2288 append_element(ele1, ele1_boundary, tid);
2289 append_element(ele2, ele2_boundary, tid);
2290 append_element(ele3, ele3_boundary, tid);
2291 append_element(ele4, ele4_boundary, tid);
2292 append_element(ele5, ele5_boundary, tid);
2293 append_element(ele6, ele6_boundary, tid);
2294 append_element(ele7, ele7_boundary, tid);
2298 void refine_wedge(
const index_t top_triangle[],
const index_t bottom_triangle[],
2312 if(third_diag != NULL){
2313 for(
int j=0; j<3; ++j){
2314 if(third_diag->edge.first == bottom_triangle[j] || third_diag->edge.second == top_triangle[j]){
2316 }
else if(third_diag->edge.first == top_triangle[j] || third_diag->edge.second == bottom_triangle[j]){
2317 index_t swap = third_diag->edge.first;
2318 third_diag->edge.first = third_diag->edge.second;
2319 third_diag->edge.second = swap;
2323 assert((third_diag->edge.first == bottom_triangle[2] && third_diag->edge.second == top_triangle[0]) ||
2324 (third_diag->edge.first == bottom_triangle[0] && third_diag->edge.second == top_triangle[2]));
2334 std::vector< DirectedEdge<index_t> > diagonals, ghostDiagonals;
2335 for(
int j=0; j<3; ++j){
2337 if(j==2 && third_diag != NULL){
2338 fwd_connected = (bottom_triangle[j] == third_diag->edge.first ?
true :
false);
2340 std::vector<index_t>::const_iterator p = std::find(_mesh->NNList[bottom_triangle[j]].begin(),
2341 _mesh->NNList[bottom_triangle[j]].end(), top_triangle[(j+1)%3]);
2342 fwd_connected = (p != _mesh->NNList[bottom_triangle[j]].end() ?
true :
false);
2354 std::vector<index_t> diag_shared;
2355 for(
int j=0;j<3;j++){
2356 index_t nid = diagonals[j].connected(diagonals[(j+1)%3]);
2358 diag_shared.push_back(nid);
2361 if(!diag_shared.empty()){
2368 assert(diag_shared.size() == 2);
2375 index_t non_shared_top=-1, non_shared_bottom=-1;
2376 for(
int j=0; j<3; ++j){
2377 if(diagonals[j].contains(diag_shared[0]) && diagonals[j].contains(diag_shared[1])){
2379 for(
int k=0; k<2; ++k){
2380 if(diagonals[(j+k+1)%3].edge.first != diag_shared[0] && diagonals[(j+k+1)%3].edge.first != diag_shared[1])
2381 non_shared_bottom = diagonals[(j+k+1)%3].edge.first;
2383 non_shared_top = diagonals[(j+k+1)%3].edge.second;
2388 assert(non_shared_top >= 0 && non_shared_bottom >= 0);
2402 for(
int j=0; j<3; ++j){
2403 if(top_triangle[j]!=diagonals[middle].edge.second && top_triangle[j]!=non_shared_top){
2404 v_top = top_triangle[j];
2405 assert(bottom_triangle[j] == diagonals[middle].edge.first);
2410 for(
int j=0; j<3; ++j){
2411 if(bottom_triangle[j]!=diagonals[middle].edge.first && bottom_triangle[j]!=non_shared_bottom){
2412 v_bottom = bottom_triangle[j];
2413 assert(top_triangle[j] == diagonals[middle].edge.second);
2418 const int ele1[] = {diagonals[middle].edge.first, diagonals[middle].edge.second, non_shared_top, v_top};
2419 const int ele2[] = {diagonals[middle].edge.first, diagonals[middle].edge.second, v_bottom, non_shared_bottom};
2420 const int ele3[] = {diagonals[middle].edge.first, diagonals[middle].edge.second, non_shared_top, non_shared_bottom};
2422 int bv_bottom, bnsb, bfirst;
2423 for(
int j=0; j<3; ++j){
2424 if(v_bottom == bottom_triangle[j]){
2425 bv_bottom = bndr[(j+1)%3];
2426 }
else if(non_shared_bottom == bottom_triangle[j]){
2427 bnsb = bndr[(j+1)%3];
2429 bfirst = bndr[(j+1)%3];
2433 const int ele1_boundary[] = {bndr[3], bv_bottom, bnsb, 0};
2434 const int ele2_boundary[] = {bfirst, bndr[4], 0, bnsb};
2435 const int ele3_boundary[] = {bfirst, bv_bottom, 0, 0};
2437 index_t ele1ID, ele2ID, ele3ID;
2438 ele1ID = splitCnt[tid];
2442 def_ops->addNE_fix(diagonals[middle].edge.first, ele1ID, tid);
2443 def_ops->addNE_fix(diagonals[middle].edge.first, ele2ID, tid);
2444 def_ops->addNE_fix(diagonals[middle].edge.first, ele3ID, tid);
2446 def_ops->addNE_fix(diagonals[middle].edge.second, ele1ID, tid);
2447 def_ops->addNE_fix(diagonals[middle].edge.second, ele2ID, tid);
2448 def_ops->addNE_fix(diagonals[middle].edge.second, ele3ID, tid);
2450 def_ops->addNE_fix(non_shared_bottom, ele2ID, tid);
2451 def_ops->addNE_fix(non_shared_bottom, ele3ID, tid);
2453 def_ops->addNE_fix(non_shared_top, ele1ID, tid);
2454 def_ops->addNE_fix(non_shared_top, ele3ID, tid);
2456 def_ops->addNE_fix(v_bottom, ele2ID, tid);
2458 def_ops->addNE_fix(v_top, ele1ID, tid);
2460 append_element(ele1, ele1_boundary, tid);
2461 append_element(ele2, ele2_boundary, tid);
2462 append_element(ele3, ele3_boundary, tid);
2482 const int ele1[] = {diagonals[0].edge.first, ghostDiagonals[0].edge.first, diagonals[0].edge.second, cid};
2483 const int ele2[] = {diagonals[0].edge.first, diagonals[0].edge.second, ghostDiagonals[0].edge.second, cid};
2484 const int ele3[] = {diagonals[1].edge.first, ghostDiagonals[1].edge.first, diagonals[1].edge.second, cid};
2485 const int ele4[] = {diagonals[1].edge.first, diagonals[1].edge.second, ghostDiagonals[1].edge.second, cid};
2486 const int ele5[] = {diagonals[2].edge.first, ghostDiagonals[2].edge.first, diagonals[2].edge.second, cid};
2487 const int ele6[] = {diagonals[2].edge.first, diagonals[2].edge.second, ghostDiagonals[2].edge.second, cid};
2488 const int ele7[] = {top_triangle[0], top_triangle[1], top_triangle[2], cid};
2489 const int ele8[] = {bottom_triangle[0], bottom_triangle[2], bottom_triangle[1], cid};
2491 const int ele1_boundary[] = {0, 0, 0, bndr[0]};
2492 const int ele2_boundary[] = {0, 0, 0, bndr[0]};
2493 const int ele3_boundary[] = {0, 0, 0, bndr[1]};
2494 const int ele4_boundary[] = {0, 0, 0, bndr[1]};
2495 const int ele5_boundary[] = {0, 0, 0, bndr[2]};
2496 const int ele6_boundary[] = {0, 0, 0, bndr[2]};
2497 const int ele7_boundary[] = {0, 0, 0, bndr[3]};
2498 const int ele8_boundary[] = {0, 0, 0, bndr[4]};
2500 index_t ele1ID, ele2ID, ele3ID, ele4ID, ele5ID, ele6ID, ele7ID, ele8ID;
2501 ele1ID = splitCnt[tid];
2510 for(
int j=0; j<3; ++j){
2511 _mesh->NNList[cid].push_back(top_triangle[j]);
2512 _mesh->NNList[cid].push_back(bottom_triangle[j]);
2513 def_ops->addNN(top_triangle[j], cid, tid);
2514 def_ops->addNN(bottom_triangle[j], cid, tid);
2517 def_ops->addNE_fix(cid, ele1ID, tid);
2518 def_ops->addNE_fix(cid, ele2ID, tid);
2519 def_ops->addNE_fix(cid, ele3ID, tid);
2520 def_ops->addNE_fix(cid, ele4ID, tid);
2521 def_ops->addNE_fix(cid, ele5ID, tid);
2522 def_ops->addNE_fix(cid, ele6ID, tid);
2523 def_ops->addNE_fix(cid, ele7ID, tid);
2524 def_ops->addNE_fix(cid, ele8ID, tid);
2526 def_ops->addNE_fix(bottom_triangle[0], ele8ID, tid);
2527 def_ops->addNE_fix(bottom_triangle[1], ele8ID, tid);
2528 def_ops->addNE_fix(bottom_triangle[2], ele8ID, tid);
2530 def_ops->addNE_fix(top_triangle[0], ele7ID, tid);
2531 def_ops->addNE_fix(top_triangle[1], ele7ID, tid);
2532 def_ops->addNE_fix(top_triangle[2], ele7ID, tid);
2534 def_ops->addNE_fix(diagonals[0].edge.first, ele1ID, tid);
2535 def_ops->addNE_fix(diagonals[0].edge.first, ele2ID, tid);
2536 def_ops->addNE_fix(diagonals[0].edge.second, ele1ID, tid);
2537 def_ops->addNE_fix(diagonals[0].edge.second, ele2ID, tid);
2538 def_ops->addNE_fix(ghostDiagonals[0].edge.first, ele1ID, tid);
2539 def_ops->addNE_fix(ghostDiagonals[0].edge.second, ele2ID, tid);
2541 def_ops->addNE_fix(diagonals[1].edge.first, ele3ID, tid);
2542 def_ops->addNE_fix(diagonals[1].edge.first, ele4ID, tid);
2543 def_ops->addNE_fix(diagonals[1].edge.second, ele3ID, tid);
2544 def_ops->addNE_fix(diagonals[1].edge.second, ele4ID, tid);
2545 def_ops->addNE_fix(ghostDiagonals[1].edge.first, ele3ID, tid);
2546 def_ops->addNE_fix(ghostDiagonals[1].edge.second, ele4ID, tid);
2548 def_ops->addNE_fix(diagonals[2].edge.first, ele5ID, tid);
2549 def_ops->addNE_fix(diagonals[2].edge.first, ele6ID, tid);
2550 def_ops->addNE_fix(diagonals[2].edge.second, ele5ID, tid);
2551 def_ops->addNE_fix(diagonals[2].edge.second, ele6ID, tid);
2552 def_ops->addNE_fix(ghostDiagonals[2].edge.first, ele5ID, tid);
2553 def_ops->addNE_fix(ghostDiagonals[2].edge.second, ele6ID, tid);
2557 std::map<Coords_t, index_t> coords_map;
2558 for(
int j=0; j<3; ++j){
2559 Coords_t cb(_mesh->get_coords(bottom_triangle[j]));
2560 coords_map[cb] = bottom_triangle[j];
2561 Coords_t ct(_mesh->get_coords(top_triangle[j]));
2562 coords_map[ct] = top_triangle[j];
2565 real_t nc[] = {0.0, 0.0, 0.0};
2567 const index_t* n = _mesh->get_element(eid);
2572 for(
typename std::map<Coords_t, index_t>::const_iterator it=coords_map.begin(); it!=coords_map.end(); ++it){
2573 const real_t *x = _mesh->get_coords(it->second);
2574 for(
int j=0; j<ndims; ++j)
2577 for(
int j=0; j<ndims; ++j){
2578 nc[j] /= coords_map.size();
2579 _mesh->_coords[cid*ndims+j] = nc[j];
2583 std::map<Coords_t, index_t> parent_coords;
2584 for(
int j=0; j<nloc; ++j){
2585 Coords_t cn(_mesh->get_coords(n[j]));
2586 parent_coords[cn] = n[j];
2589 std::vector<const real_t *> x;
2590 std::vector<index_t> sorted_n;
2591 for(
typename std::map<Coords_t, index_t>::const_iterator it=parent_coords.begin(); it!=parent_coords.end(); ++it){
2592 x.push_back(_mesh->get_coords(it->second));
2593 sorted_n.push_back(it->second);
2597 real_t
L = fabs(property->volume(x[0], x[1], x[2], x[3]));
2600 ll[0] = fabs(property->volume(nc , x[1], x[2], x[3])/
L);
2601 ll[1] = fabs(property->volume(x[0], nc , x[2], x[3])/
L);
2602 ll[2] = fabs(property->volume(x[0], x[1], nc , x[3])/
L);
2603 ll[3] = fabs(property->volume(x[0], x[1], x[2], nc )/
L);
2605 for(
int i=0; i<msize; i++){
2606 nm[i] = ll[0] * _mesh->metric[sorted_n[0]*msize+i]+
2607 ll[1] * _mesh->metric[sorted_n[1]*msize+i]+
2608 ll[2] * _mesh->metric[sorted_n[2]*msize+i]+
2609 ll[3] * _mesh->metric[sorted_n[3]*msize+i];
2610 _mesh->metric[cid*msize+i] = nm[i];
2615 Eigen::Matrix<real_t, Eigen::Dynamic, Eigen::Dynamic>
A =
2616 Eigen::Matrix<real_t, Eigen::Dynamic, Eigen::Dynamic>::Zero(3, 3);
2617 Eigen::Matrix<real_t, Eigen::Dynamic, 1> q = Eigen::Matrix<real_t, Eigen::Dynamic, 1>::Zero(3);
2619 for(
typename std::map<Coords_t, index_t>::const_iterator it=coords_map.begin(); it!=coords_map.end(); ++it){
2620 const real_t *il = _mesh->get_coords(it->second);
2621 real_t x = il[0]-nc[0];
2622 real_t y = il[1]-nc[1];
2623 real_t z = il[2]-nc[2];
2625 q[0] += nm[0]*x + nm[1]*y + nm[2]*z;
2626 q[1] += nm[1]*x + nm[3]*y + nm[4]*z;
2627 q[2] += nm[2]*x + nm[4]*y + nm[5]*z;
2629 A[0] += nm[0]; A[1] += nm[1]; A[2] += nm[2];
2630 A[4] += nm[3]; A[5] += nm[4];
2638 Eigen::Matrix<real_t, Eigen::Dynamic, 1> b = Eigen::Matrix<real_t, Eigen::Dynamic, 1>::Zero(3);
2639 A.svd().solve(q, &b);
2641 for(
int i=0; i<3; ++i){
2646 real_t l[]={-1, -1, -1, -1};
2648 std::vector<index_t> sorted_best_e(nloc);
2649 const index_t *welements[] = {ele1, ele2, ele3, ele4, ele5, ele6, ele7, ele8};
2651 for(
int ele=0; ele<8; ++ele){
2652 std::map<Coords_t, index_t> local_coords;
2653 for(
int j=0; j<nloc; ++j){
2654 Coords_t cl(_mesh->get_coords(welements[ele][j]));
2655 local_coords[cl] = welements[ele][j];
2658 std::vector<const real_t *> x;
2659 std::vector<index_t> sorted_n;
2660 for(
typename std::map<Coords_t, index_t>::const_iterator it=local_coords.begin(); it!=local_coords.end(); ++it){
2661 x.push_back(_mesh->get_coords(it->second));
2662 sorted_n.push_back(it->second);
2665 real_t L = fabs(property->volume(x[0], x[1], x[2], x[3]));
2670 ll[0] = fabs(property->volume(nc , x[1], x[2], x[3])/
L);
2671 ll[1] = fabs(property->volume(x[0], nc , x[2], x[3])/
L);
2672 ll[2] = fabs(property->volume(x[0], x[1], nc , x[3])/
L);
2673 ll[3] = fabs(property->volume(x[0], x[1], x[2], nc )/
L);
2675 real_t min_l = std::min(std::min(ll[0], ll[1]), std::min(ll[2], ll[3]));
2678 for(
int j=0;j<nloc;++j){
2680 sorted_best_e[j] = sorted_n[j];
2685 for(
int i=0; i<ndims; ++i){
2686 _mesh->_coords[cid*ndims+i] = nc[i];
2689 for(
int i=0; i<msize; ++i)
2690 _mesh->metric[cid*msize+i] = l[0]*_mesh->metric[sorted_best_e[0]*msize+i]+
2691 l[1]*_mesh->metric[sorted_best_e[1]*msize+i]+
2692 l[2]*_mesh->metric[sorted_best_e[2]*msize+i]+
2693 l[3]*_mesh->metric[sorted_best_e[3]*msize+i];
2695 append_element(ele1, ele1_boundary, tid);
2696 append_element(ele2, ele2_boundary, tid);
2697 append_element(ele3, ele3_boundary, tid);
2698 append_element(ele4, ele4_boundary, tid);
2699 append_element(ele5, ele5_boundary, tid);
2700 append_element(ele6, ele6_boundary, tid);
2701 append_element(ele7, ele7_boundary, tid);
2702 append_element(ele8, ele8_boundary, tid);
2707 _mesh->node_owner[cid] = 0;
2708 _mesh->lnn2gnn[cid] = cid;
2711 for(
int j=0; j<nloc; ++j)
2712 owner = std::min(owner, _mesh->node_owner[n[j]]);
2714 _mesh->node_owner[cid] = owner;
2716 if(_mesh->node_owner[cid] != rank){
2718 Wedge wedge(cid, _mesh->get_coords(cid));
2719 #pragma omp critical
2720 cidRecv_additional[_mesh->node_owner[cid]].insert(wedge);
2724 if(_mesh->is_halo_node(n[0]) && _mesh->is_halo_node(n[1]) && _mesh->is_halo_node(n[2]) && _mesh->is_halo_node(n[3])){
2726 std::set<int> processes;
2727 for(
int j=0; j<nloc; ++j)
2728 processes.insert(_mesh->node_owner[n[j]]);
2730 processes.erase(rank);
2732 Wedge wedge(cid, _mesh->get_coords(cid));
2733 for(
typename std::set<int>::const_iterator proc=processes.begin(); proc!=processes.end(); ++proc){
2734 #pragma omp critical
2735 cidSend_additional[*proc].insert(wedge);
2740 _mesh->lnn2gnn[cid] = _mesh->gnn_offset+cid;
2746 inline void append_element(
const index_t *elem,
const int *boundary,
const size_t tid){
2749 const real_t *x0 = &(_mesh->_coords[elem[0]*ndims]);
2750 const real_t *x1 = &(_mesh->_coords[elem[1]*ndims]);
2751 const real_t *
x2 = &(_mesh->_coords[elem[2]*ndims]);
2752 const real_t *
x3 = &(_mesh->_coords[elem[3]*ndims]);
2754 real_t av =
property->volume(x0, x1, x2, x3);
2758 int *b =
const_cast<int *
>(
boundary);
2772 for(
size_t i=0; i<nloc; ++i){
2773 newElements[tid].push_back(elem[i]);
2774 newBoundaries[tid].push_back(boundary[i]);
2778 inline void replace_element(
const index_t eid,
const index_t *n,
const int *boundary){
2781 const real_t *x0 = &(_mesh->_coords[n[0]*ndims]);
2782 const real_t *x1 = &(_mesh->_coords[n[1]*ndims]);
2783 const real_t *x2 = &(_mesh->_coords[n[2]*ndims]);
2784 const real_t *x3 = &(_mesh->_coords[n[3]*ndims]);
2786 real_t av =
property->volume(x0, x1, x2, x3);
2790 int *b =
const_cast<int *
>(
boundary);
2804 for(
size_t i=0;i<nloc;i++){
2805 _mesh->_ENList[eid*nloc+i]=n[i];
2806 _mesh->boundary[eid*nloc+i]=boundary[i];
2811 const int *n=_mesh->get_element(eid);
2819 if(n[1]==v1 || n[1]==v2){
2820 if(n[2]==v1 || n[2]==v2)
2837 if(n[0]==v1 || n[0]==v2){
2838 if(n[1]==v1 || n[1]==v2)
2840 else if(n[2]==v1 || n[2]==v2)
2844 }
else if(n[1]==v1 || n[1]==v2){
2845 if(n[2]==v1 || n[2]==v2)
2860 Coords_t(
const real_t *x){
2867 bool operator<(
const Coords_t& in)
const{
2870 for(
int i=0; i<3; ++i){
2871 if(coords[i] < in.coords[i]){
2874 }
else if(coords[i] > in.coords[i]){
2887 const Coords_t coords;
2890 Wedge(
const index_t id,
const real_t *cid_coords) : coords(cid_coords), cid(id){}
2893 bool operator<(
const Wedge& in)
const{
2894 return coords < in.coords;
2898 std::vector< std::vector< DirectedEdge<index_t> > > newVertices;
2899 std::vector< std::vector<real_t> > newCoords;
2900 std::vector< std::vector<double> > newMetric;
2901 std::vector< std::vector<index_t> > newElements;
2902 std::vector< std::vector<int> > newBoundaries;
2903 std::vector<index_t> new_vertices_per_element;
2905 std::vector<size_t> threadIdx, splitCnt;
2906 std::vector< DirectedEdge<index_t> > allNewVertices;
2907 std::vector< std::set<Wedge> > cidRecv_additional, cidSend_additional;
2910 static const int defOp_scaling_factor = 32;
2915 static const size_t ndims=dim, nloc=(dim+1), msize=(dim==2?3:6), nedge=(dim==2?3:6);
2916 int nprocs, rank, nthreads;
2919 void (
Refine<real_t,dim>::* refineMode3D[nedge])(std::vector< DirectedEdge<index_t> >&, int, int);
void refine(real_t L_max)
Refine(Mesh< real_t > &mesh)
Default constructor.
int pragmatic_process_id(MPI_Comm comm)
bool contains(index_t nid) const
Calculates a number of element properties.
index_t connected(const DirectedEdge &in) const
~Refine()
Default destructor.
int pragmatic_thread_id()
Performs 2D mesh refinement.
size_t pragmatic_omp_atomic_capture(size_t *shared, size_t inc)
int pragmatic_nprocesses(MPI_Comm comm)