Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/improve2gen.cpp
3206 views
#include <mystdlib.h>12#include "meshing.hpp"3#include <opti.hpp>45namespace netgen6{78class ImprovementRule9{10public:11ARRAY<Element2d> oldels;12ARRAY<Element2d> newels;13ARRAY<INDEX_2> deledges;14ARRAY<int> incelsonnode;15ARRAY<int> reused;16int bonus;17int onp;18};192021void MeshOptimize2d :: GenericImprove (Mesh & mesh)22{23if (!faceindex)24{25if (writestatus)26PrintMessage (3, "Generic Improve");2728for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++)29GenericImprove (mesh);3031faceindex = 0;32}3334// int j, k, l, ri;35int np = mesh.GetNP();36int ne = mesh.GetNSE();37// SurfaceElementIndex sei;383940// for (SurfaceElementIndex sei = 0; sei < ne; sei++)41// {42// const Element2d & el = mesh[sei];43// (*testout) << "element " << sei << ": " <<flush;44// for(int j=0; j<el.GetNP(); j++)45// (*testout) << el[j] << " " << flush;46// (*testout) << "IsDeleted() " << el.IsDeleted()<< endl;47// }4849bool ok;50int olddef, newdef;5152ARRAY<ImprovementRule*> rules;53ARRAY<SurfaceElementIndex> elmap;54ARRAY<int> elrot;55ARRAY<PointIndex> pmap;56ARRAY<PointGeomInfo> pgi;5758int surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr();5960ImprovementRule * r1;6162// 2 triangles to quad63r1 = new ImprovementRule;64r1->oldels.Append (Element2d (1, 2, 3));65r1->oldels.Append (Element2d (3, 2, 4));66r1->newels.Append (Element2d (1, 2, 4, 3));67r1->deledges.Append (INDEX_2 (2,3));68r1->onp = 4;69r1->bonus = 2;70rules.Append (r1);7172// 2 quad to 1 quad73r1 = new ImprovementRule;74r1->oldels.Append (Element2d (1, 2, 3, 4));75r1->oldels.Append (Element2d (4, 3, 2, 5));76r1->newels.Append (Element2d (1, 2, 5, 4));77r1->deledges.Append (INDEX_2 (2, 3));78r1->deledges.Append (INDEX_2 (3, 4));79r1->onp = 5;80r1->bonus = 0;81rules.Append (r1);8283// swap quads84r1 = new ImprovementRule;85r1->oldels.Append (Element2d (1, 2, 3, 4));86r1->oldels.Append (Element2d (3, 2, 5, 6));87r1->newels.Append (Element2d (1, 6, 3, 4));88r1->newels.Append (Element2d (1, 2, 5, 6));89r1->deledges.Append (INDEX_2 (2, 3));90r1->onp = 6;91r1->bonus = 0;92rules.Append (r1);9394// three quads to 295r1 = new ImprovementRule;96r1->oldels.Append (Element2d (1, 2, 3, 4));97r1->oldels.Append (Element2d (2, 5, 6, 3));98r1->oldels.Append (Element2d (3, 6, 7, 4));99r1->newels.Append (Element2d (1, 2, 5, 4));100r1->newels.Append (Element2d (4, 5, 6, 7));101r1->deledges.Append (INDEX_2 (2, 3));102r1->deledges.Append (INDEX_2 (3, 4));103r1->deledges.Append (INDEX_2 (3, 6));104r1->onp = 7;105r1->bonus = -1;106rules.Append (r1);107108// quad + 2 connected trigs to quad109r1 = new ImprovementRule;110r1->oldels.Append (Element2d (1, 2, 3, 4));111r1->oldels.Append (Element2d (2, 5, 3));112r1->oldels.Append (Element2d (3, 5, 4));113r1->newels.Append (Element2d (1, 2, 5, 4));114r1->deledges.Append (INDEX_2 (2, 3));115r1->deledges.Append (INDEX_2 (3, 4));116r1->deledges.Append (INDEX_2 (3, 5));117r1->onp = 5;118r1->bonus = 0;119rules.Append (r1);120121// quad + 2 non-connected trigs to quad (a and b)122r1 = new ImprovementRule;123r1->oldels.Append (Element2d (1, 2, 3, 4));124r1->oldels.Append (Element2d (2, 6, 3));125r1->oldels.Append (Element2d (1, 4, 5));126r1->newels.Append (Element2d (1, 3, 4, 5));127r1->newels.Append (Element2d (1, 2, 6, 3));128r1->deledges.Append (INDEX_2 (1, 4));129r1->deledges.Append (INDEX_2 (2, 3));130r1->onp = 6;131r1->bonus = 0;132rules.Append (r1);133134r1 = new ImprovementRule;135r1->oldels.Append (Element2d (1, 2, 3, 4));136r1->oldels.Append (Element2d (2, 6, 3));137r1->oldels.Append (Element2d (1, 4, 5));138r1->newels.Append (Element2d (1, 2, 4, 5));139r1->newels.Append (Element2d (4, 2, 6, 3));140r1->deledges.Append (INDEX_2 (1, 4));141r1->deledges.Append (INDEX_2 (2, 3));142r1->onp = 6;143r1->bonus = 0;144rules.Append (r1);145146// two quad + trig -> one quad + trig147r1 = new ImprovementRule;148r1->oldels.Append (Element2d (1, 2, 3, 4));149r1->oldels.Append (Element2d (2, 5, 6, 3));150r1->oldels.Append (Element2d (4, 3, 6));151r1->newels.Append (Element2d (1, 2, 6, 4));152r1->newels.Append (Element2d (2, 5, 6));153r1->deledges.Append (INDEX_2 (2, 3));154r1->deledges.Append (INDEX_2 (3, 4));155r1->deledges.Append (INDEX_2 (3, 6));156r1->onp = 6;157r1->bonus = -1;158rules.Append (r1);159160// swap quad + trig (a and b)161r1 = new ImprovementRule;162r1->oldels.Append (Element2d (1, 2, 3, 4));163r1->oldels.Append (Element2d (2, 5, 3));164r1->newels.Append (Element2d (2, 5, 3, 4));165r1->newels.Append (Element2d (1, 2, 4));166r1->deledges.Append (INDEX_2 (2, 3));167r1->onp = 5;168r1->bonus = 0;169rules.Append (r1);170171r1 = new ImprovementRule;172r1->oldels.Append (Element2d (1, 2, 3, 4));173r1->oldels.Append (Element2d (2, 5, 3));174r1->newels.Append (Element2d (1, 2, 5, 3));175r1->newels.Append (Element2d (1, 3, 4));176r1->deledges.Append (INDEX_2 (2, 3));177r1->onp = 5;178r1->bonus = 0;179rules.Append (r1);180181182// 2 quads to quad + 2 trigs183r1 = new ImprovementRule;184r1->oldels.Append (Element2d (1, 2, 3, 4));185r1->oldels.Append (Element2d (3, 2, 5, 6));186r1->newels.Append (Element2d (1, 5, 6, 4));187r1->newels.Append (Element2d (1, 2, 5));188r1->newels.Append (Element2d (4, 6, 3));189r1->deledges.Append (INDEX_2 (2, 3));190r1->onp = 6;191r1->bonus = 0;192// rules.Append (r1);193194195196197ARRAY<int> mapped(rules.Size());198ARRAY<int> used(rules.Size());199used = 0;200mapped = 0;201202203204for (int ri = 0; ri < rules.Size(); ri++)205{206ImprovementRule & rule = *rules[ri];207rule.incelsonnode.SetSize (rule.onp);208rule.reused.SetSize (rule.onp);209210for (int j = 1; j <= rule.onp; j++)211{212rule.incelsonnode.Elem(j) = 0;213rule.reused.Elem(j) = 0;214}215216for (int j = 1; j <= rule.oldels.Size(); j++)217{218const Element2d & el = rule.oldels.Elem(j);219for (int k = 1; k <= el.GetNP(); k++)220rule.incelsonnode.Elem(el.PNum(k))--;221}222223for (int j = 1; j <= rule.newels.Size(); j++)224{225const Element2d & el = rule.newels.Elem(j);226for (int k = 1; k <= el.GetNP(); k++)227{228rule.incelsonnode.Elem(el.PNum(k))++;229rule.reused.Elem(el.PNum(k)) = 1;230}231}232}233234235236237TABLE<int,PointIndex::BASE> elonnode(np);238ARRAY<int,PointIndex::BASE> nelonnode(np);239TABLE<SurfaceElementIndex> nbels(ne);240241nelonnode = -4;242243for (SurfaceElementIndex sei = 0; sei < ne; sei++)244{245const Element2d & el = mesh[sei];246247if (el.GetIndex() == faceindex && !el.IsDeleted())248{249for (int j = 0; j < el.GetNP(); j++)250elonnode.Add (el[j], sei);251}252if(!el.IsDeleted())253{254for (int j = 0; j < el.GetNP(); j++)255nelonnode[el[j]]++;256}257}258259for (SurfaceElementIndex sei = 0; sei < ne; sei++)260{261const Element2d & el = mesh[sei];262if (el.GetIndex() == faceindex && !el.IsDeleted())263{264for (int j = 0; j < el.GetNP(); j++)265{266for (int k = 0; k < elonnode[el[j]].Size(); k++)267{268int nbel = elonnode[el[j]] [k];269bool inuse = false;270for (int l = 0; l < nbels[sei].Size(); l++)271if (nbels[sei][l] == nbel)272inuse = true;273if (!inuse)274nbels.Add (sei, nbel);275}276}277}278}279280281for (int ri = 0; ri < rules.Size(); ri++)282{283const ImprovementRule & rule = *rules[ri];284285elmap.SetSize (rule.oldels.Size());286elrot.SetSize (rule.oldels.Size());287pmap.SetSize (rule.onp);288pgi.SetSize (rule.onp);289290291for (SurfaceElementIndex sei = 0; sei < ne; sei++)292{293if (multithread.terminate)294break;295if (mesh[sei].IsDeleted()) continue;296297elmap[0] = sei;298FlatArray<SurfaceElementIndex> neighbours = nbels[sei];299300for (elrot[0] = 0; elrot[0] < mesh[sei].GetNP(); elrot[0]++)301{302const Element2d & el0 = mesh[sei];303const Element2d & rel0 = rule.oldels[0];304305if (el0.GetIndex() != faceindex) continue;306if (el0.IsDeleted()) continue;307if (el0.GetNP() != rel0.GetNP()) continue;308309310pmap = -1;311312for (int k = 0; k < el0.GetNP(); k++)313{314pmap.Elem(rel0[k]) = el0.PNumMod(k+elrot[0]+1);315pgi.Elem(rel0[k]) = el0.GeomInfoPiMod(k+elrot[0]+1);316}317318ok = 1;319for (int i = 1; i < elmap.Size(); i++)320{321// try to find a mapping for reference-element i322323const Element2d & rel = rule.oldels[i];324bool possible = 0;325326for (elmap[i] = 0; elmap[i] < neighbours.Size(); elmap[i]++)327{328const Element2d & el = mesh[neighbours[elmap[i]]];329if (el.IsDeleted()) continue;330if (el.GetNP() != rel.GetNP()) continue;331332for (elrot[i] = 0; elrot[i] < rel.GetNP(); elrot[i]++)333{334possible = 1;335336for (int k = 0; k < rel.GetNP(); k++)337if (pmap.Elem(rel[k]) != -1 &&338pmap.Elem(rel[k]) != el.PNumMod (k+elrot[i]+1))339possible = 0;340341if (possible)342{343for (int k = 0; k < el.GetNP(); k++)344{345pmap.Elem(rel[k]) = el.PNumMod(k+elrot[i]+1);346pgi.Elem(rel[k]) = el.GeomInfoPiMod(k+elrot[i]+1);347}348break;349}350}351if (possible) break;352}353354if (!possible)355{356ok = 0;357break;358}359360elmap[i] = neighbours[elmap[i]];361}362363for(int i=0; ok && i<rule.deledges.Size(); i++)364{365ok = !mesh.IsSegment(pmap.Elem(rule.deledges[i].I1()),366pmap.Elem(rule.deledges[i].I2()));367}368369370371372if (!ok) continue;373374mapped[ri]++;375376olddef = 0;377for (int j = 1; j <= pmap.Size(); j++)378olddef += sqr (nelonnode[pmap.Get(j)]);379olddef += rule.bonus;380381newdef = 0;382for (int j = 1; j <= pmap.Size(); j++)383if (rule.reused.Get(j))384newdef += sqr (nelonnode[pmap.Get(j)] +385rule.incelsonnode.Get(j));386387if (newdef > olddef)388continue;389390// calc metric badness391double bad1 = 0, bad2 = 0;392Vec<3> n;393394SelectSurfaceOfPoint (mesh.Point(pmap.Get(1)), pgi.Get(1));395GetNormalVector (surfnr, mesh.Point(pmap.Get(1)), pgi.Elem(1), n);396397for (int j = 1; j <= rule.oldels.Size(); j++)398bad1 += mesh.SurfaceElement(elmap.Get(j)).CalcJacobianBadness (mesh.Points(), n);399400// check new element:401for (int j = 1; j <= rule.newels.Size(); j++)402{403const Element2d & rnel = rule.newels.Get(j);404Element2d nel(rnel.GetNP());405for (int k = 1; k <= rnel.GetNP(); k++)406nel.PNum(k) = pmap.Get(rnel.PNum(k));407408bad2 += nel.CalcJacobianBadness (mesh.Points(), n);409}410411if (bad2 > 1e3) continue;412413if (newdef == olddef && bad2 > bad1) continue;414415416// generate new element:417for (int j = 1; j <= rule.newels.Size(); j++)418{419const Element2d & rnel = rule.newels.Get(j);420Element2d nel(rnel.GetNP());421nel.SetIndex (faceindex);422for (int k = 1; k <= rnel.GetNP(); k++)423{424nel.PNum(k) = pmap.Get(rnel.PNum(k));425nel.GeomInfoPi(k) = pgi.Get(rnel.PNum(k));426}427428mesh.AddSurfaceElement(nel);429}430431for (int j = 0; j < rule.oldels.Size(); j++)432mesh.DeleteSurfaceElement ( elmap[j] );433434for (int j = 1; j <= pmap.Size(); j++)435nelonnode[pmap.Get(j)] += rule.incelsonnode.Get(j);436437used[ri]++;438}439}440}441442mesh.Compress();443444for (int ri = 0; ri < rules.Size(); ri++)445{446PrintMessage (5, "rule ", ri+1, " ",447mapped[ri], "/", used[ri], " mapped/used");448}449}450451452453454}455456457