43 #include <boost/math/special_functions/fpclassify.hpp>
53 ProcessIsoContour::create,
54 "Extract an isocontour of fieldid variable and at value fieldvalue, Optionally fieldstr can be specified for a string defiition or smooth for smoothing");
61 "string of isocontour to be extracted");
63 "name for isocontour if fieldstr "
64 "specified, default is isocon");
67 "field id to extract");
69 "field value to extract");
72 "Globally condense contour to unique "
76 "Smooth isocontour (implies global "
79 "Number of smoothing cycle, default = "
82 "Postive diffusion coefficient "
83 "(0 < lambda < 1), default = 0.5");
85 "Negative diffusion coefficient "
86 "(0 < mu < 1), default = 0.495");
96 vector<IsoSharedPtr> iso;
107 m_f->m_fieldPts->m_nFields++;
109 int nfields =
m_f->m_fieldPts->m_nFields;
110 int coordim =
m_f->m_fieldPts->m_ptsDim;
114 Array<OneD, Array<OneD, NekDouble> > newpts(nfields+coordim);
117 for(
int i = 0; i < nfields+coordim-1; ++i)
119 newpts[i] =
m_f->m_fieldPts->m_pts[i];
121 int npts =
m_f->m_fieldPts->m_pts[0].num_elements();
122 newpts[nfields+coordim-1] = Array<OneD, NekDouble>(
npts);
124 m_f->m_fieldPts->m_pts = newpts;
128 string varstr =
"x y z";
129 vector<Array<OneD, const NekDouble> > interpfields;
131 for(
int i = 0; i < coordim; ++i)
133 interpfields.push_back(
m_f->m_fieldPts->m_pts[i]);
135 for(
int i = 0; i < nfields-1; ++i)
137 varstr +=
" " +
m_f->m_fieldPts->m_fields[i];
138 interpfields.push_back(
m_f->m_fieldPts->m_pts[i+3]);
142 std::string str =
m_config[
"fieldstr"].as<
string>();
145 strEval.
Evaluate(ExprId, interpfields,
146 m_f->m_fieldPts->m_pts[nfields+coordim-1]);
149 m_f->m_fieldPts->m_fields.push_back(
150 m_config[
"fieldname"].as<string>());
154 fieldid =
m_config[
"fieldid"].as<
int>();
160 bool smoothing =
m_config[
"smooth"].m_beenSet;
161 bool globalcondense =
m_config[
"globalcondense"].m_beenSet;
162 if(smoothing||globalcondense)
164 vector<IsoSharedPtr> glob_iso;
165 int nfields =
m_f->m_fieldPts->m_pts.num_elements();
168 g_iso->globalcondense(iso);
172 int niter =
m_config[
"smoothiter"].as<
int>();
175 g_iso->smooth(niter,lambda,-mu);
178 glob_iso.push_back(g_iso);
194 Array<OneD, NekDouble> &cy,
195 Array<OneD, NekDouble> &cz,
200 if (((cx[0]-cx[1])==0.0)&&
201 ((cy[0]-cy[1])==0.0)&&
202 ((cz[0]-cz[1])==0.0))
204 if (((cx[2]-cx[3])==0.0)&&
205 ((cy[2]-cy[3])==0.0)&&
206 ((cz[2]-cz[3])==0.0))
284 printf(
"Error in 5-point triangulation in ThreeSimilar");
293 vector<IsoSharedPtr> returnval;
295 Array<OneD, NekDouble> x =
m_f->m_fieldPts->m_pts[0];
296 Array<OneD, NekDouble> y =
m_f->m_fieldPts->m_pts[1];
297 Array<OneD, NekDouble> z =
m_f->m_fieldPts->m_pts[2];
299 int coordim =
m_f->m_exp[0]->GetCoordim(0);
300 int nfields =
m_f->m_fieldPts->m_pts.num_elements();
303 "This methods is currently only set up for 3D fields");
304 ASSERTL1(coordim + fieldid < nfields,
305 "field id is larger than number contained in FieldPts");
306 Array<OneD, Array<OneD, NekDouble> > fields =
m_f->m_fieldPts->m_pts;
308 Array<OneD, NekDouble> c = fields[coordim + fieldid];
310 int i, j, k, ii, jj, kk, r, s, n, counter, boolean;
311 Array<OneD, Array<OneD, NekDouble> > intfields(nfields);
312 intfields[0] = Array<OneD, NekDouble>(5*nfields);
313 for(i = 1; i < nfields; ++i)
315 intfields[i] = intfields[i-1] + 5;
317 Array<OneD, NekDouble> cx = intfields[0];
318 Array<OneD, NekDouble> cy = intfields[1];
319 Array<OneD, NekDouble> cz = intfields[2];
321 for(
int zone = 0; zone <
m_f->m_fieldPts->m_ptsConn.size(); ++zone)
327 int nelmt =
m_f->m_fieldPts->m_ptsConn[zone].num_elements()
330 Array<OneD, int> conn =
m_f->m_fieldPts->m_ptsConn[zone];
332 for (n = 0, i = 0; i < nelmt; ++i)
335 if(!(((c[conn[i*4]] >val)&&(c[conn[i*4+1]]>val)&&
336 (c[conn[i*4+2]]>val)&&(c[conn[i*4+3]]>val))||
337 ((c[conn[i*4 ]]<val)&&(c[conn[i*4+1]]<val)&&
338 (c[conn[i*4+2]]<val)&&(c[conn[i*4+3]]<val))))
343 for (counter = 0, j=0; j<=2; j++)
345 for (k=j+1; k<=3; k++)
347 if (((c[conn[i*4+j]]>=val)&&
348 (val>=c[conn[i*4+k]]))||
349 ((c[conn[i*4+j]]<=val)&&
350 (val<=c[conn[i*4+k]])))
358 if(fabs(cj-ck) > 1e-12)
361 for(
int f = 0; f < nfields; ++f)
367 intfields[f][counter] =
368 fields[f][conn[4*i+j]] +
369 factor*(fields[f][conn[4*i+k]] -
370 fields[f][conn[4*i+j]]);
382 iso->resize_fields(3*n);
384 for(j = 0; j < 3; ++j)
386 iso->set_fields(3*(n-1)+j,intfields,j);
392 iso->resize_fields(3*n);
394 for(j = 0; j < 3; ++j)
396 iso->set_fields(3*(n-2)+j,intfields,j);
397 iso->set_fields(3*(n-1)+j,intfields,j+1);
403 iso->resize_fields(3*n);
406 for (ii=0;ii<=2;ii++)
408 for (jj=ii+1;jj<=3;jj++)
410 for (kk=jj+1;kk<=4;kk++)
412 if((((cx[ii]-cx[jj])==0.0)&&
413 ((cy[ii]-cy[jj])==0.0)&&
414 ((cz[ii]-cz[jj])==0.0))&&
415 (((cx[ii]-cx[kk])==0.0)&&
416 ((cy[ii]-cy[kk])==0.0)&&
417 ((cz[ii]-cz[kk])==0.0)))
422 iso->set_fields(3*(n-1) ,intfields,ii);
423 iso->set_fields(3*(n-1)+1,intfields,r);
424 iso->set_fields(3*(n-1)+2,intfields,s);
438 iso->set_fields(3*(n-1) ,intfields,0);
439 iso->set_fields(3*(n-1)+1,intfields,2);
440 iso->set_fields(3*(n-1)+2,intfields,r);
450 returnval.push_back(iso);
459 int nfields =
m_f->m_fieldPts->m_pts.num_elements();
464 Array<OneD, Array<OneD, NekDouble> > newfields(nfields);
468 for(
int i =0; i < iso.size(); ++i)
470 npts += iso[i]->get_nvert();
474 newfields[0] = Array<OneD, NekDouble>(
npts);
475 newfields[1] = Array<OneD, NekDouble>(
npts);
476 newfields[2] = Array<OneD, NekDouble>(
npts);
479 for(
int i =0; i < iso.size(); ++i)
481 for(
int j = 0; j < iso[i]->get_nvert(); ++j,++cnt)
483 newfields[0][cnt] = iso[i]->get_x(j);
484 newfields[1][cnt] = iso[i]->get_y(j);
485 newfields[2][cnt] = iso[i]->get_z(j);
491 for(
int f = 0; f < nfields-3; ++f)
493 newfields[f+3] = Array<OneD, NekDouble>(
npts);
496 for(
int i =0; i < iso.size(); ++i)
498 for(
int j = 0; j < iso[i]->get_nvert(); ++j,++cnt)
500 newfields[f+3][cnt] = iso[i]->get_fields(f,j);
505 m_f->m_fieldPts->m_pts = newfields;
509 m_f->m_fieldPts->m_ptsConn.clear();
510 for(
int i =0; i < iso.size(); ++i)
512 int ntris = iso[i]->get_ntris();
513 Array<OneD, int> conn(ntris*3);
515 for(
int j = 0; j < 3*ntris; ++j)
517 conn[j] = cnt + iso[i]->get_vid(j);
519 m_f->m_fieldPts->m_ptsConn.push_back(conn);
520 cnt += iso[i]->get_nvert();
526 register int i,j,cnt;
528 vector<IsoVertex> vert;
542 for(cnt =0, i = 0; i < 3; ++i)
547 for(
int f = 0; f <
m_fields.size(); ++f)
559 for(j = 0; j < 3; ++j)
565 pt =
find(vert.begin(),vert.end(),v);
568 m_vid[3*i+j] = pt[0].m_id;
574 for(
int f = 0; f <
m_fields.size(); ++f)
595 for(j = 3*i; j < 3*(m_ntris-1); ++j)
613 for(
int f = 0; f <
m_fields.size(); ++f)
620 m_x[i] = vert[i].m_x;
621 m_y[i] = vert[i].m_y;
622 m_z[i] = vert[i].m_z;
623 for(
int f = 0; f <
m_fields.size(); ++f)
625 m_fields[f][i] = vert[i].m_fields[f];
651 if((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2) <
SQ_PNT_TOL)
665 Array<OneD, Array<OneD, int> > vidmap;
670 vidmap = Array<OneD, Array<OneD, int> > (niso);
673 for(i = 0; i < niso; ++i)
677 m_ntris += iso[i]->m_ntris;
684 for(i = 0; i < niso; ++i)
688 m_nvert += iso[i]->m_nvert;
692 vector< vector<int> > isocon;
699 vector<Array<OneD, NekDouble> > sph(niso);
700 Array<OneD, NekDouble> rng(6);
701 for(i = 0; i < niso; ++i)
703 sph[i] = Array<OneD, NekDouble>(4);
706 rng[0] = rng[3] = iso[i]->m_x[0];
707 rng[1] = rng[4] = iso[i]->m_x[1];
708 rng[2] = rng[5] = iso[i]->m_x[2];
710 for(id1 = 1; id1 < iso[i]->m_nvert;++id1)
712 rng[0] = min(rng[0],iso[i]->
m_x[i]);
713 rng[1] = min(rng[1],iso[i]->
m_y[i]);
714 rng[2] = min(rng[2],iso[i]->
m_z[i]);
716 rng[3] = max(rng[3],iso[i]->
m_x[i]);
717 rng[4] = max(rng[4],iso[i]->
m_y[i]);
718 rng[5] = max(rng[5],iso[i]->
m_z[i]);
722 sph[i][0] = (rng[3]+rng[0])/2.0;
723 sph[i][1] = (rng[4]+rng[1])/2.0;
724 sph[i][2] = (rng[5]+rng[2])/2.0;
727 sph[i][3] = sqrt((rng[3]-rng[0])*(rng[3]-rng[0]) +
728 (rng[4]-rng[1])*(rng[4]-rng[1]) +
729 (rng[5]-rng[2])*(rng[5]-rng[2]));
732 for(i = 0; i < niso; ++i)
734 for(j = i+1; j < niso; ++j)
736 NekDouble diff=sqrt((sph[i][0]-sph[j][0])*(sph[i][0]-sph[j][0])+
737 (sph[i][1]-sph[j][1])*(sph[i][1]-sph[j][1])+
738 (sph[i][2]-sph[j][2])*(sph[i][2]-sph[j][2]));
741 if(diff < sph[i][3] + sph[j][3])
743 isocon[i].push_back(j);
750 for(i = 0; i < niso; ++i)
752 vidmap[i] = Array<OneD, int>(iso[i]->m_nvert,-1);
756 cout <<
"Matching Vertices [" <<flush;
758 for(i = 0; i < niso; ++i)
760 for(n = 0; n < isocon[i].size(); ++n)
762 int con = isocon[i][n];
763 for(id1 = 0; id1 < iso[i]->m_nvert;++id1)
765 for(id2 = 0; id2 < iso[con]->m_nvert;++id2,++cnt)
775 iso[i]->
m_z[id1], iso[con]->
m_x[id2],
776 iso[con]->
m_y[id2],iso[con]->
m_z[id2]))
778 if((vidmap[i][id1] == -1) &&
779 (vidmap[con][id2] != -1))
781 vidmap[i][id1] = vidmap[con][id2];
783 else if((vidmap[con][id2] == -1) &&
784 (vidmap[i][id1] != -1))
786 vidmap[con][id2] = vidmap[i][id1];
788 else if((vidmap[con][id2] == -1) &&
789 (vidmap[i][id1] == -1))
791 vidmap[i][id1] = vidmap[con][id2] = nvert++;
799 for(id1 = 0; id1 < iso[i]->m_nvert;++id1)
801 if(vidmap[i][id1] == -1)
803 vidmap[i][id1] = nvert++;
812 for(n = 0; n < niso; ++n)
814 for(i = 0; i < iso[n]->m_ntris; ++i,nelmt++)
818 m_vid[3*nelmt+j] = vidmap[n][iso[n]->m_vid[3*i+j]];
830 for(i = 0; i < iso[0]->m_fields.size(); ++i)
837 for(n = 0; n < niso; ++n)
839 for(i = 0; i < iso[n]->m_nvert; ++i)
841 m_x[vidmap[n][i]] = iso[n]->m_x[i];
842 m_y[vidmap[n][i]] = iso[n]->m_y[i];
843 m_z[vidmap[n][i]] = iso[n]->m_z[i];
845 for(j = 0; j <
m_fields.size(); ++j)
847 m_fields[j][vidmap[n][i]] = iso[n]->m_fields[j][i];
858 Array<OneD, NekDouble> xtemp, ytemp, ztemp;
859 vector< vector<int> > adj,vertcon;
867 for(j = 0; j < 3; ++j)
869 vertcon[
m_vid[3*i+j]].push_back(i);
878 for(ipt = vertcon[i].begin(); ipt != vertcon[i].end(); ++ipt)
880 for(j = 0; j < 3; ++j)
883 if(
m_vid[3*(*ipt)+j] != i)
886 for(iad = adj[i].begin(); iad != adj[i].end();++iad)
888 if(*iad == (
m_vid[3*(*ipt)+j]))
break;
891 if(iad == adj[i].end())
893 adj[i].push_back(
m_vid[3*(*ipt)+j]);
900 xtemp = Array<OneD, NekDouble>(
m_nvert);
901 ytemp = Array<OneD, NekDouble>(
m_nvert);
902 ztemp = Array<OneD, NekDouble>(
m_nvert);
905 for (iter=0;iter<n_iter;iter++)
912 del_v[0] = del_v[1] = del_v[2] = 0.0;
914 for(iad = adj[i].begin(); iad != adj[i].end(); ++iad)
916 del_v[0] = del_v[0] + (
m_x[*iad]-
m_x[i])*w;
917 del_v[1] = del_v[1] + (
m_y[*iad]-
m_y[i])*w;
918 del_v[2] = del_v[2] + (
m_z[*iad]-
m_z[i])*w;
921 xtemp[i] =
m_x[i] + del_v[0] * lambda;
922 ytemp[i] =
m_y[i] + del_v[1] * lambda;
923 ztemp[i] =
m_z[i] + del_v[2] * lambda;
931 del_v[0] = del_v[1] = del_v[2] = 0;
933 for(iad = adj[i].begin(); iad != adj[i].end(); ++iad)
935 del_v[0] = del_v[0] + (
m_x[*iad]-
m_x[i])*w;
936 del_v[1] = del_v[1] + (
m_y[*iad]-
m_y[i])*w;
937 del_v[2] = del_v[2] + (
m_z[*iad]-
m_z[i])*w;
940 m_x[i] = xtemp[i] + del_v[0] * mu;
941 m_y[i] = ytemp[i] + del_v[1] * mu;
942 m_z[i] = ztemp[i] + del_v[2] * mu;