diff --git a/Common/LuaBindings.cpp b/Common/LuaBindings.cpp index a68607dff5535aa5434db04d9c149ec2f102e7ff..1996015a457a3aaf1989cf8b65da1e97145c40d8 100644 --- a/Common/LuaBindings.cpp +++ b/Common/LuaBindings.cpp @@ -6,6 +6,8 @@ #include "Context.h" #include "MVertex.h" #include "MElement.h" +#include "GFace.h" +#include "DivideAndConquer.h" #include "Bindings.h" #include "dgSystemOfEquations.h" #include "luaFunction.h" @@ -234,6 +236,7 @@ binding::binding(){ } _instance=this; L = lua_open(); + /* luaopen_base(L); luaopen_table(L); luaopen_os(L); @@ -241,6 +244,8 @@ binding::binding(){ luaopen_string(L); luaopen_math(L); luaopen_debug(L); + */ + luaL_openlibs(L); lua_register(L,"help",luaHelp); #ifdef HAVE_READLINE @@ -248,6 +253,11 @@ binding::binding(){ lua_register(L,"clearHistory",luaClear); #endif + // lua_pushcfunction(L, luaopen_io); + // lua_call(L, 0, 0); + + + // Register Lua bindings GModel::registerBindings(this); fullMatrix<double>::registerBindings(this); @@ -263,6 +273,9 @@ binding::binding(){ function::registerDefaultFunctions(); MVertex::registerBindings(this); MElement::registerBindings(this); + DocRecord::registerBindings(this); + GEntity::registerBindings(this); + GFace::registerBindings(this); } binding *binding::_instance=NULL; #endif diff --git a/Geo/GEntity.cpp b/Geo/GEntity.cpp index 39572e24ce6031557155ba13c27715d510f87292..17247cb3a65e769b737b0f384b870bdf717474df 100644 --- a/Geo/GEntity.cpp +++ b/Geo/GEntity.cpp @@ -64,3 +64,25 @@ std::string GEntity::getInfoString() return sstream.str(); } + +#include "Bindings.h" + +void GEntity::registerBindings(binding *b) +{ + classBinding *cb = b->addClass<GEntity>("GEntity"); + cb->setDescription("A GEntity is a geometrical entity of the model."); + + methodBinding *cm; + cm = cb->addMethod("model", &GEntity::model); + cm->setDescription("returns the geometric model the entity belongs to."); + + /* + cm = cb->addMethod("getNumMeshElements", (unsigned int (GEntity::*)() ) &GEntity::getNumMeshElements); + cm->setDescription("Return the number of elements of the mesh of the entity."); + cm = cb->addMethod("getMeshElement", &GEntity::getMeshElement); + cm->setDescription("returns the ith MElement."); + cm->setArgNames("i",NULL); + */ + +} + diff --git a/Geo/GEntity.h b/Geo/GEntity.h index 90bc88fefec67dc03d4e676474f9270f1bdbc022..b24b6db0d7b9c8877ddebc087c7c75d2779c7a69 100644 --- a/Geo/GEntity.h +++ b/Geo/GEntity.h @@ -22,6 +22,7 @@ class GRegion; class MVertex; class MElement; class VertexArray; +class binding; // A geometric model entity. class GEntity { @@ -266,6 +267,10 @@ class GEntity { // get the mesh vertex at the given index MVertex *getMeshVertex(unsigned int index) { return mesh_vertices[index]; } + + // bindings + static void registerBindings(binding *b); + }; class GEntityLessThan { diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp index 803c7ef6d9682f69088593ab494c5c1e9e9331e6..7032c53b1a9990b75a0337af854d3eb8b7da3716 100644 --- a/Geo/GFace.cpp +++ b/Geo/GFace.cpp @@ -17,6 +17,7 @@ #include "Numeric.h" #include "GaussLegendre1D.h" #include "Context.h" +#include "meshGFaceLloyd.h" #define SQU(a) ((a)*(a)) @@ -1044,3 +1045,22 @@ bool GFace::fillPointCloud(double maxDist, std::vector<SPoint3> *points, } return true; } + +void GFace::lloyd(int nbiter, int infn){ + lloydAlgorithm algo(nbiter, infn); + algo(this); +} + +#include "Bindings.h" + +void GFace::registerBindings(binding *b) +{ + classBinding *cb = b->addClass<GFace>("GFace"); + cb->setParentClass<GEntity>(); + cb->setDescription("A Geometrical Face."); + methodBinding *cm; + cm = cb->addMethod("lloyd", &GFace::lloyd); + cm->setDescription("do N iteration of Lloyd's algorithm using or not the infinite norm"); + cm->setArgNames("N","infiniteNorm",NULL); +} + diff --git a/Geo/GFace.h b/Geo/GFace.h index 768897e4a12545b4983d511084f764a16cae9be9..09a2f988e254857d5da33a5ea38c0d2a176e3b49 100644 --- a/Geo/GFace.h +++ b/Geo/GFace.h @@ -238,6 +238,9 @@ class GFace : public GEntity bool fillPointCloud(double maxDist, std::vector<SPoint3> *points, std::vector<SVector3> *normals=0); + // apply Lloyd's algorithm to the mesh + void lloyd (int nIter, int infNorm = 0); + struct { // do we recombine the triangles of the mesh? int recombine; @@ -285,6 +288,16 @@ class GFace : public GEntity std::vector<MTriangle*> triangles; std::vector<MQuadrangle*> quadrangles; std::vector<MPolygon*> polygons; + + // an array with additional vertices that are supposed to exist + // in the final mesh of the model face. This can be used for + // boundary layer meshes or when using Lloyd-like smoothing algorithms + // those vertices are classifed on this GFace, their type is MFaceVertex. + // After mesh generation, those are moved to the mesh_vertices array + std::vector<MVertex*> _additional_vertices; + + + static void registerBindings(binding *b); }; #endif diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 81c9fde60c4e1401664b3259eac110ef1951cf0d..82707ba69848a06e570ebcf336d507c267aea321 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -1372,6 +1372,9 @@ void GModel::registerBindings(binding *b) cm = cb->addMethod("getMeshVertexByTag",&GModel::getMeshVertexByTag); cm->setDescription("access a mesh vertex by tag, using the vertex cache"); cm->setArgNames("tag",NULL); + cm = cb->addMethod("getFaceByTag",&GModel::getFaceByTag); + cm->setDescription("access a model face by its tag"); + cm->setArgNames("tag",NULL); cm = cb->setConstructor<GModel>(); cm->setDescription("Create an empty GModel."); } diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp index 02c352e1e1d2adf2f0fd940b2b5a07c758d98ead..39dc4f2feddefe0b39f9f016bc534d0aff42b25b 100644 --- a/Geo/MElement.cpp +++ b/Geo/MElement.cpp @@ -818,6 +818,8 @@ void MElement::registerBindings(binding *b) cm->setArgNames("i",NULL); cm = cb->addMethod("getType", &MElement::getType); cm->setDescription("get the type of the element"); + cm = cb->addMethod("getTypeForMSH", &MElement::getTypeForMSH); + cm->setDescription("get the gmsh type of the element"); cm = cb->addMethod("getPartition", &MElement::getPartition); cm->setDescription("get the partition to which the element belongs"); cm = cb->addMethod("getPolynomialOrder", &MElement::getPolynomialOrder); diff --git a/Mesh/CMakeLists.txt b/Mesh/CMakeLists.txt index b49f985f36202be68c20d83d5d65be364b834bcc..53395398219266715b500f2f2295a9e7b9dc008f 100644 --- a/Mesh/CMakeLists.txt +++ b/Mesh/CMakeLists.txt @@ -13,6 +13,7 @@ set(SRC meshGFaceExtruded.cpp meshGFaceBDS.cpp meshGFaceDelaunayInsertion.cpp + meshGFaceLloyd.cpp meshGFaceOptimize.cpp meshGFaceQuadrilateralize.cpp meshGRegion.cpp diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index 818fb7eed069e6279a80b1cffce89b54c0bb52be..822e029a63c5c0d0acc42f0ae898f2835609fe1b 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -301,6 +301,11 @@ static bool meshGenerator(GFace *gf, int RECUR_ITER, ++itvx; } + // add _additional_vertices + all_vertices.insert(gf->_additional_vertices.begin(), + gf->_additional_vertices.end()); + + if(all_vertices.size() < 3){ Msg::Warning("Mesh Generation of Model Face %d Skipped: " "Only %d Mesh Vertices on The Contours", @@ -478,7 +483,7 @@ static bool meshGenerator(GFace *gf, int RECUR_ITER, if(RECUR_ITER > 0) Msg::Warning(":-) Gmsh was able to recover all edges after %d iterations", - RECUR_ITER); + RECUR_ITER); Msg::Debug("Boundary Edges recovered for surface %d", gf->tag()); @@ -1234,7 +1239,7 @@ void deMeshGFace::operator() (GFace *gf) gf->meshStatistics.nbTriangle = gf->meshStatistics.nbEdge = 0; } -int debugSurface = -1; +int debugSurface = -100; void meshGFace::operator() (GFace *gf) { diff --git a/Numeric/DivideAndConquer.cpp b/Numeric/DivideAndConquer.cpp index 3f79f9ef02dba2ffaf6c5eb771bf56995c184ad5..bd4ce25304e9f7c0a8f489716f6e482e6546e66f 100644 --- a/Numeric/DivideAndConquer.cpp +++ b/Numeric/DivideAndConquer.cpp @@ -19,7 +19,6 @@ #include "DivideAndConquer.h" #include "Numeric.h" #include "robustPredicates.h" -#include "MallocUtils.h" #define Pred(x) ((x)->prev) #define Succ(x) ((x)->next) @@ -334,7 +333,7 @@ int DocRecord::DListInsert(DListRecord **dlist, DPoint center, PointNumero newPo double alpha1, alpha, beta, xx, yy; int first; - newp = (DListRecord *) Malloc(sizeof(DListRecord)); + newp = new DListRecord; newp->point_num = newPoint; if(*dlist == NULL) { @@ -406,7 +405,7 @@ int DocRecord::DListDelete(DListPeek *dlist, PointNumero oldPoint) return 0; if(Succ(*dlist) == *dlist) { if((*dlist)->point_num == oldPoint) { - Free(*dlist); + delete *dlist; *dlist = NULL; return 1; } @@ -421,7 +420,7 @@ int DocRecord::DListDelete(DListPeek *dlist, PointNumero oldPoint) if(p == *dlist) { *dlist = Succ(p); } - Free(p); + delete p; return 1; } p = Succ(p); @@ -440,10 +439,10 @@ int DocRecord::Delete(PointNumero a, PointNumero b) } // compte les points sur le polygone convexe -int DocRecord::CountPointsOnHull(int n) +int DocRecord::CountPointsOnHull() { PointNumero p, p2, temp; - int i; + int i, n=numPoints; if(points[0].adjacent == NULL) return 0; @@ -459,6 +458,26 @@ int DocRecord::CountPointsOnHull(int n) return (i <= n) ? i : -1; } +// compte les points sur le polygone convexe +void DocRecord::ConvexHull() +{ + PointNumero p, p2, temp; + + if(points[0].adjacent == NULL) + return; + int count = 0; + p = 0; + _hull[count++] = p; + p2 = First(0); + while((p2 != 0) && (count < numPoints)) { + temp = p2; + p2 = Successor(p2, p); + p = temp; + _hull[count++] = p; + } +} + + PointNumero *DocRecord::ConvertDlistToArray(DListPeek *dlist, int *n) { DListPeek p, temp; @@ -470,7 +489,7 @@ PointNumero *DocRecord::ConvertDlistToArray(DListPeek *dlist, int *n) max++; p = Pred(p); } while(p != *dlist); - ptr = (PointNumero *) Malloc((max + 1) * sizeof(PointNumero)); + ptr = new PointNumero[max + 1]; if(ptr == NULL) return NULL; p = *dlist; @@ -478,7 +497,7 @@ PointNumero *DocRecord::ConvertDlistToArray(DListPeek *dlist, int *n) ptr[i] = p->point_num; temp = p; p = Pred(p); - Free(temp); + delete temp; } ptr[max] = ptr[0]; *dlist = NULL; @@ -486,6 +505,185 @@ PointNumero *DocRecord::ConvertDlistToArray(DListPeek *dlist, int *n) return ptr; } +// build ready to use voronoi datas +void DocRecord::ConvertDListToVoronoiData() +{ + if (_adjacencies){ + for(int i = 0; i < numPoints; i++) + if (_adjacencies[i].t) + delete [] _adjacencies[i].t; + delete [] _adjacencies; + } + if (_hull)delete [] _hull; + _hullSize = CountPointsOnHull (); + _hull = new PointNumero[_hullSize]; + ConvexHull(); + std::sort(_hull, _hull+_hullSize); + _adjacencies = new STriangle[numPoints]; + + for(PointNumero i = 0; i < numPoints; i++) + _adjacencies[i].t = ConvertDlistToArray(&points[i].adjacent, + &_adjacencies[i].t_length); + +} + +void DocRecord::voronoiCell (PointNumero pt, std::vector<SPoint2> &pts) const { + + if (!_adjacencies){ + printf("no adjacencies were created\n"); + throw; + } + const int n = _adjacencies[pt].t_length; + for(int j = 0; j < n; j++) { + PointNumero a = _adjacencies[pt].t[j]; + PointNumero b = _adjacencies[pt].t[(j+1) %n]; + double pa[2] = {(double)points[a].where.h, (double)points[a].where.v}; + double pb[2] = {(double)points[b].where.h, (double)points[b].where.v}; + double pc[2] = {(double)points[pt].where.h, (double)points[pt].where.v}; + double center[2]; + circumCenterXY (pa,pb,pc,center); + pts.push_back(SPoint2(center[0],center[1])); + } +} + +/* + Consider N points {X_1, \dots, X_N} + We want to find the point X_P that verifies + + min max | X_i - X_P | , i=1,\dots,N + + L2 norm + + min \int_V || X - X_P||^2 dv + + => 2 \int_V || X - X_P|| dv = 0 => X_P is the centroid + + min \int_V || X - X_P||^{2m} dv + + => 2 \int_V || X - X_P||^{2m-1} dv = 0 => X_P is somewhere ... + + now in infinite norm, how to find X_P ? + +*/ + +void DocRecord::makePosView(std::string fileName) { + FILE *f = fopen(fileName.c_str(),"w"); + if (_adjacencies){ + fprintf(f,"View \"voronoi\" {\n"); + for(PointNumero i = 0; i < numPoints; i++) { + std::vector<SPoint2> pts; + double pc[2] = {(double)points[i].where.h, (double)points[i].where.v}; + if (!onHull(i)){ + fprintf(f,"SP(%g,%g,%g) {%g};\n",pc[0],pc[1],0.0,(double)i); + voronoiCell (i,pts); + for (int j=0;j<pts.size();j++){ + fprintf(f,"SL(%g,%g,%g,%g,%g,%g) {%g,%g};\n", + pts[j].x(),pts[j].y(),0.0, + pts[(j+1)%pts.size()].x(),pts[(j+1)%pts.size()].y(),0.0, + (double)i,(double)i); + } + } + else { + fprintf(f,"SP(%g,%g,%g) {%g};\n",pc[0],pc[1],0.0,-(double)i); + } + } + fprintf(f,"};\n"); + } + fclose(f); +} + +void centroidOfOrientedBox(std::vector<SPoint2> &pts, + const double &angle, + double &xc, + double &yc, + double &inertia) { + const int N = pts.size(); + + double sina = sin(angle); + double cosa = cos(angle); + + double xmin = cosa* pts[0].x()+ sina*pts[0].y(); + double xmax = cosa* pts[0].x()+ sina*pts[0].y(); + double ymin = -sina* pts[0].x()+ cosa*pts[0].y(); + double ymax = -sina* pts[0].x()+ cosa*pts[0].y(); + for (int j=1;j<N;j++){ + xmin = std::min(cosa* pts[j].x()+ sina*pts[j].y(),xmin); + ymin = std::min(-sina* pts[j].x()+ cosa*pts[j].y(),ymin); + xmax = std::max(cosa* pts[j].x()+ sina*pts[j].y(),xmax); + ymax = std::max(-sina* pts[j].x()+ cosa*pts[j].y(),ymax); + } + double XC = 0.5*(xmax+xmin); + double YC = 0.5*(ymax+ymin); + xc = XC*cosa - YC *sina; + yc = XC*sina + YC *cosa; + inertia = std::max(xmax-xmin,ymax-ymin); +} + +void centroidOfPolygon(SPoint2 &pc, + std::vector<SPoint2> &pts, + double &xc, + double &yc, + double &inertia) { + double area_tot = 0; + SPoint2 center(0,0); + for (int j=0;j<pts.size();j++){ + SPoint2 &pa =pts[j]; + SPoint2 &pb =pts[(j+1)%pts.size()]; + const double area = triangle_area2d(pa,pb,pc); + area_tot += area; + center += ((pa+pb+pc) * (area/3.0)); + } + SPoint2 x = center * (1.0/area_tot); + inertia = 0; + for (int j=0;j<pts.size();j++){ + SPoint2 &pa =pts[j]; + SPoint2 &pb =pts[(j+1)%pts.size()]; + const double area = triangle_area2d(pa,pb,pc); + + const double b = sqrt ( (pa.x()-pb.x())*(pa.x()-pb.x()) + + (pa.y()-pb.y())*(pa.y()-pb.y()) ); + const double h = 2.0 * area / b; + const double a = fabs((pb.x()-pa.x())*(pc.x()-pa.x())* + (pb.y()-pa.y())*(pc.y()-pa.y()))/b; + + const double j2 = (h*b*b*b + h*a*b*b + h*a*a*b + b*h*h*h) / 12.0; + + center = (pa+pb+pc) * (1.0/3.0); + const SPoint2 dx = x - center; + inertia += j2 + area*area*(dx.x()+dx.x()+dx.y()*dx.y()); + } + xc = x.x(); + yc = x.y(); +} + +double DocRecord::Lloyd(int type) { + fullMatrix<double> cgs(numPoints,2); + double inertia_tot; + for(PointNumero i = 0; i < numPoints; i++) { + PointRecord &pt = points[i]; + std::vector<SPoint2> pts; + voronoiCell (i,pts); + double E; + + if (!points[i].data){ + SPoint2 p (pt.where.h,pt.where.v); + if (type == 0) + centroidOfPolygon (p,pts, cgs(i,0), cgs(i,1),E); + else + centroidOfOrientedBox (pts, 0.0, cgs(i,0),cgs(i,1),E); + } + inertia_tot += E; + } + + for(PointNumero i = 0; i < numPoints; i++) { + if (!points[i].data){ + points[i].where.h = cgs(i,0); + points[i].where.v = cgs(i,1); + } + } + return inertia_tot; +} + // Convertir les listes d'adjacence en triangles int DocRecord::ConvertDListToTriangles() { @@ -495,14 +693,15 @@ int DocRecord::ConvertDListToTriangles() int count = 0, count2 = 0; PointNumero aa, bb, cc; - STriangle *striangle = (STriangle *) Malloc(n * sizeof(STriangle)); + STriangle *striangle = new STriangle[n]; - count2 = CountPointsOnHull(n); + count2 = CountPointsOnHull(); // nombre de triangles que l'on doit obtenir count2 = 2 * (n - 1) - count2; - triangles = (Triangle *) Malloc(2 * count2 * sizeof(Triangle)); + // FIXME ::: WHY 2 * ??????????????????? + triangles = new Triangle[2 * count2]; for(i = 0; i < n; i++) { // on cree une liste de points connectes au point i (t) + nombre @@ -530,8 +729,8 @@ int DocRecord::ConvertDListToTriangles() numTriangles = count2; for(int i = 0; i < n; i++) - Free(striangle[i].t); - Free(striangle); + delete [] striangle[i].t; + delete striangle; return 1; } @@ -548,23 +747,29 @@ void DocRecord::RemoveAllDList() do { temp = p; p = Pred(p); - Free(temp); + delete temp; } while(p != points[i].adjacent); points[i].adjacent = NULL; } } DocRecord::DocRecord(int n) - : numPoints(n), points(NULL), numTriangles(0), triangles(NULL) + : numPoints(n), points(NULL), numTriangles(0), triangles(NULL), _hullSize(0), _hull(NULL),_adjacencies(NULL) { if(numPoints) - points = (PointRecord*)Malloc(numPoints * sizeof(PointRecord)); + points = new PointRecord[numPoints]; } DocRecord::~DocRecord() { - if(points) Free(points); - if(triangles) Free(triangles); + if(points) delete [] points; + if(triangles) delete []triangles; + if(_hull) delete [] _hull; + if (_adjacencies){ + for(int i = 0; i < numPoints; i++) + delete [] _adjacencies[i].t; + delete _adjacencies; + } } void DocRecord::MakeMeshWithPoints() @@ -575,3 +780,49 @@ void DocRecord::MakeMeshWithPoints() RemoveAllDList(); } +void DocRecord::Voronoi() +{ + if(numPoints < 3) return; + BuildDelaunay(); + ConvertDListToVoronoiData(); +} + +void DocRecord::setPoints(fullMatrix<double> *p){ + if (numPoints != p->size1())throw; + for (int i=0;i<p->size1();i++){ + x(i) = (*p)(i,0); + y(i) = (*p)(i,1); + data(i) = (*p)(i,2) < 0 ? (void *) 1 : NULL; + } +} + + +#include "Bindings.h" + +void DocRecord::registerBindings(binding *b) +{ + classBinding *cb = b->addClass<DocRecord>("Triangulator"); + cb->setDescription("A class that does 2D delaunay triangulation (JF's SANDBOX for the moment)"); + methodBinding *cm; + + cm = cb->addMethod("setPoints", &DocRecord::setPoints); + cm->setDescription("Set the NumPoints points of the triangulation (x,y,fixed)"); + cm->setArgNames("points",NULL); + cm = cb->addMethod("Triangulate", &DocRecord::MakeMeshWithPoints); + cm->setDescription("Compute the Delaunay triangulation"); + cm = cb->addMethod("Voronoi", &DocRecord::Voronoi); + cm->setDescription("Compute the Voronoi cells"); + cm = cb->addMethod("hullSize", &DocRecord::hullSize); + cm->setDescription("returns the size of the hull"); + cm = cb->addMethod("makePosView", &DocRecord::makePosView); + cm->setDescription("save a .pos file with the voronoi"); + cm->setArgNames("FileName",NULL); + cm = cb->addMethod("Lloyd", &DocRecord::Lloyd); + cm->setDescription("do one iteration of Lloyd's algorithm"); + cm->setArgNames("Type",NULL); + cm = cb->setConstructor<DocRecord,int>(); + cm->setDescription ("A Triangulator"); + cm->setArgNames("NumPoints",NULL); +} + + diff --git a/Numeric/DivideAndConquer.h b/Numeric/DivideAndConquer.h index 5f23ab104773420f66f624fabac294b9fcb935c9..90f04276d431fc5b063a826b44f7a4a14a70067c 100644 --- a/Numeric/DivideAndConquer.h +++ b/Numeric/DivideAndConquer.h @@ -5,7 +5,13 @@ #ifndef _DIVIDE_AND_CONQUER_H_ #define _DIVIDE_AND_CONQUER_H_ +#include <vector> +#include <algorithm> +#include "fullMatrix.h" +#include "SPoint2.h" +class binding; +class GFace; typedef struct _CDLIST DListRecord, *DListPeek; typedef int PointNumero; @@ -14,11 +20,12 @@ typedef struct{ double h; }DPoint; -typedef struct{ +struct PointRecord{ DPoint where; DListPeek adjacent; void *data; -}PointRecord; + PointRecord () : data (0) , adjacent(0) {} +}; struct _CDLIST{ PointNumero point_num; @@ -46,6 +53,9 @@ typedef struct{ class DocRecord{ private: + int _hullSize; + PointNumero *_hull; + STriangle * _adjacencies; PointNumero Predecessor(PointNumero a, PointNumero b); PointNumero Successor(PointNumero a, PointNumero b); int FixFirst(PointNumero x, PointNumero f); @@ -57,15 +67,17 @@ class DocRecord{ int Qtest(PointNumero h, PointNumero i, PointNumero j, PointNumero k); int Merge(DT vl, DT vr); DT RecurTrig(PointNumero left, PointNumero right); - int BuildDelaunay(); int DListInsert(DListRecord **dlist, DPoint center, PointNumero newPoint); int Insert(PointNumero a, PointNumero b); int DListDelete(DListPeek *dlist, PointNumero oldPoint); int Delete(PointNumero a, PointNumero b); - int CountPointsOnHull(int n); PointNumero *ConvertDlistToArray(DListPeek *dlist, int *n); int ConvertDListToTriangles(); + void ConvertDListToVoronoiData(); void RemoveAllDList(); + int BuildDelaunay(); + int CountPointsOnHull(); + void ConvexHull(); public: int numPoints; // number of points PointRecord *points; // points to triangulate @@ -74,8 +86,29 @@ class DocRecord{ DocRecord(int n); double &x(int i){ return points[i].where.v; } double &y(int i){ return points[i].where.h; } + void* &data(int i){ return points[i].data; } + void setPoints(fullMatrix<double> *p); ~DocRecord(); void MakeMeshWithPoints(); + void Voronoi (); + int hullSize() {return _hullSize;} + int onHull(PointNumero i) {return std::binary_search(_hull, _hull+_hullSize, i);} + void makePosView(std::string); + double Lloyd (int); + void voronoiCell (PointNumero pt, std::vector<SPoint2> &pts) const; + static void registerBindings(binding *b); }; +void centroidOfOrientedBox(std::vector<SPoint2> &pts, + const double &angle, + double &xc, + double &yc, + double &inertia); +void centroidOfPolygon(SPoint2 &pc, + std::vector<SPoint2> &pts, + double &xc, + double &yc, + double &inertia); + + #endif diff --git a/Numeric/Numeric.cpp b/Numeric/Numeric.cpp index 70ec4ba66228dcd37f63dc10a9dd11b102cca838..6166c77bce209cf36c97a3307dc35429780b4e4a 100644 --- a/Numeric/Numeric.cpp +++ b/Numeric/Numeric.cpp @@ -281,6 +281,21 @@ double triangle_area(double p0[3], double p1[3], double p2[3]) return 0.5 * sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]); } +double triangle_area2d(double p0[2], double p1[2], double p2[2]) +{ + const double c = + (p2[0] - p1[0])*(p0[1] - p1[1]) - + (p2[1] - p1[1])*(p0[0] - p1[0]); + + return 0.5 * sqrt(c*c); +} + +double triangle_polar_inertia(double p0[2], double p1[2], double p2[2]) +{ + throw; +} + + void circumCenterXY(double *p1, double *p2, double *p3, double *res) { double d, a1, a2, a3; @@ -294,7 +309,7 @@ void circumCenterXY(double *p1, double *p2, double *p3, double *res) d = 2. * (double)(y1 * (x2 - x3) + y2 * (x3 - x1) + y3 * (x1 - x2)); if(d == 0.0) { - Msg::Warning("Colinear points in circum circle computation"); + // Msg::Warning("Colinear points in circum circle computation"); res[0] = res[1] = -99999.; return ; } diff --git a/Numeric/Numeric.h b/Numeric/Numeric.h index 631683a9c04b2e4d7653981aedd76c84923fd604..605b6688273a19cad90bdcf0ba84b812f79307f0 100644 --- a/Numeric/Numeric.h +++ b/Numeric/Numeric.h @@ -62,6 +62,8 @@ double inv2x2(double mat[2][2], double inv[2][2]); double angle_02pi(double A3); double angle_plan(double V[3], double P1[3], double P2[3], double n[3]); double triangle_area(double p0[3], double p1[3], double p2[3]); +double triangle_area2d(double p0[2], double p1[2], double p2[2]); +double triangle_polar_inertia(double p0[2], double p1[2], double p2[2]); void circumCenterXY(double *p1, double *p2, double *p3, double *res); void circumCenterXYZ(double *p1, double *p2, double *p3, double *res, double *uv=0); char float2char(float f); diff --git a/Numeric/fullMatrix.cpp b/Numeric/fullMatrix.cpp index 97f7a42375105eca659dc3d571d0fc0537317a35..f7d154e46f0af611d77f6785a0374be3ccceb46e 100644 --- a/Numeric/fullMatrix.cpp +++ b/Numeric/fullMatrix.cpp @@ -308,6 +308,9 @@ void fullMatrix<double>::registerBindings(binding *b) cm = cb->addMethod("gemm", &fullMatrix<double>::gemm); cm->setArgNames("A","B","alpha","beta",NULL); cm->setDescription("this = beta*this + alpha * (A.B)"); + cm = cb->addMethod("gemm_naive", &fullMatrix<double>::gemm_naive); + cm->setArgNames("A","B","alpha","beta",NULL); + cm->setDescription("this = beta*this + alpha * (A.B)"); cm = cb->setConstructor<fullMatrix<double>,int,int>(); cm->setDescription ("A new matrix of size 'nRows' x 'nColumns'"); cm->setArgNames("nRows","nColumns",NULL); diff --git a/Numeric/fullMatrix.h b/Numeric/fullMatrix.h index 49e91e46b430fca1c5968db6770fa1ada50bfe24..dd6018c3209e9275bef5bd8045ac2e770c9a355e 100644 --- a/Numeric/fullMatrix.h +++ b/Numeric/fullMatrix.h @@ -197,8 +197,7 @@ class fullMatrix for(int j = j0, destj = destj0; j < j0 + nj; j++, destj++) (*this)(desti, destj) = a(i, j); } - void mult(const fullMatrix<scalar> &b, fullMatrix<scalar> &c)const -#if !defined(HAVE_BLAS) + void mult_naive(const fullMatrix<scalar> &b, fullMatrix<scalar> &c)const { c.scale(0.); for(int i = 0; i < _r; i++) @@ -206,18 +205,30 @@ class fullMatrix for(int k = 0; k < _c; k++) c._data[i + _r * j] += (*this)(i, k) * b(k, j); } -#endif ; - void gemm(const fullMatrix<scalar> &a, const fullMatrix<scalar> &b, - scalar alpha=1., scalar beta=1.) + void mult(const fullMatrix<scalar> &b, fullMatrix<scalar> &c)const #if !defined(HAVE_BLAS) + { + mult_naive(b,c); + } +#endif + ; + void gemm_naive(const fullMatrix<scalar> &a, const fullMatrix<scalar> &b, + scalar alpha=1., scalar beta=1.) { fullMatrix<scalar> temp(a.size1(), b.size2()); - a.mult(b, temp); + a.mult_naive(b, temp); temp.scale(alpha); scale(beta); add(temp); } + ; + void gemm(const fullMatrix<scalar> &a, const fullMatrix<scalar> &b, + scalar alpha=1., scalar beta=1.) +#if !defined(HAVE_BLAS) + { + gemm_naive(anb,alpha,beta); + } #endif ; inline void setAll(const scalar &m) diff --git a/Solver/TESTCASES/CylinderEddies.lua b/Solver/TESTCASES/CylinderEddies.lua index 92987c61d022ac23b26d132629cfa003ab93186a..b35dc895fef726a621989fe53b4785792f5eded8 100644 --- a/Solver/TESTCASES/CylinderEddies.lua +++ b/Solver/TESTCASES/CylinderEddies.lua @@ -71,7 +71,7 @@ for i=1,2 do end if (i % 100 == 0) then DG:exportSolution(string.format("output/cyl-%06d", i)) - DG:saveSolution(string.format("output/cyl-%06d.bin", i)) +-- DG:saveSolution(string.format("output/cyl-%06d.bin", i)) end end diff --git a/benchmarks/2d/conge.geo b/benchmarks/2d/conge.geo index cec41f9134b95ab020b52d427c130682e5a30c6d..8d59bd00fab50acf1160bee46f4cb0d8f58364dc 100644 --- a/benchmarks/2d/conge.geo +++ b/benchmarks/2d/conge.geo @@ -14,7 +14,7 @@ r = 1.0 * unit ; ccos = (-h5*R1+e2* (h5*h5+e2*e2-R1*R1)^0.5) / (h5*h5+e2*e2) ; ssin = ( 1.0 - ccos*ccos )^0.5 ; -Lc1 = 0.01 ; +Lc1 = 0.003 ; Lc2 = 0.003 ; Point(1) = { -e1-e2, 0.0 , 0.0 , Lc1};