/* $Log: post.c,v $ * Revision 1.1 1995/02/21 07:53:52 martenl * Initial revision * * Revision 1.5 1994/10/26 13:01:55 martenl * Added memory allocation for vecX and vecY * * Revision 1.4 1994/10/26 12:58:59 martenl * Added plotVectors * * Revision 1.3 1994/10/25 09:25:56 martenl * Major cleanup * * Revision 1.2 1994/10/14 13:24:23 martenl * (readSolution): Added a filename argument * */ #define min(x, y) (((x) < (y)) ? (x) : (y)) #define max(x, y) (((x) > (y)) ? (x) : (y)) #include #include #include #include #include "libsx.h" #include "globals.h" #include "geodata.h" #include "kraftwerk.h" #include "grid.h" #include "crosshair.h" #include "graph.h" int setUpMycolorMap(int ncolor); void lingraph(); void dolingraph(); float xlin1, xlin2, ylin1, ylin2; float xold[1000], fold[1000]; int xplin1, xplin2, yplin1, yplin2; int nlin, nold; int linitem; void drawText(char *text, float x, float y); int clickedInElement(int x, int y, int *thisEl); void updateLevelButtons() { int i; for(i = 0; i < MAXLEVELS; i++){ SetWidgetState(solButt[i], FALSE); } if(state == HAVE_SOLUTION){ for(i = 0; i < NoOfMeshes; i++) SetWidgetState(solButt[i], TRUE); } } /* * * +-------------------------------------------+ * | Allocate memory for the mesh and solution | * +-------------------------------------------+ * */ int allocateMemory(int imesh, int elnum, int nnode) { int ierr; ierr = 0; /* allocate new mwmory */ mySol[imesh].nodpek = malloc(NOBF*elnum * sizeof(int)); if(mySol[imesh].nodpek == NULL){ errorHandler("Unable to allocate memory"); ierr = 1; } mySol[imesh].coord = malloc(2*nnode * sizeof(float)); if(mySol[imesh].coord == NULL){ errorHandler("Unable to allocate memory"); ierr = 1; } mySol[imesh].u = malloc(nnode * sizeof(float)); if(mySol[imesh].u == NULL){ errorHandler("Unable to allocate memory"); ierr = 1; } mySol[imesh].vecX = malloc(nnode * sizeof(float)); if(mySol[imesh].vecX == NULL){ errorHandler("Unable to allocate memory"); ierr = 1; } mySol[imesh].vecY = malloc(nnode * sizeof(float)); if(mySol[imesh].vecY == NULL){ errorHandler("Unable to allocate memory"); ierr = 1; } return ierr; } /* * * +---------------+ * | Plot the mesh | * +---------------+ * */ void plotMesh() { float x[4], y[4]; int i, el, nod, ncells; float cfl, xmin, ymin, umax, vmax; getDrawingScale(); cfl = -1000.; mySetColor(GREY); for( el = 0; el < mySol[currentSolution].elnum; el++){ xmin = -1000.; ymin = -1000.; umax = -1000.; vmax = -1000.; for( i = 0; i < NOBF; i++){ nod = mySol[currentSolution].nodpek[el][i]; x[i] = mySol[currentSolution].coord[ nod ][0]; y[i] = mySol[currentSolution].coord[ nod ][1]; } x[NOBF] = x[0]; y[NOBF] = y[0]; /* for( i = 0; i < NOBF; i++){ nod = mySol[currentSolution].nodpek[el][i]; xmin = max(xmin, (float) fabs( (double) (x[i]-x[i+1]))); umax = max(umax, (float) fabs( (double) mySol[currentSolution].vecX[ nod ])); ymin = max(ymin, (float) fabs( (double) (y[i]-y[i+1]))); vmax = max(vmax, (float) fabs( (double) mySol[currentSolution].vecY[ nod ])); x[i] += mySol[currentSolution].vecX[ nod ]*arrwscl; y[i] += mySol[currentSolution].vecY[ nod ]*arrwscl; } cfl = max(cfl, arrwscl * umax / xmin); cfl = max(cfl, arrwscl * vmax / ymin); x[NOBF] = x[0]; y[NOBF] = y[0]; */ line(x, y, NOBF+1); } mySetColor(WHITE); drawTitle("Mesh"); /* printf("dt = %f, cfl = %f\n", arrwscl, cfl); */ } void plotElementNumbers() { char number[3]; int el, i, node; float xx, yy; int x, y; for( el = 0; el < mySol[currentSolution].elnum; el++){ xx = 0.; yy = 0.; for(i = 0; i < NOBF; i++){ node = mySol[currentSolution].nodpek[el][i]; xx += mySol[currentSolution].coord[node][0]; yy += mySol[currentSolution].coord[node][1]; } xx = xx / NOBF; yy = yy / NOBF; sprintf(number, "%i", el + 1); phys2pix(&x, &y, xx, yy); myDrawText(number, x, y); } } void plotNodeNumbers() { char number[3]; int el, i, node; float xx, yy; int x, y; for( el = 0; el < mySol[currentSolution].elnum; el++){ for(i = 0; i < NOBF; i++){ node = mySol[currentSolution].nodpek[el][i]; xx = mySol[currentSolution].coord[node][0]; yy = mySol[currentSolution].coord[node][1]; sprintf(number, "%i", node + 1); phys2pix(&x, &y, xx, yy); myDrawText(number, x, y); } } } void plotPhysBoundary() { int i,j; int n, nb; float xx[2], yy[2]; GEO_NODE *g; BND_NODE *s; FOR_ALL_BOUNDARIES(g){ FOR_ALL_SEGMENTS(g, s){ xx[0] = ((s->seg)->pts1)->physicalX; yy[0] = ((s->seg)->pts1)->physicalY; xx[1] = ((s->seg)->pts2)->physicalX; yy[1] = ((s->seg)->pts2)->physicalY; line(xx, yy, 2); } } } void plotVectors(int this) { int i, ptr, ncells; float xx, xy, xu, xv; float umax, uu; ncells = setUpMycolorMap(ncolor); getDrawingScale(); ptr = mySol[currentSolution].ptr[this]; umax = 0.0; for( i = 0; i < mySol[currentSolution].nnode; i++){ xu = mySol[currentSolution].f[i + ptr]; xv = mySol[currentSolution].f[i + ptr + mySol[currentSolution].nnode]; umax = max(umax, xu*xu+xv*xv); } umax = (float)sqrt((double) umax); for( i = 0; i < mySol[currentSolution].nnode; i++){ xu = mySol[currentSolution].f[i + ptr]; xv = mySol[currentSolution].f[i + ptr + mySol[currentSolution].nnode]; uu = (float) sqrt((double)xu*xu+xv*xv) ; if(uu <= umax*maxscalarX && uu >= umax*minscalarX){ xx = mySol[currentSolution].coord[i][0]; xy = mySol[currentSolution].coord[i][1]; xu = xx + maxarrwscl*arrwscl*xu; xv = xy + maxarrwscl*arrwscl*xv; mySetMyColor( (uu-umax*minscalarX)/ (umax*maxscalarX-umax*minscalarX)); arrow(xx, xy, xu, xv); } } mySetColor(WHITE); plotPhysBoundary(); drawTitle(mySol[currentSolution].name[this]); #ifdef NAVIERSTOKES dolingraph(); #endif } void plotIsolines(int this) { double maxscalar, minscalar, scl; double xx[NOBF+1], yy[NOBF+1], sc[NOBF+1]; float xp[10], yp[10]; double level; int el, i, ilev, ii, node, ptr, ntext, ncells; char text[100]; float xf, yf, dx, dy; int last_level, last_levely[40]; int ix, iy,x1, y1, nx, ny; ntext = 0; linitem = this; ncells = setUpMycolorMap(ncolor); getDrawingScale(); ptr = mySol[currentSolution].ptr[this]; maxscalar = -100000.; minscalar = 100000.; for(i = 0; i < mySol[currentSolution].nnode; i++){ maxscalar = max(maxscalar, (double) mySol[currentSolution].f[i+ptr]); minscalar = min(minscalar, (double) mySol[currentSolution].f[i+ptr]); } scl = maxscalar - minscalar; maxscalar = minscalar +(double) maxscalarX * scl; minscalar = minscalar +(double) minscalarX * scl; scl = maxscalar - minscalar; sprintf(text, "Min scalar: %f , Max scalar: %f", minscalar, maxscalar); infoHandler(text); for( el = 0; el < mySol[currentSolution].elnum; el++){ for(i = 0; i < NOBF; i++){ node = mySol[currentSolution].nodpek[el][i]; xx[i] = (double)mySol[currentSolution].coord[node][0]; yy[i] = (double)mySol[currentSolution].coord[node][1]; sc[i] = (double)mySol[currentSolution].f[node + ptr]; } xx[NOBF] = xx[0]; yy[NOBF] = yy[0]; sc[NOBF] = sc[0]; for(ilev = 0; ilev < nlev; ilev++){ level = -scl + (double) ilev*2*scl/nlev; level = 1.*ilev*scl / nlev + minscalar; level = minscalar + scl * (double) ilev/nlev; ii = 0; for(i = 0; i < NOBF; i++){ if( (sc[i]-level)*(sc[i+1]-level) <= 0.0){ if(sc[i+1]-sc[i] != 0.){ xp[ii] = (float) xx[i] +(level-sc[i])/(sc[i+1]-sc[i])*(xx[i+1]-xx[i]); yp[ii] = (float) yy[i] +(level-sc[i])/(sc[i+1]-sc[i])*(yy[i+1]-yy[i]); ii += 1; } } } if(ii > 0){ mySetMyColor( (float) ilev / (float) nlev); line(xp, yp, ii); } } } /* next element */ mySetColor(WHITE); plotPhysBoundary(); drawTitle(mySol[currentSolution].name[this]); } void plotIsolineLabels(int this) { double maxscalar, minscalar, scl; double xx[NOBF+1], yy[NOBF+1], sc[NOBF+1]; float xp[10], yp[10]; double level; int el, i, ilev, ii, node, ptr, ntext, ncells; char text[100]; float xf, yf, dx, dy; int last_level, last_levely[40]; int ix, iy,x1, y1, nx, ny; ntext = 0; linitem = this; ncells = setUpMycolorMap(ncolor); getDrawingScale(); ptr = mySol[currentSolution].ptr[this]; maxscalar = -100000.; minscalar = 100000.; for(i = 0; i < mySol[currentSolution].nnode; i++){ maxscalar = max(maxscalar, (double) mySol[currentSolution].f[i+ptr]); minscalar = min(minscalar, (double) mySol[currentSolution].f[i+ptr]); } scl = maxscalar - minscalar; maxscalar = minscalar +(double) maxscalarX * scl; minscalar = minscalar +(double) minscalarX * scl; scl = maxscalar - minscalar; /* Put up labels on the isolines */ nx = 15; ny = 15; dx = (float)(xmax - xmin ) / nx; dy = (float)(ymax - ymin ) / ny; ntext = 0; last_level = 1233; for(ix = 0; ix <=nx; ix++) last_levely[ix] = 121222; for( iy = 0; iy <= ny; iy=iy+2){ for( ix = 0; ix <= nx; ix=ix+2){ xf = xmin + (float)ix*dx; yf = ymin + (float)iy*dy; phys2pix(&x1, &y1, xf, yf); if(clickedInElement(x1, y1, &el) == TRUE){ for(i = 0; i < NOBF; i++){ node = mySol[currentSolution].nodpek[el][i]; xx[i] = (double)mySol[currentSolution].coord[node][0]; yy[i] = (double)mySol[currentSolution].coord[node][1]; sc[i] = (double)mySol[currentSolution].f[node + ptr]; } xx[NOBF] = xx[0]; yy[NOBF] = yy[0]; sc[NOBF] = sc[0]; for(ilev = 0; ilev <= nlev; ilev=ilev+1){ level = minscalar + scl * (double) ((ilev+ntext)%nlev)/nlev; ii = 0; for(i = 0; i < NOBF; i++){ if( (sc[i]-level)*(sc[i+1]-level) <= 0.0){ if(sc[i+1]-sc[i] != 0.){ xp[ii] = (float) xx[i] +(level-sc[i])/(sc[i+1]-sc[i])*(xx[i+1]-xx[i]); yp[ii] = (float) yy[i] +(level-sc[i])/(sc[i+1]-sc[i])*(yy[i+1]-yy[i]); ii += 1; } } } if(ii > 0){ mySetMyColor( (float)((ilev+ntext)%nlev/(float)nlev)); if((ilev+ntext)%nlev != last_level){ if((ilev+ntext)%nlev != last_levely[ix]){ phys2pix(&x1, &y1, xp[0], yp[0]); sprintf(text, "%.3g", level); myDrawText(text, x1+2, y1-2); myDrawCross(x1, y1, 4); last_level = (ilev+ntext)%nlev; last_levely[ix] = (ilev+ntext)%nlev; } } ntext++; if(ntext > nlev) ntext = 0; break; } } } } } mySetColor(WHITE); } void plotIsoColorLines(int this) { float maxscalar, minscalar, scl; int xx[NOBF+1], yy[NOBF+1], sc[NOBF+1]; int ix, iy; float x, y; int level; int lmin, lmax; int start, end; int el, i, ilev, ii, node, ncells, ptr; XPoint *pp, *pts; char text[100]; pts = (XPoint *) malloc( 10 * sizeof(XPoint) ); pp = pts; ncells = setUpMycolorMap(ncolor); getDrawingScale(); ptr = mySol[currentSolution].ptr[this]; maxscalar = -100000.; minscalar = 100000.; for(i = 0; i < mySol[currentSolution].nnode; i++){ maxscalar = max(maxscalar, mySol[currentSolution].f[i+ptr]); minscalar = min(minscalar, mySol[currentSolution].f[i+ptr]); } scl = maxscalar - minscalar; sprintf(text, "Min scalar: %f , Max scalar: %f", minscalar, maxscalar); infoHandler(text); for( el = 0; el < mySol[currentSolution].elnum; el++){ lmax = -10000; lmin = 10000; for(i = 0; i < NOBF; i++){ node = mySol[currentSolution].nodpek[el][i]; sc[i] =(int) floor((double)(ncells-1)* (mySol[currentSolution].f[ptr+node]-minscalar) / scl); x = mySol[currentSolution].coord[node][0]; y = mySol[currentSolution].coord[node][1]; phys2pix(&ix, &iy, x, y); xx[i] = ix; yy[i] = iy; lmax = max(lmax, sc[i]); lmin = min(lmin, sc[i]); } xx[NOBF] = xx[0]; yy[NOBF] = yy[0]; sc[NOBF] = sc[0]; start = max(0, lmin); end = min(ncells - 1, lmax); for(ilev = start; ilev < end + 1; ilev++){ level = ilev; ii = 0; for(i = 0; i < NOBF; i++){ if(sc[i] >= level){ pp[ii].x = xx[i]; pp[ii].y = yy[i]; ii += 1; } if( (sc[i]-level)*(sc[i+1]-level) <= 0){ if(sc[i+1]-sc[i] != 0){ pp[ii].x = xx[i] +(level-sc[i])*(xx[i+1]-xx[i])/(sc[i+1]-sc[i]); pp[ii].y = yy[i] +(level-sc[i])*(yy[i+1]-yy[i])/(sc[i+1]-sc[i]); ii++; } else{ pp[ii].x = xx[i]; pp[ii].y = yy[i]; ii++; } } } mySetMyColor((float)ilev/ (float)ncells); if(ii > 0){ pp[ii].x = pp[0].x; pp[ii].y = pp[0].y; ii += 1; myDrawFilledPolygon(pp, ii); } } } /* next element */ plotPhysBoundary(); free(pts); } void solfcn(Widget w, void *data) { int hh = 10, ww = 10; int i; for( i = 0; i < NoOfMeshes; i++){ if( GetToggleState( solButt[i])){ currentSolution = i; redisplay(w, hh, ww, data); } } } void putUpLevelButtons() { int i; char text[2]; currentSolution = 0; label = MakeLabel(" Refinment Level:"); sprintf(text,"%i",0); solButt[0] = MakeToggle(text, TRUE, NULL, solfcn, NULL); for(i = 1; i < MAXLEVELS; i++){ sprintf(text,"%i",i); solButt[i] = MakeToggle(text, FALSE, solButt[0], solfcn, NULL); } SetWidgetPos(label, PLACE_RIGHT, plotMenu.name, NO_CARE, NULL); SetWidgetPos(solButt[0], PLACE_RIGHT, label, NO_CARE, NULL); for(i = 1; i < MAXLEVELS; i++) SetWidgetPos(solButt[i], PLACE_RIGHT, solButt[i-1], NO_CARE, NULL); /* ShowDisplay(); */ } void linMouse(Widget w, int x, int y, void *data) { int width, height; GetDrawAreaSize(&width, &height); crossHair(x, y); if(nlin == 1){ SetDrawMode(SANE_XOR); DrawLine(xplin2, yplin2, xplin1, yplin1); DrawLine(xplin2, yplin2, x, y); xplin1 = x; yplin1 = y; SetDrawMode(GXcopy); } /* if(nlin == 0){ nold = 0; pix2phys(x, 0, &xlin1, &ylin1); pix2phys(x+1, height, &xlin2, &ylin2); SetDrawMode(SANE_XOR); if(have_colors == TRUE) SetColor(YELLOW); if(have_colors == TRUE) SetColor(WHITE); SetDrawMode(GXcopy); nlin = 1; } else{ SetDrawMode(SANE_XOR); pix2phys(x, 0, &xlin1, &ylin1); pix2phys(x+1, height, &xlin2, &ylin2); if(have_colors == TRUE) SetColor(YELLOW); if(have_colors == TRUE) SetColor(WHITE); SetDrawMode(GXcopy); nlin = 1; } */ } void linDown(Widget w, int button, int x, int y, void *data) { if(nlin == 0){ pix2phys(x, y, &xlin2, &ylin2); xplin2 = x; yplin2 = y; xplin1 = x; yplin1 = y; nlin = 1; } else{ if(x == xplin2) x = x + 1; pix2phys(x, y, &xlin1, &ylin1); deleteCrossHair(); SetButtonDownCB(drawWindow, NULL); SetMouseMotionCB(drawWindow, NULL); lingraph(); } } void findFunction(float *xx, float *yy, int *n) { double x1, y1; /* Starting point of line */ double x2, y2; /* End point of line */ double k0, y0, k, m; double xp[NOBF+1], yp[NOBF+1]; double ux[NOBF+1]; double xcross, ycross, r, f, li, xi; int indx, el, i, node; int ptr; ptr = mySol[currentSolution].ptr[linitem]; x1 = (double) xlin1; x2 = (double) xlin2; y1 = (double) ylin1; y2 = (double) ylin2; k0 = (y2 - y1) / (x2 - x1); y0 = y1 - k0 * x1 ; indx = 0; for( el = 0; el < mySol[currentSolution].elnum; el++){ for(i = 0; i < NOBF; i++){ node = (double) mySol[currentSolution].nodpek[el][i]; xp[i] = (double) mySol[currentSolution].coord[node][0]; yp[i] = (double) mySol[currentSolution].coord[node][1]; ux[i] = (double) mySol[currentSolution].f[node + ptr]; } xp[NOBF] = xp[0]; yp[NOBF] = yp[0]; ux[NOBF] = ux[0]; for(i = 0; i < NOBF; i++){ if(xp[i] != xp[i+1]){ k = (yp[i] - yp[i+1]) / (xp[i] - xp[i+1]); m = yp[i] - k * xp[i]; if( k != k0){ xcross = (y0 - m) / (k - k0); ycross = k*xcross + m; if( (xcross - xp[i])*(xcross - xp[i+1]) <= 0.0){ if( (ycross - yp[i])*(ycross - yp[i+1]) <= 0.0){ if( (xcross-x1)*(xcross-x2) <=0.0 && (ycross-y1)*(ycross-y2) <=0.0){ r = (xcross - x1)*(xcross - x1) + (ycross - y1)*(ycross - y1); li = (xp[i+1] - xp[i])*(xp[i+1] - xp[i]) + (yp[i+1] - yp[i])*(yp[i+1] - yp[i]); xi = (xcross - xp[i])*(xcross - xp[i]) + (ycross - yp[i])*(ycross - yp[i]); xi = sqrt(xi/li); f = ux[i] + xi * (ux[i+1] - ux[i]); xx[indx] = (float) sqrt(r); yy[indx] = (float) f; indx++; } } } } } } } *n = indx; } void dolingraph() { nlin = 0; SetButtonDownCB(drawWindow, linDown); SetMouseMotionCB(drawWindow, linMouse); } void lingraph() { float x[1000], f[1000]; float tst, tmp; /* float xmin, xmax, ymin, ymax;*/ int n; int width, height; int i, j; float xx[3], yy[3]; findFunction(x, f, &n); /* printf("Plotting linear graph with %i points\n", n); */ xmax = -1000.; ymax = -1000.; xmin = 1000.; ymin = 1000.; for(i = 0; i < n; i++){ ymax = max(ymax, f[i]); ymin = min(ymin, f[i]); xmax = max(xmax, x[i]); xmin = min(xmin, x[i]); } /* printf("xmin, xmax : %f, %f\n", xmin, xmax); printf("ymin, ymax : %f, %f\n", ymin, ymax); */ for(i = 0; i < n; i++){ tst = x[i]; for(j = i + 1; j < n; j++){ if(x[j] < tst){ tst = x[j]; tmp = x[i]; x[i] = x[j]; x[j] = tmp; tmp = f[i]; f[i] = f[j]; f[j] = tmp; } } } ClearDrawArea(); GetDrawAreaSize(&width, &height); getDrawingScale(); for(i = 0; i < n - 1; i++){ xx[0] = x[i]; yy[0] = f[i]; xx[1] = x[i+1]; yy[1] = f[i+1]; line(xx, yy, 2); } xx[0] = xmin; yy[0] = ymin; xx[1] = xmax; yy[1] = ymin; line(xx, yy, 2); xx[0] = xmax; yy[0] = ymin; xx[1] = xmax; yy[1] = ymax; line(xx, yy, 2); xx[0] = xmax; yy[0] = ymax; xx[1] = xmin; yy[1] = ymax; line(xx, yy, 2); xx[0] = xmin; yy[0] = ymax; xx[1] = xmin; yy[1] = ymin; line(xx, yy, 2); /* DrawLine((int)(0.1*width),(int)( 0.1*height),(int)( 0.9*width),(int)( 0.1*height)); DrawLine((int)(0.1*width),(int)( 0.1*height),(int)( 0.1*width),(int)( 0.9*height)); DrawLine((int)(0.9*width),(int)( 0.1*height),(int)( 0.9*width),(int)( 0.9*height)); DrawLine((int)(0.1*width),(int)( 0.9*height),(int)( 0.9*width),(int)( 0.9*height)); if(xmin*xmax <= 0.0){ xp = (int) (width *(0.8 * (0.0 - xmin)/(xmax - xmin) + 0.1)); DrawLine(xp,(int)( 0.1*height), xp, (int)( 0.9*height)); } */ }