Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/localh.cpp
3206 views
#include <mystdlib.h>1#include "meshing.hpp"234namespace netgen5{67GradingBox :: GradingBox (const double * ax1, const double * ax2)8{9h2 = 0.5 * (ax2[0] - ax1[0]);10for (int i = 0; i <= 2; i++)11{12/*13x1[i] = ax1[i];14x2[i] = ax2[i];15*/16xmid[i] = 0.5 * (ax1[i] + ax2[i]);17}1819/*20(*testout) << "new box: " << xmid[0] << "-" << xmid[1] << "-" << xmid[2]21<< " h = " << (x2[0] - x1[0]) << endl;22*/2324for (int i = 0; i < 8; i++)25childs[i] = NULL;26father = NULL;2728flags.cutboundary = 0;29flags.isinner = 0;30flags.oldcell = 0;31flags.pinner = 0;3233// hopt = x2[0] - x1[0];34hopt = 2 * h2;35}36373839BlockAllocator GradingBox :: ball(sizeof (GradingBox));4041void * GradingBox :: operator new(size_t)42{43return ball.Alloc();44}4546void GradingBox :: operator delete (void * p)47{48ball.Free (p);49}5051525354555657void GradingBox :: DeleteChilds()58{59int i;60for (i = 0; i < 8; i++)61if (childs[i])62{63childs[i]->DeleteChilds();64delete childs[i];65childs[i] = NULL;66}67}686970LocalH :: LocalH (const Point3d & pmin, const Point3d & pmax, double agrading)71{72double x1[3], x2[3];73double hmax;74int i;7576boundingbox = Box3d (pmin, pmax);77grading = agrading;7879// a small enlargement, non-regular points80double val = 0.0879;81for (i = 1; i <= 3; i++)82{8384x1[i-1] = (1 + val * i) * pmin.X(i) - val * i * pmax.X(i);85x2[i-1] = 1.1 * pmax.X(i) - 0.1 * pmin.X(i);86}8788hmax = x2[0] - x1[0];89for (i = 1; i <= 2; i++)90if (x2[i] - x1[i] > hmax)91hmax = x2[i] - x1[i];9293for (i = 0; i <= 2; i++)94x2[i] = x1[i] + hmax;9596root = new GradingBox (x1, x2);97boxes.Append (root);98}99100LocalH :: ~LocalH ()101{102root->DeleteChilds();103delete root;104}105106void LocalH :: Delete ()107{108root->DeleteChilds();109}110111void LocalH :: SetH (const Point3d & p, double h)112{113/*114(*testout) << "Set h at " << p << " to " << h << endl;115if (h < 1e-8)116{117cout << "do not set h to " << h << endl;118return;119}120*/121122if (fabs (p.X() - root->xmid[0]) > root->h2 ||123fabs (p.Y() - root->xmid[1]) > root->h2 ||124fabs (p.Z() - root->xmid[2]) > root->h2)125return;126127/*128if (p.X() < root->x1[0] || p.X() > root->x2[0] ||129p.Y() < root->x1[1] || p.Y() > root->x2[1] ||130p.Z() < root->x1[2] || p.Z() > root->x2[2])131return;132*/133134135if (GetH(p) <= 1.2 * h) return;136137138GradingBox * box = root;139GradingBox * nbox = root;140GradingBox * ngb;141int childnr;142double x1[3], x2[3];143144while (nbox)145{146box = nbox;147childnr = 0;148if (p.X() > box->xmid[0]) childnr += 1;149if (p.Y() > box->xmid[1]) childnr += 2;150if (p.Z() > box->xmid[2]) childnr += 4;151nbox = box->childs[childnr];152};153154155while (2 * box->h2 > h)156{157childnr = 0;158if (p.X() > box->xmid[0]) childnr += 1;159if (p.Y() > box->xmid[1]) childnr += 2;160if (p.Z() > box->xmid[2]) childnr += 4;161162double h2 = box->h2;163if (childnr & 1)164{165x1[0] = box->xmid[0];166x2[0] = x1[0]+h2; // box->x2[0];167}168else169{170x2[0] = box->xmid[0];171x1[0] = x2[0]-h2; // box->x1[0];172}173174if (childnr & 2)175{176x1[1] = box->xmid[1];177x2[1] = x1[1]+h2; // box->x2[1];178}179else180{181x2[1] = box->xmid[1];182x1[1] = x2[1]-h2; // box->x1[1];183}184185if (childnr & 4)186{187x1[2] = box->xmid[2];188x2[2] = x1[2]+h2; // box->x2[2];189}190else191{192x2[2] = box->xmid[2];193x1[2] = x2[2]-h2; // box->x1[2];194}195196ngb = new GradingBox (x1, x2);197box->childs[childnr] = ngb;198ngb->father = box;199200boxes.Append (ngb);201box = box->childs[childnr];202}203204box->hopt = h;205206207double hbox = 2 * box->h2; // box->x2[0] - box->x1[0];208double hnp = h + grading * hbox;209210Point3d np;211int i;212for (i = 1; i <= 3; i++)213{214np = p;215np.X(i) = p.X(i) + hbox;216SetH (np, hnp);217218np.X(i) = p.X(i) - hbox;219SetH (np, hnp);220}221/*222Point3d np;223int i1, i2, i3;224for (i1 = -1; i1 <= 1; i1++)225for (i2 = -1; i2 <= 1; i2++)226for (i3 = -1; i3 <= 1; i3++)227{228np.X() = p.X() + hbox * i1;229np.Y() = p.Y() + hbox * i2;230np.Z() = p.Z() + hbox * i3;231232SetH (np, hnp);233}234*/235}236237238239double LocalH :: GetH (const Point3d & x) const240{241const GradingBox * box = root;242const GradingBox * nbox;243int childnr;244245while (1)246{247childnr = 0;248if (x.X() > box->xmid[0]) childnr += 1;249if (x.Y() > box->xmid[1]) childnr += 2;250if (x.Z() > box->xmid[2]) childnr += 4;251nbox = box->childs[childnr];252if (nbox)253box = nbox;254else255{256// (*testout) << "diam = " << (box->x2[0] - box->x1[0])257// << " h = " << box->hopt << endl;258return box->hopt;259}260}261}262263264/// minimal h in box (pmin, pmax)265double LocalH :: GetMinH (const Point3d & pmin, const Point3d & pmax) const266{267Point3d pmin2, pmax2;268for (int j = 1; j <= 3; j++)269if (pmin.X(j) < pmax.X(j))270{ pmin2.X(j) = pmin.X(j); pmax2.X(j) = pmax.X(j); }271else272{ pmin2.X(j) = pmax.X(j); pmax2.X(j) = pmin.X(j); }273274return GetMinHRec (pmin2, pmax2, root);275}276277278double LocalH :: GetMinHRec (const Point3d & pmin, const Point3d & pmax,279const GradingBox * box) const280{281double h2 = box->h2;282if (pmax.X() < box->xmid[0]-h2 || pmin.X() > box->xmid[0]+h2 ||283pmax.Y() < box->xmid[1]-h2 || pmin.Y() > box->xmid[1]+h2 ||284pmax.Z() < box->xmid[2]-h2 || pmin.Z() > box->xmid[2]+h2)285return 1e8;286/*287if (pmax.X() < box->x1[0] || pmin.X() > box->x2[0] ||288pmax.Y() < box->x1[1] || pmin.Y() > box->x2[1] ||289pmax.Z() < box->x1[2] || pmin.Z() > box->x2[2])290return 1e8;291*/292293294double hmin = 2 * box->h2; // box->x2[0] - box->x1[0];295int i;296297for (i = 0; i <= 7; i++)298{299if (box->childs[i])300{301double hi = GetMinHRec (pmin, pmax, box->childs[i]);302if (hi < hmin)303hmin = hi;304}305}306307return hmin;308}309310311void LocalH :: CutBoundaryRec (const Point3d & pmin, const Point3d & pmax,312GradingBox * box)313{314double h2 = box->h2;315if (pmax.X() < box->xmid[0]-h2 || pmin.X() > box->xmid[0]+h2 ||316pmax.Y() < box->xmid[1]-h2 || pmin.Y() > box->xmid[1]+h2 ||317pmax.Z() < box->xmid[2]-h2 || pmin.Z() > box->xmid[2]+h2)318return;319/*320if (pmax.X() < box->x1[0] || pmin.X() > box->x2[0] ||321pmax.Y() < box->x1[1] || pmin.Y() > box->x2[1] ||322pmax.Z() < box->x1[2] || pmin.Z() > box->x2[2])323return;324*/325326box->flags.cutboundary = 1;327for (int i = 0; i < 8; i++)328if (box->childs[i])329CutBoundaryRec (pmin, pmax, box->childs[i]);330}331332333334335void LocalH :: FindInnerBoxes ( // int (*sameside)(const Point3d & p1, const Point3d & p2),336AdFront3 * adfront,337int (*testinner)(const Point3d & p1))338{339int i;340341int nf = adfront->GetNF();342343for (i = 0; i < boxes.Size(); i++)344boxes[i] -> flags.isinner = 0;345346root->flags.isinner = 0;347348Point3d rpmid(root->xmid[0], root->xmid[1], root->xmid[2]);349Vec3d rv(root->h2, root->h2, root->h2);350Point3d rx2 = rpmid + rv;351Point3d rx1 = rpmid - rv;352353354root->flags.pinner = !adfront->SameSide (rpmid, rx2);355356if (testinner)357(*testout) << "inner = " << root->flags.pinner << " =?= "358<< testinner(Point3d(root->xmid[0], root->xmid[1], root->xmid[2])) << endl;359360ARRAY<int> faceinds(nf);361ARRAY<Box3d> faceboxes(nf);362363for (i = 1; i <= nf; i++)364{365faceinds.Elem(i) = i;366adfront->GetFaceBoundingBox(i, faceboxes.Elem(i));367}368369for (i = 0; i < 8; i++)370FindInnerBoxesRec2 (root->childs[i], adfront, faceboxes, faceinds, nf);371}372373374void LocalH ::375FindInnerBoxesRec2 (GradingBox * box,376class AdFront3 * adfront,377ARRAY<Box3d> & faceboxes,378ARRAY<int> & faceinds, int nfinbox)379{380if (!box) return;381382int i, j;383384GradingBox * father = box -> father;385386Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]);387Vec3d v(box->h2, box->h2, box->h2);388Box3d boxc(c-v, c+v);389390Point3d fc(father->xmid[0], father->xmid[1], father->xmid[2]);391Vec3d fv(father->h2, father->h2, father->h2);392Box3d fboxc(fc-fv, fc+fv);393394Box3d boxcfc(c,fc);395396397static ARRAY<int> faceused;398static ARRAY<int> faceused2;399static ARRAY<int> facenotused;400401faceused.SetSize(0);402facenotused.SetSize(0);403faceused2.SetSize(0);404405for (j = 1; j <= nfinbox; j++)406{407// adfront->GetFaceBoundingBox (faceinds.Get(j), facebox);408const Box3d & facebox = faceboxes.Get(faceinds.Get(j));409410if (boxc.Intersect (facebox))411faceused.Append(faceinds.Get(j));412else413facenotused.Append(faceinds.Get(j));414415if (boxcfc.Intersect (facebox))416faceused2.Append (faceinds.Get(j));417}418419for (j = 1; j <= faceused.Size(); j++)420faceinds.Elem(j) = faceused.Get(j);421for (j = 1; j <= facenotused.Size(); j++)422faceinds.Elem(j+faceused.Size()) = facenotused.Get(j);423424425if (!father->flags.cutboundary)426{427box->flags.isinner = father->flags.isinner;428box->flags.pinner = father->flags.pinner;429}430else431{432Point3d cf(father->xmid[0], father->xmid[1], father->xmid[2]);433434if (father->flags.isinner)435box->flags.pinner = 1;436else437{438if (adfront->SameSide (c, cf, &faceused2))439box->flags.pinner = father->flags.pinner;440else441box->flags.pinner = 1 - father->flags.pinner;442}443444if (box->flags.cutboundary)445box->flags.isinner = 0;446else447box->flags.isinner = box->flags.pinner;448}449450int nf = faceused.Size();451for (i = 0; i < 8; i++)452FindInnerBoxesRec2 (box->childs[i], adfront, faceboxes, faceinds, nf);453}454455456457458459460461462463464465466/*467void LocalH :: FindInnerBoxes ( // int (*sameside)(const Point3d & p1, const Point3d & p2),468AdFront3 * adfront,469int (*testinner)(const Point3d & p1))470{471int i;472for (i = 1; i <= boxes.Size(); i++)473boxes.Elem(i)->flags.isinner = 0;474475root->flags.isinner = 0;476477Point3d rpmid(root->xmid[0], root->xmid[1], root->xmid[2]);478Point3d rx2 = rpmid + Vec3d (root->h2, root->h2, root->h2);479480root->flags.pinner = !adfront->SameSide (rpmid, rx2);481482if (testinner)483(*testout) << "inner = " << root->flags.pinner << " =?= "484<< testinner(Point3d(root->xmid[0], root->xmid[1], root->xmid[2])) << endl;485486487for (i = 2; i <= boxes.Size(); i++)488{489GradingBox * box = boxes.Elem(i);490GradingBox * father = box -> father;491492Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]);493Vec3d v(box->h2, box->h2, box->h2);494Point3d x1 = c-v;495Point3d x2 = c+v;496497498if (!father->flags.cutboundary)499{500box->flags.isinner = father->flags.isinner;501box->flags.pinner = father->flags.pinner;502}503else504{505Point3d cf(father->xmid[0], father->xmid[1], father->xmid[2]);506507if (father->flags.isinner)508box->flags.pinner = 1;509else510{511if (adfront->SameSide (c, cf))512box->flags.pinner = father->flags.pinner;513else514box->flags.pinner = 1 - father->flags.pinner;515}516517if (box->flags.cutboundary)518box->flags.isinner = 0;519else520box->flags.isinner = box->flags.pinner;521}522}523// FindInnerBoxesRec (inner, root);524}525*/526527528void LocalH :: FindInnerBoxesRec ( int (*inner)(const Point3d & p),529GradingBox * box)530{531int i;532if (box->flags.cutboundary)533{534for (i = 0; i < 8; i++)535if (box->childs[i])536FindInnerBoxesRec (inner, box->childs[i]);537}538else539{540if (inner (Point3d (box->xmid[0], box->xmid[1], box->xmid[2])))541SetInnerBoxesRec (box);542}543}544545546void LocalH :: SetInnerBoxesRec (GradingBox * box)547{548box->flags.isinner = 1;549for (int i = 0; i < 8; i++)550if (box->childs[i])551ClearFlagsRec (box->childs[i]);552}553554void LocalH :: ClearFlagsRec (GradingBox * box)555{556box->flags.cutboundary = 0;557box->flags.isinner = 0;558for (int i = 0; i < 8; i++)559if (box->childs[i])560ClearFlagsRec (box->childs[i]);561}562563564void LocalH :: WidenRefinement ()565{566int nb = boxes.Size();567int i;568// (*testout) << "old boxes: " << nb << endl;569for (i = 1; i <= nb; i++)570{571GradingBox * box = boxes.Get(i);572// double h = box->x2[0] - box->x1[0];573double h = box->hopt;574Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]);575// (*testout) << " i = " << i576// << " c = " << c << " h = " << h << endl;577578for (int i1 = -1; i1 <= 1; i1++)579for (int i2 = -1; i2 <= 1; i2++)580for (int i3 = -1; i3 <= 1; i3++)581SetH (Point3d (c.X() + i1 * h,582c.Y() + i2 * h,583c.Z() + i3 * h), 1.001 * h);584}585}586587void LocalH :: GetInnerPoints (ARRAY<Point3d> & points)588{589int i, nb = boxes.Size();590591for (i = 1; i <= nb; i++)592{593GradingBox * box = boxes.Get(i);594/*595if (box->flags.pinner)596points.Append (box->randomip);597*/598// if (box->flags.pinner)599if (box->flags.isinner)600{601Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]);602points.Append (c);603/*604cout << "add point " << c << "; h = " << box->hopt605<< "; max-min = " << (box->x2[0]-box->x1[0]) << endl;606*/607}608}609}610611612613void LocalH :: GetOuterPoints (ARRAY<Point3d> & points)614{615int i, nb = boxes.Size();616617for (i = 1; i <= nb; i++)618{619GradingBox * box = boxes.Get(i);620if (!box->flags.isinner &&621!box->flags.cutboundary)622{623Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]);624points.Append (c);625}626}627}628629630631void LocalH :: Convexify ()632{633ConvexifyRec (root);634}635636void LocalH :: ConvexifyRec (GradingBox * box)637{638Point3d center(box->xmid[0], box->xmid[1], box->xmid[2]);639Point3d hp;640641double size = 2 * box->h2; // box->x2[0] - box->x1[0];642double dx = 0.6 * size;643644double maxh = box->hopt;645int i;646647648649for (i = 1; i <= 6; i++)650{651hp = center;652switch (i)653{654case 1: hp.X() += dx; break;655case 2: hp.X() -= dx; break;656case 3: hp.Y() += dx; break;657case 4: hp.Y() -= dx; break;658case 5: hp.Z() += dx; break;659case 6: hp.Z() -= dx; break;660}661662double hh = GetH (hp);663if (hh > maxh) maxh = hh;664}665666if (maxh < 0.95 * box->hopt)667SetH (center, maxh);668669for (i = 0; i < 8; i++)670if (box->childs[i])671ConvexifyRec (box->childs[i]);672}673674void LocalH :: PrintMemInfo (ostream & ost) const675{676ost << "LocalH: " << boxes.Size() << " boxes of " << sizeof(GradingBox)677<< " bytes = " << boxes.Size()*sizeof(GradingBox) << " bytes" << endl;678}679}680681682