diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index 1e10d104c83c7cde54e62f8836f28d4b52e8f7c0..d546b9da70ea9f46d700823c62d40d5b2b4ce551 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.260 2004-07-30 12:22:02 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.261 2004-08-03 15:22:18 remacle Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -2489,6 +2489,7 @@ void geometry_physical_add_point_cb(CALLBACK_ARGS) void geometry_physical_add_line_cb(CALLBACK_ARGS) { + WID->call_for_solver_plugin(1); _add_physical("Line"); } diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp index 2efa890a13ebc284ba1b2cdf5d9c1bcac40edc61..977e6a83280c18fade1cce39e9acfed952daa36d 100644 --- a/Fltk/GUI.cpp +++ b/Fltk/GUI.cpp @@ -1,4 +1,4 @@ -// $Id: GUI.cpp,v 1.329 2004-07-30 12:22:02 geuzaine Exp $ +// $Id: GUI.cpp,v 1.330 2004-08-03 15:22:18 remacle Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -44,6 +44,7 @@ #include "Context.h" #include "Options.h" #include "Geo.h" +#include "CAD.h" #include "Mesh.h" #include "Draw.h" #include "GUI.h" @@ -762,6 +763,7 @@ GUI::GUI(int argc, char **argv) create_clip_window(); create_about_window(); create_geometry_context_window(0); + call_for_solver_plugin (-1); create_mesh_context_window(0); for(i = 0; i < MAXSOLVERS; i++) { solver[i].window = NULL; @@ -3579,6 +3581,19 @@ void GUI::create_geometry_context_window(int num) context_geometry_window->end(); } +// Create the window for physical context dependant definitions + +void GUI::call_for_solver_plugin (int dim) +{ + GMSH_Solve_Plugin *sp = GMSH_PluginManager::instance()->findSolverPlugin(); + if (sp) + { + sp->popupPropertiesForPhysicalEntity(dim); + } +} + + + // Create the window for mesh context dependant definitions void GUI::create_mesh_context_window(int num) diff --git a/Fltk/GUI.h b/Fltk/GUI.h index 27c3119b72b3caaa128105af2765e414d8b4c349..692b524e650bb70949a08eb6c16dfbac1c7660d1 100644 --- a/Fltk/GUI.h +++ b/Fltk/GUI.h @@ -263,6 +263,7 @@ public: void create_message_window(); void create_about_window(); void create_geometry_context_window(int num); + void call_for_solver_plugin (int dim); void create_mesh_context_window(int num); void create_solver_window(int num); diff --git a/Plugin/Makefile b/Plugin/Makefile index 50c9f35e96e91e9638c6617f62c5a29d973788f6..bca299036c25b0b870f01e04a76b27142b3cc7fc 100644 --- a/Plugin/Makefile +++ b/Plugin/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.52 2004-07-16 18:59:52 geuzaine Exp $ +# $Id: Makefile,v 1.53 2004-08-03 15:22:18 remacle Exp $ # # Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle # @@ -36,6 +36,7 @@ SRC = Plugin.cpp\ Triangulate.cpp\ SphericalRaise.cpp\ DisplacementRaise.cpp\ + StructuralSolver.cpp\ Skin.cpp\ Extract.cpp\ DecomposeInSimplex.cpp\ diff --git a/Plugin/Plugin.cpp b/Plugin/Plugin.cpp index 14fe73cd6c1dbb80dc2b5f9fcf9cb6f61a7609dd..2bc716db2798f91496a457ceeaf26f9d7f077be5 100644 --- a/Plugin/Plugin.cpp +++ b/Plugin/Plugin.cpp @@ -1,4 +1,4 @@ -// $Id: Plugin.cpp,v 1.55 2004-06-20 23:25:33 geuzaine Exp $ +// $Id: Plugin.cpp,v 1.56 2004-08-03 15:22:18 remacle Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -47,6 +47,7 @@ #include "Triangulate.h" #include "SphericalRaise.h" #include "DisplacementRaise.h" +#include "StructuralSolver.h" #include "Evaluate.h" using namespace std; @@ -73,6 +74,21 @@ GMSH_Plugin *GMSH_PluginManager::find(char *pluginName) return (*it).second; } +GMSH_Solve_Plugin *GMSH_PluginManager::findSolverPlugin() +{ + iter it = allPlugins.begin(); + iter ite = allPlugins.end(); + for (;it!=ite;++it) + { + GMSH_Plugin *p = (*it).second; + if (p->getType() == GMSH_Plugin::GMSH_SOLVE_PLUGIN) + { + return (GMSH_Solve_Plugin*)(p); + } + } + return 0; +} + void GMSH_PluginManager::action(char *pluginName, char *action, void *data) { GMSH_Plugin *plugin = find(pluginName); @@ -138,6 +154,10 @@ GMSH_PluginManager *GMSH_PluginManager::instance() void GMSH_PluginManager::registerDefaultPlugins() { + // SOLVE PLUGINS + // allPlugins.insert(std::pair < char *, GMSH_Plugin * > + // ("StructuralSolver", GMSH_RegisterStructuralSolverPlugin())); + // POST PLUGINS allPlugins.insert(std::pair < char *, GMSH_Plugin * > ("StreamLines", GMSH_RegisterStreamLinesPlugin())); allPlugins.insert(std::pair < char *, GMSH_Plugin * > diff --git a/Plugin/Plugin.h b/Plugin/Plugin.h index 3cbd610a9a1081971eddbad618d24c9558049588..5c0b3b99f650e4e868a49fd1d97eebc4dd3835f1 100644 --- a/Plugin/Plugin.h +++ b/Plugin/Plugin.h @@ -94,4 +94,26 @@ public: virtual Post_View *execute(Post_View *) = 0; }; +/* + A solver plugin. The idea here is to be able to associate + some properties to physical entities. The goal is to be able + to interface gmsh with a solver (ABAQUS...) i.e. create the + input file for the solver. +*/ + +class GMSH_Solve_Plugin : public GMSH_Plugin +{ +public: + virtual int getNbOptionsStr() const { return 0; }; + virtual StringXString *getOptionStr(int iopt) { return NULL; }; + virtual int getNbOptions() const { return 0; }; + virtual StringXNumber *getOption(int iopt) { return NULL; }; + inline GMSH_PLUGIN_TYPE getType() const { return GMSH_Plugin::GMSH_SOLVE_PLUGIN; } + virtual void run() {};// do nothing + virtual void popupPropertiesForPhysicalEntity (int dim) = 0;// popup dialog box + virtual void receiveNewPhysicalGroup (int dim, int id) = 0;// add the given group to the solver data's + virtual void loadSolverFile ( FILE *f ) = 0; // load the solver input file related to the gmsh geo file + virtual void writeSolverFile ( FILE *f ) const = 0; // save the solver file +}; + #endif diff --git a/Plugin/PluginManager.h b/Plugin/PluginManager.h index bb9f2b822cd7da8e50b2d53221ad44ba4212784c..b733604fd61d12b477aa92f95c5f1d6aaa776563 100644 --- a/Plugin/PluginManager.h +++ b/Plugin/PluginManager.h @@ -67,7 +67,9 @@ public : inline iter end() {return allPlugins.end();} // Find a plugin named pluginName - GMSH_Plugin *find(char *pluginName); + GMSH_Plugin *find (char *pluginName); + // Get The ONLY Solver Plugin + GMSH_Solve_Plugin *findSolverPlugin(); // Perform an action on the plugin. Default action are Run and // Save. Other plugins may perform other actions. diff --git a/Plugin/StructuralSolver.cpp b/Plugin/StructuralSolver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..af51a2165ce18069bc9f3bafdcd9f17519ad2fbb --- /dev/null +++ b/Plugin/StructuralSolver.cpp @@ -0,0 +1,221 @@ +#include "StructuralSolver.h" + + +#if defined(HAVE_FLTK) +#include <FL/Fl.H> +#include <FL/filename.H> +#endif + +extern Mesh *THEM; + + +extern "C" +{ + GMSH_Plugin *GMSH_RegisterStructuralSolverPlugin() + { + return new StructuralSolver(); + } +} + +Structural_BeamSection:: ~Structural_BeamSection() +{ + Mesh *kk = THEM; + Init_Mesh(&m); + THEM=kk; +} + +Structural_BeamSection:: Structural_BeamSection( const char *direct, std::string _name ) +: name (_name) +{ + Mesh *kk = THEM; + Init_Mesh(&m); + + size_t l = name.size(); + char temp[256]; + sprintf(temp, "%s/%s", direct,name.c_str()); + // read the section (msh format) + FILE *f = fopen (temp,"r"); + Read_Mesh (&m, f, temp,FORMAT_MSH); + fclose(f); + // get rid of the extension + name.erase(name.find(".")); + printf("%s\n",name.c_str()); + THEM=kk; +} + +void StructuralSolver :: RegisterBeamSections () +{ +#if defined(HAVE_FLTK) + struct dirent **list; + char ext[6]; + + char *homeplugins = getenv("GMSHPLUGINSHOME"); + + int nbFiles = fl_filename_list(homeplugins, &list); + if(nbFiles <= 0) + return; + for(int i = 0; i < nbFiles; i++) { + char *name = list[i]->d_name; + if(strlen(name) > 3) { + strcpy(ext, name + (strlen(name) - 3)); + if(!strcmp(ext, "msh")) { + Structural_BeamSection *section = + new Structural_BeamSection ( homeplugins, std::string(name) ); + beam_sections.push_back ( section ); + } + } + } + for(int i = 0; i < nbFiles; i++) + free(list[i]); + free(list); +#endif + +} + +void StructuralSolver::getName(char *name) const +{ + strcpy(name, "Structural Solver"); +} + +void StructuralSolver::catchErrorMessage(char *errorMessage) const +{ + strcpy(errorMessage, "Structural Solver failed..."); +} + +void StructuralSolver::getInfos(char *author, char *copyright, + char *help_text) const +{ + strcpy(author, "J.-F. Remacle (remacle@scorec.rpi.edu)"); + strcpy(copyright, "DGR (www.multiphysics.com)"); + strcpy(help_text, + "Interface to a structural solver\n"); +} + + + +StructuralSolver :: StructuralSolver () +{ + RegisterBeamSections (); +} +StructuralSolver :: ~StructuralSolver () +{ + std::list<struct Structural_BeamSection* > :: iterator it = beam_sections.begin(); + std::list<struct Structural_BeamSection* > :: iterator ite = beam_sections.end(); + + for (;it!=ite;++it) + { + delete *it; + } + +} + +void StructuralSolver ::popupPropertiesForPhysicalEntity (int dim) +{ + static Fl_Group *g[10]; + int i; + +// if(context_geometry_window) { +// for(i = 0; i < 6; i++) +// g[i]->hide(); +// g[num]->show(); +// context_geometry_window->show(); +// return; +// } + +// int width = 31 * fontsize; +// int height = 5 * WB + 9 * BH; + +// context_geometry_window = new Fl_Window(width, height, "Contextual geometry definitions"); +// context_geometry_window->box(WINDOW_BOX); +// { +// Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH); +// // 0: Parameter +// { +// g[0] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Parameter"); +// context_geometry_input[0] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Name"); +// context_geometry_input[0]->value("lc"); +// context_geometry_input[1] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Value"); +// context_geometry_input[1]->value("1.0"); +// for(i = 0; i < 2; i++) { +// context_geometry_input[i]->align(FL_ALIGN_RIGHT); +// } +// { +// Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 7 * BH, BB, BH, "Add"); +// o->callback(con_geometry_define_parameter_cb); +// } +// g[0]->end(); +// } +// // 1: Point +// { +// g[1] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Point"); +// context_geometry_input[2] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X coordinate"); +// context_geometry_input[2]->value("0.0"); +// context_geometry_input[3] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y coordinate"); +// context_geometry_input[3]->value("0.0"); +// context_geometry_input[4] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z coordinate"); +// context_geometry_input[4]->value("0.0"); +// context_geometry_input[5] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Characteristic length"); +// context_geometry_input[5]->value("1.0"); +// for(i = 2; i < 6; i++) { +// context_geometry_input[i]->align(FL_ALIGN_RIGHT); +// } +// { +// Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 7 * BH, BB, BH, "Add"); +// o->callback(con_geometry_define_point_cb); +// } +// g[1]->end(); +// } +// // 2: Translation +// { +// g[2] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Translation"); +// context_geometry_input[6] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X component"); +// context_geometry_input[6]->value("0.0"); +// context_geometry_input[7] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y component"); +// context_geometry_input[7]->value("0.0"); +// context_geometry_input[8] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z component"); +// context_geometry_input[8]->value("1.0"); +// for(i = 6; i < 9; i++) { +// context_geometry_input[i]->align(FL_ALIGN_RIGHT); +// } +// g[2]->end(); +// } +// // 3: Rotation +// { +// g[3] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Rotation"); +// context_geometry_input[9] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X coordinate of an axis point"); +// context_geometry_input[9]->value("0.0"); +// context_geometry_input[10] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y coordinate of an axis point"); +// context_geometry_input[10]->value("0.0"); +// context_geometry_input[11] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z coordinate of an axis point"); +// context_geometry_input[11]->value("0.0"); +// context_geometry_input[12] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "X component of direction"); +// context_geometry_input[12]->value("0.0"); +// context_geometry_input[13] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Y component of direction"); +// context_geometry_input[13]->value("1.0"); +// context_geometry_input[14] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Z component of direction"); +// context_geometry_input[14]->value("0.0"); +// context_geometry_input[15] = new Fl_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Angle in radians"); +// context_geometry_input[15]->value("Pi/4"); +// for(i = 9; i < 16; i++) { +// context_geometry_input[i]->align(FL_ALIGN_RIGHT); +// } +// g[3]->end(); +// } +// // 4: Scale +// { +// g[4] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Scale"); +// context_geometry_input[16] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X component of direction"); +// context_geometry_input[16]->value("1.0"); +// context_geometry_input[17] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y component of direction"); +// context_geometry_input[17]->value("0.0"); +// context_geometry_input[18] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z component of direction"); +// context_geometry_input[18]->value("0.0"); +// context_geometry_input[19] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Factor"); +// context_geometry_input[19]->value("2.0"); +// for(i = 16; i < 20; i++) { +// context_geometry_input[i]->align(FL_ALIGN_RIGHT); +// } +// g[4]->end(); +// } +} + diff --git a/Plugin/StructuralSolver.h b/Plugin/StructuralSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..75f02bf07da9b8ac56788aae974da3ddf7eb54ec --- /dev/null +++ b/Plugin/StructuralSolver.h @@ -0,0 +1,95 @@ +#ifndef STRUCTURAL_SOLVER_H_ +#define STRUCTURAL_SOLVER_H_ +// Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to <gmsh@geuz.org>. + +#include <list> +#include "Mesh.h" +#include "Plugin.h" +#include <string> + +#ifdef HAVE_FLTK +#include <FL/Fl_Window.H> +#include <FL/Fl_Box.H> +#include <FL/Fl_Menu_Bar.H> +#include <FL/fl_draw.H> +#include <FL/gl.h> +#include <FL/Fl_Choice.H> +#include <FL/Fl_Scroll.H> +#include <FL/Fl_Tabs.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_Return_Button.H> +#include <FL/Fl_Repeat_Button.H> +#include <FL/Fl_Light_Button.H> +#include <FL/Fl_Menu_Button.H> +#include <FL/Fl_Check_Button.H> +#include <FL/Fl_Input.H> +#include <FL/Fl_Value_Input.H> +#include <FL/Fl_Output.H> +#include <FL/Fl_Multiline_Output.H> +#include <FL/Fl_Bitmap.H> +#include <FL/Fl_Browser.H> +#include <FL/Fl_Multi_Browser.H> +#include <FL/Fl_Hold_Browser.H> +#include <FL/x.H> +#include <FL/Fl_Color_Chooser.H> +#include <FL/fl_ask.H> +#include <FL/Fl_Tooltip.H> +#endif + +extern "C" +{ + GMSH_Plugin *GMSH_RegisterStructuralSolverPlugin(); +} + +struct Structural_BeamSection +{ + Mesh m; + std::string name; + Structural_BeamSection ( const char *direct, std::string _name ); + ~Structural_BeamSection(); +}; + + +class StructuralSolver : public GMSH_Solve_Plugin +{ + std::list < struct Structural_BeamSection* > beam_sections; + void RegisterBeamSections (); +#ifdef HAVE_FLTK + Fl_Window *context_mesh_window ; + Fl_Input *context_mesh_input[20] ; + Fl_Choice *context_mesh_choice[20] ; +#endif +public: + StructuralSolver(); + ~StructuralSolver(); + virtual void getName(char *name) const; + virtual void getInfos(char *author, char *copyright, char *helpText) const; + + // When an error is thrown by the plugin, the plugin manager will + // show the message and hopefully continue + virtual void catchErrorMessage(char *errorMessage) const; + virtual void popupPropertiesForPhysicalEntity (int dim); + virtual void receiveNewPhysicalGroup (int dim, int id){} + virtual void writeSolverFile ( FILE *f ) const{} + virtual void loadSolverFile ( FILE *f ){} +}; + +#endif + diff --git a/benchmarks/1d/ligne.geo b/benchmarks/1d/ligne.geo index a3f4b3bc95db336b61cc751152228925eac2a4e8..37a82f7f19de1909e81c4f6c488ae80d8e54cf8d 100644 --- a/benchmarks/1d/ligne.geo +++ b/benchmarks/1d/ligne.geo @@ -1,3 +1,15 @@ Point(1) = {0.0,0.0,0.0,.1}; Point(2) = {1,0.0,0.0,.1}; Line(1) = {1,2}; +Physical Point(2) = {2}; +Physical Point(3) = {2,1}; +Physical Point(4) = {2,1}; +Physical Point(5) = {2,1}; +Physical Point(6) = {2,1}; +Physical Point(7) = {2}; +Physical Point(8) = {1}; +Physical Point(9) = {2}; +Physical Point(10) = {1}; +Physical Line(11) = {1}; +Physical Line(12) = {1}; +Physical Line(13) = {1}; diff --git a/benchmarks/2d/HEA100.geo b/benchmarks/2d/HEA100.geo new file mode 100644 index 0000000000000000000000000000000000000000..792cf749558e721879974f4f40b4936770340d1c --- /dev/null +++ b/benchmarks/2d/HEA100.geo @@ -0,0 +1,6 @@ +h=96; +c = 100/2; +d = 5; +t = 8; +r = 12; +Include "IPE.geo"; \ No newline at end of file diff --git a/benchmarks/2d/IPE.geo b/benchmarks/2d/IPE.geo new file mode 100644 index 0000000000000000000000000000000000000000..cc385ea3026083c65a8c06cb35db7ae273baa974 --- /dev/null +++ b/benchmarks/2d/IPE.geo @@ -0,0 +1,48 @@ +LC = h; +LC2 = r/4; + +Point(1) = {-c,-h/2,0,LC}; +Point(2) = {-c,-h/2+t,0,LC}; +Point(3) = {-t/2-r,-h/2+t,0,LC2}; +Point(4) = {-t/2,-h/2+t+r,0,LC2}; +Point(5) = {-t/2-r,-h/2+t+r,0,LC2}; + +Point(11) = {-c,h/2,0,LC}; +Point(12) = {-c,h/2-t,0,LC}; +Point(13) = {-t/2-r,h/2-t,0,LC2}; +Point(14) = {-t/2,h/2-t-r,0,LC2}; +Point(15) = {-t/2-r,h/2-t-r,0,LC2}; + +Point(21) = {c,-h/2,0,LC}; +Point(22) = {c,-h/2+t,0,LC}; +Point(23) = {t/2+r,-h/2+t,0,LC2}; +Point(24) = {t/2,-h/2+t+r,0,LC2}; +Point(25) = {t/2+r,-h/2+t+r,0,LC2}; + +Point(31) = {c,h/2,0,LC}; +Point(32) = {c,h/2-t,0,LC}; +Point(33) = {t/2+r,h/2-t,0,LC2}; +Point(34) = {t/2,h/2-t-r,0,LC2}; +Point(35) = {t/2+r,h/2-t-r,0,LC2}; + + +Line(1) = {1,21}; +Line(2) = {21,22}; +Line(3) = {22,23}; +Line(4) = {1,2}; +Line(5) = {2,3}; +Line(6) = {4,14}; +Line(7) = {34,24}; +Line(8) = {11,31}; +Line(9) = {31,32}; +Line(10) = {32,33}; +Line(11) = {11,12}; +Line(12) = {12,13}; +Circle(13) = {13,15,14}; +Circle(14) = {33,35,34}; +Circle(15) = {3,5,4}; +Circle(16) = {23,25,24}; +Line Loop(17) = {-7,-14,-10,-9,-8,11,12,13,-6,-15,-5,-4,1,2,3,16}; +Plane Surface(18) = {17}; +Physical Line(19) = {8,9,10,14,7,16,3,2,1,4,5,15,6,13,12,11}; +Physical Surface(20) = {18};