Logo Search packages:      
Sourcecode: felt version File versions  Download package

graph.c

/*
    This file is part of the FElt finite element analysis package.
    Copyright (C) 1993-2000 Jason I. Gobat and Darren C. Atkinson

    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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/************************************************************************
 * File:    graph.c                                         *
 *                                                    *
 * Description:   This file contains the function definitions for the   *
 *          time-displacement graphing plots                *
 ************************************************************************/

# include <stdio.h>
# include <math.h>
# include <X11/Intrinsic.h>
# include <X11/StringDefs.h>
# include <X11/Xaw/Command.h>
# include <X11/Shell.h>
# include "Layout.h"
# include "Drawing.h"
# include "util.h"
# include "fe.h"
# include "error.h"
# include "problem.h"
# include "allocate.h"
# include "procedures.h"
# include "TabGroup.h"

# define MAJOR_TICK     10.0
# define MINOR_TICK     5.0
# define LEGEND_LINE    40.0
# define LEGEND_WIDTH   125.0
# define WIDTH          400.0
# define HEIGHT         300.0
# define BUFFER         75.0

      /*    
       * some servers have all of these fonts, but some only
       * seem to have one set of the sizes or the other
       */

# define LABEL_FONT1   "-adobe-helvetica-medium-r-normal--10*"
# define LABEL_FONT2   "-adobe-helvetica-medium-r-normal--11*"
# define LEGEND_FONT1  "-adobe-helvetica-medium-r-normal--14*"
# define LEGEND_FONT2  "-adobe-helvetica-medium-r-normal--14*"
# define TITLE_FONT1   "-adobe-helvetica-medium-r-normal--24*"
# define TITLE_FONT2   "-adobe-helvetica-medium-r-normal--25*"
# define AXIS_FONT1    "-adobe-helvetica-medium-r-normal--18*"
# define AXIS_FONT2    "-adobe-helvetica-medium-r-normal--17*"

static char       *axis_font_name;
static char       *label_font_name;
static char       *title_font_name;
static char       *legend_font_name;
static XFontStruct      *axis_font;
static XFontStruct      *label_font;
static XFontStruct      *title_font;
static XFontStruct      *legend_font;

extern Widget           toplevel;
extern XtAppContext     app_context;

static Widget     tdShell = NULL;
static Widget     td_dw;
static Widget     fpShell = NULL;
static Widget     fp_dw;
static Widget   forceShell = NULL;
static Widget   force_dw;

static char *colors [ ] = {
   "black", "red", "green", "blue", "yellow", "brown", 
   "gray", "violet", "cyan", "magenta", "orange"
};

static int  lines [ ] = {
   DW_LineSolid, DW_LineDashed, DW_LineDotted, 
   DW_LineDotDashed, DW_LineLongDashed
};

typedef struct graph {
   double   xscale;
   double   yscale;
   double   min_y;
   double   max_y;
   double   min_x;
   double   max_x;
   double   y_inc;
   double   y_minor;
   double   x_inc;
   double   x_minor;
   unsigned numcurves;
} graph;

static graph td_gr;
static graph fp_gr;
static graph force_gr;

static String table =
"<Key>space: AutoRepeat(off) set()\n\
 <Key>Return: AutoRepeat(off) set()\n\
 <KeyUp>Return: AutoRepeat(saved) unset() GraphAction(button)\n\
 <KeyUp>space: AutoRepeat(saved) unset() GraphAction(button)";

static void DismissCallback (w, client_data, call_data)
   Widget   w;
   XtPointer      client_data;
   XtPointer      call_data;
{
   XtPopdown ((Widget) client_data); 
}

static void SaveCallback (w, client_data, call_data)
   Widget   w;
   XtPointer      client_data;
   XtPointer      call_data;
{
   Widget   graph_dw = *(Widget *) client_data;

   DumpDrawingArea (graph_dw, "Save Line Plot", True);
}

static void GraphAction (w, event, params, num_params)
   Widget   w;
   XEvent   *event;
   String   *params;
   Cardinal *num_params;
{
   if (strcmp (params [0], "tdShell") == 0)
      DismissCallback (NULL, (XtPointer) &tdShell, NULL);
   else if (strcmp (params [0], "fpShell") == 0)
      DismissCallback (NULL, (XtPointer) &fpShell, NULL);
   else
      XtCallCallbacks (w, XtNcallback, NULL);
}

