Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/bisect.cpp
3206 views
#include <mystdlib.h>1#include "meshing.hpp"23#define noDEBUG456namespace netgen7{8//#include "../interface/writeuser.hpp"9class MarkedTet;10class MarkedPrism;11class MarkedIdentification;12class MarkedTri;13class MarkedQuad;1415typedef MoveableArray<MarkedTet> T_MTETS;16typedef MoveableArray<MarkedPrism> T_MPRISMS;17typedef MoveableArray<MarkedIdentification> T_MIDS;18typedef MoveableArray<MarkedTri> T_MTRIS;19typedef MoveableArray<MarkedQuad> T_MQUADS;20212223class MarkedTet24{25public:26/// pnums of tet27PointIndex pnums[4];28/// material number29int matindex;30/// element marked for refinement31/// marked = 1: marked by element marker, marked = 2 due to closure32unsigned int marked:2;33/// flag of Arnold-Mukherjee algorithm34unsigned int flagged:1;35/// tetedge (local coordinates 0..3)36unsigned int tetedge1:3;37unsigned int tetedge2:3;38// marked edge of faces39// face_j : face without node j,40// mark_k : edge without node k4142char faceedges[4];43// unsigned char faceedges[4];44bool incorder;45unsigned int order:6;4647MarkedTet()48{49for (int i = 0; i < 4; i++) { faceedges[i] = 255; }50}51};5253ostream & operator<< (ostream & ost, const MarkedTet & mt)54{55for(int i=0; i<4; i++)56ost << mt.pnums[i] << " ";5758ost << mt.matindex << " " << int(mt.marked) << " " << int(mt.flagged) << " " << int(mt.tetedge1) << " " << int(mt.tetedge2) << " ";5960ost << "faceedges = ";61for(int i=0; i<4; i++)62ost << int(mt.faceedges[i]) << " ";6364ost << " order = ";65ost << mt.incorder << " " << int(mt.order) << "\n";66return ost;67}68istream & operator>> (istream & ost, MarkedTet & mt)69{70for(int i=0; i<4; i++)71ost >> mt.pnums[i];7273ost >> mt.matindex;7475int auxint;76ost >> auxint;77mt.marked = auxint;78ost >> auxint;79mt.flagged = auxint;80ost >> auxint;81mt.tetedge1 = auxint;82ost >> auxint;83mt.tetedge2 = auxint;8485char auxchar;8687for(int i=0; i<4; i++)88{89ost >> auxchar;90mt.faceedges[i] = auxchar;91}9293ost >> mt.incorder;94ost >> auxint;95mt.order = auxint;96return ost;97}9899class MarkedPrism100{101public:102/// 6 point numbers103PointIndex pnums[6];104/// material number105int matindex;106/// marked for refinement107int marked;108/// edge without node k (0,1,2)109int markededge;110111bool incorder;112unsigned int order:6;113};114115116ostream & operator<< (ostream & ost, const MarkedPrism & mp)117{118for(int i=0; i<6; i++)119ost << mp.pnums[i] << " ";120121ost << mp.matindex << " " << mp.marked << " " << mp.markededge << " " << mp.incorder << " " << int(mp.order) << "\n";122return ost;123}124istream & operator>> (istream & ist, MarkedPrism & mp)125{126for(int i=0; i<6; i++)127ist >> mp.pnums[i];128129ist >> mp.matindex >> mp.marked >> mp.markededge >> mp.incorder;130int auxint;131ist >> auxint;132mp.order = auxint;133return ist;134}135136137class MarkedIdentification138{139public:140// number of points of one face (3 or 4)141int np;142/// 6 or 8 point numbers143PointIndex pnums[8];144/// marked for refinement145int marked;146/// edge starting with node k (0,1,2, or 3)147int markededge;148149bool incorder;150unsigned int order:6;151};152153154ostream & operator<< (ostream & ost, const MarkedIdentification & mi)155{156ost << mi.np << " ";157for(int i=0; i<2*mi.np; i++)158ost << mi.pnums[i] << " ";159ost << mi.marked << " " << mi.markededge << " " << mi.incorder << " " << int(mi.order) << "\n";160return ost;161}162istream & operator>> (istream & ist, MarkedIdentification & mi)163{164ist >> mi.np;165for(int i=0; i<2*mi.np; i++)166ist >> mi.pnums[i];167ist >> mi.marked >> mi.markededge >> mi.incorder;168int auxint;169ist >> auxint;170mi.order = auxint;171return ist;172}173174175176177178class MarkedTri179{180public:181/// three point numbers182PointIndex pnums[3];183/// three geominfos184PointGeomInfo pgeominfo[3];185/// marked for refinement186int marked;187/// edge without node k188int markededge;189/// surface id190int surfid;191192bool incorder;193unsigned int order:6;194};195196ostream & operator<< (ostream & ost, const MarkedTri & mt)197{198for(int i=0; i<3; i++)199ost << mt.pnums[i] << " ";200for(int i=0; i<3; i++)201ost << mt.pgeominfo[i] << " ";202ost << mt.marked << " " << mt.markededge << " " << mt.surfid << " " << mt.incorder << " " << int(mt.order) << "\n";203return ost;204}205istream & operator>> (istream & ist, MarkedTri & mt)206{207for(int i=0; i<3; i++)208ist >> mt.pnums[i];209for(int i=0; i<3; i++)210ist >> mt.pgeominfo[i];211ist >> mt.marked >> mt.markededge >> mt.surfid >> mt.incorder;212int auxint;213ist >> auxint;214mt.order = auxint;215return ist;216}217218219220class MarkedQuad221{222public:223/// point numbers224PointIndex pnums[4];225///226PointGeomInfo pgeominfo[4];227/// marked for refinement228int marked;229/// marked edge: 0/2 = vertical, 1/3 = horizontal230int markededge;231/// surface id232int surfid;233234bool incorder;235unsigned int order:6;236};237238ostream & operator<< (ostream & ost, const MarkedQuad & mt)239{240for(int i=0; i<4; i++)241ost << mt.pnums[i] << " ";242for(int i=0; i<4; i++)243ost << mt.pgeominfo[i] << " ";244ost << mt.marked << " " << mt.markededge << " " << mt.surfid << " " << mt.incorder << " " << int(mt.order) << "\n";245return ost;246}247istream & operator>> (istream & ist, MarkedQuad & mt)248{249for(int i=0; i<4; i++)250ist >> mt.pnums[i];251for(int i=0; i<4; i++)252ist >> mt.pgeominfo[i];253ist >> mt.marked >> mt.markededge >> mt.surfid >> mt.incorder;254int auxint;255ist >> auxint;256mt.order = auxint;257return ist;258}259260261262263void PrettyPrint(ostream & ost, const MarkedTet & mt)264{265int te1 = mt.tetedge1;266int te2 = mt.tetedge2;267int order = mt.order;268269ost << "MT: " << mt.pnums[0] << " - " << mt.pnums[1] << " - "270<< mt.pnums[2] << " - " << mt.pnums[3] << endl271<< "marked edge: " << te1 << " - " << te2272<< ", order = " << order << endl;273//for (int k = 0; k < 4; k++)274// ost << int(mt.faceedges[k]) << " ";275for (int k = 0; k < 4; k++)276{277ost << "face";278for (int j=0; j<4; j++)279if(j != k)280ost << " " << mt.pnums[j];281for(int i=0; i<3; i++)282for(int j=i+1; j<4; j++)283if(i != k && j != k && int(mt.faceedges[k]) == 6-k-i-j)284ost << " marked edge " << mt.pnums[i] << " " << mt.pnums[j] << endl;285}286ost << endl;287}288289290291292int BTSortEdges (const Mesh & mesh,293const ARRAY< ARRAY<int,PointIndex::BASE>* > & idmaps,294INDEX_2_CLOSED_HASHTABLE<int> & edgenumber)295{296PrintMessage(4,"sorting ... ");297298// if (mesh.PureTetMesh())299if (1)300{301// new, fast version302303ARRAY<INDEX_2> edges;304ARRAY<int> eclasses;305306int i, j, k;307int cntedges = 0;308int go_on;309int ned(0);310311// enumerate edges:312for (i = 1; i <= mesh.GetNE(); i++)313{314const Element & el = mesh.VolumeElement (i);315static int tetedges[6][2] =316{ { 1, 2 },317{ 1, 3 },318{ 1, 4 },319{ 2, 3 },320{ 2, 4 },321{ 3, 4 } } ;322static int prismedges[9][2] =323{ { 1, 2 },324{ 1, 3 },325{ 2, 3 },326{ 4, 5 },327{ 4, 6 },328{ 5, 6 },329{ 1, 4 },330{ 2, 5 },331{ 3, 6 } };332int pyramidedges[6][2] =333{ { 1, 2 },334{ 3, 4 },335{ 1, 5 },336{ 2, 5 },337{ 3, 5 },338{ 4, 5 } };339340int (*tip)[2] = NULL;341342switch (el.GetType())343{344case TET:345case TET10:346{347tip = tetedges;348ned = 6;349break;350}351case PRISM:352case PRISM12:353{354tip = prismedges;355ned = 6;356break;357}358case PYRAMID:359{360tip = pyramidedges;361ned = 6;362break;363}364}365366for (j = 0; j < ned; j++)367{368INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1]));369i2.Sort();370//(*testout) << "edge " << i2 << endl;371if (!edgenumber.Used(i2))372{373cntedges++;374edges.Append (i2);375edgenumber.Set(i2, cntedges);376}377}378}379380// additional surface edges:381for (i = 1; i <= mesh.GetNSE(); i++)382{383const Element2d & el = mesh.SurfaceElement (i);384static int trigedges[3][2] =385{ { 1, 2 },386{ 2, 3 },387{ 3, 1 } };388389static int quadedges[4][2] =390{ { 1, 2 },391{ 2, 3 },392{ 3, 4 },393{ 4, 1 } };394395396int (*tip)[2] = NULL;397398switch (el.GetType())399{400case TRIG:401case TRIG6:402{403tip = trigedges;404ned = 3;405break;406}407case QUAD:408case QUAD6:409{410tip = quadedges;411ned = 4;412break;413}414default:415{416cerr << "Error: Sort for Bisect, SE has " << el.GetNP() << " points" << endl;417ned = 0;418}419}420421for (j = 0; j < ned; j++)422{423INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1]));424i2.Sort();425if (!edgenumber.Used(i2))426{427cntedges++;428edges.Append (i2);429edgenumber.Set(i2, cntedges);430}431}432}433434435436437438eclasses.SetSize (cntedges);439for (i = 1; i <= cntedges; i++)440eclasses.Elem(i) = i;441442// identify edges in element stack443do444{445go_on = 0;446for (i = 1; i <= mesh.GetNE(); i++)447{448const Element & el = mesh.VolumeElement (i);449450if (el.GetType() != PRISM &&451el.GetType() != PRISM12 &&452el.GetType() != PYRAMID)453continue;454455int prismpairs[3][4] =456{ { 1, 2, 4, 5 },457{ 2, 3, 5, 6 },458{ 1, 3, 4, 6 } };459460int pyramidpairs[3][4] =461{ { 1, 2, 4, 3 },462{ 1, 5, 4, 5 },463{ 2, 5, 3, 5 } };464465int (*pairs)[4] = NULL;466switch (el.GetType())467{468case PRISM:469case PRISM12:470{471pairs = prismpairs;472break;473}474case PYRAMID:475{476pairs = pyramidpairs;477break;478}479}480481for (j = 0; j < 3; j++)482{483INDEX_2 e1 (el.PNum(pairs[j][0]),484el.PNum(pairs[j][1]));485INDEX_2 e2 (el.PNum(pairs[j][2]),486el.PNum(pairs[j][3]));487e1.Sort();488e2.Sort();489490int eclass1 = edgenumber.Get (e1);491int eclass2 = edgenumber.Get (e2);492493// (*testout) << "identify edges " << eclass1 << "-" << eclass2 << endl;494495if (eclasses.Get(eclass1) >496eclasses.Get(eclass2))497{498eclasses.Elem(eclass1) =499eclasses.Get(eclass2);500go_on = 1;501}502else if (eclasses.Get(eclass2) >503eclasses.Get(eclass1))504{505eclasses.Elem(eclass2) =506eclasses.Get(eclass1);507go_on = 1;508}509}510}511512for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)513{514const Element2d & el2d = mesh[sei];515516for(i = 0; i < el2d.GetNP(); i++)517{518INDEX_2 e1(el2d[i], el2d[(i+1) % el2d.GetNP()]);519e1.Sort();520INDEX_2 e2;521522for(k = 0; k < idmaps.Size(); k++)523{524e2.I1() = (*idmaps[k])[e1.I1()];525e2.I2() = (*idmaps[k])[e1.I2()];526527if(e2.I1() == 0 || e2.I2() == 0 ||528e1.I1() == e2.I1() || e1.I2() == e2.I2())529continue;530531e2.Sort();532if(!edgenumber.Used(e2))533continue;534535536int eclass1 = edgenumber.Get (e1);537int eclass2 = edgenumber.Get (e2);538539if (eclasses.Get(eclass1) >540eclasses.Get(eclass2))541{542eclasses.Elem(eclass1) =543eclasses.Get(eclass2);544545546go_on = 1;547}548else if (eclasses.Get(eclass2) >549eclasses.Get(eclass1))550{551eclasses.Elem(eclass2) =552eclasses.Get(eclass1);553go_on = 1;554}555}556}557558}559560}561while (go_on);562563// for (i = 1; i <= cntedges; i++)564// {565// (*testout) << "edge " << i << ": "566// << edges.Get(i).I1() << "-" << edges.Get(i).I2()567// << ", class = " << eclasses.Get(i) << endl;568// }569570// compute classlength:571ARRAY<double> edgelength(cntedges);572573/*574for (i = 1; i <= cntedges; i++)575edgelength.Elem(i) = 1e20;576*/577578for (i = 1; i <= cntedges; i++)579{580INDEX_2 edge = edges.Get(i);581double elen = Dist (mesh.Point(edge.I1()),582mesh.Point(edge.I2()));583edgelength.Elem (i) = elen;584}585586/*587for (i = 1; i <= mesh.GetNE(); i++)588{589const Element & el = mesh.VolumeElement (i);590591if (el.GetType() == TET)592{593for (j = 1; j <= 3; j++)594for (k = j+1; k <= 4; k++)595{596INDEX_2 i2(el.PNum(j), el.PNum(k));597i2.Sort();598599int enr = edgenumber.Get(i2);600double elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));601if (elen < edgelength.Get(enr))602edgelength.Set (enr, elen);603}604}605else if (el.GetType() == PRISM)606{607for (j = 1; j <= 3; j++)608{609k = (j % 3) + 1;610611INDEX_2 i2(el.PNum(j), el.PNum(k));612i2.Sort();613614int enr = edgenumber.Get(i2);615double elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));616if (elen < edgelength.Get(enr))617edgelength.Set (enr, elen);618619i2 = INDEX_2(el.PNum(j+3), el.PNum(k+3));620i2.Sort();621622enr = edgenumber.Get(i2);623elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));624if (elen < edgelength.Get(enr))625edgelength.Set (enr, elen);626627if (!edgenumber.Used(i2))628{629cntedges++;630edgenumber.Set(i2, cntedges);631}632i2 = INDEX_2(el.PNum(j), el.PNum(j+3));633i2.Sort();634635enr = edgenumber.Get(i2);636elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2()));637if (elen < edgelength.Get(enr))638edgelength.Set (enr, elen);639}640}641}642*/643644645for (i = 1; i <= cntedges; i++)646{647if (eclasses.Get(i) != i)648{649if (edgelength.Get(i) < edgelength.Get(eclasses.Get(i)))650edgelength.Elem(eclasses.Get(i)) = edgelength.Get(i);651edgelength.Elem(i) = 1e20;652}653}654655656TABLE<int> eclasstab(cntedges);657for (i = 1; i <= cntedges; i++)658eclasstab.Add1 (eclasses.Get(i), i);659660661// sort edges:662ARRAY<int> sorted(cntedges);663664QickSort (edgelength, sorted);665666int cnt = 0;667for (i = 1; i <= cntedges; i++)668{669int ii = sorted.Get(i);670for (j = 1; j <= eclasstab.EntrySize(ii); j++)671{672cnt++;673edgenumber.Set (edges.Get(eclasstab.Get(ii, j)), cnt);674}675}676return cnt;677}678679else680681{682// old version683684int i, j;685int cnt = 0;686int found;687double len2, maxlen2;688INDEX_2 ep;689690// sort edges by length, parallel edges (on prisms)691// are added in blocks692693do694{695found = 0;696maxlen2 = 1e30;697698for (i = 1; i <= mesh.GetNE(); i++)699{700const Element & el = mesh.VolumeElement (i);701int ned;702int tetedges[6][2] =703{ { 1, 2 },704{ 1, 3 },705{ 1, 4 },706{ 2, 3 },707{ 2, 4 },708{ 3, 4 } };709int prismedges[6][2] =710{ { 1, 2 },711{ 1, 3 },712{ 2, 4 },713{ 4, 5 },714{ 4, 6 },715{ 5, 6 } };716int pyramidedges[6][2] =717{ { 1, 2 },718{ 3, 4 },719{ 1, 5 },720{ 2, 5 },721{ 3, 5 },722{ 4, 5 } };723724int (*tip)[2];725726switch (el.GetType())727{728case TET:729{730tip = tetedges;731ned = 6;732break;733}734case PRISM:735{736tip = prismedges;737ned = 6;738break;739}740case PYRAMID:741{742tip = pyramidedges;743ned = 6;744break;745}746}747748for (j = 0; j < ned; j++)749{750INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1]));751i2.Sort();752if (!edgenumber.Used(i2))753{754len2 = Dist (mesh.Point (i2.I1()),755mesh.Point (i2.I2()));756if (len2 < maxlen2)757{758maxlen2 = len2;759ep = i2;760found = 1;761}762}763}764}765if (found)766{767cnt++;768edgenumber.Set (ep, cnt);769770771// find connected edges:772int go_on = 0;773do774{775go_on = 0;776for (i = 1; i <= mesh.GetNE(); i++)777{778const Element & el = mesh.VolumeElement (i);779if (el.GetNP() != 6) continue;780781int prismpairs[3][4] =782{ { 1, 2, 4, 5 },783{ 2, 3, 5, 6 },784{ 1, 3, 4, 6 } };785786int pyramidpairs[3][4] =787{ { 1, 2, 4, 3 },788{ 1, 5, 4, 5 },789{ 2, 5, 3, 5 } };790791int (*pairs)[4];792switch (el.GetType())793{794case PRISM:795{796pairs = prismpairs;797break;798}799case PYRAMID:800{801pairs = pyramidpairs;802break;803}804}805806for (j = 0; j < 3; j++)807{808INDEX_2 e1 (el.PNum(pairs[j][0]),809el.PNum(pairs[j][1]));810INDEX_2 e2 (el.PNum(pairs[j][2]),811el.PNum(pairs[j][3]));812e1.Sort();813e2.Sort();814815int used1 = edgenumber.Used (e1);816int used2 = edgenumber.Used (e2);817818if (used1 && !used2)819{820cnt++;821edgenumber.Set (e2, cnt);822go_on = 1;823}824if (used2 && !used1)825{826cnt++;827edgenumber.Set (e1, cnt);828go_on = 1;829}830}831}832}833while (go_on);834}835}836while (found);837838return cnt;839}840}841842843844845void BTDefineMarkedTet (const Element & el,846INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,847MarkedTet & mt)848{849int i, j, k;850for (i = 0; i < 4; i++)851mt.pnums[i] = el[i];852853mt.marked = 0;854mt.flagged = 0;855856mt.incorder = 0;857mt.order = 1;858859int val = 0;860// find marked edge of tet:861for (i = 0; i < 3; i++)862for (j = i+1; j < 4; j++)863{864INDEX_2 i2(mt.pnums[i], mt.pnums[j]);865i2.Sort();866int hval = edgenumber.Get(i2);867if (hval > val)868{869val = hval;870mt.tetedge1 = i;871mt.tetedge2 = j;872}873}874875876// find marked edges of faces:877for (k = 0; k < 4; k++)878{879val = 0;880for (i = 0; i < 3; i++)881for (j = i+1; j < 4; j++)882if (i != k && j != k)883{884INDEX_2 i2(mt.pnums[i], mt.pnums[j]);885i2.Sort();886int hval = edgenumber.Get(i2);887if (hval > val)888{889val = hval;890int hi = 6 - k - i - j;891mt.faceedges[k] = char(hi);892}893}894}895}896897898899900void BTDefineMarkedPrism (const Element & el,901INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,902MarkedPrism & mp)903{904int i, j;905906if (el.GetType() == PRISM ||907el.GetType() == PRISM12)908{909for (i = 0; i < 6; i++)910mp.pnums[i] = el[i];911}912else if (el.GetType() == PYRAMID)913{914static int map[6] =915{ 1, 2, 5, 4, 3, 5 };916for (i = 0; i < 6; i++)917mp.pnums[i] = el.PNum(map[i]);918}919else if (el.GetType() == TET ||920el.GetType() == TET10)921{922static int map[6] =923{ 1, 4, 3, 2, 4, 3 };924for (i = 0; i < 6; i++)925mp.pnums[i] = el.PNum(map[i]);926927}928else929{930PrintSysError ("Define marked prism called for non-prism and non-pyramid");931}932933934935mp.marked = 0;936937mp.incorder = 0;938mp.order = 1;939940int val = 0;941for (i = 0; i < 2; i++)942for (j = i+1; j < 3; j++)943{944INDEX_2 i2(mp.pnums[i], mp.pnums[j]);945i2.Sort();946int hval = edgenumber.Get(i2);947if (hval > val)948{949val = hval;950mp.markededge = 3 - i - j;951}952}953}954955956957bool BTDefineMarkedId(const Element2d & el,958INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,959const ARRAY<int,PointIndex::BASE> & idmap,960MarkedIdentification & mi)961{962963bool identified = true;964mi.np = el.GetNP();965int min1(0),min2(0);966for(int j = 0; identified && j < mi.np; j++)967{968mi.pnums[j] = el[j];969mi.pnums[j+mi.np] = idmap[el[j]];970971if(j == 0 || el[j] < min1)972min1 = el[j];973if(j == 0 || mi.pnums[j+mi.np] < min2)974min2 = mi.pnums[j+mi.np];975976identified = (mi.pnums[j+mi.np] != 0 && mi.pnums[j+mi.np] != mi.pnums[j]);977}978979identified = identified && (min1 < min2);980981if(identified)982{983mi.marked = 0;984985mi.incorder = 0;986mi.order = 1;987988int val = 0;989for (int i = 0; i < mi.np; i++)990{991INDEX_2 i2(mi.pnums[i], mi.pnums[(i+1)%mi.np]);992i2.Sort();993int hval = edgenumber.Get(i2);994if (hval > val)995{996val = hval;997mi.markededge = i;998}999}1000}10011002return identified;1003}100410051006void BTDefineMarkedTri (const Element2d & el,1007INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,1008MarkedTri & mt)1009{1010int i, j;1011for (i = 0; i < 3; i++)1012{1013mt.pnums[i] = el[i];1014mt.pgeominfo[i] = el.GeomInfoPi (i+1);1015}10161017mt.marked = 0;1018mt.surfid = el.GetIndex();10191020mt.incorder = 0;1021mt.order = 1;10221023int val = 0;1024for (i = 0; i < 2; i++)1025for (j = i+1; j < 3; j++)1026{1027INDEX_2 i2(mt.pnums[i], mt.pnums[j]);1028i2.Sort();1029int hval = edgenumber.Get(i2);1030if (hval > val)1031{1032val = hval;1033mt.markededge = 3 - i - j;1034}1035}1036}1037103810391040void PrettyPrint(ostream & ost, const MarkedTri & mt)1041{1042ost << "MarkedTrig: " << endl;1043ost << " pnums = "; for (int i=0; i<3; i++) ost << mt.pnums[i] << " "; ost << endl;1044ost << " marked = " << mt.marked << ", markededge=" << mt.markededge << endl;1045for(int i=0; i<2; i++)1046for(int j=i+1; j<3; j++)1047if(mt.markededge == 3-i-j)1048ost << " marked edge pnums = " << mt.pnums[i] << " " << mt.pnums[j] << endl;1049}105010511052void PrettyPrint(ostream & ost, const MarkedQuad & mq)1053{1054ost << "MarkedQuad: " << endl;1055ost << " pnums = "; for (int i=0; i<4; i++) ost << mq.pnums[i] << " "; ost << endl;1056ost << " marked = " << mq.marked << ", markededge=" << mq.markededge << endl;1057}105810591060106110621063void BTDefineMarkedQuad (const Element2d & el,1064INDEX_2_CLOSED_HASHTABLE<int> & edgenumber,1065MarkedQuad & mq)1066{1067int i;1068for (i = 0; i < 4; i++)1069mq.pnums[i] = el[i];1070Swap (mq.pnums[2], mq.pnums[3]);10711072mq.marked = 0;1073mq.markededge = 0;1074mq.surfid = el.GetIndex();1075}10761077107810791080// mark elements due to local h1081int BTMarkTets (T_MTETS & mtets,1082T_MPRISMS & mprisms,1083const Mesh & mesh)1084{1085int i, j, k;1086int step;10871088int marked = 0;10891090int np = mesh.GetNP();1091Vector hv(np);1092for (i = 1; i <= np; i++)1093hv.Elem(i) = mesh.GetH (mesh.Point(i));10941095double hfac = 1;10961097for (step = 1; step <= 2; step++)1098{1099for (i = 1; i <= mtets.Size(); i++)1100{1101double h = 0;11021103for (j = 0; j < 3; j++)1104for (k = j+1; k < 4; k++)1105{1106const Point<3> & p1 = mesh.Point (mtets.Get(i).pnums[j]);1107const Point<3> & p2 = mesh.Point (mtets.Get(i).pnums[k]);1108double hh = Dist2 (p1, p2);1109if (hh > h) h = hh;1110}1111h = sqrt (h);11121113double hshould = 1e10;1114for (j = 0; j < 4; j++)1115{1116double hi = hv.Get (mtets.Get(i).pnums[j]);1117if (hi < hshould)1118hshould = hi;1119}112011211122if (step == 1)1123{1124if (h / hshould > hfac)1125hfac = h / hshould;1126}1127else1128{1129if (h > hshould * hfac)1130{1131mtets.Elem(i).marked = 1;1132marked = 1;1133}1134else1135mtets.Elem(i).marked = 0;1136}11371138}1139for (i = 1; i <= mprisms.Size(); i++)1140{1141double h = 0;11421143for (j = 0; j < 2; j++)1144for (k = j+1; k < 3; k++)1145{1146const Point<3> & p1 = mesh.Point (mprisms.Get(i).pnums[j]);1147const Point<3> & p2 = mesh.Point (mprisms.Get(i).pnums[k]);1148double hh = Dist2 (p1, p2);1149if (hh > h) h = hh;1150}1151h = sqrt (h);11521153double hshould = 1e10;1154for (j = 0; j < 6; j++)1155{1156double hi = hv.Get (mprisms.Get(i).pnums[j]);1157if (hi < hshould)1158hshould = hi;1159}116011611162if (step == 1)1163{1164if (h / hshould > hfac)1165hfac = h / hshould;1166}1167else1168{1169if (h > hshould * hfac)1170{1171mprisms.Elem(i).marked = 1;1172marked = 1;1173}1174else1175mprisms.Elem(i).marked = 0;1176}11771178}1179118011811182if (step == 1)1183{1184if (hfac > 2)1185hfac /= 2;1186else1187hfac = 1;1188}11891190}1191return marked;1192}119311941195119611971198119912001201120212031204120512061207void BTBisectTet (const MarkedTet & oldtet, int newp,1208MarkedTet & newtet1, MarkedTet & newtet2)1209{1210#ifdef DEBUG1211*testout << "bisect tet " << oldtet << endl;1212#endif12131214int i, j, k;121512161217// points vis a vis from tet-edge1218int vis1, vis2;1219vis1 = 0;1220while (vis1 == oldtet.tetedge1 || vis1 == oldtet.tetedge2)1221vis1++;1222vis2 = 6 - vis1 - oldtet.tetedge1 - oldtet.tetedge2;122312241225122612271228// is tet of type P ?1229int istypep = 0;1230for (i = 0; i < 4; i++)1231{1232int cnt = 0;1233for (j = 0; j < 4; j++)1234if (oldtet.faceedges[j] == i)1235cnt++;1236if (cnt == 3)1237istypep = 1;1238}1239124012411242for (i = 0; i < 4; i++)1243{1244newtet1.pnums[i] = oldtet.pnums[i];1245newtet2.pnums[i] = oldtet.pnums[i];1246}1247newtet1.flagged = istypep && !oldtet.flagged;1248newtet2.flagged = istypep && !oldtet.flagged;12491250int nm = oldtet.marked - 1;1251if (nm < 0) nm = 0;1252newtet1.marked = nm;1253newtet2.marked = nm;12541255#ifdef DEBUG1256*testout << "newtet1,before = " << newtet1 << endl;1257*testout << "newtet2,before = " << newtet2 << endl;1258#endif12591260for (i = 0; i < 4; i++)1261{1262if (i == oldtet.tetedge1)1263{1264newtet2.pnums[i] = newp;1265newtet2.faceedges[i] = oldtet.faceedges[i]; // inherited face1266newtet2.faceedges[vis1] = i; // cut faces1267newtet2.faceedges[vis2] = i;12681269j = 0;1270while (j == i || j == oldtet.faceedges[i])1271j++;1272k = 6 - i - oldtet.faceedges[i] - j;1273newtet2.tetedge1 = j; // tet-edge1274newtet2.tetedge2 = k;12751276// new face:1277if (istypep && oldtet.flagged)1278{1279int hi = 6 - oldtet.tetedge1 - j - k;1280newtet2.faceedges[oldtet.tetedge2] = char(hi);1281}1282else1283newtet2.faceedges[oldtet.tetedge2] = oldtet.tetedge1;128412851286*testout << "i = " << i << ", j = " << j << " k = " << k1287<< " oldtet.tetedge1 = " << oldtet.tetedge11288<< " oldtet.tetedge2 = " << oldtet.tetedge21289<< " 6-oldtet.tetedge1-j-k = " << 6 - oldtet.tetedge1 - j - k1290<< " 6-oldtet.tetedge1-j-k = " << short(6 - oldtet.tetedge1 - j - k)1291<< endl;1292*testout << "vis1 = " << vis1 << ", vis2 = " << vis2 << endl;1293for (int j = 0; j < 4; j++)1294if (newtet2.faceedges[j] > 3)1295{1296*testout << "ERROR1" << endl;1297}1298}12991300if (i == oldtet.tetedge2)1301{1302newtet1.pnums[i] = newp;1303newtet1.faceedges[i] = oldtet.faceedges[i]; // inherited face1304newtet1.faceedges[vis1] = i;1305newtet1.faceedges[vis2] = i;1306j = 0;1307while (j == i || j == oldtet.faceedges[i])1308j++;1309k = 6 - i - oldtet.faceedges[i] - j;1310newtet1.tetedge1 = j;1311newtet1.tetedge2 = k;13121313// new face:1314if (istypep && oldtet.flagged)1315{1316int hi = 6 - oldtet.tetedge2 - j - k;1317newtet1.faceedges[oldtet.tetedge1] = char(hi);1318}1319else1320newtet1.faceedges[oldtet.tetedge1] = oldtet.tetedge2;13211322for (int j = 0; j < 4; j++)1323if (newtet2.faceedges[j] > 3)1324{1325*testout << "ERROR2" << endl;1326}13271328}1329}13301331newtet1.matindex = oldtet.matindex;1332newtet2.matindex = oldtet.matindex;1333newtet1.incorder = 0;1334newtet1.order = oldtet.order;1335newtet2.incorder = 0;1336newtet2.order = oldtet.order;13371338*testout << "newtet1 = " << newtet1 << endl;1339*testout << "newtet2 = " << newtet2 << endl;1340}13411342134313441345void BTBisectPrism (const MarkedPrism & oldprism, int newp1, int newp2,1346MarkedPrism & newprism1, MarkedPrism & newprism2)1347{1348int i;13491350for (i = 0; i < 6; i++)1351{1352newprism1.pnums[i] = oldprism.pnums[i];1353newprism2.pnums[i] = oldprism.pnums[i];1354}13551356int pe1, pe2;1357pe1 = 0;1358if (pe1 == oldprism.markededge)1359pe1++;1360pe2 = 3 - oldprism.markededge - pe1;13611362newprism1.pnums[pe2] = newp1;1363newprism1.pnums[pe2+3] = newp2;1364newprism1.markededge = pe2;1365newprism2.pnums[pe1] = newp1;1366newprism2.pnums[pe1+3] = newp2;1367newprism2.markededge = pe1;13681369newprism1.matindex = oldprism.matindex;1370newprism2.matindex = oldprism.matindex;13711372int nm = oldprism.marked - 1;1373if (nm < 0) nm = 0;1374newprism1.marked = nm;1375newprism2.marked = nm;13761377newprism1.incorder = 0;1378newprism1.order = oldprism.order;1379newprism2.incorder = 0;1380newprism2.order = oldprism.order;1381}138213831384void BTBisectIdentification (const MarkedIdentification & oldid,1385ARRAY<int> & newp,1386MarkedIdentification & newid1,1387MarkedIdentification & newid2)1388{1389for(int i=0; i<2*oldid.np; i++)1390{1391newid1.pnums[i] = oldid.pnums[i];1392newid2.pnums[i] = oldid.pnums[i];1393}1394newid1.np = newid2.np = oldid.np;13951396if(oldid.np == 3)1397{1398newid1.pnums[(oldid.markededge+1)%3] = newp[0];1399newid1.pnums[(oldid.markededge+1)%3+3] = newp[1];1400newid1.markededge = (oldid.markededge+2)%3;14011402newid2.pnums[oldid.markededge] = newp[0];1403newid2.pnums[oldid.markededge+3] = newp[1];1404newid2.markededge = (oldid.markededge+1)%3;1405}1406else if(oldid.np == 4)1407{1408newid1.pnums[(oldid.markededge+1)%4] = newp[0];1409newid1.pnums[(oldid.markededge+2)%4] = newp[2];1410newid1.pnums[(oldid.markededge+1)%4+4] = newp[1];1411newid1.pnums[(oldid.markededge+2)%4+4] = newp[3];1412newid1.markededge = (oldid.markededge+3)%4;14131414newid2.pnums[oldid.markededge] = newp[0];1415newid2.pnums[(oldid.markededge+3)%4] = newp[2];1416newid2.pnums[oldid.markededge+4] = newp[1];1417newid2.pnums[(oldid.markededge+3)%4+4] = newp[3];1418newid2.markededge = (oldid.markededge+1)%4;1419}142014211422int nm = oldid.marked - 1;1423if (nm < 0) nm = 0;1424newid1.marked = newid2.marked = nm;14251426newid1.incorder = newid2.incorder = 0;1427newid1.order = newid2.order = oldid.order;1428}1429143014311432void BTBisectTri (const MarkedTri & oldtri, int newp, const PointGeomInfo & newpgi,1433MarkedTri & newtri1, MarkedTri & newtri2)1434{1435int i;14361437for (i = 0; i < 3; i++)1438{1439newtri1.pnums[i] = oldtri.pnums[i];1440newtri1.pgeominfo[i] = oldtri.pgeominfo[i];1441newtri2.pnums[i] = oldtri.pnums[i];1442newtri2.pgeominfo[i] = oldtri.pgeominfo[i];1443}14441445int pe1, pe2;1446pe1 = 0;1447if (pe1 == oldtri.markededge)1448pe1++;1449pe2 = 3 - oldtri.markededge - pe1;14501451newtri1.pnums[pe2] = newp;1452newtri1.pgeominfo[pe2] = newpgi;1453newtri1.markededge = pe2;14541455newtri2.pnums[pe1] = newp;1456newtri2.pgeominfo[pe1] = newpgi;1457newtri2.markededge = pe1;145814591460newtri1.surfid = oldtri.surfid;1461newtri2.surfid = oldtri.surfid;14621463int nm = oldtri.marked - 1;1464if (nm < 0) nm = 0;1465newtri1.marked = nm;1466newtri2.marked = nm;14671468newtri1.incorder = 0;1469newtri1.order = oldtri.order;1470newtri2.incorder = 0;1471newtri2.order = oldtri.order;147214731474}147514761477void BTBisectQuad (const MarkedQuad & oldquad,1478int newp1, const PointGeomInfo & npgi1,1479int newp2, const PointGeomInfo & npgi2,1480MarkedQuad & newquad1, MarkedQuad & newquad2)1481{1482int i;14831484for (i = 0; i < 4; i++)1485{1486newquad1.pnums[i] = oldquad.pnums[i];1487newquad1.pgeominfo[i] = oldquad.pgeominfo[i];1488newquad2.pnums[i] = oldquad.pnums[i];1489newquad2.pgeominfo[i] = oldquad.pgeominfo[i];1490}14911492/* if (oldquad.marked==1) // he/sz: 2d quads or 3d prism1493{1494newquad1.pnums[1] = newp1;1495newquad1.pgeominfo[1] = npgi1;1496newquad1.pnums[3] = newp2;1497newquad1.pgeominfo[3] = npgi2;14981499newquad2.pnums[0] = newp1;1500newquad2.pgeominfo[0] = npgi1;1501newquad2.pnums[2] = newp2;1502newquad2.pgeominfo[2] = npgi2;1503}15041505else if (oldquad.marked==2) // he/sz: 2d quads only1506{1507newquad1.pnums[0] = newp1;1508newquad1.pnums[1] = newp2;1509newquad1.pnums[3] = oldquad.pnums[2];1510newquad1.pnums[2] = oldquad.pnums[0];1511newquad1.pgeominfo[0] = npgi1;1512newquad1.pgeominfo[1] = npgi2;1513newquad1.pgeominfo[3] = oldquad.pgeominfo[2];1514newquad1.pgeominfo[2] = oldquad.pgeominfo[0];15151516newquad2.pnums[0] = newp2;1517newquad2.pnums[1] = newp1;1518newquad2.pnums[3] = oldquad.pnums[1];1519newquad2.pnums[2] = oldquad.pnums[3];1520newquad2.pgeominfo[0] = npgi2;1521newquad2.pgeominfo[1] = npgi1;1522newquad2.pgeominfo[3] = oldquad.pgeominfo[1];1523newquad2.pgeominfo[2] = oldquad.pgeominfo[3];1524}15251526*/15271528if (oldquad.markededge==0 || oldquad.markededge==2)1529{1530newquad1.pnums[1] = newp1;1531newquad1.pgeominfo[1] = npgi1;1532newquad1.pnums[3] = newp2;1533newquad1.pgeominfo[3] = npgi2;15341535newquad2.pnums[0] = newp1;1536newquad2.pgeominfo[0] = npgi1;1537newquad2.pnums[2] = newp2;1538newquad2.pgeominfo[2] = npgi2;1539}1540else // 1 || 31541{1542newquad1.pnums[2] = newp1;1543newquad1.pgeominfo[2] = npgi1;1544newquad1.pnums[3] = newp2;1545newquad1.pgeominfo[3] = npgi2;15461547newquad2.pnums[0] = newp1;1548newquad2.pgeominfo[0] = npgi1;1549newquad2.pnums[1] = newp2;1550newquad2.pgeominfo[1] = npgi2;1551}1552newquad1.surfid = oldquad.surfid;1553newquad2.surfid = oldquad.surfid;15541555int nm = oldquad.marked - 1;1556if (nm < 0) nm = 0;15571558newquad1.marked = nm;1559newquad2.marked = nm;15601561if (nm==1)1562{1563newquad1.markededge=1;1564newquad2.markededge=1;1565}1566else1567{1568newquad1.markededge=0;1569newquad2.markededge=0;1570}15711572}157315741575int MarkHangingIdentifications(T_MIDS & mids,1576const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)1577{1578int i, j;15791580int hanging = 0;1581for (i = 1; i <= mids.Size(); i++)1582{1583if (mids.Elem(i).marked)1584{1585hanging = 1;1586continue;1587}15881589const int np = mids.Get(i).np;15901591for(j = 0; j < np; j++)1592{1593INDEX_2 edge1(mids.Get(i).pnums[j],1594mids.Get(i).pnums[(j+1) % np]);1595INDEX_2 edge2(mids.Get(i).pnums[j+np],1596mids.Get(i).pnums[((j+1) % np) + np]);15971598edge1.Sort();1599edge2.Sort();1600if (cutedges.Used (edge1) ||1601cutedges.Used (edge2))1602{1603mids.Elem(i).marked = 1;1604hanging = 1;1605}1606}1607}16081609return hanging;1610}161116121613/*1614void IdentifyCutEdges(Mesh & mesh,1615INDEX_2_CLOSED_HASHTABLE<int> & cutedges)1616{1617int i,j,k;16181619ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps;1620for(i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)1621{1622idmaps.Append(new ARRAY<int,PointIndex::BASE>);1623mesh.GetIdentifications().GetMap(i,*idmaps.Last());1624}1625162616271628for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)1629{1630const Element2d & el2d = mesh[sei];16311632for(i = 0; i < el2d.GetNP(); i++)1633{1634INDEX_2 e1(el2d[i], el2d[(i+1) % el2d.GetNP()]);1635e1.Sort();16361637if(!cutedges.Used(e1))1638continue;163916401641for(k = 0; k < idmaps.Size(); k++)1642{1643INDEX_2 e2((*idmaps[k])[e1.I1()],1644(*idmaps[k])[e1.I2()]);16451646if(e2.I1() == 0 || e2.I2() == 0 ||1647e1.I1() == e2.I1() || e1.I2() == e2.I2())1648continue;16491650e2.Sort();16511652if(cutedges.Used(e2))1653continue;16541655Point3d np = Center(mesh.Point(e2.I1()),1656mesh.Point(e2.I2()));1657int newp = mesh.AddPoint(np);1658cutedges.Set(e2,newp);1659(*testout) << "DAAA" << endl;1660}1661}1662}166316641665for(i=0; i<idmaps.Size(); i++)1666delete idmaps[i];1667idmaps.DeleteAll();1668}1669*/167016711672int MarkHangingTets (T_MTETS & mtets,1673const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)1674{1675int i, j, k;16761677int hanging = 0;1678for (i = 1; i <= mtets.Size(); i++)1679{1680MarkedTet & teti = mtets.Elem(i);16811682if (teti.marked)1683{1684hanging = 1;1685continue;1686}16871688for (j = 0; j < 3; j++)1689for (k = j+1; k < 4; k++)1690{1691INDEX_2 edge(teti.pnums[j],1692teti.pnums[k]);1693edge.Sort();1694if (cutedges.Used (edge))1695{1696teti.marked = 1;1697hanging = 1;1698}1699}1700}17011702return hanging;1703}1704170517061707int MarkHangingPrisms (T_MPRISMS & mprisms,1708const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)1709{1710int i, j, k;17111712int hanging = 0;1713for (i = 1; i <= mprisms.Size(); i++)1714{1715if (mprisms.Elem(i).marked)1716{1717hanging = 1;1718continue;1719}17201721for (j = 0; j < 2; j++)1722for (k = j+1; k < 3; k++)1723{1724INDEX_2 edge1(mprisms.Get(i).pnums[j],1725mprisms.Get(i).pnums[k]);1726INDEX_2 edge2(mprisms.Get(i).pnums[j+3],1727mprisms.Get(i).pnums[k+3]);1728edge1.Sort();1729edge2.Sort();1730if (cutedges.Used (edge1) ||1731cutedges.Used (edge2))1732{1733mprisms.Elem(i).marked = 1;1734hanging = 1;1735}1736}1737}1738return hanging;1739}1740174117421743int MarkHangingTris (T_MTRIS & mtris,1744const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)1745{1746int i, j, k;17471748int hanging = 0;1749for (i = 1; i <= mtris.Size(); i++)1750{1751if (mtris.Get(i).marked)1752{1753hanging = 1;1754continue;1755}1756for (j = 0; j < 2; j++)1757for (k = j+1; k < 3; k++)1758{1759INDEX_2 edge(mtris.Get(i).pnums[j],1760mtris.Get(i).pnums[k]);1761edge.Sort();1762if (cutedges.Used (edge))1763{1764mtris.Elem(i).marked = 1;1765hanging = 1;1766}1767}1768}1769return hanging;1770}1771177217731774int MarkHangingQuads (T_MQUADS & mquads,1775const INDEX_2_CLOSED_HASHTABLE<int> & cutedges)1776{1777int i;17781779int hanging = 0;1780for (i = 1; i <= mquads.Size(); i++)1781{1782if (mquads.Elem(i).marked)1783{1784hanging = 1;1785continue;1786}17871788INDEX_2 edge1(mquads.Get(i).pnums[0],1789mquads.Get(i).pnums[1]);1790INDEX_2 edge2(mquads.Get(i).pnums[2],1791mquads.Get(i).pnums[3]);1792edge1.Sort();1793edge2.Sort();1794if (cutedges.Used (edge1) ||1795cutedges.Used (edge2))1796{1797mquads.Elem(i).marked = 1;1798mquads.Elem(i).markededge = 0;1799hanging = 1;1800continue;1801}18021803// he/sz: second case: split horizontally1804INDEX_2 edge3(mquads.Get(i).pnums[1],1805mquads.Get(i).pnums[3]);1806INDEX_2 edge4(mquads.Get(i).pnums[2],1807mquads.Get(i).pnums[0]);18081809edge3.Sort();1810edge4.Sort();1811if (cutedges.Used (edge3) ||1812cutedges.Used (edge4))1813{1814mquads.Elem(i).marked = 1;1815mquads.Elem(i).markededge = 1;1816hanging = 1;1817continue;1818}18191820}1821return hanging;1822}1823182418251826void ConnectToNodeRec (int node, int tonode,1827const TABLE<int> & conto, ARRAY<int> & connecttonode)1828{1829int i, n2;1830// (*testout) << "connect " << node << " to " << tonode << endl;1831for (i = 1; i <= conto.EntrySize(node); i++)1832{1833n2 = conto.Get(node, i);1834if (!connecttonode.Get(n2))1835{1836connecttonode.Elem(n2) = tonode;1837ConnectToNodeRec (n2, tonode, conto, connecttonode);1838}1839}1840}18411842184318441845T_MTETS mtets;1846T_MPRISMS mprisms;1847T_MIDS mids;1848T_MTRIS mtris;1849T_MQUADS mquads;185018511852void WriteMarkedElements(ostream & ost)1853{1854ost << "Marked Elements\n";18551856ost << mtets.Size() << "\n";1857for(int i=0; i<mtets.Size(); i++)1858ost << mtets[i];18591860ost << mprisms.Size() << "\n";1861for(int i=0; i<mprisms.Size(); i++)1862ost << mprisms[i];18631864ost << mids.Size() << "\n";1865for(int i=0; i<mids.Size(); i++)1866ost << mids[i];18671868ost << mtris.Size() << "\n";1869for(int i=0; i<mtris.Size(); i++)1870ost << mtris[i];18711872ost << mquads.Size() << "\n";1873for(int i=0; i<mquads.Size(); i++)1874ost << mquads[i];1875ost << endl;1876}18771878bool ReadMarkedElements(istream & ist, const Mesh & mesh)1879{1880string auxstring("");1881if(ist)1882ist >> auxstring;18831884if(auxstring != "Marked")1885return false;18861887if(ist)1888ist >> auxstring;18891890if(auxstring != "Elements")1891return false;18921893int size;18941895ist >> size;1896mtets.SetSize(size);1897for(int i=0; i<size; i++)1898{1899ist >> mtets[i];1900if(mtets[i].pnums[0] > mesh.GetNV() ||1901mtets[i].pnums[1] > mesh.GetNV() ||1902mtets[i].pnums[2] > mesh.GetNV() ||1903mtets[i].pnums[3] > mesh.GetNV())1904return false;1905}19061907ist >> size;1908mprisms.SetSize(size);1909for(int i=0; i<size; i++)1910ist >> mprisms[i];19111912ist >> size;1913mids.SetSize(size);1914for(int i=0; i<size; i++)1915ist >> mids[i];19161917ist >> size;1918mtris.SetSize(size);1919for(int i=0; i<size; i++)1920ist >> mtris[i];19211922ist >> size;1923mquads.SetSize(size);1924for(int i=0; i<size; i++)1925ist >> mquads[i];19261927return true;1928}192919301931193219331934void BisectTetsCopyMesh (Mesh & mesh, const class CSGeometry *,1935BisectionOptions & opt,1936const ARRAY< ARRAY<int,PointIndex::BASE>* > & idmaps,1937const string & refinfofile)1938{1939mtets.SetName ("bisection, tets");1940mprisms.SetName ("bisection, prisms");1941mtris.SetName ("bisection, trigs");1942mquads.SetName ("bisection, quads");1943mids.SetName ("bisection, identifications");19441945//int np = mesh.GetNP();1946int ne = mesh.GetNE();1947int nse = mesh.GetNSE();1948int i, j, k, l, m;19491950/*1951if (mtets.Size() + mprisms.Size() == mesh.GetNE())1952return;1953*/19541955bool readok = false;19561957if(refinfofile != "")1958{1959PrintMessage(3,"Reading marked-element information from \"",refinfofile,"\"");1960ifstream ist(refinfofile.c_str());19611962readok = ReadMarkedElements(ist,mesh);19631964ist.close();1965}19661967if(!readok)1968{1969PrintMessage(3,"resetting marked-element information");1970mtets.SetSize(0);1971mprisms.SetSize(0);1972mids.SetSize(0);1973mtris.SetSize(0);1974mquads.SetSize(0);197519761977INDEX_2_HASHTABLE<int> shortedges(100);1978for (i = 1; i <= ne; i++)1979{1980const Element & el = mesh.VolumeElement(i);1981if (el.GetType() == PRISM ||1982el.GetType() == PRISM12)1983{1984for (j = 1; j <= 3; j++)1985{1986INDEX_2 se(el.PNum(j), el.PNum(j+3));1987se.Sort();1988shortedges.Set (se, 1);1989}1990}1991}1992199319941995// INDEX_2_HASHTABLE<int> edgenumber(np);1996INDEX_2_CLOSED_HASHTABLE<int> edgenumber(9*ne+4*nse);19971998BTSortEdges (mesh, idmaps, edgenumber);199920002001for (i = 1; i <= ne; i++)2002{2003const Element & el = mesh.VolumeElement(i);20042005switch (el.GetType())2006{2007case TET:2008case TET10:2009{2010// if tet has short edge, it is handled as degenerated prism20112012int foundse = 0;2013for (j = 1; j <= 3; j++)2014for (k = j+1; k <= 4; k++)2015{2016INDEX_2 se(el.PNum(j), el.PNum(k));2017se.Sort();2018if (shortedges.Used (se))2019{2020// cout << "tet converted to prism" << endl;20212022foundse = 1;2023int p3 = 1;2024while (p3 == j || p3 == k)2025p3++;2026int p4 = 10 - j - k - p3;20272028// even permutation ?2029int pi[4];2030pi[0] = j;2031pi[1] = k;2032pi[2] = p3;2033pi[3] = p4;2034int cnt = 0;2035for (l = 1; l <= 4; l++)2036for (m = 0; m < 3; m++)2037if (pi[m] > pi[m+1])2038{2039Swap (pi[m], pi[m+1]);2040cnt++;2041}2042if (cnt % 2)2043Swap (p3, p4);20442045Element hel = el;2046hel.PNum(1) = el.PNum(j);2047hel.PNum(2) = el.PNum(k);2048hel.PNum(3) = el.PNum(p3);2049hel.PNum(4) = el.PNum(p4);20502051MarkedPrism mp;2052BTDefineMarkedPrism (hel, edgenumber, mp);2053mp.matindex = el.GetIndex();2054mprisms.Append (mp);2055}2056}2057if (!foundse)2058{2059MarkedTet mt;2060BTDefineMarkedTet (el, edgenumber, mt);2061mt.matindex = el.GetIndex();2062mtets.Append (mt);2063}2064break;2065}2066case PYRAMID:2067{2068// eventually rotate2069MarkedPrism mp;20702071INDEX_2 se(el.PNum(1), el.PNum(2));2072se.Sort();2073if (shortedges.Used (se))2074{2075Element hel = el;2076hel.PNum(1) = el.PNum(2);2077hel.PNum(2) = el.PNum(3);2078hel.PNum(3) = el.PNum(4);2079hel.PNum(4) = el.PNum(1);2080BTDefineMarkedPrism (hel, edgenumber, mp);2081}2082else2083{2084BTDefineMarkedPrism (el, edgenumber, mp);2085}20862087mp.matindex = el.GetIndex();2088mprisms.Append (mp);2089break;2090}2091case PRISM:2092case PRISM12:2093{2094MarkedPrism mp;2095BTDefineMarkedPrism (el, edgenumber, mp);2096mp.matindex = el.GetIndex();2097mprisms.Append (mp);2098break;2099}2100}2101}21022103for (i = 1; i <= nse; i++)2104{2105const Element2d & el = mesh.SurfaceElement(i);2106if (el.GetType() == TRIG ||2107el.GetType() == TRIG6)2108{2109MarkedTri mt;2110BTDefineMarkedTri (el, edgenumber, mt);2111mtris.Append (mt);2112}2113else2114{2115MarkedQuad mq;2116BTDefineMarkedQuad (el, edgenumber, mq);2117mquads.Append (mq);2118}21192120MarkedIdentification mi;2121for(j=0; j<idmaps.Size(); j++)2122if(BTDefineMarkedId(el, edgenumber, *idmaps[j], mi))2123mids.Append(mi);2124}2125}21262127212821292130mesh.mlparentelement.SetSize(ne);2131for (i = 1; i <= ne; i++)2132mesh.mlparentelement.Elem(i) = 0;2133mesh.mlparentsurfaceelement.SetSize(nse);2134for (i = 1; i <= nse; i++)2135mesh.mlparentsurfaceelement.Elem(i) = 0;21362137if (printmessage_importance>0)2138{2139ostringstream str1,str2;2140str1 << "copied " << mtets.Size() << " tets, " << mprisms.Size() << " prisms";2141str2 << " " << mtris.Size() << " trigs, " << mquads.Size() << " quads";21422143PrintMessage(4,str1.str());2144PrintMessage(4,str2.str());2145}2146}214721482149/*2150void UpdateEdgeMarks2(Mesh & mesh,2151const ARRAY< ARRAY<int,PointIndex::BASE>* > & idmaps)2152{2153ARRAY< ARRAY<MarkedTet>*,PointIndex::BASE > mtets_old(mesh.GetNP());2154ARRAY< ARRAY<MarkedPrism>*,PointIndex::BASE > mprisms_old(mesh.GetNP());2155ARRAY< ARRAY<MarkedIdentification>*,PointIndex::BASE > mids_old(mesh.GetNP());2156ARRAY< ARRAY<MarkedTri>*,PointIndex::BASE > mtris_old(mesh.GetNP());2157ARRAY< ARRAY<MarkedQuad>*,PointIndex::BASE > mquads_old(mesh.GetNP());21582159for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)2160mtets_old[i] = new ARRAY<MarkedTet>;2161for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)2162mprisms_old[i] = new ARRAY<MarkedPrism>;2163for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)2164mids_old[i] = new ARRAY<MarkedIdentification>;2165for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)2166mtris_old[i] = new ARRAY<MarkedTri>;2167for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)2168mquads_old[i] = new ARRAY<MarkedQuad>;21692170for(int i=0; i<mtets.Size(); i++)2171mtets_old[mtets[i].pnums[0]]->Append(mtets[i]);2172for(int i=0; i<mprisms.Size(); i++)2173mprisms_old[mprisms[i].pnums[0]]->Append(mprisms[i]);2174for(int i=0; i<mids.Size(); i++)2175mids_old[mids[i].pnums[0]]->Append(mids[i]);2176for(int i=0; i<mtris.Size(); i++)2177{2178(*testout) << "i " << i << endl;2179(*testout) << "mtris[i] " << mtris[i].pnums[0] << " " << mtris[i].pnums[1] << " " << mtris[i].pnums[2] << endl;2180mtris_old[mtris[i].pnums[0]]->Append(mtris[i]);2181}2182for(int i=0; i<mquads.Size(); i++)2183mquads_old[mquads[i].pnums[0]]->Append(mquads[i]);2184218521862187int np = mesh.GetNP();2188int ne = mesh.GetNE();2189int nse = mesh.GetNSE();2190int i, j, k, l, m;219121922193// if (mtets.Size() + mprisms.Size() == mesh.GetNE())2194// return;2195219621972198mtets.SetSize(0);2199mprisms.SetSize(0);2200mids.SetSize(0);2201mtris.SetSize(0);2202mquads.SetSize(0);220322042205INDEX_2_HASHTABLE<int> shortedges(100);2206for (i = 1; i <= ne; i++)2207{2208const Element & el = mesh.VolumeElement(i);2209if (el.GetType() == PRISM ||2210el.GetType() == PRISM12)2211{2212for (j = 1; j <= 3; j++)2213{2214INDEX_2 se(el.PNum(j), el.PNum(j+3));2215se.Sort();2216shortedges.Set (se, 1);2217}2218}2219}2220222122222223// INDEX_2_HASHTABLE<int> edgenumber(np);2224INDEX_2_CLOSED_HASHTABLE<int> edgenumber(9*ne+4*nse);22252226BTSortEdges (mesh, idmaps, edgenumber);222722282229for (i = 1; i <= ne; i++)2230{2231const Element & el = mesh.VolumeElement(i);22322233switch (el.GetType())2234{2235case TET:2236case TET10:2237{2238// if tet has short edge, it is handled as degenerated prism22392240int foundse = 0;2241for (j = 1; j <= 3; j++)2242for (k = j+1; k <= 4; k++)2243{2244INDEX_2 se(el.PNum(j), el.PNum(k));2245se.Sort();2246if (shortedges.Used (se))2247{2248// cout << "tet converted to prism" << endl;22492250foundse = 1;2251int p3 = 1;2252while (p3 == j || p3 == k)2253p3++;2254int p4 = 10 - j - k - p3;22552256// even permutation ?2257int pi[4];2258pi[0] = j;2259pi[1] = k;2260pi[2] = p3;2261pi[3] = p4;2262int cnt = 0;2263for (l = 1; l <= 4; l++)2264for (m = 0; m < 3; m++)2265if (pi[m] > pi[m+1])2266{2267Swap (pi[m], pi[m+1]);2268cnt++;2269}2270if (cnt % 2)2271Swap (p3, p4);22722273Element hel = el;2274hel.PNum(1) = el.PNum(j);2275hel.PNum(2) = el.PNum(k);2276hel.PNum(3) = el.PNum(p3);2277hel.PNum(4) = el.PNum(p4);22782279MarkedPrism mp;22802281BTDefineMarkedPrism (hel, edgenumber, mp);2282mp.matindex = el.GetIndex();2283mprisms.Append (mp);2284}2285}2286if (!foundse)2287{2288MarkedTet mt;22892290int oldind = -1;2291for(l = 0; oldind < 0 && l<mtets_old[el[0]]->Size(); l++)2292if(el[1] == (*mtets_old[el[0]])[l].pnums[1] &&2293el[2] == (*mtets_old[el[0]])[l].pnums[2] &&2294el[3] == (*mtets_old[el[0]])[l].pnums[3])2295oldind = l;22962297if(oldind >= 0)2298mtets.Append((*mtets_old[el[0]])[oldind]);2299else2300{2301BTDefineMarkedTet (el, edgenumber, mt);2302mt.matindex = el.GetIndex();2303mtets.Append (mt);2304}2305}2306break;2307}2308case PYRAMID:2309{2310// eventually rotate2311MarkedPrism mp;23122313INDEX_2 se(el.PNum(1), el.PNum(2));2314se.Sort();2315if (shortedges.Used (se))2316{2317Element hel = el;2318hel.PNum(1) = el.PNum(2);2319hel.PNum(2) = el.PNum(3);2320hel.PNum(3) = el.PNum(4);2321hel.PNum(4) = el.PNum(1);2322BTDefineMarkedPrism (hel, edgenumber, mp);2323}2324else2325{2326BTDefineMarkedPrism (el, edgenumber, mp);2327}23282329mp.matindex = el.GetIndex();2330mprisms.Append (mp);2331break;2332}2333case PRISM:2334case PRISM12:2335{2336MarkedPrism mp;2337BTDefineMarkedPrism (el, edgenumber, mp);2338mp.matindex = el.GetIndex();2339mprisms.Append (mp);2340break;2341}2342}2343}23442345for (i = 1; i <= nse; i++)2346{2347const Element2d & el = mesh.SurfaceElement(i);2348if (el.GetType() == TRIG ||2349el.GetType() == TRIG6)2350{2351MarkedTri mt;2352BTDefineMarkedTri (el, edgenumber, mt);2353mtris.Append (mt);2354}2355else2356{2357MarkedQuad mq;2358BTDefineMarkedQuad (el, edgenumber, mq);2359mquads.Append (mq);2360}23612362MarkedIdentification mi;2363236423652366for(j=0; j<idmaps.Size(); j++)2367if(BTDefineMarkedId(el, edgenumber, *idmaps[j], mi))2368{2369mids.Append(mi);23702371int oldind = -1;2372for(l = 0; oldind < 0 && l<mids_old[mi.pnums[0]]->Size(); l++)2373{2374bool equal = true;2375for(int m = 1; equal && m < mi.np; m++)2376equal = (mi.pnums[m] == (*mids_old[el[0]])[l].pnums[m]);2377if(equal)2378oldind = l;2379}23802381if(oldind >= 0)2382mids.Last() = (*mids_old[mi.pnums[0]])[oldind];2383}23842385}2386238723882389for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)2390delete mtets_old[i];2391for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)2392delete mprisms_old[i];2393for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)2394delete mids_old[i];2395for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)2396delete mtris_old[i];2397for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)2398delete mquads_old[i];2399}2400*/240124022403void UpdateEdgeMarks (Mesh & mesh,2404const ARRAY< ARRAY<int,PointIndex::BASE>* > & idmaps)2405//const ARRAY < ARRAY<Element>* > & elements_before,2406//const ARRAY < ARRAY<int>* > & markedelts_num,2407// const ARRAY < ARRAY<Element2d>* > & surfelements_before,2408// const ARRAY < ARRAY<int>* > & markedsurfelts_num)2409{2410T_MTETS mtets_old; mtets_old.Copy(mtets);2411T_MPRISMS mprisms_old; mprisms_old.Copy(mprisms);2412T_MIDS mids_old; mids_old.Copy(mids);2413T_MTRIS mtris_old; mtris_old.Copy(mtris);2414T_MQUADS mquads_old; mquads_old.Copy(mquads);24152416241724182419mtets.SetSize(0);2420mprisms.SetSize(0);2421mids.SetSize(0);2422mtris.SetSize(0);2423mquads.SetSize(0);24242425//int nv = mesh.GetNV();242624272428INDEX_2_CLOSED_HASHTABLE<int> edgenumber(9*mesh.GetNE()+4*mesh.GetNSE());24292430int maxnum = BTSortEdges (mesh, idmaps, edgenumber);24312432for(int m = 0; m < mtets_old.Size(); m++)2433{2434MarkedTet & mt = mtets_old[m];24352436//(*testout) << "old mt " << mt;24372438INDEX_2 edge (mt.pnums[mt.tetedge1],mt.pnums[mt.tetedge2]);2439edge.Sort();2440if(edgenumber.Used(edge))2441{2442int val = edgenumber.Get(edge);2443//(*testout) << "set voledge " << edge << " from " << val;2444if(val <= maxnum)2445{2446val += 2*maxnum;2447edgenumber.Set(edge,val);2448}2449else if(val <= 2*maxnum)2450{2451val += maxnum;2452edgenumber.Set(edge,val);2453}2454//(*testout) << " to " << val << endl;2455}24562457for(int k=0; k<4; k++)2458for(int i=0; i<3; i++)2459for(int j=i+1; i != k && j<4; j++)2460if(j != k && int(mt.faceedges[k]) == 6-k-i-j)2461{2462edge[0] = mt.pnums[i];2463edge[1] = mt.pnums[j];2464edge.Sort();2465if(edgenumber.Used(edge))2466{2467int val = edgenumber.Get(edge);2468//(*testout) << "set faceedge " << edge << " from " << val;2469if(val <= maxnum)2470{2471val += maxnum;2472edgenumber.Set(edge,val);2473}2474//(*testout) << " to " << val << endl;2475}2476}2477}24782479248024812482for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++)2483{2484const Element & el = mesh[ei];24852486//int pos = elements_before[el[0]]->Pos(el);2487//int elnum = (pos >= 0) ? (*markedelts_num[el[0]])[pos] : -1;24882489switch (el.GetType())2490{2491case TET:2492case TET10:2493{2494//if(elnum >= 0)2495// {2496// mtets.Append(mtets_old[elnum]);2497// }2498//else2499// {2500MarkedTet mt;2501BTDefineMarkedTet (el, edgenumber, mt);2502mt.matindex = el.GetIndex();25032504mtets.Append (mt);25052506//(*testout) << "mtet " << mtets.Last() << endl;2507break;2508}2509case PYRAMID:2510{2511cerr << "Refinement :: UpdateEdgeMarks not yet implemented for pyramids"2512<< endl;2513break;2514}25152516case PRISM:2517case PRISM12:2518{2519cerr << "Refinement :: UpdateEdgeMarks not yet implemented for prisms"2520<< endl;2521break;2522}2523}25242525}2526252725282529for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)2530{2531const Element2d & el = mesh[sei];25322533/*2534for(int k=0; k<3; k++)2535auxind3[k] = el[k];25362537auxind3.Sort();25382539int pos = oldfaces[auxind3[0]]->Pos(auxind3);2540if(pos < 0)2541cout << "UIUIUI" << endl;2542*/25432544switch (el.GetType())2545{2546case TRIG:2547case TRIG6:2548{2549MarkedTri mt;2550BTDefineMarkedTri (el, edgenumber, mt);2551mtris.Append (mt);2552break;2553}25542555case QUAD:2556case QUAD6:2557{2558MarkedQuad mt;2559BTDefineMarkedQuad (el, edgenumber, mt);2560mquads.Append (mt);2561break;2562}2563}256425652566MarkedIdentification mi;2567for(int j=0; j<idmaps.Size(); j++)2568if(BTDefineMarkedId(el, edgenumber, *idmaps[j], mi))2569mids.Append(mi);257025712572/*2573int pos = surfelements_before[el[0]]->Pos(el);2574int elnum = (pos >= 0) ? (*markedsurfelts_num[el[0]])[pos] : -1;257525762577switch (el.GetType())2578{2579case TRIG:2580case TRIG6:2581{2582if(elnum >= 0)2583mtris.Append(mtris_old[elnum]);2584else2585{2586MarkedTri mt;2587BTDefineMarkedTri (el, edgenumber, mt);2588mtris.Append (mt);2589(*testout) << "(new) ";2590}2591(*testout) << "mtri " << mtris.Last();2592break;2593}25942595case QUAD:2596case QUAD6:2597{2598if(elnum >= 0)2599mquads.Append(mquads_old[elnum]);2600else2601{2602MarkedQuad mt;2603BTDefineMarkedQuad (el, edgenumber, mt);2604mquads.Append (mt);2605}2606break;2607}2608}2609*/2610}26112612/*2613for(int i=0; i<oldfaces.Size(); i++)2614{2615delete oldfaces[i];2616delete oldmarkededges[i];2617}2618*/26192620}26212622262326242625void Refinement :: Bisect (Mesh & mesh,2626BisectionOptions & opt,2627ARRAY<double> * quality_loss)2628{2629PrintMessage(1,"Mesh bisection");2630PushStatus("Mesh bisection");26312632static int localizetimer = NgProfiler::CreateTimer("localize edgepoints");2633NgProfiler::RegionTimer * loct = new NgProfiler::RegionTimer(localizetimer);2634LocalizeEdgePoints(mesh);2635delete loct;26362637ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps;2638for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)2639{2640if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC)2641{2642idmaps.Append(new ARRAY<int,PointIndex::BASE>);2643mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true);2644}2645}264626472648string refelementinfofileread = "";2649string refelementinfofilewrite = "";26502651if(opt.refinementfilename)2652{2653ifstream inf(opt.refinementfilename);2654string st;2655inf >> st;2656if(st == "refinementinfo")2657{2658while(inf)2659{2660while(inf && st != "markedelementsfile")2661inf >> st;26622663if(inf)2664inf >> st;26652666if(st == "read" && inf)2667ReadEnclString(inf,refelementinfofileread,'\"');2668else if(st == "write" && inf)2669ReadEnclString(inf,refelementinfofilewrite,'\"');2670}2671}2672inf.close();2673}2674267526762677if (mesh.mglevels == 1 || idmaps.Size() > 0)2678BisectTetsCopyMesh(mesh, NULL, opt, idmaps, refelementinfofileread);267926802681mesh.ComputeNVertices();26822683int np = mesh.GetNV();2684mesh.SetNP(np);26852686// int ne = mesh.GetNE();2687// int nse = mesh.GetNSE();2688int i, j, l;26892690// int initnp = np;2691// int maxsteps = 3;26922693mesh.mglevels++;26942695/*2696if (opt.refinementfilename || opt.usemarkedelements)2697maxsteps = 3;2698*/2699270027012702if (opt.refine_p)2703{2704int ne = mesh.GetNE();2705int nse = mesh.GetNSE();2706int ox,oy,oz;2707for (ElementIndex ei = 0; ei < ne; ei++)2708if (mesh[ei].TestRefinementFlag())2709{2710mesh[ei].GetOrder(ox,oy,oz);2711mesh[ei].SetOrder (ox+1,oy+1,oz+1);2712if (mesh[ei].TestStrongRefinementFlag())2713mesh[ei].SetOrder (ox+2,oy+2,oz+2);2714}2715for (SurfaceElementIndex sei = 0; sei < nse; sei++)2716if (mesh[sei].TestRefinementFlag())2717{2718mesh[sei].GetOrder(ox,oy);2719mesh[sei].SetOrder(ox+1,oy+1);2720if (mesh[sei].TestStrongRefinementFlag())2721mesh[sei].SetOrder(ox+2,oy+2);2722}27232724/*2725#ifndef SABINE //Nachbarelemente mit ordx,ordy,ordz27262727ARRAY<int,PointIndex::BASE> v_order (mesh.GetNP());2728v_order = 0;27292730for (ElementIndex ei = 0; ei < ne; ei++)2731for (j = 0; j < mesh[ei].GetNP(); j++)2732if (mesh[ei].GetOrder() > v_order[mesh[ei][j]])2733v_order[mesh[ei][j]] = mesh[ei].GetOrder();27342735for (SurfaceElementIndex sei = 0; sei < nse; sei++)2736for (j = 0; j < mesh[sei].GetNP(); j++)2737if (mesh[sei].GetOrder() > v_order[mesh[sei][j]])2738v_order[mesh[sei][j]] = mesh[sei].GetOrder();27392740for (ElementIndex ei = 0; ei < ne; ei++)2741for (j = 0; j < mesh[ei].GetNP(); j++)2742if (mesh[ei].GetOrder() < v_order[mesh[ei][j]]-1)2743mesh[ei].SetOrder(v_order[mesh[ei][j]]-1);27442745for (SurfaceElementIndex sei = 0; sei < nse; sei++)2746for (j = 0; j < mesh[sei].GetNP(); j++)2747if (mesh[sei].GetOrder() < v_order[mesh[sei][j]]-1)2748mesh[sei].SetOrder(v_order[mesh[sei][j]]-1);27492750#endif2751*/27522753PopStatus();2754return;2755}2756275727582759// INDEX_2_HASHTABLE<int> cutedges(10 + 5 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size()));2760INDEX_2_CLOSED_HASHTABLE<int> cutedges(10 + 9 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size()));27612762bool noprojection = false;27632764for (l = 1; l <= 1; l++)2765{2766int marked = 0;2767if (opt.refinementfilename)2768{2769ifstream inf(opt.refinementfilename);2770PrintMessage(3,"load refinementinfo from file ",opt.refinementfilename);27712772string st;2773inf >> st;2774if(st == "refinementinfo")2775// new version2776{2777for(i=1; i<=mtets.Size(); i++)2778mtets.Elem(i).marked = 0;2779for(i=1; i<=mprisms.Size(); i++)2780mprisms.Elem(i).marked = 0;2781for(i=1; i<=mtris.Size(); i++)2782mtris.Elem(i).marked = 0;2783for(i=1; i<=mquads.Size(); i++)2784mquads.Elem(i).marked = 0;2785for(i=1; i<=mprisms.Size(); i++)2786mids.Elem(i).marked = 0;27872788inf >> st;2789while(inf)2790{2791if(st[0] == '#')2792{2793inf.ignore(10000,'\n');2794inf >> st;2795}2796else if(st == "markedelementsfile")2797{2798inf >> st;2799ReadEnclString(inf,st,'\"');2800inf >> st;2801}2802else if(st == "noprojection")2803{2804noprojection = true;2805inf >> st;2806}2807else if(st == "refine")2808{2809inf >> st;2810if(st == "elements")2811{2812inf >> st;2813bool isint = true;2814for(string::size_type ii=0; isint && ii<st.size(); ii++)2815isint = (isdigit(st[ii]) != 0);28162817while(inf && isint)2818{2819mtets.Elem(atoi(st.c_str())).marked = 3;2820marked = 1;28212822inf >> st;2823isint = true;2824for(string::size_type ii=0; isint && ii<st.size(); ii++)2825isint = (isdigit(st[ii]) != 0);2826}2827}2828else if(st == "orthobrick")2829{2830double bounds[6];2831for(i=0; i<6; i++)2832inf >> bounds[i];28332834int cnt = 0;28352836for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++)2837{2838const Element & el = mesh[ei];28392840//2841Point<3> center(0,0,0);2842for(i=0; i<el.GetNP(); i++)2843{2844const MeshPoint & point = mesh[el[i]];2845center(0) += point(0);2846center(1) += point(1);2847center(2) += point(2);2848}2849for(i=0; i<3; i++)2850center(i) *= 1./double(el.GetNP());2851if(bounds[0] <= center(0) && center(0) <= bounds[3] &&2852bounds[1] <= center(1) && center(1) <= bounds[4] &&2853bounds[2] <= center(2) && center(2) <= bounds[5])2854{2855mtets[ei].marked = 3;2856cnt++;2857}285828592860// bool contained = false;2861// for(int i=0; !contained && i<el.GetNP(); i++)2862// {2863// const MeshPoint & point = mesh[el[i]];2864// contained = (bounds[0] <= point.X() && point.X() <= bounds[3] &&2865// bounds[1] <= point.Y() && point.Y() <= bounds[4] &&2866// bounds[2] <= point.Z() && point.Z() <= bounds[5]);2867// }2868// if(contained)2869// {2870// mtets[ei].marked = 3;2871// cnt++;2872// }2873}287428752876ostringstream strstr;2877strstr.precision(2);2878strstr << "marked " << float(cnt)/float(mesh.GetNE())*100.2879#ifdef WIN322880<< "%%"2881#else2882<< "%"2883#endif2884<<" of the elements";2885PrintMessage(4,strstr.str());28862887if(cnt > 0)2888marked = 1;288928902891inf >> st;2892}2893else2894{2895throw NgException("something wrong with refinementinfo file");2896}2897}2898}2899}2900else2901{2902inf.close();2903inf.open(opt.refinementfilename);29042905char ch;2906for (i = 1; i <= mtets.Size(); i++)2907{2908inf >> ch;2909if(!inf)2910throw NgException("something wrong with refinementinfo file (old format)");2911mtets.Elem(i).marked = (ch == '1');2912}2913marked = 1;2914}2915inf.close();2916}29172918else if (opt.usemarkedelements)2919{2920int cntm = 0;29212922// all in one !2923if (mprisms.Size())2924{2925int cnttet = 0;2926int cntprism = 0;2927for (i = 1; i <= mesh.GetNE(); i++)2928{2929if (mesh.VolumeElement(i).GetType() == TET ||2930mesh.VolumeElement(i).GetType() == TET10)2931{2932cnttet++;2933mtets.Elem(cnttet).marked =29343 * mesh.VolumeElement(i).TestRefinementFlag();2935if (mtets.Elem(cnttet).marked)2936cntm++;2937}2938else2939{2940cntprism++;2941mprisms.Elem(cntprism).marked =29422 * mesh.VolumeElement(i).TestRefinementFlag();2943if (mprisms.Elem(cntprism).marked)2944cntm++;2945}29462947}2948}2949else2950for (i = 1; i <= mtets.Size(); i++)2951{2952mtets.Elem(i).marked =29533 * mesh.VolumeElement(i).TestRefinementFlag();2954if (mtets.Elem(i).marked)2955cntm++;2956}29572958// (*testout) << "mtets = " << mtets << endl;29592960/*2961for (i = 1; i <= mtris.Size(); i++)2962mtris.Elem(i).marked = 0;2963for (i = 1; i <= mquads.Size(); i++)2964mquads.Elem(i).marked = 0;2965*/29662967if (printmessage_importance>0)2968{2969ostringstream str;2970str << "marked elements: " << cntm;2971PrintMessage(4,str.str());2972}29732974int cnttrig = 0;2975int cntquad = 0;2976for (i = 1; i <= mesh.GetNSE(); i++)2977{2978if (mesh.SurfaceElement(i).GetType() == TRIG ||2979mesh.SurfaceElement(i).GetType() == TRIG6)2980{2981cnttrig++;2982mtris.Elem(cnttrig).marked =2983mesh.SurfaceElement(i).TestRefinementFlag() ? 2 : 0;2984// mtris.Elem(cnttrig).marked = 0;2985if (mtris.Elem(cnttrig).marked)2986cntm++;2987}2988else2989{2990cntquad++;2991// 2d: marked=2, 3d prisms: marked=12992mquads.Elem(cntquad).marked =2993mesh.SurfaceElement(i).TestRefinementFlag() ? 4-mesh.GetDimension() : 0 ;2994// mquads.Elem(cntquad).marked = 0;2995if (mquads.Elem(cntquad).marked)2996cntm++;2997}2998}29993000if (printmessage_importance>0)3001{3002ostringstream str;3003str << "with surface-elements: " << cntm;3004PrintMessage(4,str.str());3005}30063007// he/sz: das wird oben schon richtig gemacht.3008// hier sind die quads vergessen!3009/*3010if (mesh.GetDimension() == 2)3011{3012cntm = 0;3013for (i = 1; i <= mtris.Size(); i++)3014{3015mtris.Elem(i).marked =30162 * mesh.SurfaceElement(i).TestRefinementFlag();3017// mtris.Elem(i).marked = 2;3018if (mtris.Elem(i).marked)3019cntm++;3020}30213022if (!cntm)3023{3024for (i = 1; i <= mtris.Size(); i++)3025{3026mtris.Elem(i).marked = 2;3027cntm++;3028}3029}3030cout << "trigs: " << mtris.Size() << " ";3031cout << "marked: " << cntm << endl;3032}3033*/30343035marked = (cntm > 0);3036}3037else3038{3039marked = BTMarkTets (mtets, mprisms, mesh);3040}30413042if (!marked) break;304330443045//(*testout) << "mtets " << mtets << endl;30463047if (opt.refine_p)3048{3049PrintMessage(3,"refine p");30503051for (i = 1; i <= mtets.Size(); i++)3052mtets.Elem(i).incorder = mtets.Elem(i).marked ? 1 : 0;30533054for (i = 1; i <= mtets.Size(); i++)3055if (mtets.Elem(i).incorder)3056mtets.Elem(i).marked = 0;305730583059for (i = 1; i <= mprisms.Size(); i++)3060mprisms.Elem(i).incorder = mprisms.Elem(i).marked ? 1 : 0;30613062for (i = 1; i <= mprisms.Size(); i++)3063if (mprisms.Elem(i).incorder)3064mprisms.Elem(i).marked = 0;306530663067for (i = 1; i <= mtris.Size(); i++)3068mtris.Elem(i).incorder = mtris.Elem(i).marked ? 1 : 0;30693070for (i = 1; i <= mtris.Size(); i++)3071{3072if (mtris.Elem(i).incorder)3073mtris.Elem(i).marked = 0;3074}3075}30763077if (opt.refine_hp)3078{3079PrintMessage(3,"refine hp");3080BitArray singv(np);3081singv.Clear();30823083if (mesh.GetDimension() == 3)3084{3085for (i = 1; i <= mesh.GetNSeg(); i++)3086{3087const Segment & seg = mesh.LineSegment(i);3088singv.Set (seg.p1);3089singv.Set (seg.p2);3090}3091/*3092for ( i=1; i<= mesh.GetNSE(); i++)3093{3094const Element2d & sel = mesh.SurfaceElement(i);3095for(int j=1; j<=sel.GetNP(); j++)3096singv.Set(sel.PNum(j));3097}3098*/3099}3100else3101{3102// vertices with 2 different bnds3103ARRAY<int> bndind(np);3104bndind = 0;3105for (i = 1; i <= mesh.GetNSeg(); i++)3106{3107const Segment & seg = mesh.LineSegment(i);3108for (j = 0; j < 2; j++)3109{3110int pi = (j == 0) ? seg.p1 : seg.p2;3111if (bndind.Elem(pi) == 0)3112bndind.Elem(pi) = seg.edgenr;3113else if (bndind.Elem(pi) != seg.edgenr)3114singv.Set (pi);3115}3116}3117}3118311931203121for (i = 1; i <= mtets.Size(); i++)3122mtets.Elem(i).incorder = 1;3123for (i = 1; i <= mtets.Size(); i++)3124{3125if (!mtets.Elem(i).marked)3126mtets.Elem(i).incorder = 0;3127for (j = 0; j < 4; j++)3128if (singv.Test (mtets.Elem(i).pnums[j]))3129mtets.Elem(i).incorder = 0;3130}3131for (i = 1; i <= mtets.Size(); i++)3132if (mtets.Elem(i).incorder)3133mtets.Elem(i).marked = 0;313431353136for (i = 1; i <= mprisms.Size(); i++)3137mprisms.Elem(i).incorder = 1;3138for (i = 1; i <= mprisms.Size(); i++)3139{3140if (!mprisms.Elem(i).marked)3141mprisms.Elem(i).incorder = 0;3142for (j = 0; j < 6; j++)3143if (singv.Test (mprisms.Elem(i).pnums[j]))3144mprisms.Elem(i).incorder = 0;3145}3146for (i = 1; i <= mprisms.Size(); i++)3147if (mprisms.Elem(i).incorder)3148mprisms.Elem(i).marked = 0;314931503151for (i = 1; i <= mtris.Size(); i++)3152mtris.Elem(i).incorder = 1;3153for (i = 1; i <= mtris.Size(); i++)3154{3155if (!mtris.Elem(i).marked)3156mtris.Elem(i).incorder = 0;3157for (j = 0; j < 3; j++)3158if (singv.Test (mtris.Elem(i).pnums[j]))3159mtris.Elem(i).incorder = 0;3160}3161for (i = 1; i <= mtris.Size(); i++)3162{3163if (mtris.Elem(i).incorder)3164mtris.Elem(i).marked = 0;3165}3166}316731683169317031713172int hangingvol, hangingsurf, hangingedge;31733174//cout << "write?" << endl;3175//string yn;3176//cin >> yn;31773178(*testout) << "refine volume elements" << endl;3179do3180{3181// refine volume elements31823183int nel = mtets.Size();3184for (i = 1; i <= nel; i++)3185if (mtets.Elem(i).marked)3186{3187MarkedTet oldtet;3188MarkedTet newtet1, newtet2;3189int newp;319031913192oldtet = mtets.Get(i);3193//if(yn == "y")3194// (*testout) << "bisected tet " << oldtet;3195INDEX_2 edge(oldtet.pnums[oldtet.tetedge1],3196oldtet.pnums[oldtet.tetedge2]);3197edge.Sort();3198if (cutedges.Used (edge))3199{3200newp = cutedges.Get(edge);3201}3202else3203{3204Point<3> npt = Center (mesh.Point (edge.I1()),3205mesh.Point (edge.I2()));3206newp = mesh.AddPoint (npt);3207cutedges.Set (edge, newp);3208}32093210BTBisectTet (oldtet, newp, newtet1, newtet2);32113212mtets.Elem(i) = newtet1;3213mtets.Append (newtet2);32143215#ifdef DEBUG3216*testout << "tet1 has elnr = " << i << ", tet2 has elnr = " << mtets.Size() << endl;3217#endif3218//if(yn == "y")3219// (*testout) << "and got " << newtet1 << "and " << newtet2 << endl;32203221mesh.mlparentelement.Append (i);3222}32233224int npr = mprisms.Size();3225for (i = 1; i <= npr; i++)3226if (mprisms.Elem(i).marked)3227{3228MarkedPrism oldprism;3229MarkedPrism newprism1, newprism2;3230int newp1, newp2;32313232oldprism = mprisms.Get(i);3233int pi1 = 0;3234if (pi1 == oldprism.markededge)3235pi1++;3236int pi2 = 3-pi1-oldprism.markededge;32373238INDEX_2 edge1(oldprism.pnums[pi1],3239oldprism.pnums[pi2]);3240INDEX_2 edge2(oldprism.pnums[pi1+3],3241oldprism.pnums[pi2+3]);3242edge1.Sort();3243edge2.Sort();32443245if (cutedges.Used (edge1))3246newp1 = cutedges.Get(edge1);3247else3248{3249Point<3> npt = Center (mesh.Point (edge1.I1()),3250mesh.Point (edge1.I2()));3251newp1 = mesh.AddPoint (npt);3252cutedges.Set (edge1, newp1);3253}3254if (cutedges.Used (edge2))3255newp2 = cutedges.Get(edge2);3256else3257{3258Point<3> npt = Center (mesh.Point (edge2.I1()),3259mesh.Point (edge2.I2()));3260newp2 = mesh.AddPoint (npt);3261cutedges.Set (edge2, newp2);3262}326332643265BTBisectPrism (oldprism, newp1, newp2, newprism1, newprism2);3266//if(yn == "y")3267// (*testout) << "bisected prism " << oldprism << "and got " << newprism1 << "and " << newprism2 << endl;3268mprisms.Elem(i) = newprism1;3269mprisms.Append (newprism2);3270}32713272int nid = mids.Size();3273for (i = 1; i <= nid; i++)3274if (mids.Elem(i).marked)3275{3276MarkedIdentification oldid,newid1,newid2;3277ARRAY<int> newp;32783279oldid = mids.Get(i);32803281ARRAY<INDEX_2> edges;3282edges.Append(INDEX_2(oldid.pnums[oldid.markededge],3283oldid.pnums[(oldid.markededge+1)%oldid.np]));3284edges.Append(INDEX_2(oldid.pnums[oldid.markededge + oldid.np],3285oldid.pnums[(oldid.markededge+1)%oldid.np + oldid.np]));32863287if(oldid.np == 4)3288{3289edges.Append(INDEX_2(oldid.pnums[(oldid.markededge+2)%oldid.np],3290oldid.pnums[(oldid.markededge+3)%oldid.np]));3291edges.Append(INDEX_2(oldid.pnums[(oldid.markededge+2)%oldid.np + oldid.np],3292oldid.pnums[(oldid.markededge+3)%oldid.np + oldid.np]));3293}3294for (j = 0; j < edges.Size(); j++)3295{3296edges[j].Sort();32973298if(cutedges.Used(edges[j]))3299newp.Append(cutedges.Get(edges[j]));3300else3301{3302Point<3> npt = Center (mesh.Point (edges[j].I1()),3303mesh.Point (edges[j].I2()));3304newp.Append(mesh.AddPoint(npt));3305cutedges.Set(edges[j],newp[j]);3306}3307}33083309BTBisectIdentification(oldid,newp,newid1,newid2);3310mids.Elem(i) = newid1;3311mids.Append(newid2);3312}331333143315//IdentifyCutEdges(mesh, cutedges);331633173318hangingvol =3319MarkHangingTets (mtets, cutedges) +3320MarkHangingPrisms (mprisms, cutedges) +3321MarkHangingIdentifications (mids, cutedges);332233233324int nsel = mtris.Size();33253326for (i = 1; i <= nsel; i++)3327if (mtris.Elem(i).marked)3328{3329MarkedTri oldtri;3330MarkedTri newtri1, newtri2;3331PointIndex newp;33323333oldtri = mtris.Get(i);3334int oldpi1 = oldtri.pnums[(oldtri.markededge+1)%3];3335int oldpi2 = oldtri.pnums[(oldtri.markededge+2)%3];3336INDEX_2 edge(oldpi1, oldpi2);3337edge.Sort();33383339// cerr << "edge = " << edge.I1() << "-" << edge.I2() << endl;33403341if (cutedges.Used (edge))3342{3343newp = cutedges.Get(edge);3344}3345else3346{3347Point<3> npt = Center (mesh.Point (edge.I1()),3348mesh.Point (edge.I2()));3349newp = mesh.AddPoint (npt);3350cutedges.Set (edge, newp);3351}3352// newp = cutedges.Get(edge);33533354int si = mesh.GetFaceDescriptor (oldtri.surfid).SurfNr();3355// geom->GetSurface(si)->Project (mesh.Point(newp));3356PointGeomInfo npgi;33573358// cerr << "project point " << newp << " old: " << mesh.Point(newp);3359if (mesh[newp].Type() != EDGEPOINT)3360PointBetween (mesh.Point (oldpi1), mesh.Point (oldpi2),33610.5, si,3362oldtri.pgeominfo[(oldtri.markededge+1)%3],3363oldtri.pgeominfo[(oldtri.markededge+2)%3],3364mesh.Point (newp), npgi);3365// cerr << " new: " << mesh.Point(newp) << endl;33663367BTBisectTri (oldtri, newp, npgi, newtri1, newtri2);3368//if(yn == "y")3369// (*testout) << "bisected tri " << oldtri << "and got " << newtri1 << "and " << newtri2 << endl;337033713372mtris.Elem(i) = newtri1;3373mtris.Append (newtri2);3374mesh.mlparentsurfaceelement.Append (i);3375}33763377int nquad = mquads.Size();3378for (i = 1; i <= nquad; i++)3379if (mquads.Elem(i).marked)3380{3381MarkedQuad oldquad;3382MarkedQuad newquad1, newquad2;3383int newp1, newp2;33843385oldquad = mquads.Get(i);3386/*3387INDEX_2 edge1(oldquad.pnums[0],3388oldquad.pnums[1]);3389INDEX_2 edge2(oldquad.pnums[2],3390oldquad.pnums[3]);3391*/3392INDEX_2 edge1, edge2;3393PointGeomInfo pgi11, pgi12, pgi21, pgi22;3394if (oldquad.markededge==0 || oldquad.markededge==2)3395{3396edge1.I1()=oldquad.pnums[0]; pgi11=oldquad.pgeominfo[0];3397edge1.I2()=oldquad.pnums[1]; pgi12=oldquad.pgeominfo[1];3398edge2.I1()=oldquad.pnums[2]; pgi21=oldquad.pgeominfo[2];3399edge2.I2()=oldquad.pnums[3]; pgi22=oldquad.pgeominfo[3];3400}3401else // 3 || 13402{3403edge1.I1()=oldquad.pnums[0]; pgi11=oldquad.pgeominfo[0];3404edge1.I2()=oldquad.pnums[2]; pgi12=oldquad.pgeominfo[2];3405edge2.I1()=oldquad.pnums[1]; pgi21=oldquad.pgeominfo[1];3406edge2.I2()=oldquad.pnums[3]; pgi22=oldquad.pgeominfo[3];3407}34083409edge1.Sort();3410edge2.Sort();34113412if (cutedges.Used (edge1))3413{3414newp1 = cutedges.Get(edge1);3415}3416else3417{3418Point<3> np1 = Center (mesh.Point (edge1.I1()),3419mesh.Point (edge1.I2()));3420newp1 = mesh.AddPoint (np1);3421cutedges.Set (edge1, newp1);3422}34233424if (cutedges.Used (edge2))3425{3426newp2 = cutedges.Get(edge2);3427}3428else3429{3430Point<3> np2 = Center (mesh.Point (edge2.I1()),3431mesh.Point (edge2.I2()));3432newp2 = mesh.AddPoint (np2);3433cutedges.Set (edge2, newp2);3434}34353436PointGeomInfo npgi1, npgi2;34373438int si = mesh.GetFaceDescriptor (oldquad.surfid).SurfNr();3439// geom->GetSurface(si)->Project (mesh.Point(newp1));3440// geom->GetSurface(si)->Project (mesh.Point(newp2));34413442// (*testout)3443// cerr << "project point 1 " << newp1 << " old: " << mesh.Point(newp1);3444PointBetween (mesh.Point (edge1.I1()), mesh.Point (edge1.I2()),34450.5, si,3446pgi11,3447pgi12,3448mesh.Point (newp1), npgi1);3449// (*testout)3450// cerr << " new: " << mesh.Point(newp1) << endl;345134523453// cerr << "project point 2 " << newp2 << " old: " << mesh.Point(newp2);3454PointBetween (mesh.Point (edge2.I1()), mesh.Point (edge2.I2()),34550.5, si,3456pgi21,3457pgi22,3458mesh.Point (newp2), npgi2);3459// cerr << " new: " << mesh.Point(newp2) << endl;346034613462BTBisectQuad (oldquad, newp1, npgi1, newp2, npgi2,3463newquad1, newquad2);34643465mquads.Elem(i) = newquad1;3466mquads.Append (newquad2);3467}346834693470hangingsurf =3471MarkHangingTris (mtris, cutedges) +3472MarkHangingQuads (mquads, cutedges);34733474hangingedge = 0;34753476int nseg = mesh.GetNSeg ();3477for (i = 1; i <= nseg; i++)3478{3479Segment & seg = mesh.LineSegment (i);3480INDEX_2 edge(seg.p1, seg.p2);3481edge.Sort();3482if (cutedges.Used (edge))3483{3484hangingedge = 1;3485Segment nseg1 = seg;3486Segment nseg2 = seg;34873488int newpi = cutedges.Get(edge);34893490nseg1.p2 = newpi;3491nseg2.p1 = newpi;34923493EdgePointGeomInfo newepgi;349434953496//3497// cerr << "move edgepoint " << newpi << " from " << mesh.Point(newpi);3498PointBetween (mesh.Point (seg.p1), mesh.Point (seg.p2),34990.5, seg.surfnr1, seg.surfnr2,3500seg.epgeominfo[0], seg.epgeominfo[1],3501mesh.Point (newpi), newepgi);3502// cerr << " to " << mesh.Point (newpi) << endl;350335043505nseg1.epgeominfo[1] = newepgi;3506nseg2.epgeominfo[0] = newepgi;35073508mesh.LineSegment (i) = nseg1;3509mesh.AddSegment (nseg2);3510}3511}3512}3513while (hangingvol || hangingsurf || hangingedge);35143515if (printmessage_importance>0)3516{3517ostringstream strstr;3518strstr << mtets.Size() << " tets" << endl3519<< mtris.Size() << " trigs" << endl;3520if (mprisms.Size())3521{3522strstr << mprisms.Size() << " prisms" << endl3523<< mquads.Size() << " quads" << endl;3524}3525strstr << mesh.GetNP() << " points";3526PrintMessage(4,strstr.str());35273528}3529}353035313532// (*testout) << "mtets = " << mtets << endl;35333534if (opt.refine_hp)3535{3536//3537ARRAY<int> v_order (mesh.GetNP());3538v_order = 0;3539if (mesh.GetDimension() == 3)3540{3541for (i = 1; i <= mtets.Size(); i++)3542if (mtets.Elem(i).incorder)3543mtets.Elem(i).order++;35443545for (i = 0; i < mtets.Size(); i++)3546for (j = 0; j < 4; j++)3547if (int(mtets[i].order) > v_order.Elem(mtets[i].pnums[j]))3548v_order.Elem(mtets[i].pnums[j]) = mtets[i].order;3549for (i = 0; i < mtets.Size(); i++)3550for (j = 0; j < 4; j++)3551if (int(mtets[i].order) < v_order.Elem(mtets[i].pnums[j])-1)3552mtets[i].order = v_order.Elem(mtets[i].pnums[j])-1;3553}3554else3555{3556for (i = 1; i <= mtris.Size(); i++)3557if (mtris.Elem(i).incorder)3558{3559mtris.Elem(i).order++;3560}35613562for (i = 0; i < mtris.Size(); i++)3563for (j = 0; j < 3; j++)3564if (int(mtris[i].order) > v_order.Elem(mtris[i].pnums[j]))3565v_order.Elem(mtris[i].pnums[j]) = mtris[i].order;3566for (i = 0; i < mtris.Size(); i++)3567{3568for (j = 0; j < 3; j++)3569if (int(mtris[i].order) < v_order.Elem(mtris[i].pnums[j])-1)3570mtris[i].order = v_order.Elem(mtris[i].pnums[j])-1;3571}3572}3573}35743575mtets.SetAllocSize (mtets.Size());3576mprisms.SetAllocSize (mprisms.Size());3577mids.SetAllocSize (mids.Size());3578mtris.SetAllocSize (mtris.Size());3579mquads.SetAllocSize (mquads.Size());358035813582mesh.ClearVolumeElements();3583mesh.VolumeElements().SetAllocSize (mtets.Size()+mprisms.Size());3584for (i = 1; i <= mtets.Size(); i++)3585{3586Element el(TET);3587el.SetIndex (mtets.Get(i).matindex);3588for (j = 1; j <= 4; j++)3589el.PNum(j) = mtets.Get(i).pnums[j-1];3590el.SetOrder (mtets.Get(i).order);3591mesh.AddVolumeElement (el);3592}3593for (i = 1; i <= mprisms.Size(); i++)3594{3595Element el(PRISM);3596el.SetIndex (mprisms.Get(i).matindex);3597for (j = 1; j <= 6; j++)3598el.PNum(j) = mprisms.Get(i).pnums[j-1];3599el.SetOrder (mprisms.Get(i).order);36003601// degenerated prism ?3602static const int map1[] = { 3, 2, 5, 6, 1 };3603static const int map2[] = { 1, 3, 6, 4, 2 };3604static const int map3[] = { 2, 1, 4, 5, 3 };360536063607const int * map = NULL;3608int deg1 = 0, deg2 = 0, deg3 = 0;3609// int deg = 0;3610if (el.PNum(1) == el.PNum(4)) { map = map1; deg1 = 1; }3611if (el.PNum(2) == el.PNum(5)) { map = map2; deg2 = 1; }3612if (el.PNum(3) == el.PNum(6)) { map = map3; deg3 = 1; }36133614switch (deg1+deg2+deg3)3615{3616case 1:3617{3618for (j = 1; j <= 5; j++)3619el.PNum(j) = mprisms.Get(i).pnums[map[j-1]-1];36203621el.SetType (PYRAMID);3622break;3623}3624case 2:3625{3626static const int tetmap1[] = { 1, 2, 3, 4 };3627static const int tetmap2[] = { 2, 3, 1, 5 };3628static const int tetmap3[] = { 3, 1, 2, 6 };3629if (!deg1) map = tetmap1;3630if (!deg2) map = tetmap2;3631if (!deg3) map = tetmap3;3632for (j = 1; j <= 4; j++)3633el.PNum(j) = mprisms.Get(i).pnums[map[j-1]-1];3634/*3635if (!deg1) el.PNum(4) = el.PNum(4);3636if (!deg2) el.PNum(4) = el.PNum(5);3637if (!deg3) el.PNum(4) = el.PNum(6);3638*/3639el.SetType(TET);3640break;3641}3642default:3643;3644}3645mesh.AddVolumeElement (el);3646}36473648mesh.ClearSurfaceElements();3649for (i = 1; i <= mtris.Size(); i++)3650{3651Element2d el(TRIG);3652el.SetIndex (mtris.Get(i).surfid);3653el.SetOrder (mtris.Get(i).order);3654for (j = 1; j <= 3; j++)3655{3656el.PNum(j) = mtris.Get(i).pnums[j-1];3657el.GeomInfoPi(j) = mtris.Get(i).pgeominfo[j-1];3658}3659mesh.AddSurfaceElement (el);3660}3661for (i = 1; i <= mquads.Size(); i++)3662{3663Element2d el(QUAD);3664el.SetIndex (mquads.Get(i).surfid);3665for (j = 1; j <= 4; j++)3666el.PNum(j) = mquads.Get(i).pnums[j-1];3667Swap (el.PNum(3), el.PNum(4));3668mesh.AddSurfaceElement (el);3669}3670367136723673// write multilevel hierarchy to mesh:3674np = mesh.GetNP();3675mesh.mlbetweennodes.SetSize(np);3676if (mesh.mglevels <= 2)3677{3678PrintMessage(4,"RESETTING mlbetweennodes");3679for (i = 1; i <= np; i++)3680{3681mesh.mlbetweennodes.Elem(i).I1() = 0;3682mesh.mlbetweennodes.Elem(i).I2() = 0;3683}3684}36853686/*3687for (i = 1; i <= cutedges.GetNBags(); i++)3688for (j = 1; j <= cutedges.GetBagSize(i); j++)3689{3690INDEX_2 edge;3691int newpi;3692cutedges.GetData (i, j, edge, newpi);3693mesh.mlbetweennodes.Elem(newpi) = edge;3694}3695*/36963697BitArray isnewpoint(np);3698isnewpoint.Clear();36993700for (i = 1; i <= cutedges.Size(); i++)3701if (cutedges.UsedPos(i))3702{3703INDEX_2 edge;3704int newpi;3705cutedges.GetData (i, edge, newpi);3706isnewpoint.Set(newpi);3707mesh.mlbetweennodes.Elem(newpi) = edge;3708}370937103711/*3712mesh.PrintMemInfo (cout);3713cout << "tets ";3714mtets.PrintMemInfo (cout);3715cout << "prims ";3716mprisms.PrintMemInfo (cout);3717cout << "tris ";3718mtris.PrintMemInfo (cout);3719cout << "quads ";3720mquads.PrintMemInfo (cout);3721cout << "cutedges ";3722cutedges.PrintMemInfo (cout);3723*/372437253726/*37273728// find connected nodes (close nodes)3729TABLE<int> conto(np);3730for (i = 1; i <= mprisms.Size(); i++)3731for (j = 1; j <= 6; j++)3732{3733int n1 = mprisms.Get(i).pnums[j-1];3734int n2 = mprisms.Get(i).pnums[(j+2)%6];3735// if (n1 != n2)3736{3737int found = 0;3738for (k = 1; k <= conto.EntrySize(n1); k++)3739if (conto.Get(n1, k) == n2)3740{3741found = 1;3742break;3743}3744if (!found)3745conto.Add (n1, n2);3746}3747}3748mesh.connectedtonode.SetSize(np);3749for (i = 1; i <= np; i++)3750mesh.connectedtonode.Elem(i) = 0;375137523753// (*testout) << "connection table: " << endl;3754// for (i = 1; i <= np; i++)3755// {3756// (*testout) << "node " << i << ": ";3757// for (j = 1; j <= conto.EntrySize(i); j++)3758// (*testout) << conto.Get(i, j) << " ";3759// (*testout) << endl;3760// }376137623763for (i = 1; i <= np; i++)3764if (mesh.connectedtonode.Elem(i) == 0)3765{3766mesh.connectedtonode.Elem(i) = i;3767ConnectToNodeRec (i, i, conto, mesh.connectedtonode);3768}3769*/37703771// mesh.BuildConnectedNodes();37723773377437753776mesh.ComputeNVertices();3777377837793780// update identification tables3781for (i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++)3782{3783ARRAY<int,PointIndex::BASE> identmap;37843785mesh.GetIdentifications().GetMap (i, identmap);378637873788/*3789for (j = 1; j <= cutedges.GetNBags(); j++)3790for (k = 1; k <= cutedges.GetBagSize(j); k++)3791{3792INDEX_2 i2;3793int newpi;3794cutedges.GetData (j, k, i2, newpi);3795INDEX_2 oi2(identmap.Get(i2.I1()),3796identmap.Get(i2.I2()));3797oi2.Sort();3798if (cutedges.Used (oi2))3799{3800int onewpi = cutedges.Get(oi2);3801mesh.GetIdentifications().Add (newpi, onewpi, i);3802}3803}3804*/38053806for (j = 1; j <= cutedges.Size(); j++)3807if (cutedges.UsedPos(j))3808{3809INDEX_2 i2;3810int newpi;3811cutedges.GetData (j, i2, newpi);3812INDEX_2 oi2(identmap.Get(i2.I1()),3813identmap.Get(i2.I2()));3814oi2.Sort();3815if (cutedges.Used (oi2))3816{3817int onewpi = cutedges.Get(oi2);3818mesh.GetIdentifications().Add (newpi, onewpi, i);3819}3820}3821}38223823382438253826// Repair works only for tets!3827bool do_repair = mesh.PureTetMesh ();38283829//if(mesh.mglevels == 3)3830// noprojection = true;38313832//noprojection = true;38333834if(noprojection)3835{3836do_repair = false;3837for(int ii=1; ii<=mesh.GetNP(); ii++)3838{3839if(isnewpoint.Test(ii) && mesh.mlbetweennodes[ii][0] > 0)3840{3841mesh.Point(ii) = Center(mesh.Point(mesh.mlbetweennodes[ii][0]),mesh.Point(mesh.mlbetweennodes[ii][1]));3842}3843}3844}384538463847// Check/Repair38483849//cout << "Hallo Welt" << endl;3850//getchar();38513852static bool repaired_once;3853if(mesh.mglevels == 1)3854repaired_once = false;38553856//mesh.Save("before.vol");38573858static int reptimer = NgProfiler::CreateTimer("check/repair");3859NgProfiler::RegionTimer * regt(NULL);3860regt = new NgProfiler::RegionTimer(reptimer);38613862ARRAY<ElementIndex> bad_elts;3863ARRAY<double> pure_badness;38643865if(do_repair || quality_loss != NULL)3866{3867pure_badness.SetSize(mesh.GetNP()+2);3868GetPureBadness(mesh,pure_badness,isnewpoint);3869}387038713872if(do_repair)3873{3874const double max_worsening = 1;38753876const bool uselocalworsening = false;38773878bool repaired = false;38793880Validate(mesh,bad_elts,pure_badness,max_worsening,uselocalworsening);38813882if (printmessage_importance>0)3883{3884ostringstream strstr;3885for(int ii=0; ii<bad_elts.Size(); ii++)3886strstr << "bad element " << bad_elts[ii] << "\n";3887PrintMessage(1,strstr.str());3888}3889if(repaired_once || bad_elts.Size() > 0)3890{3891clock_t t1(clock());389238933894// update id-maps3895j=0;3896for(i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)3897{3898if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC)3899{3900mesh.GetIdentifications().GetMap(i,*idmaps[j],true);3901j++;3902}3903}390439053906// do the repair3907try3908{3909RepairBisection(mesh,bad_elts,isnewpoint,*this,3910pure_badness,3911max_worsening,uselocalworsening,3912idmaps);3913repaired = true;3914repaired_once = true;3915}3916catch(NgException & ex)3917{3918PrintMessage(1,string("Problem: ") + ex.What());3919}392039213922if (printmessage_importance>0)3923{3924ostringstream strstr;3925strstr << "Time for Repair: " << double(clock() - t1)/double(CLOCKS_PER_SEC) << endl3926<< "bad elements after repair: " << bad_elts << endl;3927PrintMessage(1,strstr.str());3928}39293930if(quality_loss != NULL)3931Validate(mesh,bad_elts,pure_badness,1e100,uselocalworsening,quality_loss);39323933if(idmaps.Size() == 0)3934UpdateEdgeMarks(mesh,idmaps);39353936/*3937if(1==1)3938UpdateEdgeMarks(mesh,idmaps);3939else3940mesh.mglevels = 1;3941*/39423943//mesh.ImproveMesh();39443945}3946}3947delete regt;39483949395039513952395339543955for(i=0; i<idmaps.Size(); i++)3956delete idmaps[i];3957idmaps.DeleteAll();39583959mesh.UpdateTopology();39603961if(refelementinfofilewrite != "")3962{3963PrintMessage(3,"writing marked-elements information to \"",refelementinfofilewrite,"\"");3964ofstream ofst(refelementinfofilewrite.c_str());39653966WriteMarkedElements(ofst);39673968ofst.close();3969}397039713972PrintMessage (1, "Bisection done");39733974PopStatus();3975}39763977397839793980BisectionOptions :: BisectionOptions ()3981{3982outfilename = NULL;3983mlfilename = NULL;3984refinementfilename = NULL;3985femcode = NULL;3986maxlevel = 50;3987usemarkedelements = 0;3988refine_hp = 0;3989refine_p = 0;3990}399139923993Refinement :: Refinement ()3994{3995optimizer2d = NULL;3996}39973998Refinement :: ~Refinement ()3999{4000;4001}400240034004void Refinement :: PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint,4005int surfi,4006const PointGeomInfo & gi1,4007const PointGeomInfo & gi2,4008Point<3> & newp, PointGeomInfo & newgi)4009{4010newp = p1+secpoint*(p2-p1);4011}40124013void Refinement :: PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint,4014int surfi1, int surfi2,4015const EdgePointGeomInfo & ap1,4016const EdgePointGeomInfo & ap2,4017Point<3> & newp, EdgePointGeomInfo & newgi)4018{4019newp = p1+secpoint*(p2-p1);4020}402140224023Vec<3> Refinement :: GetTangent (const Point<3> & p, int surfi1, int surfi2,4024const EdgePointGeomInfo & ap1) const4025{4026cerr << "Refinement::GetTangent not overloaded" << endl;4027return Vec<3> (0,0,0);4028}40294030Vec<3> Refinement :: GetNormal (const Point<3> & p, int surfi1,4031const PointGeomInfo & gi) const4032{4033cerr << "Refinement::GetNormal not overloaded" << endl;4034return Vec<3> (0,0,0);4035}403640374038void Refinement :: ProjectToSurface (Point<3> & p, int surfi)4039{4040if (printmessage_importance>0)4041cerr << "Refinement :: ProjectToSurface ERROR: no geometry set" << endl;4042};40434044void Refinement :: ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const4045{4046cerr << "Refinement::ProjectToEdge not overloaded" << endl;4047}4048}404940504051