44 #include <boost/math/special_functions/fpclassify.hpp>
54 ProcessIsoContour::create,
55 "Extract an isocontour of fieldid variable and at "
56 "value fieldvalue, Optionally fieldstr can be "
57 "specified for a string defiition or smooth for "
65 "string of isocontour to be extracted");
67 "name for isocontour if fieldstr "
68 "specified, default is isocon");
71 "field id to extract");
74 "field value to extract");
77 "Globally condense contour to unique "
81 "Smooth isocontour (might require "
85 "Number of smoothing cycle, default = "
89 "Postive diffusion coefficient "
90 "(0 < lambda < 1), default = 0.5");
93 "Negative diffusion coefficient "
94 "(0 < mu < 1), default = 0.495");
97 "Remove contours with less than specified number of triangles."
98 "Only valid with GlobalCondense or Smooth options.");
109 int rank =
m_f->m_comm->GetRank();
115 cout <<
"ProcessIsoContour: Extracting contours..." << endl;
119 vector<IsoSharedPtr> iso;
121 if(
m_f->m_fieldPts.get())
127 if(
m_f->m_exp.size() == 0)
140 fieldid =
m_f->m_fieldPts->GetNFields();
146 string varstr =
"x y z";
147 vector<Array<OneD, const NekDouble> > interpfields;
149 for(
int i = 0; i <
m_f->m_fieldPts->GetDim(); ++i)
151 interpfields.push_back(
m_f->m_fieldPts->GetPts(i));
153 for(
int i = 0; i <
m_f->m_fieldPts->GetNFields(); ++i)
155 varstr +=
" " +
m_f->m_fieldPts->GetFieldName(i);
156 interpfields.push_back(
m_f->m_fieldPts->GetPts(i+3));
160 std::string str =
m_config[
"fieldstr"].as<
string>();
161 ExprId = strEval.DefineFunction(varstr.c_str(), str);
163 strEval.Evaluate(ExprId, interpfields, pts);
166 string fieldName =
m_config[
"fieldname"].as<
string>();
168 m_f->m_fieldPts->AddField(pts, fieldName);
172 ASSERTL0(
m_config[
"fieldid"].as<string>() !=
"NotSet",
"fieldid must be specified");
173 fieldid =
m_config[
"fieldid"].as<
int>();
176 ASSERTL0(
m_config[
"fieldvalue"].as<string>() !=
"NotSet",
"fieldvalue must be specified");
184 bool smoothing =
m_config[
"smooth"].m_beenSet;
185 bool globalcondense =
m_config[
"globalcondense"].m_beenSet;
188 int nfields =
m_f->m_fieldPts->GetNFields() +
m_f->m_fieldPts->GetDim();
191 g_iso->globalcondense(iso,
m_f->m_verbose);
195 iso.push_back(g_iso);
200 int niter =
m_config[
"smoothiter"].as<
int>();
203 for(
int i =0 ; i < iso.size(); ++i)
205 iso[i]->smooth(niter,lambda,-mu);
210 if((mincontour =
m_config[
"removesmallcontour"].as<int>()))
212 vector<IsoSharedPtr> new_iso;
216 cout <<
"Identifying separate regions [." << flush ;
218 for(
int i =0 ; i < iso.size(); ++i)
220 iso[i]->separate_regions(new_iso,mincontour,
m_f->m_verbose);
225 cout <<
"]" << endl << flush ;
247 if (((cx[0]-cx[1])==0.0)&&
248 ((cy[0]-cy[1])==0.0)&&
249 ((cz[0]-cz[1])==0.0))
251 if (((cx[2]-cx[3])==0.0)&&
252 ((cy[2]-cy[3])==0.0)&&
253 ((cz[2]-cz[3])==0.0))
332 ASSERTL0(
false,
"Error in 5-point triangulation in ThreeSimilar");
341 vector<IsoSharedPtr> returnval;
343 int coordim =
m_f->m_fieldPts->GetDim();
344 int nfields =
m_f->m_fieldPts->GetNFields() + coordim;
347 "This methods is currently only set up for 3D fields");
348 ASSERTL1(coordim + fieldid < nfields,
349 "field id is larger than number contained in FieldPts");
351 m_f->m_fieldPts->GetPts(fields);
355 int i, j, k, ii, jj, kk, r, s, n, counter, boolean;
358 for(i = 1; i < nfields; ++i)
360 intfields[i] = intfields[i-1] + 5;
366 vector<Array<OneD, int> > ptsConn;
367 m_f->m_fieldPts->GetConnectivity(ptsConn);
368 for(
int zone = 0; zone < ptsConn.size(); ++zone)
374 int nelmt = ptsConn[zone].num_elements()
379 for (n = 0, i = 0; i < nelmt; ++i)
382 if(!(((c[conn[i*4]] >val)&&(c[conn[i*4+1]]>val)&&
383 (c[conn[i*4+2]]>val)&&(c[conn[i*4+3]]>val))||
384 ((c[conn[i*4 ]]<val)&&(c[conn[i*4+1]]<val)&&
385 (c[conn[i*4+2]]<val)&&(c[conn[i*4+3]]<val))))
390 for (counter = 0, j=0; j<=2; j++)
392 for (k=j+1; k<=3; k++)
394 if (((c[conn[i*4+j]]>=val)&&
395 (val>=c[conn[i*4+k]]))||
396 ((c[conn[i*4+j]]<=val)&&
397 (val<=c[conn[i*4+k]])))
405 if(fabs(cj-ck) > 1e-12)
408 for(
int f = 0; f < nfields; ++f)
414 intfields[f][counter] =
415 fields[f][conn[4*i+j]] +
416 factor*(fields[f][conn[4*i+k]] -
417 fields[f][conn[4*i+j]]);
429 iso->resize_fields(3*n);
431 for(j = 0; j < 3; ++j)
433 iso->set_fields(3*(n-1)+j,intfields,j);
438 iso->resize_fields(3*n);
440 for(j = 0; j < 3; ++j)
442 iso->set_fields(3*(n-2)+j,intfields,j);
443 iso->set_fields(3*(n-1)+j,intfields,j+1);
448 iso->resize_fields(3*n);
451 for (ii=0;ii<=2;ii++)
453 for (jj=ii+1;jj<=3;jj++)
455 for (kk=jj+1;kk<=4;kk++)
457 if((((cx[ii]-cx[jj])==0.0)&&
458 ((cy[ii]-cy[jj])==0.0)&&
459 ((cz[ii]-cz[jj])==0.0))&&
460 (((cx[ii]-cx[kk])==0.0)&&
461 ((cy[ii]-cy[kk])==0.0)&&
462 ((cz[ii]-cz[kk])==0.0)))
467 iso->set_fields(3*(n-1) ,intfields,ii);
468 iso->set_fields(3*(n-1)+1,intfields,r);
469 iso->set_fields(3*(n-1)+2,intfields,s);
483 iso->set_fields(3*(n-1) ,intfields,0);
484 iso->set_fields(3*(n-1)+1,intfields,2);
485 iso->set_fields(3*(n-1)+2,intfields,r);
495 returnval.push_back(iso);
504 int nfields =
m_f->m_fieldPts->GetNFields() +
m_f->m_fieldPts->GetDim();
513 for(
int i =0; i < iso.size(); ++i)
515 npts += iso[i]->get_nvert();
524 for(
int i =0; i < iso.size(); ++i)
526 for(
int j = 0; j < iso[i]->get_nvert(); ++j,++cnt)
528 newfields[0][cnt] = iso[i]->get_x(j);
529 newfields[1][cnt] = iso[i]->get_y(j);
530 newfields[2][cnt] = iso[i]->get_z(j);
536 for(
int f = 0; f < nfields-3; ++f)
541 for(
int i =0; i < iso.size(); ++i)
543 for(
int j = 0; j < iso[i]->get_nvert(); ++j,++cnt)
545 newfields[f+3][cnt] = iso[i]->get_fields(f,j);
550 m_f->m_fieldPts->SetPts(newfields);
553 vector<Array<OneD, int> > ptsConn;
554 m_f->m_fieldPts->GetConnectivity(ptsConn);
557 for(
int i =0; i < iso.size(); ++i)
559 int ntris = iso[i]->get_ntris();
562 for(
int j = 0; j < 3*ntris; ++j)
564 conn[j] = cnt + iso[i]->get_vid(j);
566 ptsConn.push_back(conn);
567 cnt += iso[i]->get_nvert();
569 m_f->m_fieldPts->SetConnectivity(ptsConn);
576 "Assume input is from ePtsTriBlock");
579 int dim =
m_f->m_fieldPts->GetDim();
580 int nfields =
m_f->m_fieldPts->GetNFields() + dim;
582 m_f->m_fieldPts->GetPts(fieldpts);
583 vector<Array<OneD, int> > ptsConn;
584 m_f->m_fieldPts->GetConnectivity(ptsConn);
588 for(
int c = 0; c < ptsConn.size(); ++c)
594 nelmt = ptsConn[c].num_elements()/3;
596 iso->set_ntris(nelmt);
597 iso->resize_vid(3*nelmt);
601 for(
int i = 0; i < ptsConn[c].num_elements(); ++i)
603 int cid = ptsConn[c][i]-cnt;
605 nvert = max(cid,nvert);
609 iso->set_nvert(nvert);
610 iso->resize_fields(nvert);
613 for(
int i = 0; i < nvert; ++i)
615 iso->set_fields(i,fieldpts,i+cnt);
618 isovec.push_back(iso);
626 register int i,j,cnt;
628 vector<IsoVertex>
vert;
642 for(cnt =0, i = 0; i < 3; ++i)
647 for(
int f = 0; f <
m_fields.size(); ++f)
659 for(j = 0; j < 3; ++j)
665 pt =
find(vert.begin(),vert.end(),v);
668 m_vid[3*i+j] = pt[0].m_id;
674 for(
int f = 0; f <
m_fields.size(); ++f)
695 for(j = 3*i; j < 3*(m_ntris-1); ++j)
713 for(
int f = 0; f <
m_fields.size(); ++f)
720 m_x[i] = vert[i].m_x;
721 m_y[i] = vert[i].m_y;
722 m_z[i] = vert[i].m_z;
723 for(
int f = 0; f <
m_fields.size(); ++f)
725 m_fields[f][i] = vert[i].m_fields[f];
751 if((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2) < SQ_PNT_TOL)
773 for(i = 0; i < niso; ++i)
777 m_ntris += iso[i]->m_ntris;
784 for(i = 0; i < niso; ++i)
788 m_nvert += iso[i]->m_nvert;
792 vector< vector<int> > isocon;
799 vector<Array<OneD, NekDouble> > sph(niso);
801 for(i = 0; i < niso; ++i)
806 rng[0] = rng[3] = iso[i]->m_x[0];
807 rng[1] = rng[4] = iso[i]->m_x[1];
808 rng[2] = rng[5] = iso[i]->m_x[2];
810 for(id1 = 1; id1 < iso[i]->m_nvert;++id1)
812 rng[0] = min(rng[0],iso[i]->
m_x[i]);
813 rng[1] = min(rng[1],iso[i]->
m_y[i]);
814 rng[2] = min(rng[2],iso[i]->
m_z[i]);
816 rng[3] = max(rng[3],iso[i]->
m_x[i]);
817 rng[4] = max(rng[4],iso[i]->
m_y[i]);
818 rng[5] = max(rng[5],iso[i]->
m_z[i]);
822 sph[i][0] = (rng[3]+rng[0])/2.0;
823 sph[i][1] = (rng[4]+rng[1])/2.0;
824 sph[i][2] = (rng[5]+rng[2])/2.0;
827 sph[i][3] = sqrt((rng[3]-rng[0])*(rng[3]-rng[0]) +
828 (rng[4]-rng[1])*(rng[4]-rng[1]) +
829 (rng[5]-rng[2])*(rng[5]-rng[2]));
832 for(i = 0; i < niso; ++i)
834 for(j = i; j < niso; ++j)
836 NekDouble diff=sqrt((sph[i][0]-sph[j][0])*(sph[i][0]-sph[j][0])+
837 (sph[i][1]-sph[j][1])*(sph[i][1]-sph[j][1])+
838 (sph[i][2]-sph[j][2])*(sph[i][2]-sph[j][2]));
841 if(diff < sph[i][3] + sph[j][3])
843 isocon[i].push_back(j);
851 for(i = 0; i < niso; ++i)
859 for(i = 0; i < niso; ++i)
861 totiso += isocon[i].size();
867 cout <<
"Progress Bar totiso: " << totiso << endl;
869 for(i = 0; i < niso; ++i)
871 for(n = 0; n < isocon[i].size(); ++n, ++cnt)
874 if(verbose && totiso >= 40)
879 int con = isocon[i][n];
880 for(id1 = 0; id1 < iso[i]->m_nvert; ++id1)
883 if(verbose && totiso < 40)
893 for(id2 = start; id2 < iso[con]->m_nvert; ++id2)
896 if((vidmap[con][id2] == -1)||(vidmap[i][id1] == -1))
899 iso[i]->
m_z[id1], iso[con]->
m_x[id2],
900 iso[con]->
m_y[id2],iso[con]->
m_z[id2]))
902 if((vidmap[i][id1] == -1) &&
903 (vidmap[con][id2] != -1))
905 vidmap[i][id1] = vidmap[con][id2];
907 else if((vidmap[con][id2] == -1) &&
908 (vidmap[i][id1] != -1))
910 vidmap[con][id2] = vidmap[i][id1];
912 else if((vidmap[con][id2] == -1) &&
913 (vidmap[i][id1] == -1))
915 vidmap[i][id1] = vidmap[con][id2] = nvert++;
923 for(id1 = 0; id1 < iso[i]->m_nvert;++id1)
925 if(vidmap[i][id1] == -1)
927 vidmap[i][id1] = nvert++;
935 for(n = 0; n < niso; ++n)
937 for(i = 0; i < iso[n]->m_ntris; ++i,nelmt++)
941 m_vid[3*nelmt+j] = vidmap[n][iso[n]->m_vid[3*i+j]];
953 for(i = 0; i < iso[0]->m_fields.size(); ++i)
959 for(n = 0; n < niso; ++n)
961 for(i = 0; i < iso[n]->m_nvert; ++i)
963 m_x[vidmap[n][i]] = iso[n]->m_x[i];
964 m_y[vidmap[n][i]] = iso[n]->m_y[i];
965 m_z[vidmap[n][i]] = iso[n]->m_z[i];
967 for(j = 0; j <
m_fields.size(); ++j)
969 m_fields[j][vidmap[n][i]] = iso[n]->m_fields[j][i];
982 vector< vector<int> > adj,vertcon;
990 for(j = 0; j < 3; ++j)
992 vertcon[
m_vid[3*i+j]].push_back(i);
1001 for(ipt = vertcon[i].begin(); ipt != vertcon[i].end(); ++ipt)
1003 for(j = 0; j < 3; ++j)
1006 if(
m_vid[3*(*ipt)+j] != i)
1009 for(iad = adj[i].begin(); iad != adj[i].end();++iad)
1011 if(*iad == (
m_vid[3*(*ipt)+j]))
break;
1014 if(iad == adj[i].end())
1016 adj[i].push_back(
m_vid[3*(*ipt)+j]);
1028 for (iter=0;iter<n_iter;iter++)
1035 del_v[0] = del_v[1] = del_v[2] = 0.0;
1037 for(iad = adj[i].begin(); iad != adj[i].end(); ++iad)
1039 del_v[0] = del_v[0] + (
m_x[*iad]-
m_x[i])*w;
1040 del_v[1] = del_v[1] + (
m_y[*iad]-
m_y[i])*w;
1041 del_v[2] = del_v[2] + (
m_z[*iad]-
m_z[i])*w;
1044 xtemp[i] =
m_x[i] + del_v[0] * lambda;
1045 ytemp[i] =
m_y[i] + del_v[1] * lambda;
1046 ztemp[i] =
m_z[i] + del_v[2] * lambda;
1054 del_v[0] = del_v[1] = del_v[2] = 0;
1056 for(iad = adj[i].begin(); iad != adj[i].end(); ++iad)
1058 del_v[0] = del_v[0] + (
m_x[*iad]-
m_x[i])*w;
1059 del_v[1] = del_v[1] + (
m_y[*iad]-
m_y[i])*w;
1060 del_v[2] = del_v[2] + (
m_z[*iad]-
m_z[i])*w;
1063 m_x[i] = xtemp[i] + del_v[0] * mu;
1064 m_y[i] = ytemp[i] + del_v[1] * mu;
1065 m_z[i] = ztemp[i] + del_v[2] * mu;
1084 for(j = 0; j < 3; ++j)
1086 vertcon[
m_vid[3*i+j]].push_back(i);
1103 if(vidregion[k] == -1)
1105 vidregion[k] = ++nregions;
1108 for(ipt = vertcon[k].begin(); ipt != vertcon[k].end(); ++ipt)
1110 for(i = 0; i < 3; ++i)
1112 if(vidregion[
id =
m_vid[3*(ipt[0])+i]] == -1)
1114 tocheck.push_back(
id);
1115 vidregion[id] = nregions;
1122 while(tocheck.size())
1124 cid = tocheck.begin();
1125 while(cid != tocheck.end())
1129 for(ipt = vertcon[*cid].begin(); ipt != vertcon[*cid].end(); ++ipt)
1131 for(i = 0; i < 3; ++i)
1133 if(vidregion[
id =
m_vid[3*(ipt[0])+i]] == -1)
1135 tocheck.push_back(
id);
1136 vidregion[id] = nregions;
1142 tocheck.pop_front();
1157 nvert[vidregion[i]] +=1;
1163 nelmt[vidregion[
m_vid[3*i]]] +=1;
1168 for(
int n = 0; n < nregions; ++n)
1170 if(nelmt[n] > minsize)
1175 iso->m_ntris = nelmt[n];
1178 iso->m_nvert = nvert[n];
1179 iso->m_x.resize(nvert[n]);
1180 iso->m_y.resize(nvert[n]);
1181 iso->m_z.resize(nvert[n]);
1183 iso->m_fields.resize(nfields);
1184 for(i = 0; i < nfields; ++i)
1186 iso->m_fields[i].resize(nvert[n]);
1195 if(vidregion[i] == n)
1204 if(vidregion[
m_vid[3*i]] == n)
1206 for(j = 0; j < 3; ++j)
1208 iso->m_vid[3*cnt+j] = vidmap[
m_vid[3*i+j]];
1210 iso->m_x[vidmap[m_vid[3*i+j]]] =
m_x[m_vid[3*i+j]];
1211 iso->m_y[vidmap[m_vid[3*i+j]]] =
m_y[m_vid[3*i+j]];
1212 iso->m_z[vidmap[m_vid[3*i+j]]] =
m_z[m_vid[3*i+j]];
1214 for(k = 0; k < nfields; ++k)
1216 iso->m_fields[k][vidmap[m_vid[3*i+j]]] =
m_fields[k][m_vid[3*i+j]];
1223 WARNINGL0(cnt == nelmt[n],
"Number of elements do not match");
1224 sep_iso.push_back(iso);
#define ASSERTL0(condition, msg)
pair< ModuleType, string > ModuleKey
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
void SetupEquiSpacedField(void)
map< string, ConfigOption > m_config
List of configuration values.
virtual ~ProcessIsoContour()
FieldSharedPtr m_f
Field object.
void separate_regions(vector< boost::shared_ptr< Iso > > &iso, int minsize, bool verbose)
vector< NekDouble > m_fields
void smooth(int n_iter, NekDouble lambda, NekDouble mu)
boost::shared_ptr< Iso > IsoSharedPtr
#define WARNINGL0(condition, msg)
bool operator!=(const IsoVertex &x, const IsoVertex &y)
void SetupIsoFromFieldPts(vector< IsoSharedPtr > &isovec)
void TwoPairs(Array< OneD, NekDouble > &cx, Array< OneD, NekDouble > &cy, Array< OneD, NekDouble > &cz, int &pr)
boost::shared_ptr< Field > FieldSharedPtr
vector< vector< NekDouble > > m_fields
This class defines evaluator of analytic (symbolic) mathematical expressions. Expressions are allowed...
Represents a command-line configuration option.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
bool operator==(TriFaceIDs const &p1, TriFaceIDs const &p2)
vector< IsoSharedPtr > ExtractContour(const int fieldid, const NekDouble val)
void globalcondense(vector< boost::shared_ptr< Iso > > &iso, bool verbose)
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
void ResetFieldPts(vector< IsoSharedPtr > &iso)
bool same(NekDouble x1, NekDouble y1, NekDouble z1, NekDouble x2, NekDouble y2, NekDouble z2)
void ThreeSimilar(const int i, const int j, const int k, int &pr, int &ps)
void Zero(int n, T *x, const int incx)
Zero vector.
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
This processing module interpolates one field to another.
void PrintProgressbar(const int position, const int goal, const string message)
Prints a progressbar.
ModuleFactory & GetModuleFactory()
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.