static void InitializeGraphShell (graphShell, graph_dw, gr)
   Widget   graphShell; 
   Widget   graph_dw;
   graph    *gr;
{
   Arg            arglist [12];
   Cardinal count;
   Dimension      width, height;
   float    Xscale, Yscale;
   float    minX, maxX, minY, maxY;

   XtRealizeWidget (graphShell);

   SetFocus (XtNameToWidget (graphShell, "layout.dismiss"));

   width = WIDTH + BUFFER + ((gr -> numcurves - 1) / 16 + 1)*LEGEND_WIDTH;
   height = HEIGHT + 2*BUFFER;

   maxX = WIDTH + ((gr -> numcurves - 1) / 16 + 1)*LEGEND_WIDTH;
   minX = -BUFFER;
   maxY = HEIGHT + BUFFER;
   minY= -BUFFER;

   Xscale = Yscale = 1.0;

   count = 0;
   XtSetArg (arglist [count], XtNxMin, Float2Arg (minX)); count++;
   XtSetArg (arglist [count], XtNxMax, Float2Arg (maxX)); count++;
   XtSetArg (arglist [count], XtNyMin, Float2Arg (minY)); count++;
   XtSetArg (arglist [count], XtNyMax, Float2Arg (maxY)); count++;
   XtSetArg (arglist [count], XtNyScale, Float2Arg (Yscale)); count++;
   XtSetArg (arglist [count], XtNxScale, Float2Arg (Xscale)); count++;
   XtSetArg (arglist [count], XtNwidth, width); count++;
   XtSetArg (arglist [count], XtNheight, height); count++;
   XtSetValues (graph_dw, arglist, count);
}

static void InitializeFonts ( )
{
   axis_font = XLoadQueryFont (XtDisplay (toplevel), AXIS_FONT1);
   if (axis_font == NULL) {
      axis_font = XLoadQueryFont (XtDisplay (toplevel), AXIS_FONT2);
      if (axis_font == NULL) {
         axis_font = XLoadQueryFont (XtDisplay (toplevel), "fixed");
         axis_font_name = "fixed";
      }
      else
         axis_font_name = AXIS_FONT2;
   }
   else
      axis_font_name = AXIS_FONT1;

   label_font = XLoadQueryFont (XtDisplay (toplevel), LABEL_FONT1);
   if (label_font == NULL) {
      label_font = XLoadQueryFont (XtDisplay (toplevel), LABEL_FONT2);
      if (label_font == NULL) {
         label_font = XLoadQueryFont (XtDisplay (toplevel), "fixed");
         label_font_name = "fixed";
      }
      else
         label_font_name = LABEL_FONT2;
   }
   else
      label_font_name = LABEL_FONT1;

   title_font = XLoadQueryFont (XtDisplay (toplevel), TITLE_FONT1);
   if (title_font == NULL) {
      title_font = XLoadQueryFont (XtDisplay (toplevel), TITLE_FONT2);
      if (title_font == NULL) {
         title_font = XLoadQueryFont (XtDisplay (toplevel), "fixed");
         title_font_name = "fixed";
      }
      else
         title_font_name = TITLE_FONT2;
   }
   else
      title_font_name = TITLE_FONT1;

   legend_font = XLoadQueryFont (XtDisplay (toplevel), LEGEND_FONT1);
   if (legend_font == NULL) {
      legend_font = XLoadQueryFont (XtDisplay (toplevel), LEGEND_FONT2);
      if (legend_font == NULL) {
         legend_font = XLoadQueryFont (XtDisplay (toplevel), "fixed");
         legend_font_name = "fixed";
      }
      else
         legend_font_name = LEGEND_FONT2;
   }
   else
      legend_font_name = LEGEND_FONT1;
}


static Widget CreateGraphShell (dw, shell_name, dw_name)
   Widget         *dw;
   char                 *shell_name;
   char                 *dw_name;
{
   Widget         graphShell;
   Arg                  args [10];
   Cardinal       count;
   Widget         layout;
   Widget         dismiss, save;
   Widget         group [2];
   Pixel          highlight;
   XtTranslations translations;
   char                 buffer [32];
   static XtActionsRec  actions [ ] = {{"GraphAction", GraphAction}};
   static char          layout_string [512];

   sprintf (layout_string, 
"vertical { \
    8 \
    horizontal { \
       8 \
       %s \
       8 \
    } \
    24 \
    horizontal { \
       8 \
       dismiss \
       8 \
       save \
       8 \
    } \
    8 \
}", dw_name);

   count = 0;
   XtSetArg (args [count], XtNtitle, "Velvet Line Plot");    count++;
   XtSetArg (args [count], XtNiconName, "Velvet Line Plot"); count++;
/*
   XtSetArg (args [count], XtNallowShellResize, True); count++;
*/
   XtSetArg (args [count], XtNwidth, 1); count++;
   XtSetArg (args [count], XtNheight, 1); count++;
   graphShell = XtCreatePopupShell (shell_name, topLevelShellWidgetClass,
                                    toplevel, args, count);

   count = 0;
   XtSetArg (args [count], XtNlayout, StringToLayout(toplevel, layout_string));
   count++;
   layout = XtCreateManagedWidget ("layout", layoutWidgetClass, 
                                   graphShell, args, count);

   count = 0;
   XtSetArg (args [count], XtNgrid, False);            count++;
   XtSetArg (args [count], XtNborderWidth, 3);         count++;
   *dw = XtCreateManagedWidget (dw_name, drawingWidgetClass, 
                                layout, args, count);

   dismiss = XtCreateManagedWidget ("dismiss", commandWidgetClass,
                                    layout, NULL, 0);
   save = XtCreateManagedWidget ("save", commandWidgetClass,
                                 layout, NULL, 0);

   group [0] = dismiss;
   group [1] = save;

   XtSetArg (args [0], XtNborderColor, &highlight);
   XtGetValues (layout, args, 1);

   CreateTabGroup (graphShell, group, 2, highlight, True);

   XtRealizeWidget (graphShell);

   XtAddCallback (dismiss, XtNcallback, DismissCallback, (XtPointer) graphShell);
   XtAddCallback (save,    XtNcallback, SaveCallback, (XtPointer) dw);

   XtAppAddActions (app_context, actions, 1);

   translations = XtParseTranslationTable (table);
   XtOverrideTranslations (dismiss, translations);
   XtOverrideTranslations (save,    translations);

   sprintf(buffer,"GraphAction(%s)", shell_name);
   AddDeleteWindowProtocol (graphShell, buffer);

   InitializeFonts ( );

   return graphShell;
}

      /*
       * the following two routines are based on the heuristics used in
       * xmgr to figure out axis extreme and tick spacing ...
       */

