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.");
111 if(
m_f->m_comm->TreatAsRankZero())
113 cout <<
"ProcessIsoContour: Extracting contours..." << endl;
117 vector<IsoSharedPtr> iso;
119 if(
m_f->m_fieldPts.get())
125 if(
m_f->m_exp.size() == 0)
138 fieldid =
m_f->m_fieldPts->GetNFields();
144 string varstr =
"x y z";
145 vector<Array<OneD, const NekDouble> > interpfields;
147 for(
int i = 0; i <
m_f->m_fieldPts->GetDim(); ++i)
149 interpfields.push_back(
m_f->m_fieldPts->GetPts(i));
151 for(
int i = 0; i <
m_f->m_fieldPts->GetNFields(); ++i)
153 varstr +=
" " +
m_f->m_fieldPts->GetFieldName(i);
154 interpfields.push_back(
m_f->m_fieldPts->GetPts(i+3));
158 std::string str =
m_config[
"fieldstr"].as<
string>();
159 ExprId = strEval.DefineFunction(varstr.c_str(), str);
161 strEval.Evaluate(ExprId, interpfields, pts);
164 string fieldName =
m_config[
"fieldname"].as<
string>();
166 m_f->m_fieldPts->AddField(pts, fieldName);
170 ASSERTL0(
m_config[
"fieldid"].as<string>() !=
"NotSet",
"fieldid must be specified");
171 fieldid =
m_config[
"fieldid"].as<
int>();
174 ASSERTL0(
m_config[
"fieldvalue"].as<string>() !=
"NotSet",
"fieldvalue must be specified");
182 bool smoothing =
m_config[
"smooth"].m_beenSet;
183 bool globalcondense =
m_config[
"globalcondense"].m_beenSet;
186 int nfields =
m_f->m_fieldPts->GetNFields() +
m_f->m_fieldPts->GetDim();
189 g_iso->globalcondense(iso,
m_f->m_verbose);
193 iso.push_back(g_iso);
198 int niter =
m_config[
"smoothiter"].as<
int>();
201 for(
int i =0 ; i < iso.size(); ++i)
203 iso[i]->smooth(niter,lambda,-mu);
208 if((mincontour =
m_config[
"removesmallcontour"].as<int>()))
210 vector<IsoSharedPtr> new_iso;
212 if(
m_f->m_comm->TreatAsRankZero())
214 cout <<
"Identifying separate regions [." << flush ;
216 for(
int i =0 ; i < iso.size(); ++i)
218 iso[i]->separate_regions(new_iso,mincontour,
m_f->m_verbose);
221 if(
m_f->m_comm->TreatAsRankZero())
223 cout <<
"]" << endl << flush ;
245 if (((cx[0]-cx[1])==0.0)&&
246 ((cy[0]-cy[1])==0.0)&&
247 ((cz[0]-cz[1])==0.0))
249 if (((cx[2]-cx[3])==0.0)&&
250 ((cy[2]-cy[3])==0.0)&&
251 ((cz[2]-cz[3])==0.0))
330 ASSERTL0(
false,
"Error in 5-point triangulation in ThreeSimilar");
339 vector<IsoSharedPtr> returnval;
341 int coordim =
m_f->m_fieldPts->GetDim();
342 int nfields =
m_f->m_fieldPts->GetNFields() + coordim;
345 "This methods is currently only set up for 3D fields");
346 ASSERTL1(coordim + fieldid < nfields,
347 "field id is larger than number contained in FieldPts");
349 m_f->m_fieldPts->GetPts(fields);
353 int i, j, k, ii, jj, kk, r, s, n, counter, boolean;
356 for(i = 1; i < nfields; ++i)
358 intfields[i] = intfields[i-1] + 5;
364 vector<Array<OneD, int> > ptsConn;
365 m_f->m_fieldPts->GetConnectivity(ptsConn);
366 for(
int zone = 0; zone < ptsConn.size(); ++zone)
372 int nelmt = ptsConn[zone].num_elements()
377 for (n = 0, i = 0; i < nelmt; ++i)
380 if(!(((c[conn[i*4]] >val)&&(c[conn[i*4+1]]>val)&&
381 (c[conn[i*4+2]]>val)&&(c[conn[i*4+3]]>val))||
382 ((c[conn[i*4 ]]<val)&&(c[conn[i*4+1]]<val)&&
383 (c[conn[i*4+2]]<val)&&(c[conn[i*4+3]]<val))))
388 for (counter = 0, j=0; j<=2; j++)
390 for (k=j+1; k<=3; k++)
392 if (((c[conn[i*4+j]]>=val)&&
393 (val>=c[conn[i*4+k]]))||
394 ((c[conn[i*4+j]]<=val)&&
395 (val<=c[conn[i*4+k]])))
403 if(fabs(cj-ck) > 1e-12)
406 for(
int f = 0; f < nfields; ++f)
412 intfields[f][counter] =
413 fields[f][conn[4*i+j]] +
414 factor*(fields[f][conn[4*i+k]] -
415 fields[f][conn[4*i+j]]);
427 iso->resize_fields(3*n);
429 for(j = 0; j < 3; ++j)
431 iso->set_fields(3*(n-1)+j,intfields,j);
436 iso->resize_fields(3*n);
438 for(j = 0; j < 3; ++j)
440 iso->set_fields(3*(n-2)+j,intfields,j);
441 iso->set_fields(3*(n-1)+j,intfields,j+1);
446 iso->resize_fields(3*n);
449 for (ii=0;ii<=2;ii++)
451 for (jj=ii+1;jj<=3;jj++)
453 for (kk=jj+1;kk<=4;kk++)
455 if((((cx[ii]-cx[jj])==0.0)&&
456 ((cy[ii]-cy[jj])==0.0)&&
457 ((cz[ii]-cz[jj])==0.0))&&
458 (((cx[ii]-cx[kk])==0.0)&&
459 ((cy[ii]-cy[kk])==0.0)&&
460 ((cz[ii]-cz[kk])==0.0)))
465 iso->set_fields(3*(n-1) ,intfields,ii);
466 iso->set_fields(3*(n-1)+1,intfields,r);
467 iso->set_fields(3*(n-1)+2,intfields,s);
481 iso->set_fields(3*(n-1) ,intfields,0);
482 iso->set_fields(3*(n-1)+1,intfields,2);
483 iso->set_fields(3*(n-1)+2,intfields,r);
493 returnval.push_back(iso);
502 int nfields =
m_f->m_fieldPts->GetNFields() +
m_f->m_fieldPts->GetDim();
511 for(
int i =0; i < iso.size(); ++i)
513 npts += iso[i]->get_nvert();
522 for(
int i =0; i < iso.size(); ++i)
524 for(
int j = 0; j < iso[i]->get_nvert(); ++j,++cnt)
526 newfields[0][cnt] = iso[i]->get_x(j);
527 newfields[1][cnt] = iso[i]->get_y(j);
528 newfields[2][cnt] = iso[i]->get_z(j);
534 for(
int f = 0; f < nfields-3; ++f)
539 for(
int i =0; i < iso.size(); ++i)
541 for(
int j = 0; j < iso[i]->get_nvert(); ++j,++cnt)
543 newfields[f+3][cnt] = iso[i]->get_fields(f,j);
548 m_f->m_fieldPts->SetPts(newfields);
551 vector<Array<OneD, int> > ptsConn;
552 m_f->m_fieldPts->GetConnectivity(ptsConn);
555 for(
int i =0; i < iso.size(); ++i)
557 int ntris = iso[i]->get_ntris();
560 for(
int j = 0; j < 3*ntris; ++j)
562 conn[j] = cnt + iso[i]->get_vid(j);
564 ptsConn.push_back(conn);
565 cnt += iso[i]->get_nvert();
567 m_f->m_fieldPts->SetConnectivity(ptsConn);
574 "Assume input is from ePtsTriBlock");
577 int dim =
m_f->m_fieldPts->GetDim();
578 int nfields =
m_f->m_fieldPts->GetNFields() + dim;
580 m_f->m_fieldPts->GetPts(fieldpts);
581 vector<Array<OneD, int> > ptsConn;
582 m_f->m_fieldPts->GetConnectivity(ptsConn);
586 for(
int c = 0; c < ptsConn.size(); ++c)
592 nelmt = ptsConn[c].num_elements()/3;
594 iso->set_ntris(nelmt);
595 iso->resize_vid(3*nelmt);
599 for(
int i = 0; i < ptsConn[c].num_elements(); ++i)
601 int cid = ptsConn[c][i]-cnt;
603 nvert = max(cid,nvert);
607 iso->set_nvert(nvert);
608 iso->resize_fields(nvert);
611 for(
int i = 0; i < nvert; ++i)
613 iso->set_fields(i,fieldpts,i+cnt);
616 isovec.push_back(iso);
624 register int i,j,cnt;
626 vector<IsoVertex>
vert;
640 for(cnt =0, i = 0; i < 3; ++i)
645 for(
int f = 0; f <
m_fields.size(); ++f)
657 for(j = 0; j < 3; ++j)
663 pt =
find(vert.begin(),vert.end(),v);
666 m_vid[3*i+j] = pt[0].m_id;
672 for(
int f = 0; f <
m_fields.size(); ++f)
693 for(j = 3*i; j < 3*(m_ntris-1); ++j)
711 for(
int f = 0; f <
m_fields.size(); ++f)
718 m_x[i] = vert[i].m_x;
719 m_y[i] = vert[i].m_y;
720 m_z[i] = vert[i].m_z;
721 for(
int f = 0; f <
m_fields.size(); ++f)
723 m_fields[f][i] = vert[i].m_fields[f];
749 if((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2) < SQ_PNT_TOL)
771 for(i = 0; i < niso; ++i)
775 m_ntris += iso[i]->m_ntris;
782 for(i = 0; i < niso; ++i)
786 m_nvert += iso[i]->m_nvert;
790 vector< vector<int> > isocon;
797 vector<Array<OneD, NekDouble> > sph(niso);
799 for(i = 0; i < niso; ++i)
804 rng[0] = rng[3] = iso[i]->m_x[0];
805 rng[1] = rng[4] = iso[i]->m_x[1];
806 rng[2] = rng[5] = iso[i]->m_x[2];
808 for(id1 = 1; id1 < iso[i]->m_nvert;++id1)
810 rng[0] = min(rng[0],iso[i]->
m_x[i]);
811 rng[1] = min(rng[1],iso[i]->
m_y[i]);
812 rng[2] = min(rng[2],iso[i]->
m_z[i]);
814 rng[3] = max(rng[3],iso[i]->
m_x[i]);
815 rng[4] = max(rng[4],iso[i]->
m_y[i]);
816 rng[5] = max(rng[5],iso[i]->
m_z[i]);
820 sph[i][0] = (rng[3]+rng[0])/2.0;
821 sph[i][1] = (rng[4]+rng[1])/2.0;
822 sph[i][2] = (rng[5]+rng[2])/2.0;
825 sph[i][3] = sqrt((rng[3]-rng[0])*(rng[3]-rng[0]) +
826 (rng[4]-rng[1])*(rng[4]-rng[1]) +
827 (rng[5]-rng[2])*(rng[5]-rng[2]));
830 for(i = 0; i < niso; ++i)
832 for(j = i; j < niso; ++j)
834 NekDouble diff=sqrt((sph[i][0]-sph[j][0])*(sph[i][0]-sph[j][0])+
835 (sph[i][1]-sph[j][1])*(sph[i][1]-sph[j][1])+
836 (sph[i][2]-sph[j][2])*(sph[i][2]-sph[j][2]));
839 if(diff < sph[i][3] + sph[j][3])
841 isocon[i].push_back(j);
849 for(i = 0; i < niso; ++i)
857 for(i = 0; i < niso; ++i)
859 totiso += isocon[i].size();
865 cout <<
"Progress Bar totiso: " << totiso << endl;
867 for(i = 0; i < niso; ++i)
869 for(n = 0; n < isocon[i].size(); ++n, ++cnt)
872 if(verbose && totiso >= 40)
877 int con = isocon[i][n];
878 for(id1 = 0; id1 < iso[i]->m_nvert; ++id1)
881 if(verbose && totiso < 40)
891 for(id2 = start; id2 < iso[con]->m_nvert; ++id2)
894 if((vidmap[con][id2] == -1)||(vidmap[i][id1] == -1))
897 iso[i]->
m_z[id1], iso[con]->
m_x[id2],
898 iso[con]->
m_y[id2],iso[con]->
m_z[id2]))
900 if((vidmap[i][id1] == -1) &&
901 (vidmap[con][id2] != -1))
903 vidmap[i][id1] = vidmap[con][id2];
905 else if((vidmap[con][id2] == -1) &&
906 (vidmap[i][id1] != -1))
908 vidmap[con][id2] = vidmap[i][id1];
910 else if((vidmap[con][id2] == -1) &&
911 (vidmap[i][id1] == -1))
913 vidmap[i][id1] = vidmap[con][id2] = nvert++;
921 for(id1 = 0; id1 < iso[i]->m_nvert;++id1)
923 if(vidmap[i][id1] == -1)
925 vidmap[i][id1] = nvert++;
933 for(n = 0; n < niso; ++n)
935 for(i = 0; i < iso[n]->m_ntris; ++i,nelmt++)
939 m_vid[3*nelmt+j] = vidmap[n][iso[n]->m_vid[3*i+j]];
951 for(i = 0; i < iso[0]->m_fields.size(); ++i)
957 for(n = 0; n < niso; ++n)
959 for(i = 0; i < iso[n]->m_nvert; ++i)
961 m_x[vidmap[n][i]] = iso[n]->m_x[i];
962 m_y[vidmap[n][i]] = iso[n]->m_y[i];
963 m_z[vidmap[n][i]] = iso[n]->m_z[i];
965 for(j = 0; j <
m_fields.size(); ++j)
967 m_fields[j][vidmap[n][i]] = iso[n]->m_fields[j][i];
980 vector< vector<int> > adj,vertcon;
988 for(j = 0; j < 3; ++j)
990 vertcon[
m_vid[3*i+j]].push_back(i);
999 for(ipt = vertcon[i].begin(); ipt != vertcon[i].end(); ++ipt)
1001 for(j = 0; j < 3; ++j)
1004 if(
m_vid[3*(*ipt)+j] != i)
1007 for(iad = adj[i].begin(); iad != adj[i].end();++iad)
1009 if(*iad == (
m_vid[3*(*ipt)+j]))
break;
1012 if(iad == adj[i].end())
1014 adj[i].push_back(
m_vid[3*(*ipt)+j]);
1026 for (iter=0;iter<n_iter;iter++)
1033 del_v[0] = del_v[1] = del_v[2] = 0.0;
1035 for(iad = adj[i].begin(); iad != adj[i].end(); ++iad)
1037 del_v[0] = del_v[0] + (
m_x[*iad]-
m_x[i])*w;
1038 del_v[1] = del_v[1] + (
m_y[*iad]-
m_y[i])*w;
1039 del_v[2] = del_v[2] + (
m_z[*iad]-
m_z[i])*w;
1042 xtemp[i] =
m_x[i] + del_v[0] * lambda;
1043 ytemp[i] =
m_y[i] + del_v[1] * lambda;
1044 ztemp[i] =
m_z[i] + del_v[2] * lambda;
1052 del_v[0] = del_v[1] = del_v[2] = 0;
1054 for(iad = adj[i].begin(); iad != adj[i].end(); ++iad)
1056 del_v[0] = del_v[0] + (
m_x[*iad]-
m_x[i])*w;
1057 del_v[1] = del_v[1] + (
m_y[*iad]-
m_y[i])*w;
1058 del_v[2] = del_v[2] + (
m_z[*iad]-
m_z[i])*w;
1061 m_x[i] = xtemp[i] + del_v[0] * mu;
1062 m_y[i] = ytemp[i] + del_v[1] * mu;
1063 m_z[i] = ztemp[i] + del_v[2] * mu;
1082 for(j = 0; j < 3; ++j)
1084 vertcon[
m_vid[3*i+j]].push_back(i);
1101 if(vidregion[k] == -1)
1103 vidregion[k] = ++nregions;
1106 for(ipt = vertcon[k].begin(); ipt != vertcon[k].end(); ++ipt)
1108 for(i = 0; i < 3; ++i)
1110 if(vidregion[
id =
m_vid[3*(ipt[0])+i]] == -1)
1112 tocheck.push_back(
id);
1113 vidregion[id] = nregions;
1120 while(tocheck.size())
1122 cid = tocheck.begin();
1123 while(cid != tocheck.end())
1127 for(ipt = vertcon[*cid].begin(); ipt != vertcon[*cid].end(); ++ipt)
1129 for(i = 0; i < 3; ++i)
1131 if(vidregion[
id =
m_vid[3*(ipt[0])+i]] == -1)
1133 tocheck.push_back(
id);
1134 vidregion[id] = nregions;
1140 tocheck.pop_front();
1155 nvert[vidregion[i]] +=1;
1161 nelmt[vidregion[
m_vid[3*i]]] +=1;
1166 for(
int n = 0; n < nregions; ++n)
1168 if(nelmt[n] > minsize)
1173 iso->m_ntris = nelmt[n];
1176 iso->m_nvert = nvert[n];
1177 iso->m_x.resize(nvert[n]);
1178 iso->m_y.resize(nvert[n]);
1179 iso->m_z.resize(nvert[n]);
1181 iso->m_fields.resize(nfields);
1182 for(i = 0; i < nfields; ++i)
1184 iso->m_fields[i].resize(nvert[n]);
1193 if(vidregion[i] == n)
1202 if(vidregion[
m_vid[3*i]] == n)
1204 for(j = 0; j < 3; ++j)
1206 iso->m_vid[3*cnt+j] = vidmap[
m_vid[3*i+j]];
1208 iso->m_x[vidmap[m_vid[3*i+j]]] =
m_x[m_vid[3*i+j]];
1209 iso->m_y[vidmap[m_vid[3*i+j]]] =
m_y[m_vid[3*i+j]];
1210 iso->m_z[vidmap[m_vid[3*i+j]]] =
m_z[m_vid[3*i+j]];
1212 for(k = 0; k < nfields; ++k)
1214 iso->m_fields[k][vidmap[m_vid[3*i+j]]] =
m_fields[k][m_vid[3*i+j]];
1221 WARNINGL0(cnt == nelmt[n],
"Number of elements do not match");
1222 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.