PageRenderTime 98ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/contrib/Netgen/libsrc/meshing/bisect.cpp

https://bitbucket.org/lge/gmsh
C++ | 4071 lines | 2648 code | 642 blank | 781 comment | 574 complexity | 39f68cbc0bf590cd14518d2f28aafb5b MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause
  1. #include <mystdlib.h>
  2. #include "meshing.hpp"
  3. #define noDEBUG
  4. namespace netgen
  5. {
  6. //#include "../interface/writeuser.hpp"
  7. class MarkedTet;
  8. class MarkedPrism;
  9. class MarkedIdentification;
  10. class MarkedTri;
  11. class MarkedQuad;
  12. typedef MoveableArray<MarkedTet> T_MTETS;
  13. typedef MoveableArray<MarkedPrism> T_MPRISMS;
  14. typedef MoveableArray<MarkedIdentification> T_MIDS;
  15. typedef MoveableArray<MarkedTri> T_MTRIS;
  16. typedef MoveableArray<MarkedQuad> T_MQUADS;
  17. class MarkedTet
  18. {
  19. public:
  20. /// pnums of tet
  21. PointIndex pnums[4];
  22. /// material number
  23. int matindex;
  24. /// element marked for refinement
  25. /// marked = 1: marked by element marker, marked = 2 due to closure
  26. unsigned int marked:2;
  27. /// flag of Arnold-Mukherjee algorithm
  28. unsigned int flagged:1;
  29. /// tetedge (local coordinates 0..3)
  30. unsigned int tetedge1:3;
  31. unsigned int tetedge2:3;
  32. // marked edge of faces
  33. // face_j : face without node j,
  34. // mark_k : edge without node k
  35. char faceedges[4];
  36. // unsigned char faceedges[4];
  37. bool incorder;
  38. unsigned int order:6;
  39. MarkedTet()
  40. {
  41. for (int i = 0; i < 4; i++) { faceedges[i] = 255; }
  42. }
  43. };
  44. ostream & operator<< (ostream & ost, const MarkedTet & mt)
  45. {
  46. for(int i=0; i<4; i++)
  47. ost << mt.pnums[i] << " ";
  48. ost << mt.matindex << " " << int(mt.marked) << " " << int(mt.flagged) << " " << int(mt.tetedge1) << " " << int(mt.tetedge2) << " ";
  49. ost << "faceedges = ";
  50. for(int i=0; i<4; i++)
  51. ost << int(mt.faceedges[i]) << " ";
  52. ost << " order = ";
  53. ost << mt.incorder << " " << int(mt.order) << "\n";
  54. return ost;
  55. }
  56. istream & operator>> (istream & ost, MarkedTet & mt)
  57. {
  58. for(int i=0; i<4; i++)
  59. ost >> mt.pnums[i];
  60. ost >> mt.matindex;
  61. int auxint;
  62. ost >> auxint;
  63. mt.marked = auxint;
  64. ost >> auxint;
  65. mt.flagged = auxint;
  66. ost >> auxint;
  67. mt.tetedge1 = auxint;
  68. ost >> auxint;
  69. mt.tetedge2 = auxint;
  70. char auxchar;
  71. for(int i=0; i<4; i++)
  72. {
  73. ost >> auxchar;
  74. mt.faceedges[i] = auxchar;
  75. }
  76. ost >> mt.incorder;
  77. ost >> auxint;
  78. mt.order = auxint;
  79. return ost;
  80. }
  81. class MarkedPrism
  82. {
  83. public:
  84. /// 6 point numbers
  85. PointIndex pnums[6];
  86. /// material number
  87. int matindex;
  88. /// marked for refinement
  89. int marked;
  90. /// edge without node k (0,1,2)
  91. int markededge;
  92. bool incorder;
  93. unsigned int order:6;
  94. };
  95. ostream & operator<< (ostream & ost, const MarkedPrism & mp)
  96. {
  97. for(int i=0; i<6; i++)
  98. ost << mp.pnums[i] << " ";
  99. ost << mp.matindex << " " << mp.marked << " " << mp.markededge << " " << mp.incorder << " " << int(mp.order) << "\n";
  100. return ost;
  101. }
  102. istream & operator>> (istream & ist, MarkedPrism & mp)
  103. {
  104. for(int i=0; i<6; i++)
  105. ist >> mp.pnums[i];
  106. ist >> mp.matindex >> mp.marked >> mp.markededge >> mp.incorder;
  107. int auxint;
  108. ist >> auxint;
  109. mp.order = auxint;
  110. return ist;
  111. }
  112. class MarkedIdentification
  113. {
  114. public:
  115. // number of points of one face (3 or 4)
  116. int np;
  117. /// 6 or 8 point numbers
  118. PointIndex pnums[8];
  119. /// marked for refinement
  120. int marked;
  121. /// edge starting with node k (0,1,2, or 3)
  122. int markededge;
  123. bool incorder;
  124. unsigned int order:6;
  125. };
  126. ostream & operator<< (ostream & ost, const MarkedIdentification & mi)
  127. {
  128. ost << mi.np << " ";
  129. for(int i=0; i<2*mi.np; i++)
  130. ost << mi.pnums[i] << " ";
  131. ost << mi.marked << " " << mi.markededge << " " << mi.incorder << " " << int(mi.order) << "\n";
  132. return ost;
  133. }
  134. istream & operator>> (istream & ist, MarkedIdentification & mi)
  135. {
  136. ist >> mi.np;
  137. for(int i=0; i<2*mi.np; i++)
  138. ist >> mi.pnums[i];
  139. ist >> mi.marked >> mi.markededge >> mi.incorder;
  140. int auxint;
  141. ist >> auxint;
  142. mi.order = auxint;
  143. return ist;
  144. }
  145. class MarkedTri
  146. {
  147. public:
  148. /// three point numbers
  149. PointIndex pnums[3];
  150. /// three geominfos
  151. PointGeomInfo pgeominfo[3];
  152. /// marked for refinement
  153. int marked;
  154. /// edge without node k
  155. int markededge;
  156. /// surface id
  157. int surfid;
  158. bool incorder;
  159. unsigned int order:6;
  160. };
  161. ostream & operator<< (ostream & ost, const MarkedTri & mt)
  162. {
  163. for(int i=0; i<3; i++)
  164. ost << mt.pnums[i] << " ";
  165. for(int i=0; i<3; i++)
  166. ost << mt.pgeominfo[i] << " ";
  167. ost << mt.marked << " " << mt.markededge << " " << mt.surfid << " " << mt.incorder << " " << int(mt.order) << "\n";
  168. return ost;
  169. }
  170. istream & operator>> (istream & ist, MarkedTri & mt)
  171. {
  172. for(int i=0; i<3; i++)
  173. ist >> mt.pnums[i];
  174. for(int i=0; i<3; i++)
  175. ist >> mt.pgeominfo[i];
  176. ist >> mt.marked >> mt.markededge >> mt.surfid >> mt.incorder;
  177. int auxint;
  178. ist >> auxint;
  179. mt.order = auxint;
  180. return ist;
  181. }
  182. class MarkedQuad
  183. {
  184. public:
  185. /// point numbers
  186. PointIndex pnums[4];
  187. ///
  188. PointGeomInfo pgeominfo[4];
  189. /// marked for refinement
  190. int marked;
  191. /// marked edge: 0/2 = vertical, 1/3 = horizontal
  192. int markededge;
  193. /// surface id
  194. int surfid;
  195. bool incorder;
  196. unsigned int order:6;
  197. };
  198. ostream & operator<< (ostream & ost, const MarkedQuad & mt)
  199. {
  200. for(int i=0; i<4; i++)
  201. ost << mt.pnums[i] << " ";
  202. for(int i=0; i<4; i++)
  203. ost << mt.pgeominfo[i] << " ";
  204. ost << mt.marked << " " << mt.markededge << " " << mt.surfid << " " << mt.incorder << " " << int(mt.order) << "\n";
  205. return ost;
  206. }
  207. istream & operator>> (istream & ist, MarkedQuad & mt)
  208. {
  209. for(int i=0; i<4; i++)
  210. ist >> mt.pnums[i];
  211. for(int i=0; i<4; i++)
  212. ist >> mt.pgeominfo[i];
  213. ist >> mt.marked >> mt.markededge >> mt.surfid >> mt.incorder;
  214. int auxint;
  215. ist >> auxint;
  216. mt.order = auxint;
  217. return ist;
  218. }
  219. void PrettyPrint(ostream & ost, const MarkedTet & mt)
  220. {
  221. int te1 = mt.tetedge1;
  222. int te2 = mt.tetedge2;
  223. int order = mt.order;
  224. ost << "MT: " << mt.pnums[0] << " - " << mt.pnums[1] << " - "
  225. << mt.pnums[2] << " - " << mt.pnums[3] << endl
  226. << "marked edge: " << te1 << " - " << te2
  227. << ", order = " << order << endl;
  228. //for (int k = 0; k < 4; k++)
  229. // ost << int(mt.faceedges[k]) << " ";
  230. for (int k = 0; k < 4; k++)
  231. {
  232. ost << "face";
  233. for (int j=0; j<4; j++)
  234. if(j != k)
  235. ost << " " << mt.pnums[j];
  236. for(int i=0; i<3; i++)
  237. for(int j=i+1; j<4; j++)
  238. if(i != k && j != k && int(mt.faceedges[k]) == 6-k-i-j)
  239. ost << " marked edge " << mt.pnums[i] << " " << mt.pnums[j] << endl;
  240. }
  241. ost << endl;
  242. }
  243. int BTSortEdges (const Mesh & mesh,
  244. const Array< Array<int,PointIndex::BASE>* > & idmaps,
  245. INDEX_2_CLOSED_HASHTABLE<int> & edgenumber)
  246. {
  247. PrintMessage(4,"sorting ... ");
  248. // if (mesh.PureTetMesh())
  249. if (1)
  250. {
  251. // new, fast version
  252. Array<INDEX_2> edges;
  253. Array<int> eclasses;
  254. int i, j, k;
  255. int cntedges = 0;
  256. int go_on;
  257. int ned(0);
  258. // enumerate edges:
  259. for (i = 1; i <= mesh.GetNE(); i++)
  260. {
  261. const Element & el = mesh.VolumeElement (i);
  262. static int tetedges[6][2] =
  263. { { 1, 2 },
  264. { 1, 3 },
  265. { 1, 4 },
  266. { 2, 3 },
  267. { 2, 4 },
  268. { 3, 4 } } ;
  269. static int prismedges[9][2] =
  270. { { 1, 2 },
  271. { 1, 3 },
  272. { 2, 3 },
  273. { 4, 5 },
  274. { 4, 6 },
  275. { 5, 6 },
  276. { 1, 4 },
  277. { 2, 5 },
  278. { 3, 6 } };
  279. int pyramidedges[6][2] =
  280. { { 1, 2 },
  281. { 3, 4 },
  282. { 1, 5 },
  283. { 2, 5 },
  284. { 3, 5 },
  285. { 4, 5 } };
  286. int (*tip)[2] = NULL;
  287. switch (el.GetType())
  288. {
  289. case TET:
  290. case TET10:
  291. {
  292. tip = tetedges;
  293. ned = 6;
  294. break;
  295. }
  296. case PRISM:
  297. case PRISM12:
  298. {
  299. tip = prismedges;
  300. ned = 6;
  301. break;
  302. }
  303. case PYRAMID:
  304. {
  305. tip = pyramidedges;
  306. ned = 6;
  307. break;
  308. }
  309. default:
  310. throw NgException("Bisect, element type not handled in switch");
  311. }
  312. for (j = 0; j < ned; j++)
  313. {
  314. INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1]));
  315. i2.Sort();
  316. //(*testout) << "edge " << i2 << endl;
  317. if (!edgenumber.Used(i2))
  318. {
  319. cntedges++;
  320. edges.Append (i2);
  321. edgenumber.Set(i2, cntedges);
  322. }
  323. }
  324. }
  325. // additional surface edges:
  326. for (i = 1; i <= mesh.GetNSE(); i++)
  327. {
  328. const Element2d & el = mesh.SurfaceElement (i);
  329. static int trigedges[3][2] =
  330. { { 1, 2 },
  331. { 2, 3 },
  332. { 3, 1 } };
  333. static int quadedges[4][2] =
  334. { { 1, 2 },
  335. { 2, 3 },
  336. { 3, 4 },
  337. { 4, 1 } };
  338. int (*tip)[2] = NULL;
  339. switch (el.GetType())
  340. {
  341. case TRIG:
  342. case TRIG6:
  343. {
  344. tip = trigedges;
  345. ned = 3;
  346. break;
  347. }
  348. case QUAD:
  349. case QUAD6:
  350. {
  351. tip = quadedges;
  352. ned = 4;
  353. break;
  354. }
  355. default:
  356. {
  357. cerr << "Error: Sort for Bisect, SE has " << el.GetNP() << " points" << endl;
  358. ned = 0;
  359. }
  360. }
  361. for (j = 0; j < ned; j++)
  362. {
  363. INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1]));
  364. i2.Sort();
  365. if (!edgenumber.Used(i2))
  366. {
  367. cntedges++;
  368. edges.Append (i2);
  369. edgenumber.Set(i2, cntedges);
  370. }
  371. }
  372. }
  373. eclasses.SetSize (cntedges);
  374. for (i = 1; i <= cntedges; i++)
  375. eclasses.Elem(i) = i;
  376. // identify edges in element stack
  377. do
  378. {
  379. go_on = 0;
  380. for (i = 1; i <= mesh.GetNE(); i++)
  381. {
  382. const Element & el = mesh.VolumeElement (i);
  383. if (el.GetType() != PRISM &&
  384. el.GetType() != PRISM12 &&
  385. el.GetType() != PYRAMID)
  386. continue;
  387. int prismpairs[3][4] =
  388. { { 1, 2, 4, 5 },
  389. { 2, 3, 5, 6 },
  390. { 1, 3, 4, 6 } };
  391. int pyramidpairs[3][4] =
  392. { { 1, 2, 4, 3 },
  393. { 1, 5, 4, 5 },
  394. { 2, 5, 3, 5 } };
  395. int (*pairs)[4] = NULL;
  396. switch (el.GetType())
  397. {
  398. case PRISM:
  399. case PRISM12:
  400. {
  401. pairs = prismpairs;
  402. break;
  403. }
  404. case PYRAMID:
  405. {
  406. pairs = pyramidpairs;
  407. break;
  408. }
  409. default:
  410. throw NgException("Bisect, element type not handled in switch, 2");
  411. }
  412. for (j = 0; j < 3; j++)
  413. {
  414. INDEX_2 e1 (el.PNum(pairs[j][0]),
  415. el.PNum(pairs[j][1]));
  416. INDEX_2 e2 (el.PNum(pairs[j][2]),
  417. el.PNum(pairs[j][3]));
  418. e1.Sort();
  419. e2.Sort();
  420. int eclass1 = edgenumber.Get (e1);
  421. int eclass2 = edgenumber.Get (e2);
  422. // (*testout) << "identify edges " << eclass1 << "-" << eclass2 << endl;
  423. if (eclasses.Get(eclass1) >
  424. eclasses.Get(eclass2))
  425. {
  426. eclasses.Elem(eclass1) =
  427. eclasses.Get(eclass2);
  428. go_on = 1;
  429. }
  430. else if (eclasses.Get(eclass2) >
  431. eclasses.Get(eclass1))
  432. {
  433. eclasses.Elem(eclass2) =
  434. eclasses.Get(eclass1);
  435. go_on = 1;
  436. }
  437. }
  438. }
  439. for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)
  440. {
  441. const Element2d & el2d = mesh[sei];
  442. for(i = 0; i < el2d.GetNP(); i++)
  443. {
  444. INDEX_2 e1(el2d[i], el2d[(i+1) % el2d.GetNP()]);
  445. e1.Sort();
  446. INDEX_2 e2;
  447. for(k = 0; k < idmaps.Size(); k++)
  448. {
  449. e2.I1() = (*idmaps[k])[e1.I1()];
  450. e2.I2() = (*idmaps[k])[e1.I2()];
  451. if(e2.I1() == 0 || e2.I2() == 0 ||
  452. e1.I1() == e2.I1() || e1.I2() == e2.I2())
  453. continue;
  454. e2.Sort();
  455. if(!edgenumber.Used(e2))
  456. continue;
  457. int eclass1 = edgenumber.Get (e1);
  458. int eclass2 = edgenumber.Get (e2);
  459. if (eclasses.Get(eclass1) >
  460. eclasses.Get(eclass2))
  461. {
  462. eclasses.Elem(eclass1) =
  463. eclasses.Get(eclass2);
  464. go_on = 1;
  465. }
  466. else if (eclasses.Get(eclass2) >
  467. eclasses.Get(eclass1))
  468. {
  469. eclasses.Elem(eclass2) =
  470. eclasses.Get(eclass1);
  471. go_on = 1;
  472. }
  473. }
  474. }
  475. }
  476. }
  477. while (go_on);
  478. // for (i = 1; i <= cntedges; i++)
  479. // {
  480. // (*testout) << "edge " << i << ": "
  481. // << edges.Get(i).I1() << "-" << edges.Get(i).I2()
  482. // << ", class = " << eclasses.Get(i) << endl;
  483. // }
  484. // compute classlength:
  485. Array<double> edgelength(cntedges);
  486. /*
  487. for (i = 1; i <= cntedges; i++)
  488. edgelength.Elem(i) = 1e20;
  489. */
  490. for (i = 1; i <= cntedges; i++)
  491. {
  492. INDEX_2 edge = edges.Get(i);
  493. double elen = Dist (mesh.Point(edge.I1()),
  494. mesh.Point(edge.I2()));
  495. edgelength.Elem (i) = elen;
  496. }
  497. /*
  498. for (i = 1; i <= mesh.GetNE(); i++)
  499. {
  500. const Element & el = mesh.VolumeElement (i);
  501. if (el.GetType() == TET)
  502. {
  503. for (j = 1; j <= 3; j++)
  504. for (k = j+1; k <= 4; k++)
  505. {
  506. INDEX_2 i2(el.PNum(j), el.PNum(k));
  507. i2.Sort();
  508. int enr = edgenumber.Get(i2);
  509. double elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));
  510. if (elen < edgelength.Get(enr))
  511. edgelength.Set (enr, elen);
  512. }
  513. }
  514. else if (el.GetType() == PRISM)
  515. {
  516. for (j = 1; j <= 3; j++)
  517. {
  518. k = (j % 3) + 1;
  519. INDEX_2 i2(el.PNum(j), el.PNum(k));
  520. i2.Sort();
  521. int enr = edgenumber.Get(i2);
  522. double elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));
  523. if (elen < edgelength.Get(enr))
  524. edgelength.Set (enr, elen);
  525. i2 = INDEX_2(el.PNum(j+3), el.PNum(k+3));
  526. i2.Sort();
  527. enr = edgenumber.Get(i2);
  528. elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));
  529. if (elen < edgelength.Get(enr))
  530. edgelength.Set (enr, elen);
  531. if (!edgenumber.Used(i2))
  532. {
  533. cntedges++;
  534. edgenumber.Set(i2, cntedges);
  535. }
  536. i2 = INDEX_2(el.PNum(j), el.PNum(j+3));
  537. i2.Sort();
  538. enr = edgenumber.Get(i2);
  539. elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));
  540. if (elen < edgelength.Get(enr))
  541. edgelength.Set (enr, elen);
  542. }
  543. }
  544. }
  545. */
  546. for (i = 1; i <= cntedges; i++)
  547. {
  548. if (eclasses.Get(i) != i)
  549. {
  550. if (edgelength.Get(i) < edgelength.Get(eclasses.Get(i)))
  551. edgelength.Elem(eclasses.Get(i)) = edgelength.Get(i);
  552. edgelength.Elem(i) = 1e20;
  553. }
  554. }
  555. TABLE<int> eclasstab(cntedges);
  556. for (i = 1; i <= cntedges; i++)
  557. eclasstab.Add1 (eclasses.Get(i), i);
  558. // sort edges:
  559. Array<int> sorted(cntedges);
  560. QuickSort (edgelength, sorted);
  561. int cnt = 0;
  562. for (i = 1; i <= cntedges; i++)
  563. {
  564. int ii = sorted.Get(i);
  565. for (j = 1; j <= eclasstab.EntrySize(ii); j++)
  566. {
  567. cnt++;
  568. edgenumber.Set (edges.Get(eclasstab.Get(ii, j)), cnt);
  569. }
  570. }
  571. return cnt;
  572. }
  573. else
  574. {
  575. // old version
  576. int i, j;
  577. int cnt = 0;
  578. int found;
  579. double len2, maxlen2;
  580. INDEX_2 ep;
  581. // sort edges by length, parallel edges (on prisms)
  582. // are added in blocks
  583. do
  584. {
  585. found = 0;
  586. maxlen2 = 1e30;
  587. for (i = 1; i <= mesh.GetNE(); i++)
  588. {
  589. const Element & el = mesh.VolumeElement (i);
  590. int ned;
  591. int tetedges[6][2] =
  592. { { 1, 2 },
  593. { 1, 3 },
  594. { 1, 4 },
  595. { 2, 3 },
  596. { 2, 4 },
  597. { 3, 4 } };
  598. int prismedges[6][2] =
  599. { { 1, 2 },
  600. { 1, 3 },
  601. { 2, 4 },
  602. { 4, 5 },
  603. { 4, 6 },
  604. { 5, 6 } };
  605. int pyramidedges[6][2] =
  606. { { 1, 2 },
  607. { 3, 4 },
  608. { 1, 5 },
  609. { 2, 5 },
  610. { 3, 5 },
  611. { 4, 5 } };
  612. int (*tip)[2];
  613. switch (el.GetType())
  614. {
  615. case TET:
  616. {
  617. tip = tetedges;
  618. ned = 6;
  619. break;
  620. }
  621. case PRISM:
  622. {
  623. tip = prismedges;
  624. ned = 6;
  625. break;
  626. }
  627. case PYRAMID:
  628. {
  629. tip = pyramidedges;
  630. ned = 6;
  631. break;
  632. }
  633. default:
  634. throw NgException("Bisect, element type not handled in switch, 3");
  635. }
  636. for (j = 0; j < ned; j++)
  637. {
  638. INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1]));
  639. i2.Sort();
  640. if (!edgenumber.Used(i2))
  641. {
  642. len2 = Dist (mesh.Point (i2.I1()),
  643. mesh.Point (i2.I2()));
  644. if (len2 < maxlen2)
  645. {
  646. maxlen2 = len2;
  647. ep = i2;
  648. found = 1;
  649. }
  650. }
  651. }
  652. }
  653. if (found)
  654. {
  655. cnt++;
  656. edgenumber.Set (ep, cnt);
  657. // find connected edges:
  658. int go_on = 0;
  659. do
  660. {
  661. go_on = 0;
  662. for (i = 1; i <= mesh.GetNE(); i++)
  663. {
  664. const Element & el = mesh.VolumeElement (i);
  665. if (el.GetNP() != 6) continue;
  666. int prismpairs[3][4] =
  667. { { 1, 2, 4, 5 },
  668. { 2, 3, 5, 6 },
  669. { 1, 3, 4, 6 } };
  670. int pyramidpairs[3][4] =
  671. { { 1, 2, 4, 3 },
  672. { 1, 5, 4, 5 },
  673. { 2, 5, 3, 5 } };
  674. int (*pairs)[4];
  675. switch (el.GetType())
  676. {
  677. case PRISM:
  678. {
  679. pairs = prismpairs;
  680. break;
  681. }
  682. case PYRAMID:
  683. {
  684. pairs = pyramidpairs;
  685. break;
  686. }
  687. default:
  688. throw NgException("Bisect, element type not handled in switch, 3a");
  689. }
  690. for (j = 0; j < 3; j++)
  691. {
  692. INDEX_2 e1 (el.PNum(pairs[j][0]),
  693. el.PNum(pairs[j][1]));
  694. INDEX_2 e2 (el.PNum(pairs[j][2]),
  695. el.PNum(pairs[j][3]));
  696. e1.Sort();
  697. e2.Sort();
  698. int used1 = edgenumber.Used (e1);
  699. int used2 = edgenumber.Used (e2);
  700. if (used1 && !used2)
  701. {
  702. cnt++;
  703. edgenumber.Set (e2, cnt);
  704. go_on = 1;
  705. }
  706. if (used2 && !used1)
  707. {
  708. cnt++;
  709. edgenumber.Set (e1, cnt);
  710. go_on = 1;
  711. }
  712. }
  713. }
  714. }
  715. while (go_on);
  716. }
  717. }
  718. while (found);
  719. return cnt;
  720. }
  721. }
  722. void BTDefineMarkedTet (const Element & el,
  723. INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,
  724. MarkedTet & mt)
  725. {
  726. int i, j, k;
  727. for (i = 0; i < 4; i++)
  728. mt.pnums[i] = el[i];
  729. mt.marked = 0;
  730. mt.flagged = 0;
  731. mt.incorder = 0;
  732. mt.order = 1;
  733. int val = 0;
  734. // find marked edge of tet:
  735. for (i = 0; i < 3; i++)
  736. for (j = i+1; j < 4; j++)
  737. {
  738. INDEX_2 i2(mt.pnums[i], mt.pnums[j]);
  739. i2.Sort();
  740. int hval = edgenumber.Get(i2);
  741. if (hval > val)
  742. {
  743. val = hval;
  744. mt.tetedge1 = i;
  745. mt.tetedge2 = j;
  746. }
  747. }
  748. // find marked edges of faces:
  749. for (k = 0; k < 4; k++)
  750. {
  751. val = 0;
  752. for (i = 0; i < 3; i++)
  753. for (j = i+1; j < 4; j++)
  754. if (i != k && j != k)
  755. {
  756. INDEX_2 i2(mt.pnums[i], mt.pnums[j]);
  757. i2.Sort();
  758. int hval = edgenumber.Get(i2);
  759. if (hval > val)
  760. {
  761. val = hval;
  762. int hi = 6 - k - i - j;
  763. mt.faceedges[k] = char(hi);
  764. }
  765. }
  766. }
  767. }
  768. void BTDefineMarkedPrism (const Element & el,
  769. INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,
  770. MarkedPrism & mp)
  771. {
  772. int i, j;
  773. if (el.GetType() == PRISM ||
  774. el.GetType() == PRISM12)
  775. {
  776. for (i = 0; i < 6; i++)
  777. mp.pnums[i] = el[i];
  778. }
  779. else if (el.GetType() == PYRAMID)
  780. {
  781. static int map[6] =
  782. { 1, 2, 5, 4, 3, 5 };
  783. for (i = 0; i < 6; i++)
  784. mp.pnums[i] = el.PNum(map[i]);
  785. }
  786. else if (el.GetType() == TET ||
  787. el.GetType() == TET10)
  788. {
  789. static int map[6] =
  790. { 1, 4, 3, 2, 4, 3 };
  791. for (i = 0; i < 6; i++)
  792. mp.pnums[i] = el.PNum(map[i]);
  793. }
  794. else
  795. {
  796. PrintSysError ("Define marked prism called for non-prism and non-pyramid");
  797. }
  798. mp.marked = 0;
  799. mp.incorder = 0;
  800. mp.order = 1;
  801. int val = 0;
  802. for (i = 0; i < 2; i++)
  803. for (j = i+1; j < 3; j++)
  804. {
  805. INDEX_2 i2(mp.pnums[i], mp.pnums[j]);
  806. i2.Sort();
  807. int hval = edgenumber.Get(i2);
  808. if (hval > val)
  809. {
  810. val = hval;
  811. mp.markededge = 3 - i - j;
  812. }
  813. }
  814. }
  815. bool BTDefineMarkedId(const Element2d & el,
  816. INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,
  817. const Array<int,PointIndex::BASE> & idmap,
  818. MarkedIdentification & mi)
  819. {
  820. bool identified = true;
  821. mi.np = el.GetNP();
  822. int min1(0),min2(0);
  823. for(int j = 0; identified && j < mi.np; j++)
  824. {
  825. mi.pnums[j] = el[j];
  826. mi.pnums[j+mi.np] = idmap[el[j]];
  827. if(j == 0 || el[j] < min1)
  828. min1 = el[j];
  829. if(j == 0 || mi.pnums[j+mi.np] < min2)
  830. min2 = mi.pnums[j+mi.np];
  831. identified = (mi.pnums[j+mi.np] != 0 && mi.pnums[j+mi.np] != mi.pnums[j]);
  832. }
  833. identified = identified && (min1 < min2);
  834. if(identified)
  835. {
  836. mi.marked = 0;
  837. mi.incorder = 0;
  838. mi.order = 1;
  839. int val = 0;
  840. for (int i = 0; i < mi.np; i++)
  841. {
  842. INDEX_2 i2(mi.pnums[i], mi.pnums[(i+1)%mi.np]);
  843. i2.Sort();
  844. int hval = edgenumber.Get(i2);
  845. if (hval > val)
  846. {
  847. val = hval;
  848. mi.markededge = i;
  849. }
  850. }
  851. }
  852. return identified;
  853. }
  854. void BTDefineMarkedTri (const Element2d & el,
  855. INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,
  856. MarkedTri & mt)
  857. {
  858. int i, j;
  859. for (i = 0; i < 3; i++)
  860. {
  861. mt.pnums[i] = el[i];
  862. mt.pgeominfo[i] = el.GeomInfoPi (i+1);
  863. }
  864. mt.marked = 0;
  865. mt.surfid = el.GetIndex();
  866. mt.incorder = 0;
  867. mt.order = 1;
  868. int val = 0;
  869. for (i = 0; i < 2; i++)
  870. for (j = i+1; j < 3; j++)
  871. {
  872. INDEX_2 i2(mt.pnums[i], mt.pnums[j]);
  873. i2.Sort();
  874. int hval = edgenumber.Get(i2);
  875. if (hval > val)
  876. {
  877. val = hval;
  878. mt.markededge = 3 - i - j;
  879. }
  880. }
  881. }
  882. void PrettyPrint(ostream & ost, const MarkedTri & mt)
  883. {
  884. ost << "MarkedTrig: " << endl;
  885. ost << " pnums = "; for (int i=0; i<3; i++) ost << mt.pnums[i] << " "; ost << endl;
  886. ost << " marked = " << mt.marked << ", markededge=" << mt.markededge << endl;
  887. for(int i=0; i<2; i++)
  888. for(int j=i+1; j<3; j++)
  889. if(mt.markededge == 3-i-j)
  890. ost << " marked edge pnums = " << mt.pnums[i] << " " << mt.pnums[j] << endl;
  891. }
  892. void PrettyPrint(ostream & ost, const MarkedQuad & mq)
  893. {
  894. ost << "MarkedQuad: " << endl;
  895. ost << " pnums = "; for (int i=0; i<4; i++) ost << mq.pnums[i] << " "; ost << endl;
  896. ost << " marked = " << mq.marked << ", markededge=" << mq.markededge << endl;
  897. }
  898. void BTDefineMarkedQuad (const Element2d & el,
  899. INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,
  900. MarkedQuad & mq)
  901. {
  902. int i;
  903. for (i = 0; i < 4; i++)
  904. mq.pnums[i] = el[i];
  905. Swap (mq.pnums[2], mq.pnums[3]);
  906. mq.marked = 0;
  907. mq.markededge = 0;
  908. mq.surfid = el.GetIndex();
  909. }
  910. // mark elements due to local h
  911. int BTMarkTets (T_MTETS & mtets,
  912. T_MPRISMS & mprisms,
  913. const Mesh & mesh)
  914. {
  915. int marked = 0;
  916. int np = mesh.GetNP();
  917. Vector hv(np);
  918. for (int i = 0; i < np; i++)
  919. hv(i) = mesh.GetH (mesh.Point(i+1));
  920. double hfac = 1;
  921. for (int step = 1; step <= 2; step++)
  922. {
  923. for (int i = 1; i <= mtets.Size(); i++)
  924. {
  925. double h = 0;
  926. for (int j = 0; j < 3; j++)
  927. for (int k = j+1; k < 4; k++)
  928. {
  929. const Point<3> & p1 = mesh.Point (mtets.Get(i).pnums[j]);
  930. const Point<3> & p2 = mesh.Point (mtets.Get(i).pnums[k]);
  931. double hh = Dist2 (p1, p2);
  932. if (hh > h) h = hh;
  933. }
  934. h = sqrt (h);
  935. double hshould = 1e10;
  936. for (int j = 0; j < 4; j++)
  937. {
  938. double hi = hv (mtets.Get(i).pnums[j]-1);
  939. if (hi < hshould)
  940. hshould = hi;
  941. }
  942. if (step == 1)
  943. {
  944. if (h / hshould > hfac)
  945. hfac = h / hshould;
  946. }
  947. else
  948. {
  949. if (h > hshould * hfac)
  950. {
  951. mtets.Elem(i).marked = 1;
  952. marked = 1;
  953. }
  954. else
  955. mtets.Elem(i).marked = 0;
  956. }
  957. }
  958. for (int i = 1; i <= mprisms.Size(); i++)
  959. {
  960. double h = 0;
  961. for (int j = 0; j < 2; j++)
  962. for (int k = j+1; k < 3; k++)
  963. {
  964. const Point<3> & p1 = mesh.Point (mprisms.Get(i).pnums[j]);
  965. const Point<3> & p2 = mesh.Point (mprisms.Get(i).pnums[k]);
  966. double hh = Dist2 (p1, p2);
  967. if (hh > h) h = hh;
  968. }
  969. h = sqrt (h);
  970. double hshould = 1e10;
  971. for (int j = 0; j < 6; j++)
  972. {
  973. double hi = hv (mprisms.Get(i).pnums[j]-1);
  974. if (hi < hshould)
  975. hshould = hi;
  976. }
  977. if (step == 1)
  978. {
  979. if (h / hshould > hfac)
  980. hfac = h / hshould;
  981. }
  982. else
  983. {
  984. if (h > hshould * hfac)
  985. {
  986. mprisms.Elem(i).marked = 1;
  987. marked = 1;
  988. }
  989. else
  990. mprisms.Elem(i).marked = 0;
  991. }
  992. }
  993. if (step == 1)
  994. {
  995. if (hfac > 2)
  996. hfac /= 2;
  997. else
  998. hfac = 1;
  999. }
  1000. }
  1001. return marked;
  1002. }
  1003. void BTBisectTet (const MarkedTet & oldtet, int newp,
  1004. MarkedTet & newtet1, MarkedTet & newtet2)
  1005. {
  1006. #ifdef DEBUG
  1007. *testout << "bisect tet " << oldtet << endl;
  1008. #endif
  1009. int i, j, k;
  1010. // points vis a vis from tet-edge
  1011. int vis1, vis2;
  1012. vis1 = 0;
  1013. while (vis1 == oldtet.tetedge1 || vis1 == oldtet.tetedge2)
  1014. vis1++;
  1015. vis2 = 6 - vis1 - oldtet.tetedge1 - oldtet.tetedge2;
  1016. // is tet of type P ?
  1017. int istypep = 0;
  1018. for (i = 0; i < 4; i++)
  1019. {
  1020. int cnt = 0;
  1021. for (j = 0; j < 4; j++)
  1022. if (oldtet.faceedges[j] == i)
  1023. cnt++;
  1024. if (cnt == 3)
  1025. istypep = 1;
  1026. }
  1027. for (i = 0; i < 4; i++)
  1028. {
  1029. newtet1.pnums[i] = oldtet.pnums[i];
  1030. newtet2.pnums[i] = oldtet.pnums[i];
  1031. }
  1032. newtet1.flagged = istypep && !oldtet.flagged;
  1033. newtet2.flagged = istypep && !oldtet.flagged;
  1034. int nm = oldtet.marked - 1;
  1035. if (nm < 0) nm = 0;
  1036. newtet1.marked = nm;
  1037. newtet2.marked = nm;
  1038. #ifdef DEBUG
  1039. *testout << "newtet1,before = " << newtet1 << endl;
  1040. *testout << "newtet2,before = " << newtet2 << endl;
  1041. #endif
  1042. for (i = 0; i < 4; i++)
  1043. {
  1044. if (i == oldtet.tetedge1)
  1045. {
  1046. newtet2.pnums[i] = newp;
  1047. newtet2.faceedges[i] = oldtet.faceedges[i]; // inherited face
  1048. newtet2.faceedges[vis1] = i; // cut faces
  1049. newtet2.faceedges[vis2] = i;
  1050. j = 0;
  1051. while (j == i || j == oldtet.faceedges[i])
  1052. j++;
  1053. k = 6 - i - oldtet.faceedges[i] - j;
  1054. newtet2.tetedge1 = j; // tet-edge
  1055. newtet2.tetedge2 = k;
  1056. // new face:
  1057. if (istypep && oldtet.flagged)
  1058. {
  1059. int hi = 6 - oldtet.tetedge1 - j - k;
  1060. newtet2.faceedges[oldtet.tetedge2] = char(hi);
  1061. }
  1062. else
  1063. newtet2.faceedges[oldtet.tetedge2] = oldtet.tetedge1;
  1064. #ifdef DEBUG
  1065. *testout << "i = " << i << ", j = " << j << " k = " << k
  1066. << " oldtet.tetedge1 = " << oldtet.tetedge1
  1067. << " oldtet.tetedge2 = " << oldtet.tetedge2
  1068. << " 6-oldtet.tetedge1-j-k = " << 6 - oldtet.tetedge1 - j - k
  1069. << " 6-oldtet.tetedge1-j-k = " << short(6 - oldtet.tetedge1 - j - k)
  1070. << endl;
  1071. *testout << "vis1 = " << vis1 << ", vis2 = " << vis2 << endl;
  1072. for (int j = 0; j < 4; j++)
  1073. if (newtet2.faceedges[j] > 3)
  1074. {
  1075. *testout << "ERROR1" << endl;
  1076. }
  1077. #endif
  1078. }
  1079. if (i == oldtet.tetedge2)
  1080. {
  1081. newtet1.pnums[i] = newp;
  1082. newtet1.faceedges[i] = oldtet.faceedges[i]; // inherited face
  1083. newtet1.faceedges[vis1] = i;
  1084. newtet1.faceedges[vis2] = i;
  1085. j = 0;
  1086. while (j == i || j == oldtet.faceedges[i])
  1087. j++;
  1088. k = 6 - i - oldtet.faceedges[i] - j;
  1089. newtet1.tetedge1 = j;
  1090. newtet1.tetedge2 = k;
  1091. // new face:
  1092. if (istypep && oldtet.flagged)
  1093. {
  1094. int hi = 6 - oldtet.tetedge2 - j - k;
  1095. newtet1.faceedges[oldtet.tetedge1] = char(hi);
  1096. }
  1097. else
  1098. newtet1.faceedges[oldtet.tetedge1] = oldtet.tetedge2;
  1099. #ifdef DEBUG
  1100. for (int j = 0; j < 4; j++)
  1101. if (newtet2.faceedges[j] > 3)
  1102. {
  1103. *testout << "ERROR2" << endl;
  1104. }
  1105. #endif
  1106. }
  1107. }
  1108. newtet1.matindex = oldtet.matindex;
  1109. newtet2.matindex = oldtet.matindex;
  1110. newtet1.incorder = 0;
  1111. newtet1.order = oldtet.order;
  1112. newtet2.incorder = 0;
  1113. newtet2.order = oldtet.order;
  1114. *testout << "newtet1 = " << newtet1 << endl;
  1115. *testout << "newtet2 = " << newtet2 << endl;
  1116. }
  1117. void BTBisectPrism (const MarkedPrism & oldprism, int newp1, int newp2,
  1118. MarkedPrism & newprism1, MarkedPrism & newprism2)
  1119. {
  1120. int i;
  1121. for (i = 0; i < 6; i++)
  1122. {
  1123. newprism1.pnums[i] = oldprism.pnums[i];
  1124. newprism2.pnums[i] = oldprism.pnums[i];
  1125. }
  1126. int pe1, pe2;
  1127. pe1 = 0;
  1128. if (pe1 == oldprism.markededge)
  1129. pe1++;
  1130. pe2 = 3 - oldprism.markededge - pe1;
  1131. newprism1.pnums[pe2] = newp1;
  1132. newprism1.pnums[pe2+3] = newp2;
  1133. newprism1.markededge = pe2;
  1134. newprism2.pnums[pe1] = newp1;
  1135. newprism2.pnums[pe1+3] = newp2;
  1136. newprism2.markededge = pe1;
  1137. newprism1.matindex = oldprism.matindex;
  1138. newprism2.matindex = oldprism.matindex;
  1139. int nm = oldprism.marked - 1;
  1140. if (nm < 0) nm = 0;
  1141. newprism1.marked = nm;
  1142. newprism2.marked = nm;
  1143. newprism1.incorder = 0;
  1144. newprism1.order = oldprism.order;
  1145. newprism2.incorder = 0;
  1146. newprism2.order = oldprism.order;
  1147. }
  1148. void BTBisectIdentification (const MarkedIdentification & oldid,
  1149. Array<int> & newp,
  1150. MarkedIdentification & newid1,
  1151. MarkedIdentification & newid2)
  1152. {
  1153. for(int i=0; i<2*oldid.np; i++)
  1154. {
  1155. newid1.pnums[i] = oldid.pnums[i];
  1156. newid2.pnums[i] = oldid.pnums[i];
  1157. }
  1158. newid1.np = newid2.np = oldid.np;
  1159. if(oldid.np == 3)
  1160. {
  1161. newid1.pnums[(oldid.markededge+1)%3] = newp[0];
  1162. newid1.pnums[(oldid.markededge+1)%3+3] = newp[1];
  1163. newid1.markededge = (oldid.markededge+2)%3;
  1164. newid2.pnums[oldid.markededge] = newp[0];
  1165. newid2.pnums[oldid.markededge+3] = newp[1];
  1166. newid2.markededge = (oldid.markededge+1)%3;
  1167. }
  1168. else if(oldid.np == 4)
  1169. {
  1170. newid1.pnums[(oldid.markededge+1)%4] = newp[0];
  1171. newid1.pnums[(oldid.markededge+2)%4] = newp[2];
  1172. newid1.pnums[(oldid.markededge+1)%4+4] = newp[1];
  1173. newid1.pnums[(oldid.markededge+2)%4+4] = newp[3];
  1174. newid1.markededge = (oldid.markededge+3)%4;
  1175. newid2.pnums[oldid.markededge] = newp[0];
  1176. newid2.pnums[(oldid.markededge+3)%4] = newp[2];
  1177. newid2.pnums[oldid.markededge+4] = newp[1];
  1178. newid2.pnums[(oldid.markededge+3)%4+4] = newp[3];
  1179. newid2.markededge = (oldid.markededge+1)%4;
  1180. }
  1181. int nm = oldid.marked - 1;
  1182. if (nm < 0) nm = 0;
  1183. newid1.marked = newid2.marked = nm;
  1184. newid1.incorder = newid2.incorder = 0;
  1185. newid1.order = newid2.order = oldid.order;
  1186. }
  1187. void BTBisectTri (const MarkedTri & oldtri, int newp, const PointGeomInfo & newpgi,
  1188. MarkedTri & newtri1, MarkedTri & newtri2)
  1189. {
  1190. int i;
  1191. for (i = 0; i < 3; i++)
  1192. {
  1193. newtri1.pnums[i] = oldtri.pnums[i];
  1194. newtri1.pgeominfo[i] = oldtri.pgeominfo[i];
  1195. newtri2.pnums[i] = oldtri.pnums[i];
  1196. newtri2.pgeominfo[i] = oldtri.pgeominfo[i];
  1197. }
  1198. int pe1, pe2;
  1199. pe1 = 0;
  1200. if (pe1 == oldtri.markededge)
  1201. pe1++;
  1202. pe2 = 3 - oldtri.markededge - pe1;
  1203. newtri1.pnums[pe2] = newp;
  1204. newtri1.pgeominfo[pe2] = newpgi;
  1205. newtri1.markededge = pe2;
  1206. newtri2.pnums[pe1] = newp;
  1207. newtri2.pgeominfo[pe1] = newpgi;
  1208. newtri2.markededge = pe1;
  1209. newtri1.surfid = oldtri.surfid;
  1210. newtri2.surfid = oldtri.surfid;
  1211. int nm = oldtri.marked - 1;
  1212. if (nm < 0) nm = 0;
  1213. newtri1.marked = nm;
  1214. newtri2.marked = nm;
  1215. newtri1.incorder = 0;
  1216. newtri1.order = oldtri.order;
  1217. newtri2.incorder = 0;
  1218. newtri2.order = oldtri.order;
  1219. }
  1220. void BTBisectQuad (const MarkedQuad & oldquad,
  1221. int newp1, const PointGeomInfo & npgi1,
  1222. int newp2, const PointGeomInfo & npgi2,
  1223. MarkedQuad & newquad1, MarkedQuad & newquad2)
  1224. {
  1225. int i;
  1226. for (i = 0; i < 4; i++)
  1227. {
  1228. newquad1.pnums[i] = oldquad.pnums[i];
  1229. newquad1.pgeominfo[i] = oldquad.pgeominfo[i];
  1230. newquad2.pnums[i] = oldquad.pnums[i];
  1231. newquad2.pgeominfo[i] = oldquad.pgeominfo[i];
  1232. }
  1233. /* if (oldquad.marked==1) // he/sz: 2d quads or 3d prism
  1234. {
  1235. newquad1.pnums[1] = newp1;
  1236. newquad1.pgeominfo[1] = npgi1;
  1237. newquad1.pnums[3] = newp2;
  1238. newquad1.pgeominfo[3] = npgi2;
  1239. newquad2.pnums[0] = newp1;
  1240. newquad2.pgeominfo[0] = npgi1;
  1241. newquad2.pnums[2] = newp2;
  1242. newquad2.pgeominfo[2] = npgi2;
  1243. }
  1244. else if (oldquad.marked==2) // he/sz: 2d quads only
  1245. {
  1246. newquad1.pnums[0] = newp1;
  1247. newquad1.pnums[1] = newp2;
  1248. newquad1.pnums[3] = oldquad.pnums[2];
  1249. newquad1.pnums[2] = oldquad.pnums[0];
  1250. newquad1.pgeominfo[0] = npgi1;
  1251. newquad1.pgeominfo[1] = npgi2;
  1252. newquad1.pgeominfo[3] = oldquad.pgeominfo[2];
  1253. newquad1.pgeominfo[2] = oldquad.pgeominfo[0];
  1254. newquad2.pnums[0] = newp2;
  1255. newquad2.pnums[1] = newp1;
  1256. newquad2.pnums[3] = oldquad.pnums[1];
  1257. newquad2.pnums[2] = oldquad.pnums[3];
  1258. newquad2.pgeominfo[0] = npgi2;
  1259. newquad2.pgeominfo[1] = npgi1;
  1260. newquad2.pgeominfo[3] = oldquad.pgeominfo[1];
  1261. newquad2.pgeominfo[2] = oldquad.pgeominfo[3];
  1262. }
  1263. */
  1264. if (oldquad.markededge==0 || oldquad.markededge==2)
  1265. {
  1266. newquad1.pnums[1] = newp1;
  1267. newquad1.pgeominfo[1] = npgi1;
  1268. newquad1.pnums[3] = newp2;
  1269. newquad1.pgeominfo[3] = npgi2;
  1270. newquad2.pnums[0] = newp1;
  1271. newquad2.pgeominfo[0] = npgi1;
  1272. newquad2.pnums[2] = newp2;
  1273. newquad2.pgeominfo[2] = npgi2;
  1274. }
  1275. else // 1 || 3
  1276. {
  1277. newquad1.pnums[2] = newp1;
  1278. newquad1.pgeominfo[2] = npgi1;
  1279. newquad1.pnums[3] = newp2;
  1280. newquad1.pgeominfo[3] = npgi2;
  1281. newquad2.pnums[0] = newp1;
  1282. newquad2.pgeominfo[0] = npgi1;
  1283. newquad2.pnums[1] = newp2;
  1284. newquad2.pgeominfo[1] = npgi2;
  1285. }
  1286. newquad1.surfid = oldquad.surfid;
  1287. newquad2.surfid = oldquad.surfid;
  1288. int nm = oldquad.marked - 1;
  1289. if (nm < 0) nm = 0;
  1290. newquad1.marked = nm;
  1291. newquad2.marked = nm;
  1292. if (nm==1)
  1293. {
  1294. newquad1.markededge=1;
  1295. newquad2.markededge=1;
  1296. }
  1297. else
  1298. {
  1299. newquad1.markededge=0;
  1300. newquad2.markededge=0;
  1301. }
  1302. }
  1303. int MarkHangingIdentifications(T_MIDS & mids,
  1304. const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
  1305. {
  1306. int i, j;
  1307. int hanging = 0;
  1308. for (i = 1; i <= mids.Size(); i++)
  1309. {
  1310. if (mids.Elem(i).marked)
  1311. {
  1312. hanging = 1;
  1313. continue;
  1314. }
  1315. const int np = mids.Get(i).np;
  1316. for(j = 0; j < np; j++)
  1317. {
  1318. INDEX_2 edge1(mids.Get(i).pnums[j],
  1319. mids.Get(i).pnums[(j+1) % np]);
  1320. INDEX_2 edge2(mids.Get(i).pnums[j+np],
  1321. mids.Get(i).pnums[((j+1) % np) + np]);
  1322. edge1.Sort();
  1323. edge2.Sort();
  1324. if (cutedges.Used (edge1) ||
  1325. cutedges.Used (edge2))
  1326. {
  1327. mids.Elem(i).marked = 1;
  1328. hanging = 1;
  1329. }
  1330. }
  1331. }
  1332. return hanging;
  1333. }
  1334. /*
  1335. void IdentifyCutEdges(Mesh & mesh,
  1336. INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
  1337. {
  1338. int i,j,k;
  1339. Array< Array<int,PointIndex::BASE>* > idmaps;
  1340. for(i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)
  1341. {
  1342. idmaps.Append(new Array<int,PointIndex::BASE>);
  1343. mesh.GetIdentifications().GetMap(i,*idmaps.Last());
  1344. }
  1345. for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)
  1346. {
  1347. const Element2d & el2d = mesh[sei];
  1348. for(i = 0; i < el2d.GetNP(); i++)
  1349. {
  1350. INDEX_2 e1(el2d[i], el2d[(i+1) % el2d.GetNP()]);
  1351. e1.Sort();
  1352. if(!cutedges.Used(e1))
  1353. continue;
  1354. for(k = 0; k < idmaps.Size(); k++)
  1355. {
  1356. INDEX_2 e2((*idmaps[k])[e1.I1()],
  1357. (*idmaps[k])[e1.I2()]);
  1358. if(e2.I1() == 0 || e2.I2() == 0 ||
  1359. e1.I1() == e2.I1() || e1.I2() == e2.I2())
  1360. continue;
  1361. e2.Sort();
  1362. if(cutedges.Used(e2))
  1363. continue;
  1364. Point3d np = Center(mesh.Point(e2.I1()),
  1365. mesh.Point(e2.I2()));
  1366. int newp = mesh.AddPoint(np);
  1367. cutedges.Set(e2,newp);
  1368. (*testout) << "DAAA" << endl;
  1369. }
  1370. }
  1371. }
  1372. for(i=0; i<idmaps.Size(); i++)
  1373. delete idmaps[i];
  1374. idmaps.DeleteAll();
  1375. }
  1376. */
  1377. int MarkHangingTets (T_MTETS & mtets,
  1378. const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
  1379. {
  1380. int i, j, k;
  1381. int hanging = 0;
  1382. for (i = 1; i <= mtets.Size(); i++)
  1383. {
  1384. MarkedTet & teti = mtets.Elem(i);
  1385. if (teti.marked)
  1386. {
  1387. hanging = 1;
  1388. continue;
  1389. }
  1390. for (j = 0; j < 3; j++)
  1391. for (k = j+1; k < 4; k++)
  1392. {
  1393. INDEX_2 edge(teti.pnums[j],
  1394. teti.pnums[k]);
  1395. edge.Sort();
  1396. if (cutedges.Used (edge))
  1397. {
  1398. teti.marked = 1;
  1399. hanging = 1;
  1400. }
  1401. }
  1402. }
  1403. return hanging;
  1404. }
  1405. int MarkHangingPrisms (T_MPRISMS & mprisms,
  1406. const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
  1407. {
  1408. int i, j, k;
  1409. int hanging = 0;
  1410. for (i = 1; i <= mprisms.Size(); i++)
  1411. {
  1412. if (mprisms.Elem(i).marked)
  1413. {
  1414. hanging = 1;
  1415. continue;
  1416. }
  1417. for (j = 0; j < 2; j++)
  1418. for (k = j+1; k < 3; k++)
  1419. {
  1420. INDEX_2 edge1(mprisms.Get(i).pnums[j],
  1421. mprisms.Get(i).pnums[k]);
  1422. INDEX_2 edge2(mprisms.Get(i).pnums[j+3],
  1423. mprisms.Get(i).pnums[k+3]);
  1424. edge1.Sort();
  1425. edge2.Sort();
  1426. if (cutedges.Used (edge1) ||
  1427. cutedges.Used (edge2))
  1428. {
  1429. mprisms.Elem(i).marked = 1;
  1430. hanging = 1;
  1431. }
  1432. }
  1433. }
  1434. return hanging;
  1435. }
  1436. int MarkHangingTris (T_MTRIS & mtris,
  1437. const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
  1438. {
  1439. int i, j, k;
  1440. int hanging = 0;
  1441. for (i = 1; i <= mtris.Size(); i++)
  1442. {
  1443. if (mtris.Get(i).marked)
  1444. {
  1445. hanging = 1;
  1446. continue;
  1447. }
  1448. for (j = 0; j < 2; j++)
  1449. for (k = j+1; k < 3; k++)
  1450. {
  1451. INDEX_2 edge(mtris.Get(i).pnums[j],
  1452. mtris.Get(i).pnums[k]);
  1453. edge.Sort();
  1454. if (cutedges.Used (edge))
  1455. {
  1456. mtris.Elem(i).marked = 1;
  1457. hanging = 1;
  1458. }
  1459. }
  1460. }
  1461. return hanging;
  1462. }
  1463. int MarkHangingQuads (T_MQUADS & mquads,
  1464. const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)
  1465. {
  1466. int i;
  1467. int hanging = 0;
  1468. for (i = 1; i <= mquads.Size(); i++)
  1469. {
  1470. if (mquads.Elem(i).marked)
  1471. {
  1472. hanging = 1;
  1473. continue;
  1474. }
  1475. INDEX_2 edge1(mquads.Get(i).pnums[0],
  1476. mquads.Get(i).pnums[1]);
  1477. INDEX_2 edge2(mquads.Get(i).pnums[2],
  1478. mquads.Get(i).pnums[3]);
  1479. edge1.Sort();
  1480. edge2.Sort();
  1481. if (cutedges.Used (edge1) ||
  1482. cutedges.Used (edge2))
  1483. {
  1484. mquads.Elem(i).marked = 1;
  1485. mquads.Elem(i).markededge = 0;
  1486. hanging = 1;
  1487. continue;
  1488. }
  1489. // he/sz: second case: split horizontally
  1490. INDEX_2 edge3(mquads.Get(i).pnums[1],
  1491. mquads.Get(i).pnums[3]);
  1492. INDEX_2 edge4(mquads.Get(i).pnums[2],
  1493. mquads.Get(i).pnums[0]);
  1494. edge3.Sort();
  1495. edge4.Sort();
  1496. if (cutedges.Used (edge3) ||
  1497. cutedges.Used (edge4))
  1498. {
  1499. mquads.Elem(i).marked = 1;
  1500. mquads.Elem(i).markededge = 1;
  1501. hanging = 1;
  1502. continue;
  1503. }
  1504. }
  1505. return hanging;
  1506. }
  1507. void ConnectToNodeRec (int node, int tonode,
  1508. const TABLE<int> & conto, Array<int> & connecttonode)
  1509. {
  1510. int i, n2;
  1511. // (*testout) << "connect " << node << " to " << tonode << endl;
  1512. for (i = 1; i <= conto.EntrySize(node); i++)
  1513. {
  1514. n2 = conto.Get(node, i);
  1515. if (!connecttonode.Get(n2))
  1516. {
  1517. connecttonode.Elem(n2) = tonode;
  1518. ConnectToNodeRec (n2, tonode, conto, connecttonode);
  1519. }
  1520. }
  1521. }
  1522. T_MTETS mtets;
  1523. T_MPRISMS mprisms;
  1524. T_MIDS mids;
  1525. T_MTRIS mtris;
  1526. T_MQUADS mquads;
  1527. void WriteMarkedElements(ostream & ost)
  1528. {
  1529. ost << "Marked Elements\n";
  1530. ost << mtets.Size() << "\n";
  1531. for(int i=0; i<mtets.Size(); i++)
  1532. ost << mtets[i];
  1533. ost << mprisms.Size() << "\n";
  1534. for(int i=0; i<mprisms.Size(); i++)
  1535. ost << mprisms[i];
  1536. ost << mids.Size() << "\n";
  1537. for(int i=0; i<mids.Size(); i++)
  1538. ost << mids[i];
  1539. ost << mtris.Size() << "\n";
  1540. for(int i=0; i<mtris.Size(); i++)
  1541. ost << mtris[i];
  1542. ost << mquads.Size() << "\n";
  1543. for(int i=0; i<mquads.Size(); i++)
  1544. ost << mquads[i];
  1545. ost << endl;
  1546. }
  1547. bool ReadMarkedElements(istream & ist, const Mesh & mesh)
  1548. {
  1549. string auxstring("");
  1550. if(ist)
  1551. ist >> auxstring;
  1552. if(auxstring != "Marked")
  1553. return false;
  1554. if(ist)
  1555. ist >> auxstring;
  1556. if(auxstring != "Elements")
  1557. return false;
  1558. int size;
  1559. ist >> size;
  1560. mtets.SetSize(size);
  1561. for(int i=0; i<size; i++)
  1562. {
  1563. ist >> mtets[i];
  1564. if(mtets[i].pnums[0] > mesh.GetNV() ||
  1565. mtets[i].pnums[1] > mesh.GetNV() ||
  1566. mtets[i].pnums[2] > mesh.GetNV() ||
  1567. mtets[i].pnums[3] > mesh.GetNV())
  1568. return false;
  1569. }
  1570. ist >> size;
  1571. mprisms.SetSize(size);
  1572. for(int i=0; i<size; i++)
  1573. ist >> mprisms[i];
  1574. ist >> size;
  1575. mids.SetSize(size);
  1576. for(int i=0; i<size; i++)
  1577. ist >> mids[i];
  1578. ist >> size;
  1579. mtris.SetSize(size);
  1580. for(int i=0; i<size; i++)
  1581. ist >> mtris[i];
  1582. ist >> size;
  1583. mquads.SetSize(size);
  1584. for(int i=0; i<size; i++)
  1585. ist >> mquads[i];
  1586. return true;
  1587. }
  1588. void BisectTetsCopyMesh (Mesh & mesh, const class CSGeometry *,
  1589. BisectionOptions & opt,
  1590. const Array< Array<int,PointIndex::BASE>* > & idmaps,
  1591. const string & refinfofile)
  1592. {
  1593. mtets.SetName ("bisection, tets");
  1594. mprisms.SetName ("bisection, prisms");
  1595. mtris.SetName ("bisection, trigs");
  1596. mquads.SetName ("bisection, quads");
  1597. mids.SetName ("bisection, identifications");
  1598. //int np = mesh.GetNP();
  1599. int ne = mesh.GetNE();
  1600. int nse = mesh.GetNSE();
  1601. int i, j, k, l, m;
  1602. /*
  1603. if (mtets.Size() + mprisms.Size() == mesh.GetNE())
  1604. return;
  1605. */
  1606. bool readok = false;
  1607. if(refinfofile != "")
  1608. {
  1609. PrintMessage(3,"Reading marked-element information from \"",refinfofile,"\"");
  1610. ifstream ist(refinfofile.c_str());
  1611. readok = ReadMarkedElements(ist,mesh);
  1612. ist.close();
  1613. }
  1614. if(!readok)
  1615. {
  1616. PrintMessage(3,"resetting marked-element information");
  1617. mtets.SetSize(0);
  1618. mprisms.SetSize(0);
  1619. mids.SetSize(0);
  1620. mtris.SetSize(0);
  1621. mquads.SetSize(0);
  1622. INDEX_2_HASHTABLE<int> shortedges(100);
  1623. for (i = 1; i <= ne; i++)
  1624. {
  1625. const Element & el = mesh.VolumeElement(i);
  1626. if (el.GetType() == PRISM ||
  1627. el.GetType() == PRISM12)
  1628. {
  1629. for (j = 1; j <= 3; j++)
  1630. {
  1631. INDEX_2 se(el.PNum(j), el.PNum(j+3));
  1632. se.Sort();
  1633. shortedges.Set (se, 1);
  1634. }
  1635. }
  1636. }
  1637. // INDEX_2_HASHTABLE<int> edgenumber(np);
  1638. INDEX_2_CLOSED_HASHTABLE<int> edgenumber(9*ne+4*nse);
  1639. BTSortEdges (mesh, idmaps, edgenumber);
  1640. for (i = 1; i <= ne; i++)
  1641. {
  1642. const Element & el = mesh.VolumeElement(i);
  1643. switch (el.GetType())
  1644. {
  1645. case TET:
  1646. case TET10:
  1647. {
  1648. // if tet has short edge, it is handled as degenerated prism
  1649. int foundse = 0;
  1650. for (j = 1; j <= 3; j++)
  1651. for (k = j+1; k <= 4; k++)
  1652. {
  1653. INDEX_2 se(el.PNum(j), el.PNum(k));
  1654. se.Sort();
  1655. if (shortedges.Used (se))
  1656. {
  1657. // cout << "tet converted to prism" << endl;
  1658. foundse = 1;
  1659. int p3 = 1;
  1660. while (p3 == j || p3 == k)
  1661. p3++;
  1662. int p4 = 10 - j - k - p3;
  1663. // even permutation ?
  1664. int pi[4];
  1665. pi[0] = j;
  1666. pi[1] = k;
  1667. pi[2] = p3;
  1668. pi[3] = p4;
  1669. int cnt = 0;
  1670. for (l = 1; l <= 4; l++)
  1671. for (m = 0; m < 3; m++)
  1672. if (pi[m] > pi[m+1])
  1673. {
  1674. Swap (pi[m], pi[m+1]);
  1675. cnt++;
  1676. }
  1677. if (cnt % 2)
  1678. Swap (p3, p4);
  1679. Element hel = el;
  1680. hel.PNum(1) = el.PNum(j);
  1681. hel.PNum(2) = el.PNum(k);
  1682. hel.PNum(3) = el.PNum(p3);
  1683. hel.PNum(4) = el.PNum(p4);
  1684. MarkedPrism mp;
  1685. BTDefineMarkedPrism (hel, edgenumber, mp);
  1686. mp.matindex = el.GetIndex();
  1687. mprisms.Append (mp);
  1688. }
  1689. }
  1690. if (!foundse)
  1691. {
  1692. MarkedTet mt;
  1693. BTDefineMarkedTet (el, edgenumber, mt);
  1694. mt.matindex = el.GetIndex();
  1695. mtets.Append (mt);
  1696. }
  1697. break;
  1698. }
  1699. case PYRAMID:
  1700. {
  1701. // eventually rotate
  1702. MarkedPrism mp;
  1703. INDEX_2 se(el.PNum(1), el.PNum(2));
  1704. se.Sort();
  1705. if (shortedges.Used (se))
  1706. {
  1707. Element hel = el;
  1708. hel.PNum(1) = el.PNum(2);
  1709. hel.PNum(2) = el.PNum(3);
  1710. hel.PNum(3) = el.PNum(4);
  1711. hel.PNum(4) = el.PNum(1);
  1712. BTDefineMarkedPrism (hel, edgenumber, mp);
  1713. }
  1714. else
  1715. {
  1716. BTDefineMarkedPrism (el, edgenumber, mp);
  1717. }
  1718. mp.matindex = el.GetIndex();
  1719. mprisms.Append (mp);
  1720. break;
  1721. }
  1722. case PRISM:
  1723. case PRISM12:
  1724. {
  1725. MarkedPrism mp;
  1726. BTDefineMarkedPrism (el, edgenumber, mp);
  1727. mp.matindex = el.GetIndex();
  1728. mprisms.Append (mp);
  1729. break;
  1730. }
  1731. default:
  1732. throw NgException("Bisect, element type not handled in switch, 4");
  1733. }
  1734. }
  1735. for (i = 1; i <= nse; i++)
  1736. {
  1737. const Element2d & el = mesh.SurfaceElement(i);
  1738. if (el.GetType() == TRIG ||
  1739. el.GetType() == TRIG6)
  1740. {
  1741. MarkedTri mt;
  1742. BTDefineMarkedTri (el, edgenumber, mt);
  1743. mtris.Append (mt);
  1744. }
  1745. else
  1746. {
  1747. MarkedQuad mq;
  1748. BTDefineMarkedQuad (el, edgenumber, mq);
  1749. mquads.Append (mq);
  1750. }
  1751. MarkedIdentification mi;
  1752. for(j=0; j<idmaps.Size(); j++)
  1753. if(BTDefineMarkedId(el, edgenumber, *idmaps[j], mi))
  1754. mids.Append(mi);
  1755. }
  1756. }
  1757. mesh.mlparentelement.SetSize(ne);
  1758. for (i = 1; i <= ne; i++)
  1759. mesh.mlparentelement.Elem(i) = 0;
  1760. mesh.mlparentsurfaceelement.SetSize(nse);
  1761. for (i = 1; i <= nse; i++)
  1762. mesh.mlparentsurfaceelement.Elem(i) = 0;
  1763. if (printmessage_importance>0)
  1764. {
  1765. ostringstream str1,str2;
  1766. str1 << "copied " << mtets.Size() << " tets, " << mprisms.Size() << " prisms";
  1767. str2 << " " << mtris.Size() << " trigs, " << mquads.Size() << " quads";
  1768. PrintMessage(4,str1.str());
  1769. PrintMessage(4,str2.str());
  1770. }
  1771. }
  1772. /*
  1773. void UpdateEdgeMarks2(Mesh & mesh,
  1774. const Array< Array<int,PointIndex::BASE>* > & idmaps)
  1775. {
  1776. Array< Array<MarkedTet>*,PointIndex::BASE > mtets_old(mesh.GetNP());
  1777. Array< Array<MarkedPrism>*,PointIndex::BASE > mprisms_old(mesh.GetNP());
  1778. Array< Array<MarkedIdentification>*,PointIndex::BASE > mids_old(mesh.GetNP());
  1779. Array< Array<MarkedTri>*,PointIndex::BASE > mtris_old(mesh.GetNP());
  1780. Array< Array<MarkedQuad>*,PointIndex::BASE > mquads_old(mesh.GetNP());
  1781. for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
  1782. mtets_old[i] = new Array<MarkedTet>;
  1783. for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
  1784. mprisms_old[i] = new Array<MarkedPrism>;
  1785. for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
  1786. mids_old[i] = new Array<MarkedIdentification>;
  1787. for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
  1788. mtris_old[i] = new Array<MarkedTri>;
  1789. for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
  1790. mquads_old[i] = new Array<MarkedQuad>;
  1791. for(int i=0; i<mtets.Size(); i++)
  1792. mtets_old[mtets[i].pnums[0]]->Append(mtets[i]);
  1793. for(int i=0; i<mprisms.Size(); i++)
  1794. mprisms_old[mprisms[i].pnums[0]]->Append(mprisms[i]);
  1795. for(int i=0; i<mids.Size(); i++)
  1796. mids_old[mids[i].pnums[0]]->Append(mids[i]);
  1797. for(int i=0; i<mtris.Size(); i++)
  1798. {
  1799. (*testout) << "i " << i << endl;
  1800. (*testout) << "mtris[i] " << mtris[i].pnums[0] << " " << mtris[i].pnums[1] << " " << mtris[i].pnums[2] << endl;
  1801. mtris_old[mtris[i].pnums[0]]->Append(mtris[i]);
  1802. }
  1803. for(int i=0; i<mquads.Size(); i++)
  1804. mquads_old[mquads[i].pnums[0]]->Append(mquads[i]);
  1805. int np = mesh.GetNP();
  1806. int ne = mesh.GetNE();
  1807. int nse = mesh.GetNSE();
  1808. int i, j, k, l, m;
  1809. // if (mtets.Size() + mprisms.Size() == mesh.GetNE())
  1810. // return;
  1811. mtets.SetSize(0);
  1812. mprisms.SetSize(0);
  1813. mids.SetSize(0);
  1814. mtris.SetSize(0);
  1815. mquads.SetSize(0);
  1816. INDEX_2_HASHTABLE<int> shortedges(100);
  1817. for (i = 1; i <= ne; i++)
  1818. {
  1819. const Element & el = mesh.VolumeElement(i);
  1820. if (el.GetType() == PRISM ||
  1821. el.GetType() == PRISM12)
  1822. {
  1823. for (j = 1; j <= 3; j++)
  1824. {
  1825. INDEX_2 se(el.PNum(j), el.PNum(j+3));
  1826. se.Sort();
  1827. shortedges.Set (se, 1);
  1828. }
  1829. }
  1830. }
  1831. // INDEX_2_HASHTABLE<int> edgenumber(np);
  1832. INDEX_2_CLOSED_HASHTABLE<int> edgenumber(9*ne+4*nse);
  1833. BTSortEdges (mesh, idmaps, edgenumber);
  1834. for (i = 1; i <= ne; i++)
  1835. {
  1836. const Element & el = mesh.VolumeElement(i);
  1837. switch (el.GetType())
  1838. {
  1839. case TET:
  1840. case TET10:
  1841. {
  1842. // if tet has short edge, it is handled as degenerated prism
  1843. int foundse = 0;
  1844. for (j = 1; j <= 3; j++)
  1845. for (k = j+1; k <= 4; k++)
  1846. {
  1847. INDEX_2 se(el.PNum(j), el.PNum(k));
  1848. se.Sort();
  1849. if (shortedges.Used (se))
  1850. {
  1851. // cout << "tet converted to prism" << endl;
  1852. foundse = 1;
  1853. int p3 = 1;
  1854. while (p3 == j || p3 == k)
  1855. p3++;
  1856. int p4 = 10 - j - k - p3;
  1857. // even permutation ?
  1858. int pi[4];
  1859. pi[0] = j;
  1860. pi[1] = k;
  1861. pi[2] = p3;
  1862. pi[3] = p4;
  1863. int cnt = 0;
  1864. for (l = 1; l <= 4; l++)
  1865. for (m = 0; m < 3; m++)
  1866. if (pi[m] > pi[m+1])
  1867. {
  1868. Swap (pi[m], pi[m+1]);
  1869. cnt++;
  1870. }
  1871. if (cnt % 2)
  1872. Swap (p3, p4);
  1873. Element hel = el;
  1874. hel.PNum(1) = el.PNum(j);
  1875. hel.PNum(2) = el.PNum(k);
  1876. hel.PNum(3) = el.PNum(p3);
  1877. hel.PNum(4) = el.PNum(p4);
  1878. MarkedPrism mp;
  1879. BTDefineMarkedPrism (hel, edgenumber, mp);
  1880. mp.matindex = el.GetIndex();
  1881. mprisms.Append (mp);
  1882. }
  1883. }
  1884. if (!foundse)
  1885. {
  1886. MarkedTet mt;
  1887. int oldind = -1;
  1888. for(l = 0; oldind < 0 && l<mtets_old[el[0]]->Size(); l++)
  1889. if(el[1] == (*mtets_old[el[0]])[l].pnums[1] &&
  1890. el[2] == (*mtets_old[el[0]])[l].pnums[2] &&
  1891. el[3] == (*mtets_old[el[0]])[l].pnums[3])
  1892. oldind = l;
  1893. if(oldind >= 0)
  1894. mtets.Append((*mtets_old[el[0]])[oldind]);
  1895. else
  1896. {
  1897. BTDefineMarkedTet (el, edgenumber, mt);
  1898. mt.matindex = el.GetIndex();
  1899. mtets.Append (mt);
  1900. }
  1901. }
  1902. break;
  1903. }
  1904. case PYRAMID:
  1905. {
  1906. // eventually rotate
  1907. MarkedPrism mp;
  1908. INDEX_2 se(el.PNum(1), el.PNum(2));
  1909. se.Sort();
  1910. if (shortedges.Used (se))
  1911. {
  1912. Element hel = el;
  1913. hel.PNum(1) = el.PNum(2);
  1914. hel.PNum(2) = el.PNum(3);
  1915. hel.PNum(3) = el.PNum(4);
  1916. hel.PNum(4) = el.PNum(1);
  1917. BTDefineMarkedPrism (hel, edgenumber, mp);
  1918. }
  1919. else
  1920. {
  1921. BTDefineMarkedPrism (el, edgenumber, mp);
  1922. }
  1923. mp.matindex = el.GetIndex();
  1924. mprisms.Append (mp);
  1925. break;
  1926. }
  1927. case PRISM:
  1928. case PRISM12:
  1929. {
  1930. MarkedPrism mp;
  1931. BTDefineMarkedPrism (el, edgenumber, mp);
  1932. mp.matindex = el.GetIndex();
  1933. mprisms.Append (mp);
  1934. break;
  1935. }
  1936. }
  1937. }
  1938. for (i = 1; i <= nse; i++)
  1939. {
  1940. const Element2d & el = mesh.SurfaceElement(i);
  1941. if (el.GetType() == TRIG ||
  1942. el.GetType() == TRIG6)
  1943. {
  1944. MarkedTri mt;
  1945. BTDefineMarkedTri (el, edgenumber, mt);
  1946. mtris.Append (mt);
  1947. }
  1948. else
  1949. {
  1950. MarkedQuad mq;
  1951. BTDefineMarkedQuad (el, edgenumber, mq);
  1952. mquads.Append (mq);
  1953. }
  1954. MarkedIdentification mi;
  1955. for(j=0; j<idmaps.Size(); j++)
  1956. if(BTDefineMarkedId(el, edgenumber, *idmaps[j], mi))
  1957. {
  1958. mids.Append(mi);
  1959. int oldind = -1;
  1960. for(l = 0; oldind < 0 && l<mids_old[mi.pnums[0]]->Size(); l++)
  1961. {
  1962. bool equal = true;
  1963. for(int m = 1; equal && m < mi.np; m++)
  1964. equal = (mi.pnums[m] == (*mids_old[el[0]])[l].pnums[m]);
  1965. if(equal)
  1966. oldind = l;
  1967. }
  1968. if(oldind >= 0)
  1969. mids.Last() = (*mids_old[mi.pnums[0]])[oldind];
  1970. }
  1971. }
  1972. for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
  1973. delete mtets_old[i];
  1974. for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
  1975. delete mprisms_old[i];
  1976. for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
  1977. delete mids_old[i];
  1978. for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
  1979. delete mtris_old[i];
  1980. for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
  1981. delete mquads_old[i];
  1982. }
  1983. */
  1984. void UpdateEdgeMarks (Mesh & mesh,
  1985. const Array< Array<int,PointIndex::BASE>* > & idmaps)
  1986. //const Array < Array<Element>* > & elements_before,
  1987. //const Array < Array<int>* > & markedelts_num,
  1988. // const Array < Array<Element2d>* > & surfelements_before,
  1989. // const Array < Array<int>* > & markedsurfelts_num)
  1990. {
  1991. T_MTETS mtets_old; mtets_old.Copy(mtets);
  1992. T_MPRISMS mprisms_old; mprisms_old.Copy(mprisms);
  1993. T_MIDS mids_old; mids_old.Copy(mids);
  1994. T_MTRIS mtris_old; mtris_old.Copy(mtris);
  1995. T_MQUADS mquads_old; mquads_old.Copy(mquads);
  1996. mtets.SetSize(0);
  1997. mprisms.SetSize(0);
  1998. mids.SetSize(0);
  1999. mtris.SetSize(0);
  2000. mquads.SetSize(0);
  2001. //int nv = mesh.GetNV();
  2002. INDEX_2_CLOSED_HASHTABLE<int> edgenumber(9*mesh.GetNE()+4*mesh.GetNSE());
  2003. int maxnum = BTSortEdges (mesh, idmaps, edgenumber);
  2004. for(int m = 0; m < mtets_old.Size(); m++)
  2005. {
  2006. MarkedTet & mt = mtets_old[m];
  2007. //(*testout) << "old mt " << mt;
  2008. INDEX_2 edge (mt.pnums[mt.tetedge1],mt.pnums[mt.tetedge2]);
  2009. edge.Sort();
  2010. if(edgenumber.Used(edge))
  2011. {
  2012. int val = edgenumber.Get(edge);
  2013. //(*testout) << "set voledge " << edge << " from " << val;
  2014. if(val <= maxnum)
  2015. {
  2016. val += 2*maxnum;
  2017. edgenumber.Set(edge,val);
  2018. }
  2019. else if(val <= 2*maxnum)
  2020. {
  2021. val += maxnum;
  2022. edgenumber.Set(edge,val);
  2023. }
  2024. //(*testout) << " to " << val << endl;
  2025. }
  2026. for(int k=0; k<4; k++)
  2027. for(int i=0; i<3; i++)
  2028. for(int j=i+1; i != k && j<4; j++)
  2029. if(j != k && int(mt.faceedges[k]) == 6-k-i-j)
  2030. {
  2031. edge[0] = mt.pnums[i];
  2032. edge[1] = mt.pnums[j];
  2033. edge.Sort();
  2034. if(edgenumber.Used(edge))
  2035. {
  2036. int val = edgenumber.Get(edge);
  2037. //(*testout) << "set faceedge " << edge << " from " << val;
  2038. if(val <= maxnum)
  2039. {
  2040. val += maxnum;
  2041. edgenumber.Set(edge,val);
  2042. }
  2043. //(*testout) << " to " << val << endl;
  2044. }
  2045. }
  2046. }
  2047. for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++)
  2048. {
  2049. const Element & el = mesh[ei];
  2050. //int pos = elements_before[el[0]]->Pos(el);
  2051. //int elnum = (pos >= 0) ? (*markedelts_num[el[0]])[pos] : -1;
  2052. switch (el.GetType())
  2053. {
  2054. case TET:
  2055. case TET10:
  2056. {
  2057. //if(elnum >= 0)
  2058. // {
  2059. // mtets.Append(mtets_old[elnum]);
  2060. // }
  2061. //else
  2062. // {
  2063. MarkedTet mt;
  2064. BTDefineMarkedTet (el, edgenumber, mt);
  2065. mt.matindex = el.GetIndex();
  2066. mtets.Append (mt);
  2067. //(*testout) << "mtet " << mtets.Last() << endl;
  2068. break;
  2069. }
  2070. case PYRAMID:
  2071. {
  2072. cerr << "Refinement :: UpdateEdgeMarks not yet implemented for pyramids"
  2073. << endl;
  2074. break;
  2075. }
  2076. case PRISM:
  2077. case PRISM12:
  2078. {
  2079. cerr << "Refinement :: UpdateEdgeMarks not yet implemented for prisms"
  2080. << endl;
  2081. break;
  2082. }
  2083. default:
  2084. throw NgException("Bisect, element type not handled in switch, 6");
  2085. }
  2086. }
  2087. for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)
  2088. {
  2089. const Element2d & el = mesh[sei];
  2090. /*
  2091. for(int k=0; k<3; k++)
  2092. auxind3[k] = el[k];
  2093. auxind3.Sort();
  2094. int pos = oldfaces[auxind3[0]]->Pos(auxind3);
  2095. if(pos < 0)
  2096. cout << "UIUIUI" << endl;
  2097. */
  2098. switch (el.GetType())
  2099. {
  2100. case TRIG:
  2101. case TRIG6:
  2102. {
  2103. MarkedTri mt;
  2104. BTDefineMarkedTri (el, edgenumber, mt);
  2105. mtris.Append (mt);
  2106. break;
  2107. }
  2108. case QUAD:
  2109. case QUAD6:
  2110. {
  2111. MarkedQuad mt;
  2112. BTDefineMarkedQuad (el, edgenumber, mt);
  2113. mquads.Append (mt);
  2114. break;
  2115. }
  2116. default:
  2117. throw NgException("Bisect, element type not handled in switch, 5");
  2118. }
  2119. MarkedIdentification mi;
  2120. for(int j=0; j<idmaps.Size(); j++)
  2121. if(BTDefineMarkedId(el, edgenumber, *idmaps[j], mi))
  2122. mids.Append(mi);
  2123. /*
  2124. int pos = surfelements_before[el[0]]->Pos(el);
  2125. int elnum = (pos >= 0) ? (*markedsurfelts_num[el[0]])[pos] : -1;
  2126. switch (el.GetType())
  2127. {
  2128. case TRIG:
  2129. case TRIG6:
  2130. {
  2131. if(elnum >= 0)
  2132. mtris.Append(mtris_old[elnum]);
  2133. else
  2134. {
  2135. MarkedTri mt;
  2136. BTDefineMarkedTri (el, edgenumber, mt);
  2137. mtris.Append (mt);
  2138. (*testout) << "(new) ";
  2139. }
  2140. (*testout) << "mtri " << mtris.Last();
  2141. break;
  2142. }
  2143. case QUAD:
  2144. case QUAD6:
  2145. {
  2146. if(elnum >= 0)
  2147. mquads.Append(mquads_old[elnum]);
  2148. else
  2149. {
  2150. MarkedQuad mt;
  2151. BTDefineMarkedQuad (el, edgenumber, mt);
  2152. mquads.Append (mt);
  2153. }
  2154. break;
  2155. }
  2156. }
  2157. */
  2158. }
  2159. /*
  2160. for(int i=0; i<oldfaces.Size(); i++)
  2161. {
  2162. delete oldfaces[i];
  2163. delete oldmarkededges[i];
  2164. }
  2165. */
  2166. }
  2167. void Refinement :: Bisect (Mesh & mesh,
  2168. BisectionOptions & opt,
  2169. Array<double> * quality_loss) const
  2170. {
  2171. PrintMessage(1,"Mesh bisection");
  2172. PushStatus("Mesh bisection");
  2173. static int timer = NgProfiler::CreateTimer ("Bisect");
  2174. NgProfiler::RegionTimer reg1 (timer);
  2175. static int localizetimer = NgProfiler::CreateTimer("localize edgepoints");
  2176. NgProfiler::RegionTimer * loct = new NgProfiler::RegionTimer(localizetimer);
  2177. LocalizeEdgePoints(mesh);
  2178. delete loct;
  2179. Array< Array<int,PointIndex::BASE>* > idmaps;
  2180. for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)
  2181. {
  2182. if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC)
  2183. {
  2184. idmaps.Append(new Array<int,PointIndex::BASE>);
  2185. mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true);
  2186. }
  2187. }
  2188. string refelementinfofileread = "";
  2189. string refelementinfofilewrite = "";
  2190. if(opt.refinementfilename)
  2191. {
  2192. ifstream inf(opt.refinementfilename);
  2193. string st;
  2194. inf >> st;
  2195. if(st == "refinementinfo")
  2196. {
  2197. while(inf)
  2198. {
  2199. while(inf && st != "markedelementsfile")
  2200. inf >> st;
  2201. if(inf)
  2202. inf >> st;
  2203. if(st == "read" && inf)
  2204. ReadEnclString(inf,refelementinfofileread,'\"');
  2205. else if(st == "write" && inf)
  2206. ReadEnclString(inf,refelementinfofilewrite,'\"');
  2207. }
  2208. }
  2209. inf.close();
  2210. }
  2211. if (mesh.mglevels == 1 || idmaps.Size() > 0)
  2212. BisectTetsCopyMesh(mesh, NULL, opt, idmaps, refelementinfofileread);
  2213. mesh.ComputeNVertices();
  2214. int np = mesh.GetNV();
  2215. mesh.SetNP(np);
  2216. // int ne = mesh.GetNE();
  2217. // int nse = mesh.GetNSE();
  2218. int i, j, l;
  2219. // int initnp = np;
  2220. // int maxsteps = 3;
  2221. mesh.mglevels++;
  2222. /*
  2223. if (opt.refinementfilename || opt.usemarkedelements)
  2224. maxsteps = 3;
  2225. */
  2226. if (opt.refine_p)
  2227. {
  2228. int ne = mesh.GetNE();
  2229. int nse = mesh.GetNSE();
  2230. int ox,oy,oz;
  2231. for (ElementIndex ei = 0; ei < ne; ei++)
  2232. if (mesh[ei].TestRefinementFlag())
  2233. {
  2234. mesh[ei].GetOrder(ox,oy,oz);
  2235. mesh[ei].SetOrder (ox+1,oy+1,oz+1);
  2236. if (mesh[ei].TestStrongRefinementFlag())
  2237. mesh[ei].SetOrder (ox+2,oy+2,oz+2);
  2238. }
  2239. for (SurfaceElementIndex sei = 0; sei < nse; sei++)
  2240. if (mesh[sei].TestRefinementFlag())
  2241. {
  2242. mesh[sei].GetOrder(ox,oy);
  2243. mesh[sei].SetOrder(ox+1,oy+1);
  2244. if (mesh[sei].TestStrongRefinementFlag())
  2245. mesh[sei].SetOrder(ox+2,oy+2);
  2246. }
  2247. #ifndef SABINE //Nachbarelemente mit ordx,ordy,ordz
  2248. Array<int,PointIndex::BASE> v_order (mesh.GetNP());
  2249. v_order = 0;
  2250. for (ElementIndex ei = 0; ei < ne; ei++)
  2251. for (j = 0; j < mesh[ei].GetNP(); j++)
  2252. if (mesh[ei].GetOrder() > v_order[mesh[ei][j]])
  2253. v_order[mesh[ei][j]] = mesh[ei].GetOrder();
  2254. for (SurfaceElementIndex sei = 0; sei < nse; sei++)
  2255. for (j = 0; j < mesh[sei].GetNP(); j++)
  2256. if (mesh[sei].GetOrder() > v_order[mesh[sei][j]])
  2257. v_order[mesh[sei][j]] = mesh[sei].GetOrder();
  2258. for (ElementIndex ei = 0; ei < ne; ei++)
  2259. for (j = 0; j < mesh[ei].GetNP(); j++)
  2260. if (mesh[ei].GetOrder() < v_order[mesh[ei][j]]-1)
  2261. mesh[ei].SetOrder(v_order[mesh[ei][j]]-1);
  2262. for (SurfaceElementIndex sei = 0; sei < nse; sei++)
  2263. for (j = 0; j < mesh[sei].GetNP(); j++)
  2264. if (mesh[sei].GetOrder() < v_order[mesh[sei][j]]-1)
  2265. mesh[sei].SetOrder(v_order[mesh[sei][j]]-1);
  2266. #endif
  2267. PopStatus();
  2268. return;
  2269. }
  2270. // INDEX_2_HASHTABLE<int> cutedges(10 + 5 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size()));
  2271. INDEX_2_CLOSED_HASHTABLE<int> cutedges(10 + 9 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size()));
  2272. bool noprojection = false;
  2273. for (l = 1; l <= 1; l++)
  2274. {
  2275. int marked = 0;
  2276. if (opt.refinementfilename)
  2277. {
  2278. ifstream inf(opt.refinementfilename);
  2279. PrintMessage(3,"load refinementinfo from file ",opt.refinementfilename);
  2280. string st;
  2281. inf >> st;
  2282. if(st == "refinementinfo")
  2283. // new version
  2284. {
  2285. for(i=1; i<=mtets.Size(); i++)
  2286. mtets.Elem(i).marked = 0;
  2287. for(i=1; i<=mprisms.Size(); i++)
  2288. mprisms.Elem(i).marked = 0;
  2289. for(i=1; i<=mtris.Size(); i++)
  2290. mtris.Elem(i).marked = 0;
  2291. for(i=1; i<=mquads.Size(); i++)
  2292. mquads.Elem(i).marked = 0;
  2293. for(i=1; i<=mprisms.Size(); i++)
  2294. mids.Elem(i).marked = 0;
  2295. inf >> st;
  2296. while(inf)
  2297. {
  2298. if(st[0] == '#')
  2299. {
  2300. inf.ignore(10000,'\n');
  2301. inf >> st;
  2302. }
  2303. else if(st == "markedelementsfile")
  2304. {
  2305. inf >> st;
  2306. ReadEnclString(inf,st,'\"');
  2307. inf >> st;
  2308. }
  2309. else if(st == "noprojection")
  2310. {
  2311. noprojection = true;
  2312. inf >> st;
  2313. }
  2314. else if(st == "refine")
  2315. {
  2316. inf >> st;
  2317. if(st == "elements")
  2318. {
  2319. inf >> st;
  2320. bool isint = true;
  2321. for(string::size_type ii=0; isint && ii<st.size(); ii++)
  2322. isint = (isdigit(st[ii]) != 0);
  2323. while(inf && isint)
  2324. {
  2325. mtets.Elem(atoi(st.c_str())).marked = 3;
  2326. marked = 1;
  2327. inf >> st;
  2328. isint = true;
  2329. for(string::size_type ii=0; isint && ii<st.size(); ii++)
  2330. isint = (isdigit(st[ii]) != 0);
  2331. }
  2332. }
  2333. else if(st == "orthobrick")
  2334. {
  2335. double bounds[6];
  2336. for(i=0; i<6; i++)
  2337. inf >> bounds[i];
  2338. int cnt = 0;
  2339. for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++)
  2340. {
  2341. const Element & el = mesh[ei];
  2342. //
  2343. Point<3> center(0,0,0);
  2344. for(i=0; i<el.GetNP(); i++)
  2345. {
  2346. const MeshPoint & point = mesh[el[i]];
  2347. center(0) += point(0);
  2348. center(1) += point(1);
  2349. center(2) += point(2);
  2350. }
  2351. for(i=0; i<3; i++)
  2352. center(i) *= 1./double(el.GetNP());
  2353. if(bounds[0] <= center(0) && center(0) <= bounds[3] &&
  2354. bounds[1] <= center(1) && center(1) <= bounds[4] &&
  2355. bounds[2] <= center(2) && center(2) <= bounds[5])
  2356. {
  2357. mtets[ei].marked = 3;
  2358. cnt++;
  2359. }
  2360. // bool contained = false;
  2361. // for(int i=0; !contained && i<el.GetNP(); i++)
  2362. // {
  2363. // const MeshPoint & point = mesh[el[i]];
  2364. // contained = (bounds[0] <= point.X() && point.X() <= bounds[3] &&
  2365. // bounds[1] <= point.Y() && point.Y() <= bounds[4] &&
  2366. // bounds[2] <= point.Z() && point.Z() <= bounds[5]);
  2367. // }
  2368. // if(contained)
  2369. // {
  2370. // mtets[ei].marked = 3;
  2371. // cnt++;
  2372. // }
  2373. }
  2374. ostringstream strstr;
  2375. strstr.precision(2);
  2376. strstr << "marked " << float(cnt)/float(mesh.GetNE())*100.
  2377. #ifdef WIN32
  2378. << "%%"
  2379. #else
  2380. << "%"
  2381. #endif
  2382. <<" of the elements";
  2383. PrintMessage(4,strstr.str());
  2384. if(cnt > 0)
  2385. marked = 1;
  2386. inf >> st;
  2387. }
  2388. else
  2389. {
  2390. throw NgException("something wrong with refinementinfo file");
  2391. }
  2392. }
  2393. }
  2394. }
  2395. else
  2396. {
  2397. inf.close();
  2398. inf.open(opt.refinementfilename);
  2399. char ch;
  2400. for (i = 1; i <= mtets.Size(); i++)
  2401. {
  2402. inf >> ch;
  2403. if(!inf)
  2404. throw NgException("something wrong with refinementinfo file (old format)");
  2405. mtets.Elem(i).marked = (ch == '1');
  2406. }
  2407. marked = 1;
  2408. }
  2409. inf.close();
  2410. }
  2411. else if (opt.usemarkedelements)
  2412. {
  2413. int cntm = 0;
  2414. // all in one !
  2415. if (mprisms.Size())
  2416. {
  2417. int cnttet = 0;
  2418. int cntprism = 0;
  2419. for (i = 1; i <= mesh.GetNE(); i++)
  2420. {
  2421. if (mesh.VolumeElement(i).GetType() == TET ||
  2422. mesh.VolumeElement(i).GetType() == TET10)
  2423. {
  2424. cnttet++;
  2425. mtets.Elem(cnttet).marked =
  2426. 3 * mesh.VolumeElement(i).TestRefinementFlag();
  2427. if (mtets.Elem(cnttet).marked)
  2428. cntm++;
  2429. }
  2430. else
  2431. {
  2432. cntprism++;
  2433. mprisms.Elem(cntprism).marked =
  2434. 2 * mesh.VolumeElement(i).TestRefinementFlag();
  2435. if (mprisms.Elem(cntprism).marked)
  2436. cntm++;
  2437. }
  2438. }
  2439. }
  2440. else
  2441. for (i = 1; i <= mtets.Size(); i++)
  2442. {
  2443. mtets.Elem(i).marked =
  2444. 3 * mesh.VolumeElement(i).TestRefinementFlag();
  2445. if (mtets.Elem(i).marked)
  2446. cntm++;
  2447. }
  2448. // (*testout) << "mtets = " << mtets << endl;
  2449. /*
  2450. for (i = 1; i <= mtris.Size(); i++)
  2451. mtris.Elem(i).marked = 0;
  2452. for (i = 1; i <= mquads.Size(); i++)
  2453. mquads.Elem(i).marked = 0;
  2454. */
  2455. if (printmessage_importance>0)
  2456. {
  2457. ostringstream str;
  2458. str << "marked elements: " << cntm;
  2459. PrintMessage(4,str.str());
  2460. }
  2461. int cnttrig = 0;
  2462. int cntquad = 0;
  2463. for (i = 1; i <= mesh.GetNSE(); i++)
  2464. {
  2465. if (mesh.SurfaceElement(i).GetType() == TRIG ||
  2466. mesh.SurfaceElement(i).GetType() == TRIG6)
  2467. {
  2468. cnttrig++;
  2469. mtris.Elem(cnttrig).marked =
  2470. mesh.SurfaceElement(i).TestRefinementFlag() ? 2 : 0;
  2471. // mtris.Elem(cnttrig).marked = 0;
  2472. if (mtris.Elem(cnttrig).marked)
  2473. cntm++;
  2474. }
  2475. else
  2476. {
  2477. cntquad++;
  2478. // 2d: marked=2, 3d prisms: marked=1
  2479. mquads.Elem(cntquad).marked =
  2480. mesh.SurfaceElement(i).TestRefinementFlag() ? 4-mesh.GetDimension() : 0 ;
  2481. // mquads.Elem(cntquad).marked = 0;
  2482. if (mquads.Elem(cntquad).marked)
  2483. cntm++;
  2484. }
  2485. }
  2486. if (printmessage_importance>0)
  2487. {
  2488. ostringstream str;
  2489. str << "with surface-elements: " << cntm;
  2490. PrintMessage(4,str.str());
  2491. }
  2492. // he/sz: das wird oben schon richtig gemacht.
  2493. // hier sind die quads vergessen!
  2494. /*
  2495. if (mesh.GetDimension() == 2)
  2496. {
  2497. cntm = 0;
  2498. for (i = 1; i <= mtris.Size(); i++)
  2499. {
  2500. mtris.Elem(i).marked =
  2501. 2 * mesh.SurfaceElement(i).TestRefinementFlag();
  2502. // mtris.Elem(i).marked = 2;
  2503. if (mtris.Elem(i).marked)
  2504. cntm++;
  2505. }
  2506. if (!cntm)
  2507. {
  2508. for (i = 1; i <= mtris.Size(); i++)
  2509. {
  2510. mtris.Elem(i).marked = 2;
  2511. cntm++;
  2512. }
  2513. }
  2514. cout << "trigs: " << mtris.Size() << " ";
  2515. cout << "marked: " << cntm << endl;
  2516. }
  2517. */
  2518. marked = (cntm > 0);
  2519. }
  2520. else
  2521. {
  2522. marked = BTMarkTets (mtets, mprisms, mesh);
  2523. }
  2524. if (!marked) break;
  2525. //(*testout) << "mtets " << mtets << endl;
  2526. if (opt.refine_p)
  2527. {
  2528. PrintMessage(3,"refine p");
  2529. for (i = 1; i <= mtets.Size(); i++)
  2530. mtets.Elem(i).incorder = mtets.Elem(i).marked ? 1 : 0;
  2531. for (i = 1; i <= mtets.Size(); i++)
  2532. if (mtets.Elem(i).incorder)
  2533. mtets.Elem(i).marked = 0;
  2534. for (i = 1; i <= mprisms.Size(); i++)
  2535. mprisms.Elem(i).incorder = mprisms.Elem(i).marked ? 1 : 0;
  2536. for (i = 1; i <= mprisms.Size(); i++)
  2537. if (mprisms.Elem(i).incorder)
  2538. mprisms.Elem(i).marked = 0;
  2539. for (i = 1; i <= mtris.Size(); i++)
  2540. mtris.Elem(i).incorder = mtris.Elem(i).marked ? 1 : 0;
  2541. for (i = 1; i <= mtris.Size(); i++)
  2542. {
  2543. if (mtris.Elem(i).incorder)
  2544. mtris.Elem(i).marked = 0;
  2545. }
  2546. }
  2547. if (opt.refine_hp)
  2548. {
  2549. PrintMessage(3,"refine hp");
  2550. BitArray singv(np);
  2551. singv.Clear();
  2552. if (mesh.GetDimension() == 3)
  2553. {
  2554. for (i = 1; i <= mesh.GetNSeg(); i++)
  2555. {
  2556. const Segment & seg = mesh.LineSegment(i);
  2557. singv.Set (seg[0]);
  2558. singv.Set (seg[1]);
  2559. }
  2560. /*
  2561. for ( i=1; i<= mesh.GetNSE(); i++)
  2562. {
  2563. const Element2d & sel = mesh.SurfaceElement(i);
  2564. for(int j=1; j<=sel.GetNP(); j++)
  2565. singv.Set(sel.PNum(j));
  2566. }
  2567. */
  2568. }
  2569. else
  2570. {
  2571. // vertices with 2 different bnds
  2572. Array<int> bndind(np);
  2573. bndind = 0;
  2574. for (i = 1; i <= mesh.GetNSeg(); i++)
  2575. {
  2576. const Segment & seg = mesh.LineSegment(i);
  2577. for (j = 0; j < 2; j++)
  2578. {
  2579. int pi = (j == 0) ? seg[0] : seg[1];
  2580. if (bndind.Elem(pi) == 0)
  2581. bndind.Elem(pi) = seg.edgenr;
  2582. else if (bndind.Elem(pi) != seg.edgenr)
  2583. singv.Set (pi);
  2584. }
  2585. }
  2586. }
  2587. for (i = 1; i <= mtets.Size(); i++)
  2588. mtets.Elem(i).incorder = 1;
  2589. for (i = 1; i <= mtets.Size(); i++)
  2590. {
  2591. if (!mtets.Elem(i).marked)
  2592. mtets.Elem(i).incorder = 0;
  2593. for (j = 0; j < 4; j++)
  2594. if (singv.Test (mtets.Elem(i).pnums[j]))
  2595. mtets.Elem(i).incorder = 0;
  2596. }
  2597. for (i = 1; i <= mtets.Size(); i++)
  2598. if (mtets.Elem(i).incorder)
  2599. mtets.Elem(i).marked = 0;
  2600. for (i = 1; i <= mprisms.Size(); i++)
  2601. mprisms.Elem(i).incorder = 1;
  2602. for (i = 1; i <= mprisms.Size(); i++)
  2603. {
  2604. if (!mprisms.Elem(i).marked)
  2605. mprisms.Elem(i).incorder = 0;
  2606. for (j = 0; j < 6; j++)
  2607. if (singv.Test (mprisms.Elem(i).pnums[j]))
  2608. mprisms.Elem(i).incorder = 0;
  2609. }
  2610. for (i = 1; i <= mprisms.Size(); i++)
  2611. if (mprisms.Elem(i).incorder)
  2612. mprisms.Elem(i).marked = 0;
  2613. for (i = 1; i <= mtris.Size(); i++)
  2614. mtris.Elem(i).incorder = 1;
  2615. for (i = 1; i <= mtris.Size(); i++)
  2616. {
  2617. if (!mtris.Elem(i).marked)
  2618. mtris.Elem(i).incorder = 0;
  2619. for (j = 0; j < 3; j++)
  2620. if (singv.Test (mtris.Elem(i).pnums[j]))
  2621. mtris.Elem(i).incorder = 0;
  2622. }
  2623. for (i = 1; i <= mtris.Size(); i++)
  2624. {
  2625. if (mtris.Elem(i).incorder)
  2626. mtris.Elem(i).marked = 0;
  2627. }
  2628. }
  2629. int hangingvol, hangingsurf, hangingedge;
  2630. //cout << "write?" << endl;
  2631. //string yn;
  2632. //cin >> yn;
  2633. (*testout) << "refine volume elements" << endl;
  2634. do
  2635. {
  2636. // refine volume elements
  2637. int nel = mtets.Size();
  2638. for (i = 1; i <= nel; i++)
  2639. if (mtets.Elem(i).marked)
  2640. {
  2641. MarkedTet oldtet;
  2642. MarkedTet newtet1, newtet2;
  2643. int newp;
  2644. oldtet = mtets.Get(i);
  2645. //if(yn == "y")
  2646. // (*testout) << "bisected tet " << oldtet;
  2647. INDEX_2 edge(oldtet.pnums[oldtet.tetedge1],
  2648. oldtet.pnums[oldtet.tetedge2]);
  2649. edge.Sort();
  2650. if (cutedges.Used (edge))
  2651. {
  2652. newp = cutedges.Get(edge);
  2653. }
  2654. else
  2655. {
  2656. Point<3> npt = Center (mesh.Point (edge.I1()),
  2657. mesh.Point (edge.I2()));
  2658. newp = mesh.AddPoint (npt);
  2659. cutedges.Set (edge, newp);
  2660. }
  2661. BTBisectTet (oldtet, newp, newtet1, newtet2);
  2662. mtets.Elem(i) = newtet1;
  2663. mtets.Append (newtet2);
  2664. #ifdef DEBUG
  2665. *testout << "tet1 has elnr = " << i << ", tet2 has elnr = " << mtets.Size() << endl;
  2666. #endif
  2667. //if(yn == "y")
  2668. // (*testout) << "and got " << newtet1 << "and " << newtet2 << endl;
  2669. mesh.mlparentelement.Append (i);
  2670. }
  2671. int npr = mprisms.Size();
  2672. for (i = 1; i <= npr; i++)
  2673. if (mprisms.Elem(i).marked)
  2674. {
  2675. MarkedPrism oldprism;
  2676. MarkedPrism newprism1, newprism2;
  2677. int newp1, newp2;
  2678. oldprism = mprisms.Get(i);
  2679. int pi1 = 0;
  2680. if (pi1 == oldprism.markededge)
  2681. pi1++;
  2682. int pi2 = 3-pi1-oldprism.markededge;
  2683. INDEX_2 edge1(oldprism.pnums[pi1],
  2684. oldprism.pnums[pi2]);
  2685. INDEX_2 edge2(oldprism.pnums[pi1+3],
  2686. oldprism.pnums[pi2+3]);
  2687. edge1.Sort();
  2688. edge2.Sort();
  2689. if (cutedges.Used (edge1))
  2690. newp1 = cutedges.Get(edge1);
  2691. else
  2692. {
  2693. Point<3> npt = Center (mesh.Point (edge1.I1()),
  2694. mesh.Point (edge1.I2()));
  2695. newp1 = mesh.AddPoint (npt);
  2696. cutedges.Set (edge1, newp1);
  2697. }
  2698. if (cutedges.Used (edge2))
  2699. newp2 = cutedges.Get(edge2);
  2700. else
  2701. {
  2702. Point<3> npt = Center (mesh.Point (edge2.I1()),
  2703. mesh.Point (edge2.I2()));
  2704. newp2 = mesh.AddPoint (npt);
  2705. cutedges.Set (edge2, newp2);
  2706. }
  2707. BTBisectPrism (oldprism, newp1, newp2, newprism1, newprism2);
  2708. //if(yn == "y")
  2709. // (*testout) << "bisected prism " << oldprism << "and got " << newprism1 << "and " << newprism2 << endl;
  2710. mprisms.Elem(i) = newprism1;
  2711. mprisms.Append (newprism2);
  2712. }
  2713. int nid = mids.Size();
  2714. for (i = 1; i <= nid; i++)
  2715. if (mids.Elem(i).marked)
  2716. {
  2717. MarkedIdentification oldid,newid1,newid2;
  2718. Array<int> newp;
  2719. oldid = mids.Get(i);
  2720. Array<INDEX_2> edges;
  2721. edges.Append(INDEX_2(oldid.pnums[oldid.markededge],
  2722. oldid.pnums[(oldid.markededge+1)%oldid.np]));
  2723. edges.Append(INDEX_2(oldid.pnums[oldid.markededge + oldid.np],
  2724. oldid.pnums[(oldid.markededge+1)%oldid.np + oldid.np]));
  2725. if(oldid.np == 4)
  2726. {
  2727. edges.Append(INDEX_2(oldid.pnums[(oldid.markededge+2)%oldid.np],
  2728. oldid.pnums[(oldid.markededge+3)%oldid.np]));
  2729. edges.Append(INDEX_2(oldid.pnums[(oldid.markededge+2)%oldid.np + oldid.np],
  2730. oldid.pnums[(oldid.markededge+3)%oldid.np + oldid.np]));
  2731. }
  2732. for (j = 0; j < edges.Size(); j++)
  2733. {
  2734. edges[j].Sort();
  2735. if(cutedges.Used(edges[j]))
  2736. newp.Append(cutedges.Get(edges[j]));
  2737. else
  2738. {
  2739. Point<3> npt = Center (mesh.Point (edges[j].I1()),
  2740. mesh.Point (edges[j].I2()));
  2741. newp.Append(mesh.AddPoint(npt));
  2742. cutedges.Set(edges[j],newp[j]);
  2743. }
  2744. }
  2745. BTBisectIdentification(oldid,newp,newid1,newid2);
  2746. mids.Elem(i) = newid1;
  2747. mids.Append(newid2);
  2748. }
  2749. //IdentifyCutEdges(mesh, cutedges);
  2750. hangingvol =
  2751. MarkHangingTets (mtets, cutedges) +
  2752. MarkHangingPrisms (mprisms, cutedges) +
  2753. MarkHangingIdentifications (mids, cutedges);
  2754. int nsel = mtris.Size();
  2755. for (i = 1; i <= nsel; i++)
  2756. if (mtris.Elem(i).marked)
  2757. {
  2758. MarkedTri oldtri;
  2759. MarkedTri newtri1, newtri2;
  2760. PointIndex newp;
  2761. oldtri = mtris.Get(i);
  2762. int oldpi1 = oldtri.pnums[(oldtri.markededge+1)%3];
  2763. int oldpi2 = oldtri.pnums[(oldtri.markededge+2)%3];
  2764. INDEX_2 edge(oldpi1, oldpi2);
  2765. edge.Sort();
  2766. // cerr << "edge = " << edge.I1() << "-" << edge.I2() << endl;
  2767. if (cutedges.Used (edge))
  2768. {
  2769. newp = cutedges.Get(edge);
  2770. }
  2771. else
  2772. {
  2773. Point<3> npt = Center (mesh.Point (edge.I1()),
  2774. mesh.Point (edge.I2()));
  2775. newp = mesh.AddPoint (npt);
  2776. cutedges.Set (edge, newp);
  2777. }
  2778. // newp = cutedges.Get(edge);
  2779. int si = mesh.GetFaceDescriptor (oldtri.surfid).SurfNr();
  2780. // geom->GetSurface(si)->Project (mesh.Point(newp));
  2781. PointGeomInfo npgi;
  2782. // cerr << "project point " << newp << " old: " << mesh.Point(newp);
  2783. if (mesh[newp].Type() != EDGEPOINT)
  2784. PointBetween (mesh.Point (oldpi1), mesh.Point (oldpi2),
  2785. 0.5, si,
  2786. oldtri.pgeominfo[(oldtri.markededge+1)%3],
  2787. oldtri.pgeominfo[(oldtri.markededge+2)%3],
  2788. mesh.Point (newp), npgi);
  2789. // cerr << " new: " << mesh.Point(newp) << endl;
  2790. BTBisectTri (oldtri, newp, npgi, newtri1, newtri2);
  2791. //if(yn == "y")
  2792. // (*testout) << "bisected tri " << oldtri << "and got " << newtri1 << "and " << newtri2 << endl;
  2793. mtris.Elem(i) = newtri1;
  2794. mtris.Append (newtri2);
  2795. mesh.mlparentsurfaceelement.Append (i);
  2796. }
  2797. int nquad = mquads.Size();
  2798. for (i = 1; i <= nquad; i++)
  2799. if (mquads.Elem(i).marked)
  2800. {
  2801. MarkedQuad oldquad;
  2802. MarkedQuad newquad1, newquad2;
  2803. int newp1, newp2;
  2804. oldquad = mquads.Get(i);
  2805. /*
  2806. INDEX_2 edge1(oldquad.pnums[0],
  2807. oldquad.pnums[1]);
  2808. INDEX_2 edge2(oldquad.pnums[2],
  2809. oldquad.pnums[3]);
  2810. */
  2811. INDEX_2 edge1, edge2;
  2812. PointGeomInfo pgi11, pgi12, pgi21, pgi22;
  2813. if (oldquad.markededge==0 || oldquad.markededge==2)
  2814. {
  2815. edge1.I1()=oldquad.pnums[0]; pgi11=oldquad.pgeominfo[0];
  2816. edge1.I2()=oldquad.pnums[1]; pgi12=oldquad.pgeominfo[1];
  2817. edge2.I1()=oldquad.pnums[2]; pgi21=oldquad.pgeominfo[2];
  2818. edge2.I2()=oldquad.pnums[3]; pgi22=oldquad.pgeominfo[3];
  2819. }
  2820. else // 3 || 1
  2821. {
  2822. edge1.I1()=oldquad.pnums[0]; pgi11=oldquad.pgeominfo[0];
  2823. edge1.I2()=oldquad.pnums[2]; pgi12=oldquad.pgeominfo[2];
  2824. edge2.I1()=oldquad.pnums[1]; pgi21=oldquad.pgeominfo[1];
  2825. edge2.I2()=oldquad.pnums[3]; pgi22=oldquad.pgeominfo[3];
  2826. }
  2827. edge1.Sort();
  2828. edge2.Sort();
  2829. if (cutedges.Used (edge1))
  2830. {
  2831. newp1 = cutedges.Get(edge1);
  2832. }
  2833. else
  2834. {
  2835. Point<3> np1 = Center (mesh.Point (edge1.I1()),
  2836. mesh.Point (edge1.I2()));
  2837. newp1 = mesh.AddPoint (np1);
  2838. cutedges.Set (edge1, newp1);
  2839. }
  2840. if (cutedges.Used (edge2))
  2841. {
  2842. newp2 = cutedges.Get(edge2);
  2843. }
  2844. else
  2845. {
  2846. Point<3> np2 = Center (mesh.Point (edge2.I1()),
  2847. mesh.Point (edge2.I2()));
  2848. newp2 = mesh.AddPoint (np2);
  2849. cutedges.Set (edge2, newp2);
  2850. }
  2851. PointGeomInfo npgi1, npgi2;
  2852. int si = mesh.GetFaceDescriptor (oldquad.surfid).SurfNr();
  2853. // geom->GetSurface(si)->Project (mesh.Point(newp1));
  2854. // geom->GetSurface(si)->Project (mesh.Point(newp2));
  2855. // (*testout)
  2856. // cerr << "project point 1 " << newp1 << " old: " << mesh.Point(newp1);
  2857. PointBetween (mesh.Point (edge1.I1()), mesh.Point (edge1.I2()),
  2858. 0.5, si,
  2859. pgi11,
  2860. pgi12,
  2861. mesh.Point (newp1), npgi1);
  2862. // (*testout)
  2863. // cerr << " new: " << mesh.Point(newp1) << endl;
  2864. // cerr << "project point 2 " << newp2 << " old: " << mesh.Point(newp2);
  2865. PointBetween (mesh.Point (edge2.I1()), mesh.Point (edge2.I2()),
  2866. 0.5, si,
  2867. pgi21,
  2868. pgi22,
  2869. mesh.Point (newp2), npgi2);
  2870. // cerr << " new: " << mesh.Point(newp2) << endl;
  2871. BTBisectQuad (oldquad, newp1, npgi1, newp2, npgi2,
  2872. newquad1, newquad2);
  2873. mquads.Elem(i) = newquad1;
  2874. mquads.Append (newquad2);
  2875. }
  2876. hangingsurf =
  2877. MarkHangingTris (mtris, cutedges) +
  2878. MarkHangingQuads (mquads, cutedges);
  2879. hangingedge = 0;
  2880. int nseg = mesh.GetNSeg ();
  2881. for (i = 1; i <= nseg; i++)
  2882. {
  2883. Segment & seg = mesh.LineSegment (i);
  2884. INDEX_2 edge(seg[0], seg[1]);
  2885. edge.Sort();
  2886. if (cutedges.Used (edge))
  2887. {
  2888. hangingedge = 1;
  2889. Segment nseg1 = seg;
  2890. Segment nseg2 = seg;
  2891. int newpi = cutedges.Get(edge);
  2892. nseg1[1] = newpi;
  2893. nseg2[0] = newpi;
  2894. EdgePointGeomInfo newepgi;
  2895. //
  2896. // cerr << "move edgepoint " << newpi << " from " << mesh.Point(newpi);
  2897. PointBetween (mesh.Point (seg[0]), mesh.Point (seg[1]),
  2898. 0.5, seg.surfnr1, seg.surfnr2,
  2899. seg.epgeominfo[0], seg.epgeominfo[1],
  2900. mesh.Point (newpi), newepgi);
  2901. // cerr << " to " << mesh.Point (newpi) << endl;
  2902. nseg1.epgeominfo[1] = newepgi;
  2903. nseg2.epgeominfo[0] = newepgi;
  2904. mesh.LineSegment (i) = nseg1;
  2905. mesh.AddSegment (nseg2);
  2906. }
  2907. }
  2908. }
  2909. while (hangingvol || hangingsurf || hangingedge);
  2910. /*
  2911. if (printmessage_importance>0)
  2912. {
  2913. ostringstream strstr;
  2914. strstr << mtets.Size() << " tets" << endl
  2915. << mtris.Size() << " trigs" << endl;
  2916. if (mprisms.Size())
  2917. {
  2918. strstr << mprisms.Size() << " prisms" << endl
  2919. << mquads.Size() << " quads" << endl;
  2920. }
  2921. strstr << mesh.GetNP() << " points";
  2922. PrintMessage(4,strstr.str());
  2923. }
  2924. */
  2925. PrintMessage (4, mtets.Size(), " tets");
  2926. PrintMessage (4, mtris.Size(), " trigs");
  2927. if (mprisms.Size())
  2928. {
  2929. PrintMessage (4, mprisms.Size(), " prisms");
  2930. PrintMessage (4, mquads.Size(), " quads");
  2931. }
  2932. PrintMessage (4, mesh.GetNP(), " points");
  2933. }
  2934. // (*testout) << "mtets = " << mtets << endl;
  2935. if (opt.refine_hp)
  2936. {
  2937. //
  2938. Array<int> v_order (mesh.GetNP());
  2939. v_order = 0;
  2940. if (mesh.GetDimension() == 3)
  2941. {
  2942. for (i = 1; i <= mtets.Size(); i++)
  2943. if (mtets.Elem(i).incorder)
  2944. mtets.Elem(i).order++;
  2945. for (i = 0; i < mtets.Size(); i++)
  2946. for (j = 0; j < 4; j++)
  2947. if (int(mtets[i].order) > v_order.Elem(mtets[i].pnums[j]))
  2948. v_order.Elem(mtets[i].pnums[j]) = mtets[i].order;
  2949. for (i = 0; i < mtets.Size(); i++)
  2950. for (j = 0; j < 4; j++)
  2951. if (int(mtets[i].order) < v_order.Elem(mtets[i].pnums[j])-1)
  2952. mtets[i].order = v_order.Elem(mtets[i].pnums[j])-1;
  2953. }
  2954. else
  2955. {
  2956. for (i = 1; i <= mtris.Size(); i++)
  2957. if (mtris.Elem(i).incorder)
  2958. {
  2959. mtris.Elem(i).order++;
  2960. }
  2961. for (i = 0; i < mtris.Size(); i++)
  2962. for (j = 0; j < 3; j++)
  2963. if (int(mtris[i].order) > v_order.Elem(mtris[i].pnums[j]))
  2964. v_order.Elem(mtris[i].pnums[j]) = mtris[i].order;
  2965. for (i = 0; i < mtris.Size(); i++)
  2966. {
  2967. for (j = 0; j < 3; j++)
  2968. if (int(mtris[i].order) < v_order.Elem(mtris[i].pnums[j])-1)
  2969. mtris[i].order = v_order.Elem(mtris[i].pnums[j])-1;
  2970. }
  2971. }
  2972. }
  2973. mtets.SetAllocSize (mtets.Size());
  2974. mprisms.SetAllocSize (mprisms.Size());
  2975. mids.SetAllocSize (mids.Size());
  2976. mtris.SetAllocSize (mtris.Size());
  2977. mquads.SetAllocSize (mquads.Size());
  2978. mesh.ClearVolumeElements();
  2979. mesh.VolumeElements().SetAllocSize (mtets.Size()+mprisms.Size());
  2980. for (i = 1; i <= mtets.Size(); i++)
  2981. {
  2982. Element el(TET);
  2983. el.SetIndex (mtets.Get(i).matindex);
  2984. for (j = 1; j <= 4; j++)
  2985. el.PNum(j) = mtets.Get(i).pnums[j-1];
  2986. el.SetOrder (mtets.Get(i).order);
  2987. mesh.AddVolumeElement (el);
  2988. }
  2989. for (i = 1; i <= mprisms.Size(); i++)
  2990. {
  2991. Element el(PRISM);
  2992. el.SetIndex (mprisms.Get(i).matindex);
  2993. for (j = 1; j <= 6; j++)
  2994. el.PNum(j) = mprisms.Get(i).pnums[j-1];
  2995. el.SetOrder (mprisms.Get(i).order);
  2996. // degenerated prism ?
  2997. static const int map1[] = { 3, 2, 5, 6, 1 };
  2998. static const int map2[] = { 1, 3, 6, 4, 2 };
  2999. static const int map3[] = { 2, 1, 4, 5, 3 };
  3000. const int * map = NULL;
  3001. int deg1 = 0, deg2 = 0, deg3 = 0;
  3002. // int deg = 0;
  3003. if (el.PNum(1) == el.PNum(4)) { map = map1; deg1 = 1; }
  3004. if (el.PNum(2) == el.PNum(5)) { map = map2; deg2 = 1; }
  3005. if (el.PNum(3) == el.PNum(6)) { map = map3; deg3 = 1; }
  3006. switch (deg1+deg2+deg3)
  3007. {
  3008. case 1:
  3009. {
  3010. for (j = 1; j <= 5; j++)
  3011. el.PNum(j) = mprisms.Get(i).pnums[map[j-1]-1];
  3012. el.SetType (PYRAMID);
  3013. break;
  3014. }
  3015. case 2:
  3016. {
  3017. static const int tetmap1[] = { 1, 2, 3, 4 };
  3018. static const int tetmap2[] = { 2, 3, 1, 5 };
  3019. static const int tetmap3[] = { 3, 1, 2, 6 };
  3020. if (!deg1) map = tetmap1;
  3021. if (!deg2) map = tetmap2;
  3022. if (!deg3) map = tetmap3;
  3023. for (j = 1; j <= 4; j++)
  3024. el.PNum(j) = mprisms.Get(i).pnums[map[j-1]-1];
  3025. /*
  3026. if (!deg1) el.PNum(4) = el.PNum(4);
  3027. if (!deg2) el.PNum(4) = el.PNum(5);
  3028. if (!deg3) el.PNum(4) = el.PNum(6);
  3029. */
  3030. el.SetType(TET);
  3031. break;
  3032. }
  3033. default:
  3034. ;
  3035. }
  3036. mesh.AddVolumeElement (el);
  3037. }
  3038. mesh.ClearSurfaceElements();
  3039. for (i = 1; i <= mtris.Size(); i++)
  3040. {
  3041. Element2d el(TRIG);
  3042. el.SetIndex (mtris.Get(i).surfid);
  3043. el.SetOrder (mtris.Get(i).order);
  3044. for (j = 1; j <= 3; j++)
  3045. {
  3046. el.PNum(j) = mtris.Get(i).pnums[j-1];
  3047. el.GeomInfoPi(j) = mtris.Get(i).pgeominfo[j-1];
  3048. }
  3049. mesh.AddSurfaceElement (el);
  3050. }
  3051. for (i = 1; i <= mquads.Size(); i++)
  3052. {
  3053. Element2d el(QUAD);
  3054. el.SetIndex (mquads.Get(i).surfid);
  3055. for (j = 1; j <= 4; j++)
  3056. el.PNum(j) = mquads.Get(i).pnums[j-1];
  3057. Swap (el.PNum(3), el.PNum(4));
  3058. mesh.AddSurfaceElement (el);
  3059. }
  3060. // write multilevel hierarchy to mesh:
  3061. np = mesh.GetNP();
  3062. mesh.mlbetweennodes.SetSize(np);
  3063. if (mesh.mglevels <= 2)
  3064. {
  3065. PrintMessage(4,"RESETTING mlbetweennodes");
  3066. for (i = 1; i <= np; i++)
  3067. {
  3068. mesh.mlbetweennodes.Elem(i).I1() = 0;
  3069. mesh.mlbetweennodes.Elem(i).I2() = 0;
  3070. }
  3071. }
  3072. /*
  3073. for (i = 1; i <= cutedges.GetNBags(); i++)
  3074. for (j = 1; j <= cutedges.GetBagSize(i); j++)
  3075. {
  3076. INDEX_2 edge;
  3077. int newpi;
  3078. cutedges.GetData (i, j, edge, newpi);
  3079. mesh.mlbetweennodes.Elem(newpi) = edge;
  3080. }
  3081. */
  3082. BitArray isnewpoint(np);
  3083. isnewpoint.Clear();
  3084. for (i = 1; i <= cutedges.Size(); i++)
  3085. if (cutedges.UsedPos(i))
  3086. {
  3087. INDEX_2 edge;
  3088. int newpi;
  3089. cutedges.GetData (i, edge, newpi);
  3090. isnewpoint.Set(newpi);
  3091. mesh.mlbetweennodes.Elem(newpi) = edge;
  3092. }
  3093. /*
  3094. mesh.PrintMemInfo (cout);
  3095. cout << "tets ";
  3096. mtets.PrintMemInfo (cout);
  3097. cout << "prims ";
  3098. mprisms.PrintMemInfo (cout);
  3099. cout << "tris ";
  3100. mtris.PrintMemInfo (cout);
  3101. cout << "quads ";
  3102. mquads.PrintMemInfo (cout);
  3103. cout << "cutedges ";
  3104. cutedges.PrintMemInfo (cout);
  3105. */
  3106. /*
  3107. // find connected nodes (close nodes)
  3108. TABLE<int> conto(np);
  3109. for (i = 1; i <= mprisms.Size(); i++)
  3110. for (j = 1; j <= 6; j++)
  3111. {
  3112. int n1 = mprisms.Get(i).pnums[j-1];
  3113. int n2 = mprisms.Get(i).pnums[(j+2)%6];
  3114. // if (n1 != n2)
  3115. {
  3116. int found = 0;
  3117. for (k = 1; k <= conto.EntrySize(n1); k++)
  3118. if (conto.Get(n1, k) == n2)
  3119. {
  3120. found = 1;
  3121. break;
  3122. }
  3123. if (!found)
  3124. conto.Add (n1, n2);
  3125. }
  3126. }
  3127. mesh.connectedtonode.SetSize(np);
  3128. for (i = 1; i <= np; i++)
  3129. mesh.connectedtonode.Elem(i) = 0;
  3130. // (*testout) << "connection table: " << endl;
  3131. // for (i = 1; i <= np; i++)
  3132. // {
  3133. // (*testout) << "node " << i << ": ";
  3134. // for (j = 1; j <= conto.EntrySize(i); j++)
  3135. // (*testout) << conto.Get(i, j) << " ";
  3136. // (*testout) << endl;
  3137. // }
  3138. for (i = 1; i <= np; i++)
  3139. if (mesh.connectedtonode.Elem(i) == 0)
  3140. {
  3141. mesh.connectedtonode.Elem(i) = i;
  3142. ConnectToNodeRec (i, i, conto, mesh.connectedtonode);
  3143. }
  3144. */
  3145. // mesh.BuildConnectedNodes();
  3146. mesh.ComputeNVertices();
  3147. mesh.RebuildSurfaceElementLists();
  3148. // update identification tables
  3149. for (i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++)
  3150. {
  3151. Array<int,PointIndex::BASE> identmap;
  3152. mesh.GetIdentifications().GetMap (i, identmap);
  3153. /*
  3154. for (j = 1; j <= cutedges.GetNBags(); j++)
  3155. for (k = 1; k <= cutedges.GetBagSize(j); k++)
  3156. {
  3157. INDEX_2 i2;
  3158. int newpi;
  3159. cutedges.GetData (j, k, i2, newpi);
  3160. INDEX_2 oi2(identmap.Get(i2.I1()),
  3161. identmap.Get(i2.I2()));
  3162. oi2.Sort();
  3163. if (cutedges.Used (oi2))
  3164. {
  3165. int onewpi = cutedges.Get(oi2);
  3166. mesh.GetIdentifications().Add (newpi, onewpi, i);
  3167. }
  3168. }
  3169. */
  3170. for (j = 1; j <= cutedges.Size(); j++)
  3171. if (cutedges.UsedPos(j))
  3172. {
  3173. INDEX_2 i2;
  3174. int newpi;
  3175. cutedges.GetData (j, i2, newpi);
  3176. INDEX_2 oi2(identmap.Get(i2.I1()),
  3177. identmap.Get(i2.I2()));
  3178. oi2.Sort();
  3179. if (cutedges.Used (oi2))
  3180. {
  3181. int onewpi = cutedges.Get(oi2);
  3182. mesh.GetIdentifications().Add (newpi, onewpi, i);
  3183. }
  3184. }
  3185. }
  3186. // Repair works only for tets!
  3187. bool do_repair = mesh.PureTetMesh ();
  3188. do_repair = false; // JS, March 2009: multigrid crashes
  3189. //if(mesh.mglevels == 3)
  3190. // noprojection = true;
  3191. //noprojection = true;
  3192. if(noprojection)
  3193. {
  3194. do_repair = false;
  3195. for(int ii=1; ii<=mesh.GetNP(); ii++)
  3196. {
  3197. if(isnewpoint.Test(ii) && mesh.mlbetweennodes[ii][0] > 0)
  3198. {
  3199. mesh.Point(ii) = Center(mesh.Point(mesh.mlbetweennodes[ii][0]),
  3200. mesh.Point(mesh.mlbetweennodes[ii][1]));
  3201. }
  3202. }
  3203. }
  3204. // Check/Repair
  3205. static bool repaired_once;
  3206. if(mesh.mglevels == 1)
  3207. repaired_once = false;
  3208. //mesh.Save("before.vol");
  3209. static int reptimer = NgProfiler::CreateTimer("check/repair");
  3210. NgProfiler::RegionTimer * regt(NULL);
  3211. regt = new NgProfiler::RegionTimer(reptimer);
  3212. Array<ElementIndex> bad_elts;
  3213. Array<double> pure_badness;
  3214. if(do_repair || quality_loss != NULL)
  3215. {
  3216. pure_badness.SetSize(mesh.GetNP()+2);
  3217. GetPureBadness(mesh,pure_badness,isnewpoint);
  3218. }
  3219. if(do_repair) // by Markus W
  3220. {
  3221. const double max_worsening = 1;
  3222. const bool uselocalworsening = false;
  3223. bool repaired = false;
  3224. Validate(mesh,bad_elts,pure_badness,max_worsening,uselocalworsening);
  3225. if (printmessage_importance>0)
  3226. {
  3227. ostringstream strstr;
  3228. for(int ii=0; ii<bad_elts.Size(); ii++)
  3229. strstr << "bad element " << bad_elts[ii] << "\n";
  3230. PrintMessage(1,strstr.str());
  3231. }
  3232. if(repaired_once || bad_elts.Size() > 0)
  3233. {
  3234. clock_t t1(clock());
  3235. // update id-maps
  3236. j=0;
  3237. for(i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)
  3238. {
  3239. if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC)
  3240. {
  3241. mesh.GetIdentifications().GetMap(i,*idmaps[j],true);
  3242. j++;
  3243. }
  3244. }
  3245. // do the repair
  3246. try
  3247. {
  3248. RepairBisection(mesh,bad_elts,isnewpoint,*this,
  3249. pure_badness,
  3250. max_worsening,uselocalworsening,
  3251. idmaps);
  3252. repaired = true;
  3253. repaired_once = true;
  3254. }
  3255. catch(NgException & ex)
  3256. {
  3257. PrintMessage(1,string("Problem: ") + ex.What());
  3258. }
  3259. if (printmessage_importance>0)
  3260. {
  3261. ostringstream strstr;
  3262. strstr << "Time for Repair: " << double(clock() - t1)/double(CLOCKS_PER_SEC) << endl
  3263. << "bad elements after repair: " << bad_elts << endl;
  3264. PrintMessage(1,strstr.str());
  3265. }
  3266. if(quality_loss != NULL)
  3267. Validate(mesh,bad_elts,pure_badness,1e100,uselocalworsening,quality_loss);
  3268. if(idmaps.Size() == 0)
  3269. UpdateEdgeMarks(mesh,idmaps);
  3270. /*
  3271. if(1==1)
  3272. UpdateEdgeMarks(mesh,idmaps);
  3273. else
  3274. mesh.mglevels = 1;
  3275. */
  3276. //mesh.ImproveMesh();
  3277. }
  3278. }
  3279. delete regt;
  3280. for(i=0; i<idmaps.Size(); i++)
  3281. delete idmaps[i];
  3282. idmaps.DeleteAll();
  3283. mesh.UpdateTopology();
  3284. if(refelementinfofilewrite != "")
  3285. {
  3286. PrintMessage(3,"writing marked-elements information to \"",refelementinfofilewrite,"\"");
  3287. ofstream ofst(refelementinfofilewrite.c_str());
  3288. WriteMarkedElements(ofst);
  3289. ofst.close();
  3290. }
  3291. mesh.CalcSurfacesOfNode();
  3292. PrintMessage (1, "Bisection done");
  3293. PopStatus();
  3294. }
  3295. BisectionOptions :: BisectionOptions ()
  3296. {
  3297. outfilename = NULL;
  3298. mlfilename = NULL;
  3299. refinementfilename = NULL;
  3300. femcode = NULL;
  3301. maxlevel = 50;
  3302. usemarkedelements = 0;
  3303. refine_hp = 0;
  3304. refine_p = 0;
  3305. }
  3306. Refinement :: Refinement ()
  3307. {
  3308. optimizer2d = NULL;
  3309. }
  3310. Refinement :: ~Refinement ()
  3311. {
  3312. ;
  3313. }
  3314. void Refinement :: PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint,
  3315. int surfi,
  3316. const PointGeomInfo & gi1,
  3317. const PointGeomInfo & gi2,
  3318. Point<3> & newp, PointGeomInfo & newgi) const
  3319. {
  3320. newp = p1+secpoint*(p2-p1);
  3321. }
  3322. void Refinement :: PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint,
  3323. int surfi1, int surfi2,
  3324. const EdgePointGeomInfo & ap1,
  3325. const EdgePointGeomInfo & ap2,
  3326. Point<3> & newp, EdgePointGeomInfo & newgi) const
  3327. {
  3328. cout << "base class edge point between" << endl;
  3329. newp = p1+secpoint*(p2-p1);
  3330. }
  3331. Vec<3> Refinement :: GetTangent (const Point<3> & p, int surfi1, int surfi2,
  3332. const EdgePointGeomInfo & ap1) const
  3333. {
  3334. cerr << "Refinement::GetTangent not overloaded" << endl;
  3335. return Vec<3> (0,0,0);
  3336. }
  3337. Vec<3> Refinement :: GetNormal (const Point<3> & p, int surfi1,
  3338. const PointGeomInfo & gi) const
  3339. {
  3340. cerr << "Refinement::GetNormal not overloaded" << endl;
  3341. return Vec<3> (0,0,0);
  3342. }
  3343. void Refinement :: ProjectToSurface (Point<3> & p, int surfi) const
  3344. {
  3345. if (printmessage_importance>0)
  3346. cerr << "Refinement :: ProjectToSurface ERROR: no geometry set" << endl;
  3347. };
  3348. void Refinement :: ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const
  3349. {
  3350. cerr << "Refinement::ProjectToEdge not overloaded" << endl;
  3351. }
  3352. }