static double NiceNumber (x, round_mode)
   double   x;
   Boolean  round_mode;
{
   double   order;
   double   fraction;
   double   y;

   order = floor (log10(x));
   fraction = x / pow(10.0, order);

   if (round_mode) {
      if (fraction < 1.5)
         y = 1.0;
      else if (fraction < 3.0)
         y = 2.0;
      else if (fraction < 7.0)
         y = 5.0;
      else
         y = 10.0;
   }
   else if (fraction <= 1.0)
      y = 1.0;
   else if (fraction <= 2.0)
      y = 2.0;
   else if (fraction <= 5.0)
      y = 5.0;
   else
      y = 10.0;

   return y*pow(10.0, order);
}

static void SetupYAxis (min, max, numticks, gr)
   double   min, max;
   int            numticks;
   graph    *gr;
{
   double   range;
   double   d;

   range = NiceNumber (max - min, False);
   d = NiceNumber (range / (numticks + 1.0), True);

   gr -> min_y = floor(min / d)*d;
   gr -> max_y = ceil(max / d)*d;
   gr -> y_inc = d;
   gr -> y_minor = d / 4;

   return;
}

static void SetupXAxis (min, max, numticks, gr)
   double   min, max;
   int            numticks;
   graph    *gr;
{
   double   range;
   double   d;

   range = NiceNumber (max - min, False);
   d = NiceNumber (range / (numticks + 1.0), True);

   gr -> min_x = floor(min / d)*d;
   gr -> max_x = ceil(max / d)*d;
   gr -> x_inc = d;
   gr -> x_minor = d / 4;

   return;
}

      /*
       * if this seems a little hokey ... it is, but I wanted to make
       * sure the time tick spacing bore some relation to the actual
       * time step
       */

static void SetupTimeAxis (gr)
   graph    *gr;
{
   int            numsteps;

   numsteps = (analysis.stop - analysis.start + analysis.step/2) / analysis.step;

   if (numsteps % 4 == 0) {
      gr -> x_inc = numsteps / 4 * analysis.step;
      gr -> x_minor = gr -> x_inc / 4.0;
   }
   else if (numsteps % 5 == 0) {
      gr -> x_inc = numsteps / 5 * analysis.step;
      gr -> x_minor = gr -> x_inc / 5.0;
   }
   else if (numsteps % 3 == 0) {
      gr -> x_inc = numsteps / 3 * analysis.step;
      gr -> x_minor = gr -> x_inc / 3.0;
   }
   else {
      gr -> x_inc = (analysis.stop - analysis.start) / 2;
      gr -> x_minor = gr -> x_inc / 4;
   }

   gr -> min_x = analysis.start;
   gr -> max_x = analysis.stop;
}

static void DrawLabel (data, axis, graph_dw, gr)
   double   data;
   int            axis;
   Widget   graph_dw;
   graph    *gr;
{
   char                 buffer [20];
   XCharStruct    cstruct;
   int                  dr, fdr, far;
   int                  width, height;
   float          x, y;

  
   sprintf (buffer,"%g", data);

   XTextExtents (label_font,buffer,strlen (buffer),&dr,&far,&fdr,&cstruct);
   width = cstruct.width;
   height = cstruct.ascent + cstruct.descent;

   if (axis == 1) {
      y = -4 - height;
      x = (data - gr -> min_x)*gr -> xscale - width/2;
   }
   else {
      y = (data - gr -> min_y)*gr -> yscale - height/2; 
      x = -4 - width;
   }
   
   DW_DrawText (graph_dw, False, x, y, buffer);

   return;
}
   
