server.cpp
来自「FreeFem++可以生成高质量的有限元网格。可以用于流体力学」· C++ 代码 · 共 985 行 · 第 1/2 页
CPP
985 行
// -*- Mode : c++ -*-//// SUMMARY : // USAGE : // ORG : // AUTHOR : Antoine Le Hyaric -// E-MAIL : lehyaric@ann.jussieu.fr///* This file is part of Freefem++ Freefem++ is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Freefem++ 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Freefem++; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */// Server-side treatments// ----------------------// Antoine Le Hyaric - LJLL Paris 6 - lehyaric@ann.jussieu.fr - 21/10/04// $Id: server.cpp,v 1.9 2006-09-29 20:30:15 hecht Exp $#define FF_GRAPH_SET_PTR#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <iostream>using namespace std;#include "tostring.hpp"#include "server.hpp"#include "commands.hpp"#include "draw.hpp"// FreeFEM++ libraries are only needed in the server#include "../fflib/AFunction.hpp"#include "../fflib/lex.hpp"#include "../lglib/lg.tab.hpp"#include "../Graphics/rgraph.hpp"#include "../fflib/strversionnumber.hpp"// FreeFEM++ output// ----------------// Defines an output stream which prints all its data into the// FreeFEM++ output window.class Tfreefemstreambuffer:public streambuf{public: Tfreefemstreambuffer():streambuf(){ char *ptr = new char[1024]; setp(ptr,ptr+1024); setg(0,0,0); } ~Tfreefemstreambuffer(){ sync(); // pbase() points to "ptr" allocated above. delete[] pbase(); }protected: int overflow(int c){ put_buffer(); // What to do with the extra character if(c!=EOF){ if (pbase() == epptr()) put_char(c); else sputc(c); } return 0; } int sync(){ put_buffer(); return 0; }private: void put_buffer(void){ // If there is text to display in the stream buffer if(pbase()!=pptr()){ // Copy the data into the window string buffer(pbase(),pptr()-pbase());#ifdef NOSOCKETS cmd_stdout(buffer);#else *serversocket<<CMD_STDOUT<<buffer;#endif // Reset the stream buffer setp(pbase(),epptr()); } } // Output one single character void put_char(int c){ string s; s.push_back(c);#ifdef NOSOCKETS cmd_stdout(s);#else *serversocket<<CMD_STDOUT<<s;#endif }};Tfreefemstreambuffer freefemstreambuffer;// Connecting to FreeFEM++// -----------------------// If the server does not use sockets but runs in a thread, we still// need to tell the client thread when the server is finished (if// sockets are used, we simply send a CMD_SERVER_DONE message).#ifdef NOSOCKETSSemaphore freefemserverended(1,1,"freefemserverended");#endif// Since we compute the line width and height in advance (to optimize// TCP communication), we approximate every character to an 'X'.double characterwidth;float characterheight;// Some required yet undeclared FreeFEM++ objectsextern bool lgdebug;void init_lgfem() ;void init_lgmesh() ;void init_algo();#ifdef HAVE_LIBARPACKvoid init_eigenvalue();#endifextern double CPUcompileInit;extern Block *currentblock;extern int Compile();// Extracted from function mymain(), file lg.tab.cppvoid runfreefem(const string program){#ifndef NDEBUG printf("server: now running FreeFem++ program\n");#endif cout << "-- FreeFem++ IDE server v" << StrVersionNumber() << endl; // Try and catch all the exceptions produced by FreeFEM++ to avoid // killing the IDE at the same time. int retvalue=0; try{ // Initialisations // --------------- // The IDE is not configured for parallel computations yet#ifdef PARALLELE assert(false);#endif withrgraphique=false; lexdebug=false; lgdebug=false; zzzfff=new mylex(cout); // Transfer the program source from the editor to FreeFEM++ zzzfff->input(program); // Mots-cl閟 zzzfff->Add("include",INCLUDE); zzzfff->Add("load",LOAD); zzzfff->Add("while",WHILE); zzzfff->Add("for",FOR); zzzfff->Add("if",IF); zzzfff->Add("else",ELSE); zzzfff->Add("end",ENDOFFILE); zzzfff->Add("break",BREAK); zzzfff->Add("continue",CONTINUE); zzzfff->Add("return",RETURN); zzzfff->Add("border",BORDER); zzzfff->Add("fespace",FESPACEID); zzzfff->Add("try",TRY); zzzfff->Add("catch",CATCH); zzzfff->Add("throw",THROW); Init_map_type(); cout << " Load: "; init_lgfem(); init_lgmesh(); init_algo();#ifdef HAVE_LIBARPACK init_eigenvalue();#endif #ifdef PARALLELE init_lgparallele(); #endif#ifdef HAVE_LIBUMFPACK cout << " UMFPACK "; #endif cout << endl; // Running FreeFEM++ // ----------------- CPUcompileInit=CPUtime(); currentblock=0; currentblock = new Block(currentblock); GetEnvironment(); // compile retvalue=Compile(); if(retvalue==0) if(currentblock) retvalue=1,cerr << "Error:a block is not close" << endl; else cerr << "Bien: On a fini Normalement" << endl; // Stopping FreeFEM++ properly // --------------------------- delete zzzfff; } catch(Error & e){ retvalue=e.errcode(); cout << "error " << e.what() << "\n code = "<< retvalue << endl; // Warn the IDE client string message=string("FreeFem++ returned error ")+tostring(retvalue);#ifdef NOSOCKETS cmd_error(message);#else *serversocket<<CMD_ERROR<<message; serversocket->writeflush();#endif }}// FreeFEM++ "rgraph" methods, modified to talk to Tffgraphics// -----------------------------------------------------------static long cube6[7][3] ={ {65535,32000,32000}, {65535,65535,0}, {0,65535,0}, {0,65535,65535}, {0,0,65535}, {65535,0,65535}, {32000,0,0}};static long grey6[2][3] ={ {65534,65534,65534}, {0,0,0}};static FILE *psfile = 0;static FILE *psfile_save = 0;static bool grey=false;static int LastColor=2; // pour est en couleur par defautconst float fMinPixel = -32000;const float fMaxPixel = +32000;static int ncolortable,fcolor;typedef struct rgb { unsigned char r; // red component of color unsigned char g; // green component of color unsigned char b; // blue component of color} rgb;static rgb *colortable=NULL;static float echx,echy;// FreeFem++ data: Minimum and maximum acceptable coordinates in// FreeFem++ internal coordinates.static float rxmin,rxmax,rymin,rymax;static int lacouleur;// FreeFem++ data: Current (virtual screen) coordinatefloat currx,curry;static int INITGRAPH=0;void myexit(int err){ cout << " The End err=" << err << endl; exit(err);}void message(char *s){ printf("%s \n",s);}void erreur(char *s){ message(s); exit(0);}void *safecalloc(size_t nb, size_t size){ void* p=NULL; p = calloc(nb, size); if (p == NULL) printf("Run out of Memory!\n"); return p;}void safefree(void** f){ if(*f){ free((char*) *f); *f=NULL;}}int LaCouleur() {return lacouleur;}void couleur(int c){ if ( lacouleur == c) // small optim return; c= c > LastColor ? 1 : c; // c=std::min(c,LastColor); pour noir et blanc lacouleur = c; color tmp(0,0,0); if (colortable) { if (c>=0 && c < ncolortable){ tmp=color(colortable[c].r, colortable[c].g, colortable[c].b); } else tmp=color(0,0,0); } else if ( c == 0 ) tmp=color(255,255,255); else tmp=color(0,0,0); // Send new color to client#ifdef NOSOCKETS defaultcolor=new color(tmp); backdrawings.push_back(new color(tmp));#else tmp.send();#endif if (psfile) { float r=1,g=1,b=1; if (colortable) { if (c>0 && c < ncolortable) { r = (float) colortable[c].r/255; g = (float) colortable[c].g/255; b = (float) colortable[c].b/255; } } else if (c!=0) r=g=b=0; fprintf(psfile,"%.3f %.3f %.3f C\n",r,g,b); }}// The color palette mechanism is kept on the server side. The client// will only hear about the RGB values taken from the palette.static rgb DefColor_rgb( int k,int nb, bool hsv,bool grey,int nbcolors,float *colors){ rgb C; float r,g,b; extern void DefColor(float & r, float & g, float & b, int k,int nb, bool hsv,bool grey,int nbcolors,float *colors); DefColor(r,g,b, k,nb,hsv,grey,nbcolors,colors); C.r=(unsigned short)(255*r); C.g=(unsigned short)(255*g); C.b=(unsigned short)(255*b); return C;}void SetColorTable(int nb){ int i; if (fcolor && nb>2 && nb < 256) { nb = std::max(nb,8); if (ncolortable == nb) return;// optim if(colortable) delete [] colortable; colortable = new rgb[nb]; ncolortable = nb; if(LastColor>1) LastColor=nb-1; int k=0; colortable[k].r=255; colortable[k].g=255; colortable[k].b=255; k++; colortable[k].r=0; colortable[k].g=0; colortable[k].b=0; k++; nb = nb -2; for (long i0=0;i0<nb;i0++,k++) { // long i1 = nb - i0; long i6 = i0*6; long j0 = i6/nb;// in 0..6 long j1 = j0+1;// in 1..6 long k0 = i0 - (nb*j0)/6L; long k1 = (nb*j1)/6L-i0; long kk = k0+k1; if ( kk <= 0) { cerr << kk << " " << nb << " " << k0 << " " << k1 << " " << endl; assert(kk); } if (! grey) { colortable[k].r= (unsigned short) ((long) (cube6[j1][0]*k0+cube6[j0][0]*k1)/kk); colortable[k].g= (unsigned short) ((long) (cube6[j1][1]*k0+cube6[j0][1]*k1)/kk); colortable[k].b= (unsigned short) ((long) (cube6[j1][2]*k0+cube6[j0][2]*k1)/kk); } else { kk=nb-1; k1 = i0; k0 = nb - i0 -1; j0=1; j1=0; colortable[k].r= (unsigned short) ((long) (grey6[j1][0]*k0+grey6[j0][0]*k1)/kk); colortable[k].g= (unsigned short) ((long) (grey6[j1][1]*k0+grey6[j0][1]*k1)/kk); colortable[k].b= (unsigned short) ((long) (grey6[j1][2]*k0+grey6[j0][2]*k1)/kk); } assert(k<ncolortable); } }}void SetColorTable1(int nb,bool hsv,int nbcolors,float *colors){ int i; if (fcolor && nb>2 && nb < 256) { nb = std::max(nb,8); if (ncolortable == nb) return;// optim if(colortable) delete [] colortable; colortable = new rgb[nb]; ncolortable = nb; if(LastColor>1) LastColor=nb-1; for (int i0=0;i0<nb;i0++) { colortable[i0]=DefColor_rgb(i0,nb,hsv,grey,nbcolors,colors); } }}void initgraphique(){ colortable=0; ncolortable=0; LastColor=2;// En couleur pas defaul fcolor=1; SetColorTable(8); // set INITGRAPH = 1;}void closegraphique(){ if(INITGRAPH){ INITGRAPH = 0; closePS(); }}void cadre(float xmin,float xmax,float ymin,float ymax){ rxmin = xmin; rxmax = xmax; rymin = ymin; rymax = ymax;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?