45 #define USE_STD_INCLUDES 1
46 #define USE_C_PREFIX_INCLUDES 1
48 #include "MeshImpl.hpp"
49 #include "MsqError.hpp"
50 #include "InstructionQueue.hpp"
51 #include "MeshSet.hpp"
52 #include "TerminationCriterion.hpp"
53 #include "QualityAssessor.hpp"
54 #include "PlanarDomain.hpp"
55 #include "ShapeImprovementWrapper.hpp"
59 #include "MeanRatioFunctions.hpp"
60 #include "EdgeLengthQualityMetric.hpp"
61 #include "LPtoPTemplate.hpp"
62 #include "FeasibleNewton.hpp"
63 #include "ConjugateGradient.hpp"
67 using namespace Mesquite;
96 using MAP::Pane_connectivity;
97 using MAP::Pane_communicator;
99 using MAP::Pane_ghost_connectivity;
105 print_legible(0,
"Entering Rocmop::~Rocmop");
112 for(
int i =0,
ni=_dcs.size();
i<
ni; ++
i){
116 print_legible(1,
"Exiting Rocmop::~Rocmop");
131 std::getline(Inf,line);
132 while((line.empty() || line[0] ==
' ' || line[0] == noop) && Inf)
133 std::getline(Inf,line);
144 Inf.open(cfname.c_str());
156 std::cerr <<
"Rocmop: Warning: Could not open configfile, "
157 << cfname <<
"." << std::endl;
162 std::istringstream Istr;
178 if(verbosity < 0 || verbosity > 10){
179 std::cerr <<
"Rocmop: Warning: Invalid verbosity from configfile. "
180 <<
"Giving up on " << cfname <<
"." << std::endl;
186 if (rank==0 && _verb){
187 std::cout <<
"Rocmop: Found configfile, " << cfname <<
"." << std::endl
188 <<
"Rocmop: Setting verbosity to " << _verb <<
"." << std::endl;
196 if(_method < 0 || _method > SMOOTH_NONE){
197 std::cerr <<
"Rocmop: Warning: Invalid smoothing method from configfile. "
198 <<
"Giving up on " << cfname <<
"." << std::endl;
203 if (rank==0 && _verb){
204 std::cout <<
"Rocmop: Setting method to "
205 << (_method == SMOOTH_VOL_MESQ_WG ?
"SMOOTH_VOL_MESQ_WG" :
206 (_method == SMOOTH_VOL_MESQ_NG ?
"SMOOTH_VOL_MESQ_NG" :
207 (_method == SMOOTH_SURF_MEDIAL ?
"SMOOTH_SURF_MEDIAL" :
208 "SMOOTH_NONE"))) <<
"." << std::endl;
219 if (rank==0 && _verb){
220 std::cout <<
"Rocmop: Setting lazy to " << _lazy <<
"." << std::endl;
229 if(tol < 0. || tol > 180.){
230 std::cerr <<
"Rocmop: Warning: Invalid dihedral angle tolerance"
231 <<
" from configfile. "
232 <<
"Giving up on " << cfname <<
"." << std::endl;
237 if (rank==0 && _verb){
238 std::cout <<
"Rocmop: Setting tolerance to " << _tol <<
"." << std::endl;
247 if(max_disp < 0. || max_disp > 10.0){
248 std::cerr <<
"Rocmop: Warning: Invalid displacement constraint from configfile. "
249 <<
"Giving up on " << cfname <<
"." << std::endl;
254 if (rank==0 && _verb){
255 std::cout <<
"Rocmop: Setting displacement constraint to "
256 << _maxdisp <<
"." << std::endl;
264 if(_smoothfreq <= 0 || _method == SMOOTH_NONE)
266 if (rank==0 && _verb){
267 if(_method == SMOOTH_NONE){
268 std::cout <<
"Rocmop: No method selected, setting N to 0"
269 <<
",disabling smoothing." << std::endl;
272 std::cout <<
"Rocmop: Setting N to " << _smoothfreq
273 << (_smoothfreq==0 ?
", disabling smoothing." :
".")
283 Istr >> _disp_thresh;
285 if(_disp_thresh < 0.0)
287 else if ((_smoothfreq > 1) && (_disp_thresh > 0.0) ){
290 std::cout <<
"Rocmop: WARNING: N reset to 1 to enable displacement thresholding."
293 if (rank==0 && _verb){
294 std::cout <<
"Rocmop: Setting displacement threshold to "
295 << _disp_thresh <<
"." << std::endl;
314 std::string glb=mname+
".global";
327 glb.c_str(),
"bibB", types);
333 glb.c_str(),
"bii", types);
340 glb.c_str(),
"bbi", types);
347 glb.c_str(),
"bbB", types);
354 glb.c_str(),
"bioo", types);
363 std::string glb=mname+
".global";
376 Profile_begin(
"Rocmop::check_disp");
379 int disp_id = w_disp->id();
380 double max_norm = 0.0;
381 static double disp_tally = 0.0;
385 std::vector<Pane*> allpanes;
386 const_cast<COM::Window*
>(_usr_window)->panes(allpanes);
389 for(
int i=0,
ni = allpanes.size();
i<
ni; ++
i){
392 COM::Attribute* ptr_att = allpanes[
i]->attribute(disp_id);
393 void* void_ptr = ptr_att->pointer();
396 for(
int j=0,
nj = allpanes[
i]->size_of_real_nodes();
j<
nj; ++
j){
411 agree_double(max_norm,
MPI_MAX);
414 disp_tally += max_norm;
417 std::ostringstream Ostr;
418 Ostr <<
"Mesh Displacement: " << disp_tally;
421 if(disp_tally > _disp_thresh){
425 print_legible(0,Ostr.str().c_str());
430 print_legible(1,Ostr.str().c_str());
433 Profile_end(
"Rocmop::check_disp");
444 Profile_begin(
"Rocmop::zero_disp");
447 int disp_id = w_disp->id();
448 std::vector<Pane*> allpanes;
449 const_cast<COM::Window*
>(_usr_window)->panes(allpanes);
451 for(
int i=0,ni = allpanes.size();
i<
ni; ++
i){
453 COM::Attribute* ptr_att = allpanes[
i]->attribute(disp_id);
454 void* void_ptr = ptr_att->pointer();
456 for(
int j=0,nj = allpanes[
i]->size_of_real_nodes();
j<
nj; ++
j){
464 Profile_end(
"Rocmop::zero_disp");
470 COM::Attribute *buf_att){
472 COM::Window* usr_window = usr_att->window();
473 COM::Window* buf_window = NULL;
475 bool del_buffer =
false;
480 std::string buf_name(usr_window->name()+
"-Rocmop_add_aspect");
481 buf_window =
new COM::Window(buf_name,
482 usr_window->get_communicator());
483 buf_window->inherit( usr_att,
"",
484 COM::Pane::INHERIT_CLONE,
true, NULL,0);
485 buf_window->init_done();
488 buf_window = _buf_window;
490 std::vector<Pane*> allpanes;
492 buf_window->panes(allpanes);
496 COM::Attribute * w_buff_R =
497 buf_window->new_attribute(
"Aspect Ratio: R (circumradius)",
'e',
COM_DOUBLE,1,
"");
498 COM::Attribute * w_buff_r =
499 buf_window->new_attribute(
"Aspect Ratio: r (inradius)",
'e',
COM_DOUBLE,1,
"");
500 COM::Attribute * w_buff_l =
501 buf_window->new_attribute(
"Aspect Ratio: l (shortest edge)",
'e',
COM_DOUBLE,1,
"");
502 COM::Attribute * w_buff_rR =
503 buf_window->new_attribute(
"Aspect Ratio: 3r/R",
'e',
COM_DOUBLE,1,
"");
504 COM::Attribute * w_buff_Rr =
505 buf_window->new_attribute(
"Aspect Ratio: R/r",
'e',
COM_DOUBLE,1,
"");
506 COM::Attribute * w_buff_Rl =
507 buf_window->new_attribute(
"Aspect Ratio: R/l",
'e',
COM_DOUBLE,1,
"");
509 COM::Attribute * w_buff_min =
510 buf_window->new_attribute(
"Aspect Ratio: min dih",
'e',
COM_DOUBLE,1,
"");
511 COM::Attribute * w_buff_max =
512 buf_window->new_attribute(
"Aspect Ratio: max dih",
'e',
COM_DOUBLE,1,
"");
513 COM::Attribute * w_buff_type =
514 buf_window->new_attribute(
"Element type",
'e',
COM_INT,1,
"");
516 buf_window->resize_array(w_buff_R,0);
517 buf_window->resize_array(w_buff_r,0);
518 buf_window->resize_array(w_buff_l,0);
519 buf_window->resize_array(w_buff_rR,0);
520 buf_window->resize_array(w_buff_Rr,0);
521 buf_window->resize_array(w_buff_Rl,0);
523 buf_window->resize_array(w_buff_min,0);
524 buf_window->resize_array(w_buff_max,0);
525 buf_window->resize_array(w_buff_type,0);
526 buf_window->init_done();
530 int R_id = w_buff_R->id();
531 int r_id = w_buff_r->id();
532 int l_id = w_buff_l->id();
533 int rR_id = w_buff_rR->id();
534 int Rr_id = w_buff_Rr->id();
535 int Rl_id = w_buff_Rl->id();
537 int min_id = w_buff_min->id();
538 int max_id = w_buff_max->id();
539 int type_id = w_buff_type->id();
543 COM::Attribute * w_usr_R =
544 usr_window->new_attribute(
"Aspect Ratio: R",
'e',
COM_DOUBLE,1,
"");
545 COM::Attribute * w_usr_r =
546 usr_window->new_attribute(
"Aspect Ratio: r",
'e',
COM_DOUBLE,1,
"");
547 COM::Attribute * w_usr_l =
548 usr_window->new_attribute(
"Aspect Ratio: l",
'e',
COM_DOUBLE,1,
"");
549 COM::Attribute * w_usr_rR =
550 usr_window->new_attribute(
"Aspect Ratio: 3r/R",
'e',
COM_DOUBLE,1,
"");
551 COM::Attribute * w_usr_Rr =
552 usr_window->new_attribute(
"Aspect Ratio: R/r",
'e',
COM_DOUBLE,1,
"");
553 COM::Attribute * w_usr_Rl =
554 usr_window->new_attribute(
"Aspect Ratio: R/l",
'e',
COM_DOUBLE,1,
"");
556 COM::Attribute * w_usr_min =
557 usr_window->new_attribute(
"Aspect Ratio: min dih",
'e',
COM_DOUBLE,1,
"");
558 COM::Attribute * w_usr_max =
559 usr_window->new_attribute(
"Aspect Ratio: max dih",
'e',
COM_DOUBLE,1,
"");
560 COM::Attribute * w_usr_type =
561 usr_window->new_attribute(
"Element type",
'e',
COM_INT,1,
"");
564 usr_window->resize_array(w_usr_R,0);
565 usr_window->resize_array(w_usr_r,0);
566 usr_window->resize_array(w_usr_l,0);
567 usr_window->resize_array(w_usr_rR,0);
568 usr_window->resize_array(w_usr_Rr,0);
569 usr_window->resize_array(w_usr_Rl,0);
571 usr_window->resize_array(w_usr_min,0);
572 usr_window->resize_array(w_usr_max,0);
573 usr_window->resize_array(w_usr_type,0);
574 usr_window->init_done();
579 double angles[] = {0.0,0.0};
581 for(
int i=0,ni=(
int)allpanes.size();
i<
ni;++
i){
584 double *R_ptr =
reinterpret_cast<double *
>
585 (allpanes[
i]->attribute(R_id)->pointer());
586 double *r_ptr =
reinterpret_cast<double *
>
587 (allpanes[
i]->attribute(r_id)->pointer());
588 double *l_ptr =
reinterpret_cast<double *
>
589 (allpanes[
i]->attribute(l_id)->pointer());
590 double *rR_ptr =
reinterpret_cast<double *
>
591 (allpanes[
i]->attribute(rR_id)->pointer());
592 double *Rr_ptr =
reinterpret_cast<double *
>
593 (allpanes[
i]->attribute(Rr_id)->pointer());
594 double *Rl_ptr =
reinterpret_cast<double *
>
595 (allpanes[
i]->attribute(Rl_id)->pointer());
597 double *min_ptr =
reinterpret_cast<double *
>
598 (allpanes[
i]->attribute(min_id)->pointer());
599 double *max_ptr =
reinterpret_cast<double *
>
600 (allpanes[
i]->attribute(max_id)->pointer());
601 int * type_ptr =
reinterpret_cast<int *
>
602 (allpanes[
i]->attribute(type_id)->pointer());
604 for(
int j=0,nj=allpanes[
i]->size_of_elements();
j<
nj;++
j){
606 Element_node_enumerator ene(allpanes[
i],
j+1);
621 "Cannot calculate aspect ratios with zero magnitude circumradius");
622 rR_ptr[
j] = (3.0*r)/R;
624 "Cannot calculate aspect ratios with zero magnitude circumradius");
627 "Cannot calculate aspect ratios with zero magnitude circumradius");
630 min_ptr[
j] = angles[0];
631 max_ptr[
j] = angles[1];
632 type_ptr[
j] = ene.type();
663 void Rocmop::get_user_coords(){
664 std::vector<Pane*> allbufpanes;
665 std::vector<Pane*> allusrpanes;
666 const_cast<COM::Window*
>(_usr_window)->panes(allusrpanes);
667 _buf_window->panes(allbufpanes);
669 "Buffer window and user window have different number of panes.");
671 double *usr_x = NULL;
672 double *usr_y = NULL;
673 double *usr_z = NULL;
679 for(
int i=0, ni = allusrpanes.size();
i<
ni; ++
i){
681 int stride = allusrpanes[
i]->attribute(
COM_NC)->stride();
684 x_space = y_space = z_space = allusrpanes[
i]->attribute(
COM_NC)->
685 size_of_components();
686 usr_x = allusrpanes[
i]->attribute(
COM_NC)->coordinates();
696 void Rocmop::get_real_disp(){
701 COM::Attribute *disp,
708 static int N = (_smoothfreq-1);
716 Profile_begin(
"Rocmop::smooth");
722 int pmesh_id = pmesh->id();
725 "Input to Rocmop::smooth must be a mesh or pmesh attribute.");
726 _is_pmesh = (pmesh_id ==
COM_PMESH) ?
true :
false;
731 if(_buf_window && (_usr_window == pmesh->window()))
734 update_buf_real_nc();
744 _usr_window = pmesh->window();
748 pconnErr = check_input_pconn();
754 std::string buf_name(_usr_window->name()+
"-Rocmopbuf");
755 _buf_window =
new COM::Window(buf_name,
756 _usr_window->get_communicator());
757 _buf_window->inherit( const_cast<COM::Attribute*>(_usr_window->attribute(
COM::COM_MESH)),
"",
758 COM::Pane::INHERIT_CLONE,
false, NULL, 0);
759 _buf_window->init_done();
762 if(_buf_window->size_of_panes_global() > 1){
763 Pane_ghost_connectivity pgc(_buf_window);
768 smoother_specific_init();
773 double mesh_qual = 190.0;
779 std::vector<const Pane*> allpanes;
780 _buf_window->panes(allpanes);
781 mesh_qual = check_all_elem_quality(allpanes);
785 bool exceeded =
true;
786 if(_disp_thresh > 0.0)
787 exceeded = check_displacements(disp);
789 if(exceeded || ((mesh_qual > _tol) && _lazy)){
790 print_legible(0,
"Smoothing...");
792 print_legible(0,
"Smoothing complete.");
796 get_usr_disp(pmesh, disp, timestep);
800 _usr_window = pmesh->window();
801 zero_displacements(disp);
805 Profile_end(
"Rocmop::smooth");
811 _usr_window = pmesh->window();
812 zero_displacements(disp);
826 std::vector<const Pane*> allbufpanes;
827 _buf_window->panes(allbufpanes);
828 std::vector<const Pane*> allusrpanes;
829 _usr_window->panes(allusrpanes);
832 "Different number of panes on buffer and user windows.");
834 for(
int i = 0, ni = allbufpanes.size();
i <
ni; ++
i)
837 const COM::Attribute *usr_nc = allusrpanes[
i]->attribute(
COM::COM_NC);
838 const COM::Attribute *buf_nc = allbufpanes[
i]->attribute(
COM::COM_NC);
841 "Rocmop can not operate on meshes with stride == 0");
844 "Number of real items differs between buffer and user windows");
846 double* usr_nc_ptr = (
double*)usr_nc->pointer();
847 double* buf_nc_ptr = (
double*)buf_nc->pointer();
850 int usr_nc_stride = usr_nc->stride();
851 int buf_nc_stride = buf_nc->stride();
852 int usr_nc_next_comp;
853 int buf_nc_next_comp;
855 if (usr_nc_stride == 1)
856 usr_nc_next_comp = usr_nc->size_of_items();
858 usr_nc_next_comp = 1;
860 if (buf_nc_stride == 1)
861 buf_nc_next_comp = buf_nc->size_of_items();
863 buf_nc_next_comp = 1;
866 for(
int j=0, nj = usr_nc->size_of_real_items();
j<
nj; ++
j){
867 *buf_nc_ptr = *usr_nc_ptr;
868 *(buf_nc_ptr+ 1*buf_nc_next_comp) = *(usr_nc_ptr + 1*usr_nc_next_comp);
869 *(buf_nc_ptr+ 2*buf_nc_next_comp) = *(usr_nc_ptr + 2*usr_nc_next_comp);
871 buf_nc_ptr += buf_nc_stride;
872 usr_nc_ptr += usr_nc_stride;
891 int ierr = MPI_Comm_rank(_usr_window->get_communicator(), &
rank);
895 std::vector<const Pane*> allusrpanes;
896 _usr_window->panes(allusrpanes);
898 for(
int i = 0, ni = allusrpanes.size();
i <
ni; ++
i)
901 const COM::Attribute *usr_nc = allusrpanes[
i]->attribute(
COM::COM_NC);
902 const COM::Attribute *usr_pconn = allusrpanes[
i]->attribute(
COM::COM_PCONN);
903 int minGhostNodeID = usr_nc->size_of_real_items() + 1;
904 int maxGhostNodeID = usr_nc->size_of_items();
905 int numGhostNodes = maxGhostNodeID - minGhostNodeID + 1;
906 int * pconnArray = (
int *)usr_pconn->pointer();
909 bool OORGhostNodes =
false;
910 bool missGhostNodes =
false;
913 int * isMarked =
new int [numGhostNodes];
914 for (
int j = 0;
j < numGhostNodes;
j++)
922 for (
int j = 0;
j < 2;
j++)
924 numNbrs = pconnArray[index];
927 for (
int k = 0;
k < numNbrs;
k++)
930 numItems = pconnArray[index];
937 numNbrs = pconnArray[index];
940 for (
int j = 0;
j < numNbrs;
j++)
943 numItems = pconnArray[index];
946 for (
int k = 0;
k < numItems;
k++)
948 int lid = pconnArray[index];
951 if (lid < minGhostNodeID || lid > maxGhostNodeID)
953 std::cerr <<
"Rocmop: Error in check_input_pconn(): Rank "
954 << rank <<
", Ghost node " << lid
955 <<
" is out of ghost node range.\n" << std::endl;
956 OORGhostNodes =
true;
958 else if (isMarked[lid - minGhostNodeID] == 1)
961 std::cerr <<
"Rocmop: Warning in check_input_pconn(): Rank "
962 << rank <<
", Ghost node " << lid
963 <<
" has > 1 owners.\n" << std::endl;
966 isMarked[lid - minGhostNodeID] = 1;
971 for (
int j = 0;
j < numGhostNodes;
j++)
972 if (isMarked[
j] == 0)
974 missGhostNodes =
true;
975 std::cerr <<
"Rocmop: Error in check_input_pconn(): Rank "
976 << rank <<
", Ghost node " << (
j + minGhostNodeID)
977 <<
" is not listed in pconn block 3.\n" << std::endl;
984 if (OORGhostNodes ==
true || missGhostNodes ==
true)
1002 COM::Attribute *disp,
1031 std::vector<const Pane*> allusrpanes;
1032 std::vector<const Pane*> allbufpanes;
1033 _usr_window->panes(allusrpanes);
1034 _buf_window->panes(allbufpanes);
1036 "Different number of panes on buffer and user windows.");
1040 int disp_id = disp->id();
1041 for(
int i = 0, ni = allusrpanes.size();
i <
ni; ++
i){
1043 const COM::Attribute *old_nc = allusrpanes[
i]->attribute(
COM::COM_NC);
1044 const COM::Attribute *new_nc = allbufpanes[
i]->attribute(
COM::COM_NC);
1045 COM::Attribute *p_disp =
const_cast<COM::Attribute*
>
1046 (allusrpanes[
i]->attribute(disp_id));
1048 COM_assertion_msg((p_disp->size_of_real_items() == new_nc->size_of_real_items()) &&
1049 (p_disp->size_of_real_items() == old_nc->size_of_real_items()),
1050 "Number of real items differs between buffer and user windows");
1052 double* old_nc_ptr = (
double*)old_nc->pointer();
1053 double* new_nc_ptr = (
double*)new_nc->pointer();
1054 double* p_disp_ptr = (
double*)p_disp->pointer();
1056 int old_nc_stride = old_nc->stride();
1057 int new_nc_stride = new_nc->stride();
1058 int p_disp_stride = p_disp->stride();
1061 int old_nc_next_comp;
1062 int new_nc_next_comp;
1063 int p_disp_next_comp;
1065 if (old_nc_stride == 1)
1066 old_nc_next_comp = old_nc->size_of_items();
1068 old_nc_next_comp = 1;
1070 if (new_nc_stride == 1)
1071 new_nc_next_comp = new_nc->size_of_items();
1073 new_nc_next_comp = 1;
1075 if (p_disp_stride == 1)
1076 p_disp_next_comp = p_disp->size_of_items();
1078 p_disp_next_comp = 1;
1081 for(
int j = 0, nj = new_nc->size_of_real_items();
j <
nj; ++
j){
1083 *p_disp_ptr = *new_nc_ptr - *old_nc_ptr;
1084 *(p_disp_ptr+1*p_disp_next_comp) = *(new_nc_ptr+1*new_nc_next_comp) - *(old_nc_ptr+1*old_nc_next_comp);
1085 *(p_disp_ptr+2*p_disp_next_comp) = *(new_nc_ptr+2*new_nc_next_comp) - *(old_nc_ptr+2*old_nc_next_comp);
1088 old_nc_ptr += old_nc_stride;
1089 new_nc_ptr += new_nc_stride;
1090 p_disp_ptr += p_disp_stride;
1096 constrain_displacements(disp);
1100 for(
int i = 0, ni = allusrpanes.size();
i <
ni; ++
i){
1102 const COM::Attribute *old_nc = allusrpanes[
i]->attribute(
COM::COM_NC);
1103 COM::Attribute *p_disp =
const_cast<COM::Attribute*
>
1104 (allusrpanes[
i]->attribute(disp_id));
1106 double* old_nc_ptr = (
double*)old_nc->pointer();
1107 double* p_disp_ptr = (
double*)p_disp->pointer();
1109 int old_nc_stride = old_nc->stride();
1110 int p_disp_stride = p_disp->stride();
1114 int old_nc_next_comp;
1115 int p_disp_next_comp;
1117 if (old_nc_stride == 1)
1118 old_nc_next_comp = old_nc->size_of_items();
1120 old_nc_next_comp = 1;
1122 if (p_disp_stride == 1)
1123 p_disp_next_comp = p_disp->size_of_items();
1125 p_disp_next_comp = 1;
1128 for(
int j = 0, nj = p_disp->size_of_real_items();
j <
nj; ++
j){
1130 *p_disp_ptr = *old_nc_ptr + *p_disp_ptr;
1131 *(p_disp_ptr+1*p_disp_next_comp) = *(old_nc_ptr+1*old_nc_next_comp) + *(p_disp_ptr+1*p_disp_next_comp);
1132 *(p_disp_ptr+2*p_disp_next_comp) = *(old_nc_ptr+2*old_nc_next_comp) + *(p_disp_ptr+2*p_disp_next_comp);
1135 old_nc_ptr += old_nc_stride;
1136 p_disp_ptr += p_disp_stride;
1146 const COM::Attribute *orig_nc = pmesh->window()->attribute(
COM::COM_NC);
1157 Profile_begin(
"Rocmop::perform_smoothing");
1159 print_legible(1,
" Entering Rocmop::perform_smoothing");
1165 perform_noniterative_smoothing();
1166 else if( _method < SMOOTH_NONE)
1167 perform_iterative_smoothing();
1171 print_legible(1,
" Exiting Rocmop::perform_smoothing");
1173 Profile_end(
"Rocmop::perform_smoothing");
1180 Profile_begin(
"Rocmop::perform_itersmooth");
1183 print_legible(1,
" Entering Rocmop::perform_iterative_smoothing");
1187 std::vector<const Pane*> allpanes;
1188 _buf_window->panes(allpanes);
1192 if(_method==SMOOTH_VOL_MESQ_WG)
1194 smooth_vol_mesq_wg();
1196 else if(_method==SMOOTH_VOL_MESQ_NG)
1198 smooth_vol_mesq_ng();
1203 if((_method==SMOOTH_VOL_MESQ_WG) || (_method==SMOOTH_VOL_MESQ_NG))
1210 print_legible(1,
" Exiting Rocmop::perform_iterative_smoothing");
1212 Profile_end(
"Rocmop::perform_itersmooth");
1218 Profile_begin(
"Rocmop::perform_nonitersmooth");
1221 print_legible(1,
" Entering Rocmop::perform_noniterative_smoothing");
1224 std::cerr <<
"Although the maximum number of iterations > 1 is selected,\n"
1225 <<
"the smoothing method is noniterative, and will run once.\n";
1232 print_legible(1,
" Exiting Rocmop::perform_noniterative_smoothing");
1234 Profile_end(
"Rocmop::perform_nonitersmooth");
1243 Profile_begin(
"Rocmop::perform_smooth_init");
1246 print_legible(1,
" Entering Rocmop::smoother_specific_init");
1249 if(_wm){
delete _wm; _wm = NULL; }
1252 if(_method==SMOOTH_SURF_MEDIAL){
1262 case SMOOTH_VOL_MESQ_WG: {
1264 determine_shared_border();
1266 invert_elements(COM::Connectivity::TET4);
1270 invert_elements(COM::Connectivity::HEX8);
1275 case SMOOTH_VOL_MESQ_NG: {
1278 const std::string surf_attr(
"is_surface");
1279 const COM::Attribute *w_is_surface = _usr_window->attribute(surf_attr);
1283 "Surface-list must have integer type");
1285 "Surface-list must be nodal");
1287 "Surface-list must have a single component");
1289 "Surface-list must be initialized");
1292 COM::Attribute * new_attr =
1293 _buf_window->inherit( const_cast<COM::Attribute *>(w_is_surface),
1294 surf_attr, COM::Pane::INHERIT_CLONE,
true, NULL, 0);
1299 COM::Attribute* w_surf_attr =
1300 _buf_window->new_attribute(
"is_surface",
'n',
COM_INT, 1,
"");
1301 _buf_window->resize_array( w_surf_attr, 0);
1303 determine_physical_border(w_surf_attr);
1305 _buf_window->init_done();
1308 invert_elements(COM::Connectivity::TET4);
1312 case SMOOTH_VOL_MESQ_WG:
1313 case SMOOTH_VOL_MESQ_NG:
1318 case SMOOTH_SURF_MEDIAL: {
1321 COM::Attribute* w_disps =
1322 _buf_window->new_attribute(
"disps",
'n',
COM_DOUBLE, 3,
"");
1323 _buf_window->resize_array( w_disps, 0);
1325 COM::Attribute* w_facenormals =
1326 _buf_window->new_attribute(
"facenormals",
'e',
COM_DOUBLE, 3,
"");
1327 _buf_window->resize_array( w_facenormals, 0);
1329 COM::Attribute* w_facecenters =
1330 _buf_window->new_attribute(
"facecenters",
'e',
COM_DOUBLE, 3,
"");
1331 _buf_window->resize_array( w_facecenters, 0);
1333 COM::Attribute* w_eigvalues =
1334 _buf_window->new_attribute(
"lambda",
'n',
COM_DOUBLE, 3,
"");
1335 _buf_window->resize_array( w_eigvalues, 0);
1337 COM::Attribute* w_vnormals =
1338 _buf_window->new_attribute(
"vnormals",
'n',
COM_DOUBLE, 3,
"");
1339 _buf_window->resize_array( w_vnormals, 0);
1341 COM::Attribute* w_awnormals =
1342 _buf_window->new_attribute(
"awnormals",
'n',
COM_DOUBLE, 3,
"");
1343 _buf_window->resize_array( w_awnormals, 0);
1345 COM::Attribute* w_uwnormals =
1346 _buf_window->new_attribute(
"uwnormals",
'n',
COM_DOUBLE, 3,
"");
1347 _buf_window->resize_array( w_uwnormals, 0);
1349 COM::Attribute* w_eigvecs =
1350 _buf_window->new_attribute(
"eigvecs",
'n',
COM_DOUBLE, 9,
"");
1351 _buf_window->resize_array( w_eigvecs, 0);
1353 COM::Attribute* w_tangranks =
1354 _buf_window->new_attribute(
"tangranks",
'n',
COM_INT, 1,
"");
1355 _buf_window->resize_array( w_tangranks, 0);
1357 COM::Attribute* w_cntnranks =
1358 _buf_window->new_attribute(
"cntnranks",
'n',
COM_INT, 1,
"");
1359 _buf_window->resize_array( w_cntnranks, 0);
1361 COM::Attribute* w_cntnvecs =
1362 _buf_window->new_attribute(
"cntnvecs",
'n',
COM_DOUBLE, 6,
"");
1363 _buf_window->resize_array( w_cntnvecs, 0);
1365 COM::Attribute* w_scales =
1366 _buf_window->new_attribute(
"scales",
'n',
COM_DOUBLE, 1,
"");
1367 _buf_window->resize_array( w_scales, 0);
1369 COM::Attribute* w_weights =
1370 _buf_window->new_attribute(
"weights",
'n',
COM_DOUBLE, 1,
"");
1371 _buf_window->resize_array( w_weights, 0);
1373 COM::Attribute* w_weights2 =
1374 _buf_window->new_attribute(
"weights2",
'n',
COM_DOUBLE, 1,
"");
1375 _buf_window->resize_array( w_weights2, 0);
1377 COM::Attribute* w_barycrds =
1378 _buf_window->new_attribute(
"barycrds",
'n',
COM_DOUBLE, 2,
"");
1379 _buf_window->resize_array( w_barycrds, 0);
1381 COM::Attribute* w_PNelemids =
1382 _buf_window->new_attribute(
"PNelemids",
'n',
COM_INT, 1,
"");
1383 _buf_window->resize_array( w_PNelemids, 0);
1387 COM::Attribute * w_pnt_contrib =
1388 _buf_window->new_attribute(
"pnt_contrib",
'n',
COM_DOUBLE, 3,
"");
1389 _buf_window->resize_array(w_pnt_contrib, 0);
1391 COM::Attribute * w_disp_count =
1392 _buf_window->new_attribute(
"disp_count",
'n',
COM_DOUBLE, 1,
"");
1393 _buf_window->resize_array(w_disp_count, 0);
1395 _buf_window->init_done();
1409 print_legible(1,
" Exiting Rocmop::smoother_specific_init");
1411 Profile_end(
"Rocmop::perform_smooth_init");
1423 "Rocmop::set_value does not except NULL parameters");
1425 if(opt) option = opt;
1426 if ( option ==
"method") {
1428 ,
"Illegal value for 'method' option");
1429 _method = *((
int*)value);
1431 else if ( option ==
"wrapper"){
1432 int wrapper = *((
int*)value);
1434 ,
"Illegal value for 'wrapper' option");
1437 else if ( option ==
"verbose"){
1438 _verb = *((
int*)value); }
1439 else if ( option ==
"lazy"){
1440 _lazy = *((
int*)value); }
1441 else if ( option ==
"tol"){
1443 ,
"Illegal value for 'tol' option");
1444 _tol = *((
float*)value); }
1445 else if ( option ==
"maxdisp"){
1447 ,
"Illegal value for 'maxdisp' option");
1448 _maxdisp = *((
float*)value); }
1449 else if ( option ==
"niter"){
1450 _niter = *((
int*)value); }
1451 else if ( option ==
"ctol"){
1453 ,
"Illegal value for '_ctol' option");
1454 _ctol = *((
float*)value); }
1455 else if ( option ==
"ncycle"){
1456 _ncycle = *((
int*)value); }
1457 else if ( option ==
"inverted"){
1458 _invert_tets = *((
int*)value);
1460 else if ( option ==
"invert_tets"){
1461 _invert_tets = *((
int*)value);
1463 else if ( option ==
"invert_hexes"){
1464 _invert_hexes = *((
int*)value);
1507 Profile_begin(
"Rocmop::smooth_mesquite");
1513 bool wg = (ghost_level == 0) ?
false :
true;
1521 mp.set_verb(_verb - 4);
1526 Profile_begin(
"Rocmop::Mesquite");
1528 mesh_quality_algorithm.run_instructions(mesh_set1,err);
1530 Profile_end(
"Rocmop::Mesquite");
1535 Profile_end(
"Rocmop::smooth_mesquite");
1540 Pane_communicator pc(att->window(), att->window()->get_communicator());
1542 pc.begin_update_shared_nodes();
1543 pc.reduce_on_shared_nodes(
MPI_SUM);
1544 pc.end_update_shared_nodes();
1549 Profile_begin(
"Rocmop::pane_border");
1552 print_legible(1,
"Entering Rocmop::determine_pane_border");
1554 std::vector<const COM::Pane*> allpanes;
1555 _buf_window->panes(allpanes);
1556 int local_npanes = (int)allpanes.size();
1558 _is_pane_bnd_node.resize(local_npanes);
1559 _is_pane_bnd_elem.resize(local_npanes);
1561 for(
int i=0;
i< local_npanes; ++
i){
1562 int size_of_real_nodes = allpanes[
i]->size_of_real_nodes();
1563 int size_of_real_elems = allpanes[
i]->size_of_real_elements();
1564 _is_pane_bnd_node[
i].resize(size_of_real_nodes,0);
1565 _is_pane_bnd_elem[
i].resize(size_of_real_elems,0);
1567 std::vector<bool> is_isolated;
1568 MAP::Pane_boundary pb (allpanes[
i]);
1569 pb.determine_border_nodes(_is_pane_bnd_node[
i], is_isolated);
1572 mark_elems_from_nodes(_is_pane_bnd_node,_is_pane_bnd_elem);
1574 print_legible(1,
"Exiting Rocmop::determine_pane_border");
1576 Profile_end(
"Rocmop::pane_border");
1583 Profile_begin(
"Rocmop::shared_border");
1586 print_legible(1,
"Entering Rocmop::determine_shared_nodes");
1588 std::vector<const COM::Pane*> allpanes;
1589 _buf_window->panes(allpanes);
1590 int local_npanes = (int)allpanes.size();
1592 _is_shared_node.resize(local_npanes);
1595 for(
int i=0;
i < (int)(local_npanes); ++
i){
1601 _is_shared_node[
i].resize(allpanes[
i]->size_of_real_nodes(),0);
1605 for (
int j=0, nj=vs_size;
j<
nj;
j+=vs[
j+1]+2) {
1606 if (_buf_window->owner_rank( vs[
j]) >=0) ++count;
1611 for (
int j=0;
j<count; ++
j, index+=vs[index+1]+2) {
1613 while ( _buf_window->owner_rank(vs[index])<0) {
1614 index+=vs[index+1]+2;
1618 for(
int k=0;
k<vs[index+1]; ++
k){
1619 _is_shared_node[
i][vs[index+2+
k]-1] = 1;
1624 mark_elems_from_nodes(_is_shared_node,_is_shared_elem);
1626 print_legible(1,
"Exiting Rocmop::determine_shared_nodes");
1628 Profile_end(
"Rocmop::shared_border");
1634 Profile_begin(
"Rocmop::phys_border");
1636 print_legible(1,
"Entering Rocmop::determine_physical_border()");
1638 const std::string surf_attr(
"is_surface");
1639 COM::Attribute* w_is_surface = _buf_window->attribute(surf_attr);
1641 int is_surface_id = w_is_surface->id();
1643 std::vector<const COM::Pane*> allpanes;
1644 _buf_window->panes(allpanes);
1645 int local_npanes = (int)allpanes.size();
1647 _is_phys_bnd_node.resize(local_npanes);
1649 for(
int i=0;
i < local_npanes; ++
i){
1650 _is_phys_bnd_node[
i].resize(allpanes[
i]->size_of_real_nodes());
1653 const COM::Attribute *p_is_surface = allpanes[
i]->attribute(is_surface_id);
1654 int *is_surface_ptr = (
int*)p_is_surface->pointer();
1657 for(
int j=0, nj =(
int) allpanes[
i]->size_of_real_nodes();
j<
nj; ++
j){
1658 if (is_surface_ptr[
j])
1659 _is_phys_bnd_node[
i][
j] =
true;
1663 mark_elems_from_nodes(_is_phys_bnd_node,_is_phys_bnd_elem);
1666 print_legible(1,
"Exiting Rocmop::determine_physical_border()");
1668 Profile_end(
"Rocmop::phys_border");
1673 std::vector<std::vector<bool> > &marked_elems){
1675 Profile_begin(
"Rocmop::mark_elem_node");
1678 print_legible(1,
"Entering Rocmop::mark_elems_from_nodes");
1680 std::vector<const COM::Pane*> allpanes;
1681 _buf_window->panes(allpanes);
1682 int local_npanes = (int)allpanes.size();
1684 marked_elems.clear();
1685 marked_elems.resize(local_npanes);
1688 for(
int i=0;
i < (int)(local_npanes); ++
i){
1690 marked_elems[
i].clear();
1691 marked_elems[
i].resize(allpanes[
i]->size_of_real_elements(),
false);
1695 int s_real_elems = allpanes[
i]->size_of_real_elements();
1696 std::vector<int> nodes;
1697 for(
int j=1;
j<= s_real_elems; ++
j){
1698 Element_node_enumerator ene(allpanes[
i],
j);
1699 ene.get_nodes(nodes);
1700 for(
int k=0,
nk=nodes.size();
k<
nk; ++
k){
1701 if (marked_nodes[
i][nodes[
k]-1])
1702 marked_elems[
i][
j-1] =
true;
1707 print_legible(1,
"Exiting Rocmop::mark_elems_from_nodes");
1709 Profile_end(
"Rocmop::mark_elem_node");
1715 Profile_begin(
"Rocmop::invert_elements");
1717 print_legible(1,
"Entering Rocmop::invert_elements");
1718 std::vector<Pane*> allpanes;
1719 _buf_window->panes(allpanes);
1720 for(
int i=0, ni = allpanes.size();
i<
ni; ++
i){
1728 print_legible(1,
"Exiting Rocmop::invert_elements");
1730 Profile_end(
"Rocmop::invert_tets");
1735 std::vector<COM::Pane*> &allpanes){
1737 Profile_begin(
"Rocmop::check_marked_quality");
1739 print_legible(1,
"Entering Rocmop::check_marked_elems");
1741 double worst_angle = 0.0;
1742 double angles[] = {0.0, 0.0};
1743 for(
int i=0,ni = allpanes.size();
i<
ni; ++
i){
1744 for(
int k =0,
nk=allpanes[
i]->size_of_real_elements();
k<
nk; ++
k){
1745 if(marked_elems[
i][
k]){
1746 Element_node_enumerator ene(allpanes[
i],k+1);
1750 if(angles[1]>worst_angle)
1751 worst_angle = angles[1];
1757 print_legible(1,
"Exiting Rocmop::check_marked_elems");
1759 Profile_end(
"Rocmop::check_marked_quality");
1767 Profile_begin(
"Rocmop::all_quality_const");
1769 print_legible(1,
"Entering Rocmop::check_all_elem_quality");
1772 int ierr = MPI_Comm_rank( _buf_window->get_communicator(),
1773 &
rank); assert( ierr == 0);
1774 double worst_angle = 0.0;
1775 double angles[] = {0.0, 0.0};
1776 for(
int i=0,ni = allpanes.size();
i<
ni; ++
i){
1777 int nk=allpanes[
i]->size_of_real_elements();
1779 nk = allpanes[
i]->size_of_elements();
1780 for(
int k =0; k<
nk; ++
k){
1781 Element_node_enumerator ene(allpanes[
i],k+1);
1785 if(angles[1]>worst_angle)
1786 worst_angle = angles[1];
1790 agree_double(worst_angle,
MPI_MAX);
1793 Profile_end(
"Rocmop::all_quality_const");
1797 print_legible(1,
"Exiting Rocmop::check_all_elem_quality");
1803 Profile_begin(
"Rocmop::all_quality");
1806 print_legible(1,
"Entering Rocmop::check_all_elem_quality");
1810 int ierr = MPI_Comm_rank( _buf_window->get_communicator(),
1811 &
rank); assert( ierr == 0);
1814 double worst_angle = 0.0;
1815 double angles[] = {0.0, 0.0};
1816 for(
int i=0,ni = allpanes.size();
i<
ni; ++
i){
1817 int nk=allpanes[
i]->size_of_real_elements();
1819 nk = allpanes[
i]->size_of_elements();
1821 for(
int k =0; k<
nk; ++
k){
1822 Element_node_enumerator ene(allpanes[
i],k+1);
1827 if(angles[1]>worst_angle)
1828 worst_angle = angles[1];
1832 Profile_end(
"Rocmop::all_quality");
1837 print_legible(1,
"Exiting Rocmop::check_all_elem_quality");
1846 int ierr = MPI_Comm_rank( _buf_window->get_communicator(),
1852 std::cout <<
"Rocmop: " << msg << std::endl;
1858 Profile_begin(
"Rocmop::const_disp");
1863 int disp_id = w_disp->id();
1864 double max_norm = 0.0;
1866 std::vector<Pane*> allpanes;
1867 const_cast<COM::Window*
>(_usr_window)->panes(allpanes);
1869 for(
int i=0,ni = allpanes.size();
i<
ni; ++
i){
1872 COM::Attribute* ptr_att = allpanes[
i]->attribute(disp_id);
1873 void* void_ptr = ptr_att->pointer();
1876 for(
int j=0,nj = allpanes[
i]->size_of_real_nodes();
j<
nj; ++
j){
1877 double norm = ptr[
j].
norm();
1883 agree_double(max_norm,
MPI_MAX);
1885 if(max_norm > _maxdisp){
1886 double div = max_norm/_maxdisp;
1891 Profile_end(
"Rocmop::const_disp");
1897 Profile_begin(
"Rocmop::ext_dihedrals");
1904 int ierr = MPI_Comm_rank( window->get_communicator(),
1912 double max_angle = 0.0;
1913 double min_angle = 180.0;
1918 double angles[] = {0.0, 0.0};
1920 std::vector<Pane*> allpanes;
1921 window->panes(allpanes);
1923 for(
int i=0,ni = allpanes.size();
i<
ni; ++
i){
1924 for(
int k =0,nk=allpanes[
i]->size_of_real_elements(); k<
nk; ++
k){
1925 Element_node_enumerator ene(allpanes[
i],k+1);
1929 if(angles[1]>max_angle){
1930 max_angle = angles[1];
1931 max_pane = allpanes[
i]->id();
1934 if(angles[0]<min_angle){
1935 min_angle = angles[0];
1936 min_pane = allpanes[
i]->id();
1949 send.value = min_angle;
1953 MPI_Allreduce(&send,&recv,1,MPI_DOUBLE_INT,MPI_MINLOC,
1954 window->get_communicator());
1956 if(recv.rank == myrank && _verb > 1){
1957 std::cout <<
"Rocmop:" << std::endl <<
"Rocmop: "
1958 << std::setw(10) << min_angle <<
" on element "
1959 << min_elem <<
" of pane " << min_pane
1960 <<
"." << std::endl;
1965 MPI_Barrier(window->get_communicator());
1970 send.value = max_angle;
1973 MPI_Allreduce(&send,&recv,1,MPI_DOUBLE_INT,MPI_MAXLOC,
1974 window->get_communicator());
1976 if(recv.rank == myrank && _verb > 1){
1977 std::cout <<
"Rocmop:" << std::endl <<
"Rocmop: "
1978 << std::setw(10) << max_angle <<
" on element "
1979 << max_elem <<
" of pane " << max_pane << std::endl;
1983 MPI_Barrier(window->get_communicator());
1986 Profile_end(
"Rocmop::ext_dihedrals");
1993 const COM::Window *win = att->window();
1999 int ierr = MPI_Comm_rank( win->get_communicator(),
2000 &
rank); assert( ierr == 0);
2003 std::vector<const Pane*> allpanes;
2004 win->panes(allpanes);
2007 min_angle[0] = 180.0;
2008 double angles[] = {0.0, 0.0};
2010 for(
int i=0,ni = allpanes.size();
i<
ni; ++
i){
2011 for(
int k =0,nk=allpanes[
i]->size_of_real_elements(); k<
nk; ++
k){
2012 Element_node_enumerator ene(allpanes[
i],k+1);
2017 if(angles[1]>max_angle[0])
2018 max_angle[0] = angles[1];
2019 if(angles[0]<min_angle[0])
2020 min_angle[0] = angles[0];
2025 double temp = max_angle[0];
2026 MPI_Allreduce(&max_angle[0], &temp, 1, MPI_DOUBLE,
MPI_MAX,
2027 win->get_communicator());
2028 max_angle[0] = temp;
2030 temp = min_angle[0];
2031 MPI_Allreduce(&min_angle[0], &temp, 1, MPI_DOUBLE,
MPI_MIN,
2032 win->get_communicator());
2033 min_angle[0] = temp;
2039 string outstr(
"angles.txt");
2049 int ierr = MPI_Comm_rank( _buf_window->get_communicator(),
2050 &
rank); assert( ierr == 0);
2053 std::vector<Pane*> allpanes;
2054 _buf_window->panes(allpanes);
2056 double max_angle = 0.0;
2057 double min_angle = 180.0;
2058 double angles[] = {0.0, 0.0};
2060 file2.open(s2.c_str());
2061 for(
int i=0,ni = allpanes.size();
i<
ni; ++
i){
2062 for(
int k =0,nk=allpanes[
i]->size_of_real_elements(); k<
nk; ++
k){
2063 Element_node_enumerator ene(allpanes[
i],k+1);
2067 file2 << angles[0] <<
" " << angles[1] << std::endl;
2068 if(angles[1]>max_angle)
2069 max_angle = angles[1];
2070 if(angles[0]<min_angle)
2071 min_angle = angles[0];
2076 agree_double(max_angle,
MPI_MAX);
2077 agree_double(min_angle,
MPI_MIN);
2080 file.open(outstr.c_str(), std::ios::app);
2082 file << std::left << std::setw(30) << s << std::setw(0)
2083 <<
"(" << min_angle <<
" , " << max_angle <<
")\n";
2089 std::vector<std::vector<bool> > &to_check){
2091 int ierr = 0, rank =0;
2094 ierr = MPI_Comm_rank( _buf_window->get_communicator()
2100 std::vector<std::vector<bool> > elem_to_check;
2101 mark_elems_from_nodes(to_check, elem_to_check);
2103 std::vector<Pane*> allpanes;
2104 _buf_window->panes(allpanes);
2106 double max_angle = 0.0;
2107 double min_angle = 180.0;
2108 double angles[] = {0.0, 0.0};
2110 for(
int i=0,ni = allpanes.size();
i<
ni; ++
i){
2111 for(
int k =0,nk = elem_to_check[
i].size(); k<
nk; ++
k){
2112 if(elem_to_check[
i][k]){
2113 Element_node_enumerator ene(allpanes[
i],k+1);
2117 if(angles[1]>max_angle)
2118 max_angle = angles[1];
2119 if(angles[0]<min_angle){
2121 min_angle = angles[0];
2127 double temp = min_angle;
2129 agree_double(max_angle,
MPI_MAX);
2130 agree_double(min_angle,
MPI_MIN);
2133 string outstr(
"angles.txt");
2134 ofstream file (outstr.c_str(), std::ios::app);
2137 file << std::left << std::setw(30) << s << std::setw(0)
2138 <<
"(" << min_angle <<
" , " << max_angle <<
")";
2141 std::cout << std::left << std::setw(30) <<
"Rocmop: " << s
2142 << std::setw(0) <<
"(" << min_angle <<
" , "
2143 << max_angle <<
")" << std::endl;
2149 ierr = MPI_Barrier(_buf_window->get_communicator());
2152 if(min_angle == temp){
2154 string outstr(
"angles.txt");
2155 ofstream file (outstr.c_str(), std::ios::app);
2158 file <<
" worst = (" << rank <<
" , " <<
id <<
")\n";
2163 ierr = MPI_Barrier(_buf_window->get_communicator());
2169 Profile_begin(
"Rocmop::perturb_stat");
2172 std::vector<const Pane*> allpanes;
2173 std::vector<const Pane*> allpanes_usr;
2174 _buf_window->panes(allpanes);
2175 _usr_window->panes(allpanes_usr);
2177 COM::Attribute *w_fgpn_bnd =
2178 _buf_window->attribute(
"is_fgpn_bnd");
2179 COM::Attribute *w_qual_b_perturb =
2180 _buf_window->attribute(
"qual_b_perturb");
2181 COM::Attribute *w_qual_a_perturb =
2182 _buf_window->attribute(
"qual_a_perturb");
2184 double angles[] = {0.0, 0.0};
2187 for(
int i=0,ni=allpanes.size();
i<
ni; ++
i){
2189 COM::Attribute *p_fgpn_bnd =
2190 const_cast<COM::Attribute*
>(allpanes[
i]->attribute(w_fgpn_bnd->id()));
2191 COM::Attribute *p_qual_b_perturb =
2192 const_cast<COM::Attribute*
>(allpanes[
i]->attribute(w_qual_b_perturb->id()));
2194 int* fgpn_bnd_ptr =
reinterpret_cast<int*
>(p_fgpn_bnd->pointer());
2195 double* qual_b_perturb_ptr =
2196 reinterpret_cast<double*
>(p_qual_b_perturb->pointer());
2198 std::vector<int> elist;
2200 for(
int j=0, nj= allpanes[
i]->size_of_real_nodes();
j<
nj; ++
j){
2201 if(fgpn_bnd_ptr[
j]){
2202 _dcs[
i]->incident_elements(j+1,elist);
2203 qual_b_perturb_ptr[
j] = 0.0;
2204 for(uint k=0, nk=elist.size(); k<
nk; ++
k){
2205 Element_node_enumerator ene(allpanes[
i],k+1);
2209 if(angles[1]>qual_b_perturb_ptr[j])
2210 qual_b_perturb_ptr[
j] = angles[1];
2218 MAP::Pane_communicator pc(_buf_window, _buf_window->get_communicator());
2219 pc.init(w_qual_b_perturb);
2220 pc.begin_update_shared_nodes();
2221 pc.reduce_on_shared_nodes(
MPI_MAX);
2222 pc.end_update_shared_nodes();
2226 for(
int i=0,ni=allpanes.size();
i<
ni; ++
i){
2228 COM::Attribute *p_fgpn_bnd =
2229 const_cast<COM::Attribute*
>(allpanes[
i]->attribute(w_fgpn_bnd->id()));
2230 COM::Attribute *p_nc =
2231 const_cast<COM::Attribute*
>(allpanes[
i]->attribute(
COM::COM_NC));
2234 reinterpret_cast<int*
>(p_fgpn_bnd->pointer());
2238 std::vector<int> elist;
2240 for(
int j=0, nj= (
int)allpanes[
i]->size_of_real_nodes(); j<
nj; ++
j){
2242 if(fgpn_bnd_ptr[j]){
2243 _dcs[
i]->incident_elements(j+1,elist);
2246 std::cout <<
"Rocmop: Perturbing node " << j+1 << std::endl;
2249 int rand_el = (
std::rand()%elist.size());
2250 Element_node_enumerator ene(allpanes[
i],elist[rand_el]);
2251 std::vector<int> enodes;
2252 ene.get_nodes(enodes);
2257 for(
int nk= (
int)enodes.size(); nindex<
nk; ++nindex){
2258 if(enodes[nindex]==j+1)
2263 "Node not found in supposedly adjacent element\n");
2264 double length = (nc_ptr[
j]-nc_ptr[enodes[(nindex+rand_ed)%4]-1]).norm();
2267 for(
int k=0; k<3; ++
k){
2270 -1.0*((double)((
std::rand()%1000)+1)/1000.0);
2272 nc_ptr[
j] += perturb;
2278 for(
int i=0,ni=(
int)allpanes.size();
i<
ni; ++
i){
2280 COM::Attribute *p_fgpn_bnd =
2281 const_cast<COM::Attribute*
>(allpanes[
i]->attribute(w_fgpn_bnd->id()));
2282 COM::Attribute *p_qual_a_perturb =
2283 const_cast<COM::Attribute*
>(allpanes[
i]->attribute(w_qual_a_perturb->id()));
2286 reinterpret_cast<int*
>(p_fgpn_bnd->pointer());
2287 double* qual_a_perturb_ptr =
2288 reinterpret_cast<double*
>(p_qual_a_perturb->pointer());
2290 std::vector<int> elist;
2292 for(
int j=0, nj= (
int)allpanes[
i]->size_of_real_nodes(); j<
nj; ++
j){
2293 if(fgpn_bnd_ptr[j]){
2294 _dcs[
i]->incident_elements(j+1,elist);
2295 qual_a_perturb_ptr[
j] = 0.0;
2296 for(
int k=0, nk=(
int)elist.size(); k<
nk; ++
k){
2297 Element_node_enumerator ene(allpanes[
i],k+1);
2301 if(angles[1]>qual_a_perturb_ptr[j])
2302 qual_a_perturb_ptr[
j] = angles[1];
2310 MAP::Pane_communicator pc(_buf_window, _buf_window->get_communicator());
2311 pc.init(w_qual_a_perturb);
2312 pc.begin_update_shared_nodes();
2313 pc.reduce_on_shared_nodes(
MPI_MAX);
2314 pc.end_update_shared_nodes();
2319 for(
int i=0,ni=allpanes.size();
i<
ni; ++
i){
2321 COM::Attribute *p_fgpn_bnd =
2322 const_cast<COM::Attribute*
>(allpanes[
i]->attribute(w_fgpn_bnd->id()));
2323 COM::Attribute *p_nc =
2324 const_cast<COM::Attribute*
>(allpanes[
i]->attribute(
COM::COM_NC));
2325 COM::Attribute *p_nc_usr =
2326 const_cast<COM::Attribute*
>(allpanes_usr[
i]->attribute(
COM::COM_NC));
2328 COM::Attribute *p_qual_b_perturb =
2329 const_cast<COM::Attribute*
>(allpanes[
i]->attribute(w_qual_b_perturb->id()));
2330 COM::Attribute *p_qual_a_perturb =
2331 const_cast<COM::Attribute*
>(allpanes[
i]->attribute(w_qual_a_perturb->id()));
2334 reinterpret_cast<int*
>(p_fgpn_bnd->pointer());
2339 double* qual_b_perturb_ptr =
2340 reinterpret_cast<double*
>(p_qual_b_perturb->pointer());
2341 double* qual_a_perturb_ptr =
2342 reinterpret_cast<double*
>(p_qual_a_perturb->pointer());
2345 for(
int j=0, nj= (
int)allpanes[
i]->size_of_real_nodes(); j<
nj; ++
j){
2346 if(fgpn_bnd_ptr[j] &&
2347 (qual_a_perturb_ptr[j] > qual_b_perturb_ptr[j]))
2348 nc_ptr[j] = nc_ptr_usr[j];
2352 Profile_end(
"Rocmop::perturb_stat");
2364 extern "C" void COM_F_FUNC2(rocmop_load_module, ROCMOP_LOAD_MODULE)(
const char *mname,
long int length)
2367 extern "C" void COM_F_FUNC2(rocmop_unload_module, ROCMOP_UNLOAD_MODULE)(
const char *mname,
long int length)
static void div_scalar(const Attribute *x, const void *y, Attribute *z, int swap=0)
Operation wrapper for division with y as a scalar pointer.
static void sub(const Attribute *x, const Attribute *y, Attribute *z)
Operation wrapper for subtraction.
int COM_Type
Indices for derived data types.
void determine_physical_border()
Determine which nodes and elements are on the physical border.
void obtain_extremal_dihedrals(const COM::Attribute *att, double *min, double *max)
Obtain the min and max dihedral angles.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_COMM_WORLD
Utility for constructing pane connectivities in parallel.
3D Aspect Ratios Metric Class
void invert()
Invert Tetrahedrons.
virtual void compute(double atts[]) const
Calculate the metric value on this element.
double check_all_elem_quality(std::vector< const COM::Pane * > &allpanes, bool with_ghost=false)
Get the largest dihedral angle of all real elements.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_MAX
const char * option(const char *const name, const int argc, const char *const *const argv, const char *defaut, const char *const usage=0)
void print_mquality(std::string &s, std::vector< std::vector< bool > > &to_check)
Print the quality range of marked elements, for debugging.
void COM_delete_window(const char *wname)
Used to hold the error state and return it to the application.
void perturb_stationary()
Randomly perturn stationary nodes on pane boundary, not on phys. surface.
void determine_pane_border()
Determine which nodes and elements are on pane borders.
#define COM_assertion_msg(EX, msg)
void smooth_boeing(COM::Attribute *att, int *niter)
This file contains the prototypes for Roccom API.
3D geometric quality Metric declarations.
void get_usr_disp(const COM::Attribute *pmesh, COM::Attribute *disp, double *timestep)
Get displacement in _usr_window based on nc in _buf_window.
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_MIN
A Roccom mesh optimization module.
std::ifstream & get_next_line(std::ifstream &Inf, std::string &line, const char noop)
void COM_set_object(const char *wa_str, int pane_id, Type *addr)
Handles communication of shared nodes, ghost nodes or ghost cells across panes.
#define COM_F_FUNC2(lowcase, uppercase)
static void reduce_sum_on_shared_nodes(COM::Attribute *att)
Perform a sum-reduction on the shared nodes for the given attribute.
void Rocmop_unload_module(const char *mname)
T norm(const NVec< DIM, T > &v)
void zero_displacements(COM::Attribute *disp)
double length(Vector3D *const v, int n)
void COM_get_object(const char *wa_str, int pane_id, Type **addr)
void update_buf_real_nc()
Update real nodal coordinates of _buf_window from _usr_window.
void read_config_file(const std::string &)
static int pconn_offset()
Retrieve an offset to avoid the number of communicating panes when reading a pconn attribute...
void perform_smoothing()
Perform smoothing on _buf_window.
void initialize(const COM::Attribute *pmesh)
Constructs the communication patterns of a distributed mesh.
void Rocmop_load_module(const char *mname)
virtual ~Rocmop()
Destructor.
A class enabling Mesquite calls on Rocmop panes.
Utility for constructing pane ghost connecvtivities in parallel.
void perform_noniterative_smoothing()
Perform noniterative smoothing.
int COM_compatible_types(COM_Type type1, COM_Type type2)
double check_marked_elem_quality(std::vector< std::vector< bool > > &marked_elems, std::vector< COM::Pane * > &allpanes)
Get the largest dihedral angle of marked real elements.
void constrain_displacements(COM::Attribute *w_disp)
Contrain displacements to _maxdisp.
Wrapper which performs a Feasible Newton solve using an objective function template with inverse mea...
static void unload(const std::string &mname)
Unloads Rocmop from Roccom.
void invert_elements(int conn_type)
Repair inverted tets or hexes.
void determine_shared_border()
Determine which nodes and elements are shared.
void COM_window_init_done(const char *w_str, int pane_changed=true)
int check_input_pconn()
Check pconn block 3 of the input mesh.
void print_legible(int verb, const char *msg)
Single process print message if given verbosity level is exceeded.
#define MOP_END_NAMESPACE
void COM_new_window(const char *wname, MPI_Comm c=MPI_COMM_NULL)
virtual void initialize(Vector_3< double > n[], int type)
Initialize a 3D Geometric Metric by nodal coords and element type.
Definition for Rocblas API.
void print_quality(std::string &s)
Print the quality range of all elements, for debugging.
void smooth(const COM::Attribute *pmesh, COM::Attribute *disp)
Smooth the mesh in a Rocmop managed buffer.
static void update_ghosts(COM::Attribute *att, const COM::Attribute *pconn=NULL)
Update ghost nodal or elemental values for the given attribute.
void getAspects(double &R, double &r, double &l)
Get the geometric aspects.
void smoother_specific_init()
Perform smoother specific initialization.
static void load(const std::string &mname)
Loads Rocmop onto Roccom with a given module name.
#define MOP_BEGIN_NAMESPACE
3D Max and Min Angle Metric Class
void print_extremal_dihedrals(COM::Window *window)
Print the min and max dihedral angles along with their locations.
static void copy(const Attribute *x, Attribute *y)
Wrapper for copy.
double rand()
Return a random variable between [0,1] with respect to an uniform distribution.
void int int REAL REAL REAL *z blockDim dim * ni
void COM_new_attribute(const char *wa_str, const char loc, const int type, int ncomp, const char *unit)
Registering an attribute type.
void COM_set_member_function(const char *wf_str, Member_func_ptr func, const char *wa_str, const char *intents, const COM_Type *types)
Geometric helper function header file.
void set_value(const char *opt, const void *val)
Set a Rocomp option.
void mark_elems_from_nodes(std::vector< std::vector< bool > > &marked_nodes, std::vector< std::vector< bool > > &marked_elems)
Mark the nodes which contain marked elems.
void add_aspect_ratios(COM::Attribute *usr_att, COM::Attribute *buf_att=NULL)
#define MSQ_ERRRTN(err)
If passed error is true, return from a void function.
void smooth_mesquite(std::vector< COM::Pane * > &allpanes, int ghost_level=0)
Smooth the panes of the working window using MESQUITE.
void add_mesh(Mesquite::Mesh *mesh, MsqError &err)
adds a mesh to the MeshSet.
void perform_iterative_smoothing()
Perform iterative smoothing.
The MeshSet class stores one or more Mesquite::Mesh pointers and manages access to the mesh informati...
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_GROUP_EMPTY INTEGER MPI_SUM
bool check_displacements(COM::Attribute *disp)