static void SetupGraphArea (min_x, max_x, min_y, max_y, graph_dw, gr, use_time)
   double   min_x, max_x;
   double   min_y, max_y;
   Widget   graph_dw;
   graph    *gr;
   unsigned use_time;
{
   double   t, x, m;
 
      /*
       * draw the border
       */

   DW_DrawRectangle (graph_dw, False, 0.0, 0.0, WIDTH, HEIGHT);

      /*
       * draw the tick marks along the time axis
       */

   DW_SetFont (graph_dw, label_font_name);

   if (use_time)
      SetupTimeAxis (gr);
   else
      SetupXAxis (min_x, max_x, 4, gr);

   gr -> xscale = WIDTH / (gr -> max_x - gr -> min_x);
   
   for (t = gr -> min_x ; t <= gr -> max_x ; t += gr -> x_inc) {
      for (m = t + gr -> x_minor ; m < t + gr -> x_inc && 
                                m < gr -> max_x ; m += gr -> x_minor)

         DW_DrawLine (graph_dw, (m - gr -> min_x)*gr -> xscale, 0.0, 
                                (m - gr -> min_x)*gr -> xscale, MINOR_TICK);

      DW_DrawLine (graph_dw, (t - gr -> min_x)*gr -> xscale, 0.0, 
                             (t - gr -> min_x)*gr -> xscale, MAJOR_TICK);

      DrawLabel (t, 1, graph_dw, gr);
   }

      /*
       * draw the tick marks along the displacement axis
       */

   SetupYAxis (min_y, max_y, 4, gr);

   gr -> yscale = HEIGHT / (gr -> max_y - gr -> min_y);

   for (x = gr -> min_y ; x <= gr -> max_y ; x += gr -> y_inc) {
      for (m = x + gr -> y_minor ; m < x + gr -> y_inc && 
                                m < gr -> max_y ; m += gr -> y_minor)

         DW_DrawLine (graph_dw, 0.0, (m - gr -> min_y)*gr -> yscale, 
                                MINOR_TICK, (m - gr -> min_y)*gr -> yscale);

      DW_DrawLine (graph_dw, 0.0, (x - gr -> min_y)*gr -> yscale, 
                             MAJOR_TICK, (x - gr -> min_y)*gr -> yscale);

      DrawLabel (x, 2, graph_dw, gr);
   }

   return;
}    

static void DrawCurveLegend (i, print_dof_names, graph_dw)
   int            i;
   Boolean  print_dof_names;
   Widget   graph_dw;
{
   static char          *symbols [ ] = {"", "Tx", "Ty", "Tz", "Rx", "Ry", "Rz"};
   static int     first = 1;
   XCharStruct          cstruct;
   char                 buffer [20];
   int                  width, height;
   int                  dr, fdr, far;
   static float         y_step;
   float          x, y;

   if (first) {
      y_step = HEIGHT / 16.0;

      first = 0;
   }

   if (print_dof_names)
      sprintf (buffer, "%s (%d)",
               symbols[(int) analysis.dofs[(i-1) % analysis.numdofs + 1]],
               analysis.nodes [(i-1) % analysis.numnodes + 1] -> number);
   else
      sprintf (buffer, "node %d", 
               analysis.nodes [(i-1) % analysis.numnodes + 1] -> number);

   XTextExtents (legend_font,buffer,strlen (buffer),&dr,&far,&fdr,&cstruct);
   width = cstruct.width;
   height = cstruct.ascent + cstruct.descent;

   x = WIDTH + 8 + (i-1)/16*LEGEND_WIDTH;
   y = HEIGHT - ((i - 1) % 16)*y_step;

   DW_DrawLine (graph_dw, x, y, x + LEGEND_LINE, y);
   DW_DrawText (graph_dw, False, x + LEGEND_LINE + 4, y - height/2, buffer);

   return;
}

static void DrawTransferLegend (i, l, curve, graph_dw)
   int            i, l;
   int            curve;
   Widget   graph_dw;
{
   static char          *symbols [ ] = {"", "Tx", "Ty", "Tz", "Rx", "Ry", "Rz"};
   static int     first = 1;
   XCharStruct          cstruct;
   char                 buffer [20];
   int                  width, height;
   int                  dr, fdr, far;
   static float         y_step;
   float          x, y;
   unsigned       inode, idof;

   if (first) {
      y_step = HEIGHT / 16.0;
      first = 0;
   }

   LocalDOF (i, &inode, &idof);

   sprintf (buffer, "%s(%d),%s(%d)",
            symbols[idof], inode, 
            symbols[(int) analysis.dofs[(l-1) % analysis.numdofs + 1]],
            analysis.nodes [(l-1) % analysis.numnodes + 1] -> number);

   XTextExtents (legend_font,buffer,strlen (buffer),&dr,&far,&fdr,&cstruct);
   width = cstruct.width;
   height = cstruct.ascent + cstruct.descent;

   x = WIDTH + 8 + (curve-1)/16*LEGEND_WIDTH;
   y = HEIGHT - ((curve - 1) % 16)*y_step;

   DW_DrawLine (graph_dw, x, y, x + LEGEND_LINE, y);
   DW_DrawText (graph_dw, False, x + LEGEND_LINE + 4, y - height/2, buffer);

   return;
}

