Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/curvedelems2.cpp
3206 views
1#include <mystdlib.h>23#include "meshing.hpp"4#ifndef CURVEDELEMS_NEW56namespace netgen7{8910// ----------------------------------------------------------------------------11// CurvedElements12// ----------------------------------------------------------------------------1314CurvedElements :: CurvedElements (const Mesh & amesh)15: mesh(amesh), top(mesh.GetTopology())16{17isHighOrder = 0;18nvisualsubsecs = 2;19nIntegrationPoints = 10;20}212223CurvedElements :: ~CurvedElements ()24{25;26}272829void CurvedElements :: BuildCurvedElements(Refinement * ref, int polydeg, bool rational)30{31if (mesh.coarsemesh)32{33mesh.coarsemesh->GetCurvedElements().BuildCurvedElements (ref, polydeg, rational);34SetHighOrder();35return;36}3738PrintMessage (2, "Build curved elements, order = ", polydeg);3940NgLock lock(const_cast<Mesh&>(mesh).Mutex(), 1);41isHighOrder = 0;42lock.UnLock();4344const_cast<Mesh &>(mesh).UpdateTopology();4546// set order of edges and faces4748BaseFiniteElement2D * fe2d;4950FEEdge edge (*this);51FESegm segm (*this);52FETrig trig (*this);53FEQuad quad (*this);5455int i, k, e, f;5657ARRAY<bool> edgedone;5859edgedone.SetSize (top.GetNEdges());6061edgeorder.SetSize (top.GetNEdges());62faceorder.SetSize (top.GetNFaces());6364int nedgestocurve = mesh.GetNSeg();6566edgedone = 0;67edgeorder = 1;68faceorder = 1;6970if (polydeg == 1)71{72isHighOrder = 0;73return;74}757677/*78for (e = 0; e < top.GetNEdges(); e++)79{80edgedone = 0;81edgeorder[e] = 1;82}8384for (f = 0; f < top.GetNFaces(); f++)85faceorder[f] = 1;86*/8788for (i = 1; i <= mesh.GetNSeg(); i++)89edgeorder[top.GetSegmentEdge(i)-1] = polydeg;909192if (mesh.GetDimension() == 3)93{94for (i = 1; i <= mesh.GetNSE(); i++)95{96faceorder[top.GetSurfaceElementFace(i)-1] = polydeg;9798Element2d elem = mesh[(SurfaceElementIndex) (i-1)];99100ARRAY<int> edgenrs;101top.GetSurfaceElementEdges(i, edgenrs);102103nedgestocurve += top.GetNEdges(elem.GetType());104105for (int e = 0; e < top.GetNEdges(elem.GetType()); e++)106edgeorder[edgenrs[e]-1] = polydeg;107}108}109110111PrintMessage (1, "Building curved elements, order = ", polydeg);112PushStatusF ("curving edges");113114115116// set edgecoeffs and facecoeffs arrays index and size117118edgecoeffsindex.SetSize (top.GetNEdges()+1);119facecoeffsindex.SetSize (top.GetNFaces()+1);120121edgecoeffsindex[0] = 0;122for (e = 2; e <= top.GetNEdges()+1; e++)123edgecoeffsindex[e-1] = edgecoeffsindex[e-2] + edgeorder[e-2]-1;124125facecoeffsindex[0] = 0;126for (f = 2; f <= top.GetNFaces()+1; f++)127{128switch (top.GetFaceType (f-1))129{130case TRIG:131facecoeffsindex[f-1] = facecoeffsindex[f-2] +132(faceorder[f-2]-1)*(faceorder[f-2]-2)/2;133break;134case QUAD:135facecoeffsindex[f-1] = facecoeffsindex[f-2] +136(faceorder[f-2]-1)*(faceorder[f-2]-1);137break;138}139}140141edgecoeffs.SetSize(edgecoeffsindex[top.GetNEdges()]);142facecoeffs.SetSize(facecoeffsindex[top.GetNFaces()]);143144145146// evaluate edge points147148PointGeomInfo newgi; // dummy variable, only needed for function call149EdgePointGeomInfo newepgi; // dummy variable, only needed for function call150Point3d xexact; // new point to be stored in ARRAY edgepts151152ARRAY<double> xi, wi;153ComputeGaussRule(nIntegrationPoints, xi, wi);154155for (i=0; i<edgecoeffsindex[top.GetNEdges()]; i++)156edgecoeffs[i] = Vec<3>(0.,0.,0.);157158159160161// all edges belonging to segments162163for (i=0; i<mesh.GetNSeg(); i++)164{165if (multithread.terminate) return;166167SetThreadPercent( double(100*i/nedgestocurve) );168169int edgenr = top.GetSegmentEdge(i+1);170171if (edgedone[edgenr-1]) continue;172173edgedone[edgenr-1] = 1;174175Segment s = mesh.LineSegment(i+1);176177segm.SetElementNumber (i+1);178179for (k = 2; k <= segm.GetEdgeOrder(); k++)180edgecoeffs[edgecoeffsindex[edgenr-1]+k-2] = Vec<3>(0.,0.,0.);181182for (int l = 0; l < nIntegrationPoints; l++)183{184segm.SetReferencePoint (Point<1>(xi[l]));185segm.CalcVertexShapes ();186segm.CalcEdgeLaplaceShapes ();187188Point<3> xv(0,0,0);189190for (int v = 0; v < 2; v++)191xv = xv + segm.GetVertexShape(v) * mesh.Point(segm.GetVertexNr(v));192193double secpoint = xi[l];194195ref->PointBetween (mesh.Point(segm.GetVertexNr(1)),196mesh.Point(segm.GetVertexNr(0)), secpoint,197s.surfnr2, s.surfnr1,198s.epgeominfo[1], s.epgeominfo[0],199xexact, newepgi);200201for (int k = 2; k <= segm.GetEdgeOrder(); k++)202edgecoeffs[edgecoeffsindex[edgenr-1]+k-2] -=203wi[l] * segm.GetEdgeLaplaceShape(k-2) * Vec<3>(xexact - xv);204205}206207for (k = 2; k <= segm.GetEdgeOrder(); k++)208edgecoeffs[edgecoeffsindex[edgenr-1]+k-2] =209(2.0*(k-1.0)+1.0)*edgecoeffs[edgecoeffsindex[edgenr-1]+k-2];210211}212213214215216217// all edges belonging to surface elements218219if (mesh.GetDimension() == 3)220{221int nedgescurved = mesh.GetNSeg();222for (int i=0; i<mesh.GetNSE(); i++)223{224if (multithread.terminate) return;225226// SetThreadPercent( double(100*(mesh.GetNSeg()+i)/nedgestocurve) );227Element2d elem = mesh[(SurfaceElementIndex) i];228const ELEMENT_EDGE * eledges = MeshTopology::GetEdges(elem.GetType());229230ARRAY<int> edgenrs;231ARRAY<int> orient;232top.GetSurfaceElementEdges(i+1, edgenrs);233top.GetSurfaceElementEdgeOrientations(i+1, orient);234235for (int e = 0; e < top.GetNEdges(elem.GetType()); e++)236{237// cout << "e = " << e << "/" << top.GetNEdges(elem.GetType()) << endl;238239nedgescurved++;240241if (edgedone[edgenrs[e]-1]) continue;242243edgedone[edgenrs[e]-1] = 1;244245SetThreadPercent( double(100*(nedgescurved)/nedgestocurve) );246247edge.SetElementNumber (edgenrs[e]);248249for (k = 2; k <= edge.GetEdgeOrder(); k++)250edgecoeffs[edgecoeffsindex[edgenrs[e]-1]+k-2] = Vec<3>(0.,0.,0.);251252for (int l = 0; l < nIntegrationPoints; l++)253{254// cout << "." << flush;255edge.SetReferencePoint (Point<1>(xi[l]));256edge.CalcVertexShapes ();257edge.CalcEdgeLaplaceShapes ();258259Point<3> xv(0,0,0);260for (int v = 0; v < 2; v++)261xv = xv + edge.GetVertexShape(v) * mesh.Point(edge.GetVertexNr(v));262263double secpoint = xi[l];264265if (orient[e] == 1)266ref->PointBetween (mesh.Point(edge.GetVertexNr(1)),267mesh.Point(edge.GetVertexNr(0)), secpoint,268mesh.GetFaceDescriptor(elem.GetIndex()).SurfNr(),269elem.GeomInfoPi(eledges[e][1]),270elem.GeomInfoPi(eledges[e][0]),271xexact, newgi);272else273ref->PointBetween (mesh.Point(edge.GetVertexNr(1)),274mesh.Point(edge.GetVertexNr(0)), secpoint,275mesh.GetFaceDescriptor(elem.GetIndex()).SurfNr(),276elem.GeomInfoPi(eledges[e][0]),277elem.GeomInfoPi(eledges[e][1]),278xexact, newgi);279280for (k = 2; k <= edge.GetEdgeOrder(); k++)281edgecoeffs[edgecoeffsindex[edgenrs[e]-1]+k-2] -=282wi[l] * edge.GetEdgeLaplaceShape(k-2) * Vec<3>(xexact - xv);283}284// cout << endl;285for (k = 2; k <= edge.GetEdgeOrder(); k++)286edgecoeffs[edgecoeffsindex[edgenrs[e]-1]+k-2] =287(2.0*(k-1.0)+1.0)*edgecoeffs[edgecoeffsindex[edgenrs[e]-1]+k-2];288289}290}291}292293294295296/*297298// L2-Projection for edges299300301cout << "WARNING: L2-Projection for edges" << endl;302303if (mesh.GetDimension() == 3)304{305for (int i=0; i<mesh.GetNSE(); i++)306{307Element2d elem = mesh[(SurfaceElementIndex) i];308const ELEMENT_EDGE * eledges = MeshTopology::GetEdges(elem.GetType());309310ARRAY<int> edgenrs;311ARRAY<int> orient;312top.GetSurfaceElementEdges(i+1, edgenrs);313top.GetSurfaceElementEdgeOrientations(i+1, orient);314315for (int e = 0; e < top.GetNEdges(elem.GetType()); e++)316{317edge.SetElementNumber (edgenrs[e]);318319int npoints = edge.GetEdgeOrder()-1;320321if (npoints == 0) continue;322323DenseMatrix mat(npoints);324DenseMatrix inv(npoints);325Vector vec[3];326327for (int k = 0; k < 3; k++)328{329vec[k].SetSize(npoints);330for (int n = 1; n <= npoints; n++) vec[k].Set(n, 0.);331}332333for (int l = 0; l < nIntegrationPoints; l++)334{335double w = wi[l];336337edge.SetReferencePoint (Point<1>(xi[l]));338edge.CalcVertexShapes ();339edge.CalcEdgeShapes ();340341for (int n = 0; n < npoints; n++)342for (int m = 0; m < npoints; m++)343mat.Set(n+1, m+1, mat.Get(n+1,m+1) +344edge.GetEdgeShape(n) * edge.GetEdgeShape(m) * w);345346Point<3> xv(0,0,0);347for (int v = 0; v < 2; v++)348xv = xv + edge.GetVertexShape(v) * mesh.Point(edge.GetVertexNr(v));349350double secpoint = xi[l];351352ref->PointBetween (mesh.Point(edge.GetVertexNr(1)),353mesh.Point(edge.GetVertexNr(0)), secpoint,354mesh.GetFaceDescriptor(elem.GetIndex()).SurfNr(),355elem.GeomInfoPi(eledges[e][1]),356elem.GeomInfoPi(eledges[e][0]),357xexact, newgi);358359for (int k = 2; k <= edge.GetEdgeOrder(); k++)360{361vec[0].Set(k-1, vec[0].Get(k-1) + Vec<3>(xexact - xv)(0)*edge.GetEdgeShape(k-2)*w );362vec[1].Set(k-1, vec[1].Get(k-1) + Vec<3>(xexact - xv)(1)*edge.GetEdgeShape(k-2)*w );363vec[2].Set(k-1, vec[2].Get(k-1) + Vec<3>(xexact - xv)(2)*edge.GetEdgeShape(k-2)*w );364}365366}367368369CalcInverse(mat,inv);370371Vector a0, a1, a2;372373a0 = inv*vec[0];374a1 = inv*vec[1];375a2 = inv*vec[2];376377int index = edgecoeffsindex[edge.GetEdgeNr()-1];378379for (int n = 0; n < npoints; n++, index++)380edgecoeffs[index] = Vec<3>(a0(n+1), a1(n+1), a2(n+1));381}382}383}384385386for (int i=0; i<mesh.GetNSeg(); i++)387{388int edgenr = top.GetSegmentEdge(i+1);389390Segment s = mesh.LineSegment(i+1);391392segm.SetElementNumber (i+1);393394int npoints = segm.GetEdgeOrder()-1;395396if (npoints == 0) continue;397398DenseMatrix mat(npoints);399DenseMatrix inv(npoints);400Vector vec[3];401402for (int k = 0; k < 3; k++)403{404vec[k].SetSize(npoints);405for (int n = 1; n <= npoints; n++) vec[k].Set(n, 0.);406}407408for (int l = 0; l < nIntegrationPoints; l++)409{410double w = wi[l];411412segm.SetReferencePoint (Point<1>(xi[l]));413segm.CalcVertexShapes ();414segm.CalcEdgeShapes ();415416for (int n = 0; n < npoints; n++)417for (int m = 0; m < npoints; m++)418mat.Set(n+1, m+1, mat.Get(n+1,m+1) +419segm.GetEdgeShape(n) * segm.GetEdgeShape(m) * w);420421Point<3> xv(0,0,0);422for (int v = 0; v < 2; v++)423xv = xv + segm.GetVertexShape(v) * mesh.Point(segm.GetVertexNr(v));424425double secpoint = xi[l];426427if (segm.GetEdgeOrientation() == -1) secpoint = 1. - secpoint; // reverse orientation428429ref->PointBetween (mesh.Point(segm.GetVertexNr(1)),430mesh.Point(segm.GetVertexNr(0)), secpoint,431s.surfnr2, s.surfnr1,432s.epgeominfo[1], s.epgeominfo[0],433xexact, newepgi);434435for (int k = 2; k <= segm.GetEdgeOrder(); k++)436{437vec[0].Set(k-1, vec[0].Get(k-1) + Vec<3>(xexact - xv)(0)*segm.GetEdgeShape(k-2)*w );438vec[1].Set(k-1, vec[1].Get(k-1) + Vec<3>(xexact - xv)(1)*segm.GetEdgeShape(k-2)*w );439vec[2].Set(k-1, vec[2].Get(k-1) + Vec<3>(xexact - xv)(2)*segm.GetEdgeShape(k-2)*w );440}441442}443444445CalcInverse(mat,inv);446447Vector a0, a1, a2;448449a0 = inv*vec[0];450a1 = inv*vec[1];451a2 = inv*vec[2];452453int index = edgecoeffsindex[segm.GetEdgeNr()-1];454455for (int n = 0; n < npoints; n++, index++)456edgecoeffs[index] = Vec<3>(a0(n+1), a1(n+1), a2(n+1));457458459460}461462*/463464465466467468// evaluate face points469470if (mesh.GetDimension() == 3)471{472PopStatus ();473PushStatusF ("curving faces");474475for (int j=0; j<facecoeffsindex[top.GetNFaces()]; j++)476facecoeffs[j] = Vec<3>(0.,0.,0.);477478for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) // for all surface elements479{480if (multithread.terminate) return;481482SetThreadPercent( double(100*i/mesh.GetNSE()) );483484Element2d elem = mesh[i];485486if (elem.GetType() == TRIG)487fe2d = &trig;488else489fe2d = &quad;490491fe2d->SetElementNumber (i+1);492493int npoints = fe2d->GetNFaceShapes();494495if (npoints == 0) continue;496497DenseMatrix mat(npoints);498DenseMatrix inv(npoints);499Vector vec[3];500501for (int k = 0; k < 3; k++)502{503vec[k].SetSize(npoints);504for (int n = 1; n <= npoints; n++) vec[k].Set(n, 0.);505}506507for (int j = 0; j < nIntegrationPoints; j++)508{509for (int k = 0; k < nIntegrationPoints; k++)510{511double w;512Point<2> xr;513514if (elem.GetType() == TRIG)515{516w = wi[j]*wi[k]*(1-xi[j]);517xr = Point<2> (xi[j], xi[k]*(1-xi[j]));518}519else520{521w = wi[j]*wi[k];522xr = Point<2> (xi[j], xi[k]);523}524525fe2d->SetReferencePoint (xr);526fe2d->CalcFaceShapes ();527fe2d->CalcVertexShapes ();528fe2d->CalcEdgeShapes ();529fe2d->CalcFaceLaplaceShapes ();530531// integration over the product of the gradients of the face shapes532533for (int n = 0; n < npoints; n++)534for (int m = 0; m < npoints; m++)535mat.Set(n+1, m+1,536mat.Get(n+1,m+1) +537fe2d->GetFaceDShape(n)*fe2d->GetFaceDShape(m)*w);538539// integration over the difference between the exact geometry and the one540// defined by vertex and edge shape functions times face shape541542// double giu = 0, giv = 0;543PointGeomInfo gi;544gi.trignum = elem.GeomInfoPi(1).trignum;545gi.u = 0.0;546gi.v = 0.0;547Point<3> xve(0.,0.,0.);548549// vertex shape functions550for (int v = 0; v < fe2d->GetNVertices(); v++)551{552xve = xve + fe2d->GetVertexShape(v) * mesh.Point(fe2d->GetVertexNr(v));553gi.u += fe2d->GetVertexShape(v) * elem.GeomInfoPi(v+1).u;554gi.v += fe2d->GetVertexShape(v) * elem.GeomInfoPi(v+1).v;555}556557// edge shape functions558int index = 0;559for (int e = 0; e < fe2d->GetNEdges(); e++)560{561int gindex = edgecoeffsindex[fe2d->GetEdgeNr(e)-1];562for (int k = 2; k <= fe2d->GetEdgeOrder(e); k++, index++, gindex++)563xve = xve + fe2d->GetEdgeShape(index) * edgecoeffs[gindex];564}565566// exact point567568Point<3> xexact = xve;569ref->ProjectToSurface (xexact, mesh.GetFaceDescriptor(elem.GetIndex()).SurfNr(), gi);570571Vec<3> v2 = w*(Vec<3>(xexact)-Vec<3>(xve));572573for (int k = 0; k < 3; k++)574for (int n = 0; n < npoints; n++)575vec[k].Set(n+1, vec[k].Get(n+1) - fe2d->GetFaceLaplaceShape(n)*v2(k));576}577}578579CalcInverse(mat,inv);580581Vector a0(npoints), a1(npoints), a2(npoints);582583/*584a0 = inv*vec[0];585a1 = inv*vec[1];586a2 = inv*vec[2];587*/588inv.Mult (vec[0], a0);589inv.Mult (vec[1], a1);590inv.Mult (vec[2], a2);591592int index = facecoeffsindex[fe2d->GetFaceNr()-1];593594for (int n = 0; n < npoints; n++, index++)595facecoeffs[index] = Vec<3>(a0.Elem(n+1), a1.Elem(n+1), a2.Elem(n+1));596}597}598599600601602/*603cout << "WARNING: L2-Projection for faces" << endl;604605// evaluate face points606607if (mesh.GetDimension() == 3)608{609for (int i=0; i<facecoeffsindex[top.GetNFaces()]; i++)610facecoeffs[i] = Vec<3>(0.,0.,0.);611612for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) // for all surface elements613{614Element2d elem = mesh[i];615616if (elem.GetType() == TRIG)617fe2d = &trig;618else619fe2d = &quad;620621fe2d->SetElementNumber (i+1);622623int npoints = fe2d->GetNFaceShapes();624625if (npoints == 0) continue;626627DenseMatrix mat(npoints);628DenseMatrix inv(npoints);629Vector vec[3];630631for (int k = 0; k < 3; k++)632{633vec[k].SetSize(npoints);634for (int n = 1; n <= npoints; n++) vec[k].Set(n, 0.);635}636637for (int j = 0; j < nIntegrationPoints; j++)638{639for (int k = 0; k < nIntegrationPoints; k++)640{641double w;642Point<2> xr;643644if (elem.GetType() == TRIG)645{646w = wi[j]*wi[k]*(1-xi[j]);647xr = Point<2> (xi[j], xi[k]*(1-xi[j]));648}649else650{651w = wi[j]*wi[k];652xr = Point<2> (xi[j], xi[k]);653}654655fe2d->SetReferencePoint (xr);656// fe2d->CalcFaceDShape (false, true);657fe2d->CalcFaceShapes ();658659// integration over the product of the gradients of the face shapes660661for (int n = 0; n < npoints; n++)662for (int m = 0; m < npoints; m++)663mat.Set(n+1, m+1, mat.Get(n+1,m+1) +664fe2d->GetFaceShape(n)*fe2d->GetFaceShape(m)*w);665666// integration over the difference between the exact geometry and the one667// defined by vertex and edge shape functions times face shape668669Point<3> xve(0.,0.,0.);670671// vertex shape functions672fe2d->CalcVertexShapes ();673// fe2d->CalcVertexShape (true, false);674for (int v = 0; v < fe2d->GetNVertices(); v++)675xve = xve + fe2d->GetVertexShape(v) * mesh.Point(fe2d->GetVertexNr(v));676677// edge shape functions678// fe2d->CalcEdgeShape (true, false);679fe2d->CalcEdgeShapes ();680681int index = 0;682for (int e = 0; e < fe2d->GetNEdges(); e++)683{684int gindex = edgecoeffsindex[fe2d->GetEdgeNr(e)-1];685686for (int k = 2; k <= fe2d->GetEdgeOrder(e); k++, index++, gindex++)687xve = xve + fe2d->GetEdgeShape(index) * edgecoeffs[gindex];688}689690// exact point691692Point<3> xexact = xve;693ref->ProjectToSurface (xexact, mesh.GetFaceDescriptor(elem.GetIndex()).SurfNr());694695Vec<3> v = w*(Vec<3>(xexact)-Vec<3>(xve));696697fe2d->CalcFaceLaplaceShapes ();698699for (int k = 0; k < 3; k++)700for (int n = 0; n < npoints; n++)701vec[k].Set(n+1, vec[k].Get(n+1) + fe2d->GetFaceShape(n)*v(k));702}703}704705CalcInverse(mat,inv);706707Vector a0, a1, a2;708709a0 = inv*vec[0];710a1 = inv*vec[1];711a2 = inv*vec[2];712713int index = facecoeffsindex[fe2d->GetFaceNr()-1];714715for (int n = 0; n < npoints; n++, index++)716facecoeffs[index] = Vec<3>(a0(n+1), a1(n+1), a2(n+1));717}718}719*/720721722PrintMessage (5, "reducing order");723724for (e = 0; e < top.GetNEdges(); e++)725if (edgeorder[e] > 1)726{727int i;728double maxcoeff = 0.;729730for (i = edgecoeffsindex[e]; i < edgecoeffsindex[e+1]; i++)731maxcoeff = max2 (maxcoeff, edgecoeffs[i].Length());732733if (maxcoeff < 1e-12) edgeorder[e] = 1;734}735736for (f = 0; f < top.GetNFaces(); f++)737if (faceorder[f] > 1)738{739int i;740double maxcoeff = 0.;741742for (i = facecoeffsindex[f]; i < facecoeffsindex[f+1]; i++)743maxcoeff = max (maxcoeff, facecoeffs[i].Length());744745if (maxcoeff < 1e-12) faceorder[f] = 1;746}747748isHighOrder = 1; // true749750PrintMessage(1, "done");751PopStatus();752// cout << "finished" << endl;753}754755} // namespace netgen756757#endif758759760