24 #define USE_STD_INCLUDES 1
25 #define USE_C_PREFIX_INCLUDES 1
27 #include "MeshImpl.hpp"
28 #include "MsqError.hpp"
29 #include "InstructionQueue.hpp"
31 #include "TerminationCriterion.hpp"
32 #include "QualityAssessor.hpp"
33 #include "PlanarDomain.hpp"
34 #include "ShapeImprovementWrapper.hpp"
37 #include "MeanRatioFunctions.hpp"
38 #include "EdgeLengthQualityMetric.hpp"
39 #include "LPtoPTemplate.hpp"
40 #include "FeasibleNewton.hpp"
41 #include "ConjugateGradient.hpp"
44 using namespace Mesquite;
460 : _a(a), _b(b), _c(c), _d(d) {}
464 return _a<x.
_a || (_a==x.
_a && (_b<x.
_b || _b==x.
_b &&
465 (_c<x.
_c || _c==x.
_c && _d<x.
_d)));
477 "Surface-list must have integer type");
479 "Surface-list must be nodal");
481 "Surface-list must have a single component");
482 int w_is_surface_id = w_is_surface->id();
505 std::vector<bool> is_border;
506 std::vector<bool> is_shared;
507 std::vector<bool> is_isolated;
508 std::vector<MAP::Facet_ID> border_facet_list;
518 std::vector<std::set<MAP::Facet_ID> > border_facets;
519 std::vector<std::vector<Corners2Face_Map> > maybe_shared;
520 std::vector<std::vector<Id_Map > > lid2ind;
521 std::vector<std::vector<Id_Map > > ind2lid;
522 std::vector<std::vector<std::set<int> > > adj_pane_set;
523 std::vector<std::vector<int> > adj_pane_id;
524 std::vector<std::vector<int> > adj_pane_recv;
527 std::vector<int> send_sizes;
529 std::set<MAP::Facet_ID>::iterator bf_it, bf_it2;
530 Id_Map::iterator idm_it,idm_it2;
531 Corners2Face_Map::iterator ms_it,ms_it2;
532 std::set<int >::iterator aps_it, aps_it2;
535 int pconn_offset = MAP::Pane_connectivity::pconn_offset();
538 std::vector<COM::Pane*> allpanes;
539 COM::Window * wrk_window = w_is_surface->window();
540 wrk_window->panes(allpanes);
542 border_facets.resize(total_npanes);
543 maybe_shared.resize(total_npanes);
544 lid2ind.resize(total_npanes);
545 ind2lid.resize(total_npanes);
546 adj_pane_set.resize(total_npanes);
547 adj_pane_id.resize(total_npanes);
548 adj_pane_recv.resize(total_npanes);
549 send_sizes.resize(total_npanes);
552 COM::Attribute * false_pconn = wrk_window->new_attribute(
"false_pconn",
'p',
COM_INT, 1,
"");
556 COM::Attribute *com_buff = wrk_window->new_attribute(
"com_buff",
'p',
COM_INT, 1,
"");
557 int w_com_buff_id = com_buff->id();
561 int size_of_real_nodes = allpanes[
i]->size_of_real_nodes();
565 is_border.resize(size_of_real_nodes,0);
566 is_shared.resize(size_of_real_nodes,0);
567 is_isolated.resize(size_of_real_nodes,0);
572 MAP::Pane_boundary pb(allpanes[
i]);
573 pb.determine_border_nodes(is_border, is_isolated, &border_facet_list);
576 for(
int j =0,
nj=border_facet_list.size();
j<
nj; ++
j)
577 border_facets[i].insert(border_facet_list[
j]);
584 const int *vs = (
const int*)pconn->pointer() + pconn_offset;
585 int vs_size = pconn->size_of_real_items() - pconn_offset;
589 for (
int j=0, nj=vs_size; j<
nj; j+=vs[j+1]+2) {
590 if (wrk_window->owner_rank( vs[j]) >=0) ++count;
595 maybe_shared[
i].resize(count);
596 lid2ind[
i].resize(count);
597 ind2lid[
i].resize(count);
598 adj_pane_set[
i].resize(count);
599 adj_pane_id[
i].resize(count);
600 adj_pane_recv[
i].resize(count);
604 for (
int j=0; j<count; ++
j, index+=vs[index+1]+2) {
606 while ( wrk_window->owner_rank(vs[index])<0) {
607 index+=vs[index+1]+2;
610 adj_pane_id[
i][
j] = vs[index];
613 for(
int k=0;
k<vs[index+1]; ++
k){
614 is_shared[vs[index+2+
k]-1]=1;
615 adj_pane_set[
i][
j].insert(vs[index+2+
k]);
616 lid2ind[
i][
j].insert(std::make_pair(vs[index+2+
k],
k));
617 ind2lid[
i][
j].insert(std::make_pair(
k,vs[index+2+
k]));
622 std::cout <<
"Pane " << allpanes[
i]->id() <<
" lid2ind = \n";
623 for(
int j=0; j < count; ++
j){
624 std::cout <<
" to Pane " << adj_pane_id[
i][
j] <<
" =\n";
625 for(
int k =0;
k < ind2lid[
i][
j].size();++
k){
626 std::cout <<
"(" <<
k <<
"," << ind2lid[
i][
j][
k] <<
") ";
630 std::cout <<
"Pane " << i <<
"\n"
631 <<
" shared nodes = \n";
633 for(
int j=0; j<is_shared.size(); ++
j){
635 std::cout << j+1 <<
" ";
637 std::cout <<
"\n\n nodes shared with othe panes";
639 aps_it = adj_pane_set[
i][0].begin();
640 for(; aps_it != adj_pane_set[
i][0].end(); ++aps_it){
641 std::cout << *aps_it <<
" ";
649 bf_it2 = border_facets[
i].end();
650 bf_it = border_facets[
i].begin();
652 for(; bf_it != bf_it2; ++bf_it){
653 Element_node_enumerator ene(allpanes[i], (*bf_it).eid());
654 Facet_node_enumerator fne (&ene, (*bf_it).lid());
656 if( is_shared[fne[0]-1] &&
657 is_shared[fne[1]-1] &&
658 is_shared[fne[2]-1] &&
659 fne.size_of_edges()>3?is_shared[fne[3]-1]:1
662 Four_tuple ns( fne[0], fne[1], fne[2], fne.size_of_edges()>3?fne[3]:-1);
663 for(
int k=0;
k<count; ++
k){
664 aps_it2 = adj_pane_set[
i][
k].end();
665 if(aps_it2 != adj_pane_set[i][
k].find(fne[0]) &&
666 aps_it2 != adj_pane_set[i][
k].find(fne[1]) &&
667 aps_it2 != adj_pane_set[i][
k].find(fne[2]) &&
668 (fne.size_of_edges()>3?(adj_pane_set[
i][
k].find(fne[3]) != aps_it2):1)){
671 Four_tuple ns( fne[0], fne[1], fne[2], fne.size_of_edges()>3?fne[3]:-1);
672 std::sort(&ns[0],&ns[4]);
673 maybe_shared[
i][
k].insert(std::make_pair(ns,(*bf_it)));
681 std::cout <<
"Pane " << allpanes[
i]->id() <<
" possibly shared panes\n";
682 for(
int j = 0; j<count; ++
j){
683 std::cout <<
" faces possibly shared with Pane " << adj_pane_id[
i][
j] <<
"\n";
684 ms_it2 = maybe_shared[
i][
j].end();
685 for(ms_it = maybe_shared[i][j].begin(); ms_it != ms_it2; ++ms_it){
686 std::cout <<
"(" << (ms_it->first)[0] <<
" "
687 << (ms_it->first)[1] <<
" "
688 << (ms_it->first)[2] <<
" "
689 << (ms_it->first)[3] <<
") ";
695 wrk_window->set_size(
"com_buff", allpanes[i]->
id(), count, 0);
697 wrk_window->resize_array(
"com_buff", (
const int)allpanes[i]->
id(),
698 reinterpret_cast<void**>(&my_buff));
705 int my_size = 3*pconn_offset + 3 + 6*count;
707 wrk_window->set_size(
"false_pconn", allpanes[i]->
id(), my_size,
708 my_size-(3+pconn_offset));
709 wrk_window->resize_array(
"false_pconn", (
const int)allpanes[i]->
id(),
710 reinterpret_cast<void**>(&my_pconn));
712 if(pconn_offset){my_pconn[0]=1;++my_pconn;}
713 my_pconn[0]=1; my_pconn[1]=1; my_pconn[2]=1;
717 if(pconn_offset){my_pconn[0]=count;++my_pconn;}
718 for(
int j=0; j<count; ++
j){
720 my_pconn[0] = adj_pane_id[
i][
j];
727 my_buff[
j] = 4*maybe_shared[
i][
j].size();
728 send_sizes[
i] += my_buff[
j];
732 if(pconn_offset){my_pconn[0]=count;++my_pconn;}
733 for(
int j=0; j<count; ++
j){
734 my_pconn[0] = adj_pane_id[
i][
j];
741 for (
int j=0; j<count; ++
j, index+=vs[index+1]+2) {
743 while ( wrk_window->owner_rank(vs[index])<0)
744 index+=vs[index+1]+2;
747 my_pconn[3*
j] = vs[index];
749 my_pconn[3*j+2] = j+1;
751 my_pconn[3*(count+
j)+pconn_offset] = vs[index];
752 my_pconn[3*(count+
j)+1+pconn_offset] = 1;
753 my_pconn[3*(count+
j)+2+pconn_offset] = j+1;
755 my_pconn[3*(2*count+
j)+2*pconn_offset] = vs[index];
756 my_pconn[3*(2*count+
j)+1+2*pconn_offset] = 1;
757 my_pconn[3*(2*count+
j)+2+2*pconn_offset] = j+1;
761 my_buff[
j] = 4*maybe_shared[
i][
j].size();
762 send_sizes[
i] += my_buff[
j];
766 std::cout <<
"pconn_offset = " << pconn_offset <<
"\n";
767 std::cout <<
"total size = " << my_size <<
"\n";
768 std::cout <<
"ghost sized = " << my_size - pconn_offset <<
"\n\n";
771 wrk_window->init_done();
776 std::cout <<
"FALSE pconn for pane " << allpanes[
i]->id() << std::endl;
777 COM::Attribute *my_pconn = allpanes[
i]->attribute(w_false_pconn_id);
778 int* ptr = (
int*)my_pconn->pointer();
779 for(
int k=0,
nk=my_pconn->size_of_items();
k<
nk;++
k){
780 std::cout << ptr[
k] <<
" ";
785 std::cout <<
"size of face list\n";
786 COM::Attribute *my_bsize = allpanes[
i]->attribute(w_com_buff_id);
787 ptr = (
int*)my_bsize->pointer();
788 for(
int j =0;
j<my_bsize->size_of_items(); ++
j)
789 std::cout << ptr[
j] <<
" ";
802 COM::Attribute *my_pconn = allpanes[
i]->attribute(w_false_pconn_id);
803 int* ptr = (
int*)my_pconn->pointer();
804 for(
int k=0,
nk=my_pconn->size_of_items();
k<
nk;++
k){
805 std::cout << ptr[
k] <<
" ";
809 std::cout <<
"possibly shared faces\n";
810 for(ms_it = maybe_shared[
i][0].begin(), ms_it2 = maybe_shared[
i][0].end();
811 ms_it != ms_it2; ++ms_it){
813 << (ms_it->first)[0] <<
" "
814 << (ms_it->first)[1] <<
" "
815 << (ms_it->first)[2] <<
" "
816 << (ms_it->first)[3] <<
") ";
820 std::cout <<
"size of communicated face list\n";
821 COM::Attribute *my_bsize = allpanes[
i]->attribute(w_com_buff_id);
822 ptr = (
int*)my_bsize->pointer();
823 for(
int j =0;
j <adj_pane_id[
i].size(); ++
j)
824 std::cout << ptr[
j] <<
" ";
834 COM::Attribute *p_com_buff = allpanes[
i]->attribute(w_com_buff_id);
835 int *com_buff_ptr = (
int*)p_com_buff->pointer();
838 int count = adj_pane_id[
i].size();
843 for(
int j=0;
j< count; ++
j){
844 recv_size += com_buff_ptr[
j];
845 adj_pane_recv[
i][
j] = com_buff_ptr[
j];
847 int send_size = send_sizes[
i];
854 int pconn_size = 3*(pconn_offset)+3+4*count+recv_size+send_size;
858 std::cout <<
" SIZES\nrecv_size = " << recv_size <<
" send_size = " << send_size
859 <<
" pconn size = " << pconn_size <<
"\n"
860 <<
" 3*pconn_offset = " << 3*pconn_offset
861 <<
" 4*count = " << 4*count <<
"\n\n";
865 wrk_window->set_size(
"com_buff", allpanes[
i]->
id(),
std::max(send_size,recv_size),0);
866 wrk_window->resize_array(
"com_buff", (
const int)allpanes[
i]->
id(),
867 reinterpret_cast<void**>(&com_buff_ptr));
869 wrk_window->set_size(
"false_pconn", allpanes[
i]->
id(), pconn_size,
870 pconn_size - (3+pconn_offset));
871 wrk_window->resize_array(
"false_pconn", (
const int)allpanes[
i]->
id(),
872 reinterpret_cast<void**>(&pconn_ptr));
875 if(pconn_offset){pconn_ptr[0]=1;++pconn_ptr;}
876 pconn_ptr[0]=1; pconn_ptr[1]=1; pconn_ptr[2]=1;
880 if(pconn_offset){pconn_ptr[0]=count;++pconn_ptr;}
882 for(
int j =0;
j<count; ++
j){
883 pconn_ptr[0]=adj_pane_id[
i][
j];
884 pconn_ptr[1]=4*maybe_shared[
i][
j].size();
886 ms_it2 = maybe_shared[
i][
j].end();
887 for(ms_it = maybe_shared[
i][
j].begin(); ms_it != ms_it2;
888 ++ms_it, com_ind+=4, pconn_ptr+=4){
892 com_buff_ptr[com_ind] = -1;
894 idm_it = lid2ind[
i][
j].find((*ft)[0]);
895 idm_it = lid2ind[
i][
j].find((*ft)[1]);
896 com_buff_ptr[com_ind+1] = idm_it->second;
897 idm_it = lid2ind[
i][
j].find((*ft)[2]);
898 com_buff_ptr[com_ind+2] = idm_it->second;
899 idm_it = lid2ind[
i][
j].find((*ft)[3]);
900 com_buff_ptr[com_ind+3] = idm_it->second;
901 std::sort(&com_buff_ptr[com_ind],&com_buff_ptr[com_ind+4]);
903 pconn_ptr[0] = com_ind+1;
904 pconn_ptr[1] = com_ind+2;
905 pconn_ptr[2] = com_ind+3;
906 pconn_ptr[3] = com_ind+4;
911 if(pconn_offset){pconn_ptr[0]=count;++pconn_ptr;}
913 for(
int j=0;
j<count; ++
j){
914 pconn_ptr[0]=adj_pane_id[
i][
j];
915 pconn_ptr[1]=adj_pane_recv[
i][
j];
916 for(
int k=0;
k<adj_pane_recv[
i][
j]; ++
k){
917 pconn_ptr[
k+2] =
k+com_ind;
919 com_ind += adj_pane_recv[
i][
j];
920 pconn_ptr += 2+adj_pane_recv[
i][
j];
927 std::cout <<
"Facet list FALSE pconn for pane " << allpanes[
i]->id() << std::endl;
928 COM::Attribute *my_pconn = allpanes[
i]->attribute(w_false_pconn_id);
929 int* ptr = (
int*)my_pconn->pointer();
930 for(
int k=0,
nk=my_pconn->size_of_items();
k<
nk;++
k){
931 std::cout << ptr[
k] <<
" ";
935 std::cout <<
"Facet list buffer for pane " << allpanes[
i]->id() << std::endl;
936 COM::Attribute *my_buff = allpanes[
i]->attribute(w_com_buff_id);
937 ptr = (
int*)my_buff->pointer();
938 for(
int k=0,nk=my_buff->size_of_items();
k<
nk;++
k){
939 std::cout << ptr[
k] <<
" ";
952 std::cout <<
"Updated Facet list buffer for pane " << allpanes[
i]->id() << std::endl;
953 COM::Attribute *my_buff = allpanes[
i]->attribute(w_com_buff_id);
954 int* ptr = (
int*)my_buff->pointer();
955 for(
int k=0,
nk=my_buff->size_of_items();
k<
nk;++
k){
956 std::cout << ptr[
k] <<
" ";
965 COM::Attribute *my_buff = allpanes[
i]->attribute(w_com_buff_id);
966 int* buff_ptr = (
int*)my_buff->pointer();
968 int count = adj_pane_recv[
i].size();
971 for(
int j=0;
j<count; buff_ptr += adj_pane_recv[
i][
j], ++
j){
976 for(
int k=0,
nk =adj_pane_recv[
i][
j];
k<
nk; ++
k){
978 buff_ptr[
k] = ind2lid[
i][
j][buff_ptr[
k]];
983 ms_it2 = maybe_shared[
i][
j].end();
984 bf_it2 = border_facets[
i].end();
985 for(
int k=0, nk=adj_pane_recv[
i][
j];
k<
nk;
k+=4){
986 Four_tuple ns(buff_ptr[
k],buff_ptr[k+1],buff_ptr[k+2],buff_ptr[k+3]);
987 std::sort(&ns[0],&ns[4]);
989 ms_it = maybe_shared[
i][
j].find(ns);
992 Element_node_enumerator ene(allpanes[
i], (ms_it->second).eid());
993 Facet_node_enumerator fne (&ene, (ms_it->second).lid());
999 MAP::Facet_ID fid = ms_it->second;
1000 bf_it = border_facets[
i].find(fid);
1002 border_facets[
i].erase(fid);
1017 bf_it2 = border_facets[
i].end();
1018 for(bf_it = border_facets[
i].begin(); bf_it!= bf_it2; ++bf_it){
1019 Element_node_enumerator ene(allpanes[
i], (*bf_it).eid());
1020 Facet_node_enumerator fne (&ene, (*bf_it).lid());
1032 COM::Attribute *p_is_surface = allpanes[
i]->attribute(w_is_surface_id);
1033 int* surf_ptr = (
int*)p_is_surface->pointer();
1035 for(
int j=0,
nj= p_is_surface->size_of_items();
j<
nj; ++
j){
1038 bf_it2 = border_facets[
i].end();
1040 for(bf_it = border_facets[
i].begin(); bf_it!= bf_it2; ++bf_it){
1041 Element_node_enumerator ene(allpanes[
i], (*bf_it).eid());
1042 Facet_node_enumerator fne (&ene, (*bf_it).lid());
1043 surf_ptr[fne[0]-1] = 1;
1044 surf_ptr[fne[1]-1] = 1;
1045 surf_ptr[fne[2]-1] = 1;
1047 if(fne.size_of_edges()>3)
1048 surf_ptr[fne[3]-1] = 1;
1073 wrk_window->delete_attribute(com_buff->name());
1074 wrk_window->delete_attribute(false_pconn->name());
bool operator<(const Four_tuple &x) const
void determine_physical_border()
Determine which nodes and elements are on the physical border.
A structure used to represent element faces.
Utility for constructing pane connectivities in parallel.
std::map< int, int > Id_Map
Contains the prototypes for the Pane object.
#define COM_assertion_msg(EX, msg)
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
This file contains the prototypes for Roccom API.
3D geometric quality Metric declarations.
const int & operator[](int i) const
Handles communication of shared nodes, ghost nodes or ghost cells across panes.
std::map< Four_tuple, Facet_ID > Corners2Face_Map
static void reduce_maxabs_on_shared_nodes(COM::Attribute *att, COM::Attribute *pconn=NULL)
Perform a maxabs-reduction on the shared nodes for the given attribute.
int COM_compatible_types(COM_Type type1, COM_Type type2)
Four_tuple(int a, int b, int c, int d)
#define MOP_END_NAMESPACE
Definition for Rocblas API.
static void update_ghosts(COM::Attribute *att, const COM::Attribute *pconn=NULL)
Update ghost nodal or elemental values for the given attribute.
#define MOP_BEGIN_NAMESPACE
Utility for detecting boundaries of a pane.