static void DrawForceLegend (i, symbol, graph_dw)
   int            i;
   char           *symbol;
   Widget   graph_dw;
{
   static int     first = 1;
   XCharStruct          cstruct;
   int                  width, height;
   int                  dr, fdr, far;
   static float         y_step;
   float          x, y;

   if (first) {
      y_step = HEIGHT / 16.0;

      first = 0;
   }

   XTextExtents (legend_font,symbol,strlen (symbol),&dr,&far,&fdr,&cstruct);
   width = cstruct.width;
   height = cstruct.ascent + cstruct.descent;

   x = WIDTH + 8 + (i-1)/16*LEGEND_WIDTH;
   y = HEIGHT - ((i - 1) % 16)*y_step;

   DW_DrawLine (graph_dw, x, y, x + LEGEND_LINE, y);
   DW_DrawText (graph_dw, False, x + LEGEND_LINE + 4, y - height/2, symbol);

   return;
}

static void PlaceTitles (alt_title, xlabel, ylabel, graph_dw, use_alt_title)
   char           *alt_title;
   char           *xlabel;
   char           *ylabel;
   Widget   graph_dw;
   int            use_alt_title;
{
   int            dr, far, fdr;
   XCharStruct    cstruct;
   int            width, height;
   char           buffer [256];
   float    x, y;


   if (problem.title == NULL || strcmp (problem.title, "") == 0 || use_alt_title)
      strcpy (buffer, alt_title);
   else
      strcpy (buffer, problem.title);

   XTextExtents (title_font,buffer,strlen (buffer),&dr,&far,&fdr,&cstruct);

   width = cstruct.width;
   height = cstruct.ascent + cstruct.descent;

   x = WIDTH / 2 - width / 2;
   y = HEIGHT + 15;

   DW_SetFont (graph_dw, title_font_name);
   DW_DrawText (graph_dw, False, x, y, buffer);

   XTextExtents (axis_font, xlabel, 4, &dr, &far, &fdr, &cstruct);

   width = cstruct.width;
   height = cstruct.ascent + cstruct.descent;

   x = WIDTH / 2 - width / 2;
   y = -25 - height;

   DW_SetFont (graph_dw, axis_font_name);
   DW_DrawText (graph_dw, False, x, y, xlabel);

   XTextExtents (axis_font, ylabel, 4, &dr, &far, &fdr, &cstruct);

   width = cstruct.width;
   height = cstruct.ascent + cstruct.descent;

   x = -BUFFER + 10;
   y = HEIGHT / 2 - height / 2;

   DW_DrawText (graph_dw, False, x, y, ylabel);

   return;
}

void VelvetPlotTD (dtable, ttable, xlabel, ylabel, alt_title, print_dof_names)
   Matrix   dtable;
   Matrix   ttable;
   char           *xlabel;
   char           *ylabel;
   char           *alt_title;
   Boolean  print_dof_names;
{
   Arg            args [1];
   int            depth;
   double   data;
   double   prev;
   double   t_prev;
   double   t;
   unsigned i,j,k;
   double   min, max;
   double   min_t, max_t;
   unsigned use_time;

   if (tdShell == NULL) 
      tdShell = CreateGraphShell (&td_dw, "tdShell", "td_dw");

   td_gr.numcurves = analysis.numnodes * analysis.numdofs;

   InitializeGraphShell  (tdShell, td_dw, &td_gr);

   DW_RemoveAll (td_dw);

   min = max = MatrixData (dtable) [1][1];
   for (i = 1 ; i <= MatrixRows (dtable) ; i++) {
      for (j = 1 ; j <= analysis.numnodes ; j++) {
         for (k = 1 ; k <= analysis.numdofs ; k++) {

            data = MatrixData (dtable) [i][(j-1)*analysis.numdofs + k];

            if (data < min)
               min = data;
            else if (data > max)
               max = data;
         }
      }
   }

   XtPopup (tdShell, XtGrabNone);

   DW_SetForeground (td_dw, "black");
   DW_SetLineStyle (td_dw, DW_LineSolid);

   XtSetArg (args [0], XtNdepth, &depth);
   XtGetValues (toplevel, args, 1);

   if (ttable == NullMatrix) {
      min_t = 0.0;
      max_t = analysis.stop;
   }
   else {
      min_t = mdata(ttable,1,1);
      max_t = mdata(ttable,Mrows(ttable),1);
   }

   if (ttable == NULL)
      use_time = 1;
   else
      use_time = 0;

   SetupGraphArea (min_t, max_t, min, max, td_dw, &td_gr, use_time);
 
   DW_SetFont (td_dw, legend_font_name);
   for (i = 1 ; i <= td_gr.numcurves ; i++) { 

      if (depth > 1)
         DW_SetForeground (td_dw, colors [(i - 1) % XtNumber (colors)]);

      DW_SetLineStyle (td_dw, lines [(i - 1) % XtNumber (lines)]);

      prev = MatrixData (dtable) [1][i];
      t_prev = min_t;
      for (j = 2 ; j <= MatrixRows (dtable) ; j++) {

         if (ttable == NullMatrix)
            t = (j - 1)*analysis.step;
         else
            t = mdata(ttable,j,1);

         data = MatrixData (dtable) [j][i];
         DW_DrawLine (td_dw, t_prev*td_gr.xscale, 
                             (prev - td_gr.min_y)*td_gr.yscale, 
                             t*td_gr.xscale, 
                             (data - td_gr.min_y)*td_gr.yscale);

         t_prev = t;
         prev = data;
      }

      DrawCurveLegend (i, print_dof_names, td_dw);
   }

   DW_SetForeground (td_dw, "black");

   PlaceTitles (alt_title, xlabel, ylabel, td_dw, 0);
}

void VelvetPlotSpectra (P, xlabel, ylabel, alt_title, print_dof_names)
   Matrix   P;
   char           *xlabel;
   char           *ylabel;
   char           *alt_title;
   Boolean  print_dof_names;
{
   Arg            args [1];
   int            depth;
   double   data;
   double   prev;
   double   f;
   unsigned i,j,k;
   double   min, max;

   if (fpShell == NULL) 
      fpShell = CreateGraphShell (&fp_dw, "fpShell", "fp_dw");

   fp_gr.numcurves = analysis.numnodes * analysis.numdofs;

   InitializeGraphShell (fpShell, fp_dw, &fp_gr);

   DW_RemoveAll (fp_dw);

   min = max = MatrixData (P) [1][1];
   for (i = 1 ; i <= MatrixRows (P) ; i++) {
      for (j = 1 ; j <= analysis.numnodes ; j++) {
         for (k = 1 ; k <= analysis.numdofs ; k++) {

            data = MatrixData (P) [i][(j-1)*analysis.numdofs + k];

            if (data < min)
               min = data;
            else if (data > max)
               max = data;
         }
      }
   }

   XtPopup (fpShell, XtGrabNone);

   DW_SetForeground (fp_dw, "black");
   DW_SetLineStyle (fp_dw, DW_LineSolid);

   XtSetArg (args [0], XtNdepth, &depth);
   XtGetValues (toplevel, args, 1);

   SetupGraphArea (analysis.start, analysis.stop, min, max, fp_dw, &fp_gr, 0);
 
   DW_SetFont (fp_dw, legend_font_name);
   for (i = 1 ; i <= fp_gr.numcurves ; i++) { 

      if (depth > 1)
         DW_SetForeground (fp_dw, colors [(i - 1) % XtNumber (colors)]);

      DW_SetLineStyle (fp_dw, lines [(i - 1) % XtNumber (lines)]);

      prev = MatrixData (P) [1][i];
      for (j = 2 ; j <= MatrixRows (P) ; j++) {

         f = (j - 1)*analysis.step;
         data = MatrixData (P) [j][i];
         DW_DrawLine (fp_dw, (f - analysis.step - fp_gr.min_x)*fp_gr.xscale, 
                             (prev - fp_gr.min_y)*fp_gr.yscale, 
                             (f - fp_gr.min_x)*fp_gr.xscale, 
                             (data - fp_gr.min_y)*fp_gr.yscale);

         prev = data;
      }

      DrawCurveLegend (i, print_dof_names, fp_dw);
   }

   DW_SetForeground (fp_dw, "black");

   PlaceTitles (alt_title, xlabel, ylabel, fp_dw, 0);
}

void VelvetPlotTransferFunctions (H, forced, numforced, xlabel, ylabel, alt_title)
   Matrix   *H;
   unsigned *forced;
   unsigned numforced;
   char           *xlabel;
   char           *ylabel;
   char           *alt_title;
{
   Arg            args [1];
   int            depth;
   double   data;
   double   prev;
   double   f;
   unsigned i,j,k,l;
   unsigned curve;
   unsigned nn;
   double   min, max;

   if (fpShell == NULL) 
      fpShell = CreateGraphShell (&fp_dw, "fpShell", "fp_dw");

   nn = analysis.numdofs * analysis.numnodes;
   fp_gr.numcurves = nn * numforced;

   InitializeGraphShell (fpShell, fp_dw, &fp_gr);

   DW_RemoveAll (fp_dw);

   min = max = MatrixData (H [1]) [1][1];
   for (i = 1 ; i <= MatrixRows (H [1]) ; i++) {
      for (l = 1 ; l <= numforced ; l++) {
         for (j = 1 ; j <= analysis.numnodes ; j++) {
            for (k = 1 ; k <= analysis.numdofs ; k++) {

               data = MatrixData (H [l]) [i][(j-1)*analysis.numdofs + k];

               if (data < min)
                  min = data;
               else if (data > max)
                  max = data;
            }
         }
      }
   }

   XtPopup (fpShell, XtGrabNone);

   DW_SetForeground (fp_dw, "black");
   DW_SetLineStyle (fp_dw, DW_LineSolid);

   XtSetArg (args [0], XtNdepth, &depth);
   XtGetValues (toplevel, args, 1);

   SetupGraphArea (analysis.start, analysis.stop, min, max, fp_dw, &fp_gr, 0);
 
   DW_SetFont (fp_dw, legend_font_name);
   for (i = 1 ; i <= numforced ; i++) { 
      for (l = 1 ; l <= nn ; l++) {

         curve = (i - 1)*nn + l;

         if (depth > 1)
            DW_SetForeground (fp_dw, colors [(curve - 1) % XtNumber (colors)]);

         DW_SetLineStyle (fp_dw, lines [(curve - 1) % XtNumber (lines)]);

         prev = MatrixData (H [i]) [1][l];
         for (j = 2 ; j <= MatrixRows (H [1]) ; j++) {

            f = (j - 1)*analysis.step;
            data = MatrixData (H [i]) [j][l];
            DW_DrawLine (fp_dw, (f - analysis.step - fp_gr.min_x)*fp_gr.xscale, 
                                (prev - fp_gr.min_y)*fp_gr.yscale, 
                                (f - fp_gr.min_x)*fp_gr.xscale, 
                                (data - fp_gr.min_y)*fp_gr.yscale);

            prev = data;
         }

         DrawTransferLegend (forced [i], l, curve, fp_dw);
      }
   }

   DW_SetForeground (fp_dw, "black");

   PlaceTitles (alt_title, xlabel, ylabel, fp_dw, 0);
}

void VelvetPlotForce (force, quantity)
   Force    force;
   char           *quantity;
{
   static char *symbols [] = {"", "Fx", "Fy", "Fz", "Mx", "My", "Mz"};
   char           *symbol [4];
   Arg            args [1];
   int            depth;
   double   data;
   double   prev;
   double   t;
   unsigned i,j;
   double   min, max;
   Matrix   ftable;     
   int            status_x, status_y, status_z;
   int            offset;
   int            n; 

   if (analysis.stop <= 0.0 || analysis.step <= 0.0) {
      error ("improper time step or time duration information");
      return;
   }

   n = analysis.stop / analysis.step + 1;

   offset = 0;    /* gcc -Wall */
   if (strcmp(quantity, "force") == 0) 
      offset = 1;
   else if (strcmp(quantity, "moment") == 0)
      offset = 4;

   status_x = status_y = status_z = 0;

   if (force -> force [offset].expr != NULL)
      status_x = 1;
   else if (force -> force [offset].value) 
      status_x = 2;

   if (force -> force [offset+1].expr != NULL)
      status_y = 1;
   else if (force -> force [offset+1].value) 
      status_y = 2;

   if (force -> force [offset+2].expr != NULL)
      status_z = 1;
   else if (force -> force [offset+2].value) 
      status_z = 2;

   force_gr.numcurves = (status_x > 0) + (status_y > 0) + (status_z > 0);

   if (force_gr.numcurves == 0) {
      error ("nothing to plot");
      return;
   }

   j = 0;
   if (status_x)
      symbol [j+1] = symbols [offset + j++];
   if (status_y)
      symbol [j+1] = symbols [offset + j++];
   if (status_z)
      symbol [j+1] = symbols [offset + j++];

   ftable = CreateMatrix (n, force_gr.numcurves);

   if (forceShell == NULL) 
      forceShell = CreateGraphShell (&force_dw, "forceShell", "force_dw");

   InitializeGraphShell  (forceShell, force_dw, &force_gr);

   DW_RemoveAll (force_dw);

   for (i = 1 ; i <= n ; i++) {
      t = (i - 1)*analysis.step;

      j = 1;

      if (status_x == 1)
         sdata(ftable,i,j++) = EvalCode (force -> force [offset].expr, t);
      else if (status_x == 2)
         sdata(ftable,i,j++) = force -> force [offset].value;

      if (status_y == 1)
         sdata(ftable,i,j++) = EvalCode (force -> force [offset+1].expr, t);
      else if (status_y == 2)
         sdata(ftable,i,j++) = force -> force [offset+1].value;

      if (status_z == 1)
         sdata(ftable,i,j++) = EvalCode (force -> force [offset+2].expr, t);
      else if (status_z == 2)
         sdata(ftable,i,j++) = force -> force [offset+2].value;
   }

   min = max = mdata(ftable,1,1);

   for (i = 1 ; i <= n ; i++) {
      for (j = 1 ; j <= force_gr.numcurves ; j++) {
         data = mdata(ftable,i,j);

         if (data < min)
            min = data;
         else if (data > max)
            max = data;
      }
   }

   XtPopup (forceShell, XtGrabNone);

   DW_SetForeground (force_dw, "black");
   DW_SetLineStyle (force_dw, DW_LineSolid);

   XtSetArg (args [0], XtNdepth, &depth);
   XtGetValues (toplevel, args, 1);

   SetupGraphArea (0.0, analysis.stop, min, max, force_dw, &force_gr, 1);
 
   DW_SetFont (force_dw, legend_font_name);
   for (i = 1 ; i <= force_gr.numcurves ; i++) { 

      if (depth > 1)
         DW_SetForeground (force_dw, colors [(i - 1) % XtNumber (colors)]);

      DW_SetLineStyle (force_dw, lines [(i - 1) % XtNumber (lines)]);

      prev = mdata(ftable,1,i);
      for (j = 2 ; j <= n ; j++) {

         t = (j - 1)*analysis.step;
         data = MatrixData (ftable) [j][i];
         DW_DrawLine (force_dw, (t - analysis.step)*force_gr.xscale, 
                             (prev - force_gr.min_y)*force_gr.yscale, 
                             t*force_gr.xscale, 
                             (data - force_gr.min_y)*force_gr.yscale);

         prev = data;
      }

      DrawForceLegend (i, symbol [i], force_dw);
   }

   DW_SetForeground (force_dw, "black");

   PlaceTitles (force -> name, "time", (offset == 1 ? "F" : "M"), force_dw, 1);

   DestroyMatrix (ftable);

   return;
}

void VelvetPlotLoadRange (dtable)
   Matrix   dtable;
{
   Arg            args [1];
   int            depth;
   double   data;
   double   prev;
   double   f_prev;
   double   f;
   unsigned i,j,k;
   double   min, max;
   double   min_f, max_f;

   if (tdShell == NULL) 
      tdShell = CreateGraphShell (&td_dw, "tdShell", "td_dw");

   td_gr.numcurves = analysis.numnodes * analysis.numdofs;

   InitializeGraphShell  (tdShell, td_dw, &td_gr);

   DW_RemoveAll (td_dw);

   min = max = MatrixData (dtable) [1][1];
   for (i = 1 ; i <= MatrixRows (dtable) ; i++) {
      for (j = 1 ; j <= analysis.numnodes ; j++) {
         for (k = 1 ; k <= analysis.numdofs ; k++) {

            data = MatrixData (dtable) [i][(j-1)*analysis.numdofs + k];

            if (data < min)
               min = data;
            else if (data > max)
               max = data;
         }
      }
   }

   XtPopup (tdShell, XtGrabNone);

   DW_SetForeground (td_dw, "black");
   DW_SetLineStyle (td_dw, DW_LineSolid);

   XtSetArg (args [0], XtNdepth, &depth);
   XtGetValues (toplevel, args, 1);

   if (analysis.step >= 0) {
      min_f = analysis.start;
      max_f = analysis.stop;
   }
   else {
      max_f = analysis.start;
      min_f = analysis.stop;
   }

   SetupGraphArea (min_f, max_f, min, max, td_dw, &td_gr, 0);
 
   DW_SetFont (td_dw, legend_font_name);
   for (i = 1 ; i <= td_gr.numcurves ; i++) { 

      if (depth > 1)
         DW_SetForeground (td_dw, colors [(i - 1) % XtNumber (colors)]);

      DW_SetLineStyle (td_dw, lines [(i - 1) % XtNumber (lines)]);

      prev = MatrixData (dtable) [1][i];
      f_prev = analysis.start;
      for (j = 2 ; j <= MatrixRows (dtable) ; j++) {

         f = (j - 1)*analysis.step + analysis.start;

         data = MatrixData (dtable) [j][i];
         DW_DrawLine (td_dw, (f_prev - td_gr.min_x)*td_gr.xscale, 
                             (prev - td_gr.min_y)*td_gr.yscale, 
                             (f - td_gr.min_x)*td_gr.xscale, 
                             (data - td_gr.min_y)*td_gr.yscale);

         f_prev = f;
         prev = data;
      }

      DrawCurveLegend (i, 1, td_dw);
   }

   DW_SetForeground (td_dw, "black");

   PlaceTitles ("Load Range Result", "force", "dx", td_dw, 0);
}

Generated by  Doxygen 1.6.0   Back to index