Date: 2022-03-04T17:37:01+00:00

Actual source code: dviewp.c

      2: /*
      3:        Provides the calling sequences for all the basic PetscDraw routines.
      4: */
      5: #include <petsc/private/drawimpl.h>

      7: /*@
      8:    PetscDrawSetViewPort - Sets the portion of the window (page) to which draw
      9:    routines will write.

     11:    Collective on PetscDraw

     13:    Input Parameters:
     14: +  xl - the horizontal coordinate of the lower left corner of the subwindow.
     15: .  yl - the vertical coordinate of the lower left corner of the subwindow.
     16: .  xr - the horizontal coordinate of the upper right corner of the subwindow.
     17: .  yr - the vertical coordinate of the upper right corner of the subwindow.
     18: -  draw - the drawing context

     20:    Notes:
     21:    These numbers must always be between 0.0 and 1.0.
     22:    Lower left corner is (0,0).

     24:    Level: advanced

     26: @*/
     27: PetscErrorCode  PetscDrawSetViewPort(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
     28: {

     33:   if (xl < 0.0 || xr > 1.0 || yl < 0.0 || yr > 1.0 || xr <= xl || yr <= yl) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"ViewPort values must be >= 0 and <= 1: Instead %g %g %g %g",(double)xl,(double)yl,(double)xr,(double)yr);
     34:   draw->port_xl = xl; draw->port_yl = yl;
     35:   draw->port_xr = xr; draw->port_yr = yr;
     36:   if (draw->ops->setviewport) {
     37:     (*draw->ops->setviewport)(draw,xl,yl,xr,yr);
     38:   }
     39:   return(0);
     40: }

     42: /*@
     43:    PetscDrawGetViewPort - Gets the portion of the window (page) to which draw
     44:    routines will write.

     46:    Collective on PetscDraw

     48:    Input Parameter:
     49: .  draw - the drawing context

     51:    Output Parameters:
     52: +  xl - the horizontal coordinate of the lower left corner of the subwindow.
     53: .  yl - the vertical coordinate of the lower left corner of the subwindow.
     54: .  xr - the horizontal coordinate of the upper right corner of the subwindow.
     55: -  yr - the vertical coordinate of the upper right corner of the subwindow.

     57:    Notes:
     58:    These numbers must always be between 0.0 and 1.0.
     59:    Lower left corner is (0,0).

     61:    Level: advanced

     63: @*/
     64: PetscErrorCode  PetscDrawGetViewPort(PetscDraw draw,PetscReal *xl,PetscReal *yl,PetscReal *xr,PetscReal *yr)
     65: {
     72:   *xl = draw->port_xl;
     73:   *yl = draw->port_yl;
     74:   *xr = draw->port_xr;
     75:   *yr = draw->port_yr;
     76:   return(0);
     77: }

     79: /*@
     80:    PetscDrawSplitViewPort - Splits a window shared by several processes into smaller
     81:    view ports. One for each process.

     83:    Collective on PetscDraw

     85:    Input Parameter:
     86: .  draw - the drawing context

     88:    Level: advanced

     90: .seealso: PetscDrawDivideViewPort(), PetscDrawSetViewPort()

     92: @*/
     93: PetscErrorCode  PetscDrawSplitViewPort(PetscDraw draw)
     94: {
     96:   PetscMPIInt    rank,size;
     97:   PetscInt       n;
     98:   PetscBool      isnull;
     99:   PetscReal      xl,xr,yl,yr,h;

    103:   PetscDrawIsNull(draw,&isnull);
    104:   if (isnull) return(0);
    105:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
    106:   MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);

    108:   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size));
    109:   while (n*n < size) n++;

    111:   h  = 1.0/n;
    112:   xl = (rank % n)*h;
    113:   xr = xl + h;
    114:   yl = (rank / n)*h;
    115:   yr = yl + h;

    117:   PetscDrawCollectiveBegin(draw);
    118:   PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK);
    119:   PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK);
    120:   PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK);
    121:   PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK);
    122:   PetscDrawCollectiveEnd(draw);
    123:   PetscDrawFlush(draw);

    125:   draw->port_xl = xl + .05*h;
    126:   draw->port_xr = xr - .05*h;
    127:   draw->port_yl = yl + .05*h;
    128:   draw->port_yr = yr - .05*h;

    130:   if (draw->ops->setviewport) {
    131:      (*draw->ops->setviewport)(draw,xl,yl,xr,yr);
    132:   }
    133:   return(0);
    134: }

    136: /*@C
    137:    PetscDrawViewPortsCreate - Splits a window into smaller view ports. Each processor shares all the viewports.

    139:    Collective on PetscDraw

    141:    Input Parameters:
    142: +  draw - the drawing context
    143: -  nports - the number of ports

    145:    Output Parameter:
    146: .  ports - a PetscDrawViewPorts context (C structure)

    148:    Options Database:
    149: .  -draw_ports - display multiple fields in the same window with PetscDrawPorts() instead of in separate windows

    151:    Level: advanced

    153: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()

    155: @*/
    156: PetscErrorCode  PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **newports)
    157: {
    158:   PetscDrawViewPorts *ports;
    159:   PetscInt           i,n;
    160:   PetscBool          isnull;
    161:   PetscMPIInt        rank;
    162:   PetscReal          *xl,*xr,*yl,*yr,h;
    163:   PetscErrorCode     ierr;

    167:   if (nports < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d", nports);
    169:   PetscDrawIsNull(draw,&isnull);
    170:   if (isnull) {*newports = NULL; return(0);}
    171:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);

    173:   PetscNew(&ports); *newports = ports;
    174:   ports->draw = draw;
    175:   ports->nports = nports;
    176:   PetscObjectReference((PetscObject)draw);
    177:   /* save previous drawport of window */
    178:   PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);

    180:   n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports));
    181:   while (n*n < nports) n++;
    182:   h = 1.0/n;

    184:   PetscMalloc4(n*n,&xl,n*n,&xr,n*n,&yl,n*n,&yr);
    185:   ports->xl = xl;
    186:   ports->xr = xr;
    187:   ports->yl = yl;
    188:   ports->yr = yr;

    190:   PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);
    191:   PetscDrawCollectiveBegin(draw);
    192:   for (i=0; i<n*n; i++) {
    193:     xl[i] = (i % n)*h;
    194:     xr[i] = xl[i] + h;
    195:     yl[i] = (i / n)*h;
    196:     yr[i] = yl[i] + h;

    198:     if (rank == 0) {
    199:       PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);
    200:       PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);
    201:       PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);
    202:       PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);
    203:     }

    205:     xl[i] += .05*h;
    206:     xr[i] -= .05*h;
    207:     yl[i] += .05*h;
    208:     yr[i] -= .05*h;
    209:   }
    210:   PetscDrawCollectiveEnd(draw);
    211:   PetscDrawFlush(draw);
    212:   return(0);
    213: }

    215: /*@C
    216:    PetscDrawViewPortsCreateRect - Splits a window into smaller
    217:        view ports. Each processor shares all the viewports. The number
    218:        of views in the x- and y-directions is specified.

    220:    Collective on PetscDraw

    222:    Input Parameters:
    223: +  draw - the drawing context
    224: .  nx - the number of x divisions
    225: -  ny - the number of y divisions

    227:    Output Parameter:
    228: .  ports - a PetscDrawViewPorts context (C structure)

    230:    Level: advanced

    232: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy()

    234: @*/
    235: PetscErrorCode  PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports)
    236: {
    237:   PetscDrawViewPorts *ports;
    238:   PetscReal          *xl,*xr,*yl,*yr,hx,hy;
    239:   PetscInt           i,j,k,n;
    240:   PetscBool          isnull;
    241:   PetscMPIInt        rank;
    242:   PetscErrorCode     ierr;

    246:   if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny);
    248:   PetscDrawIsNull(draw,&isnull);
    249:   if (isnull) {*newports = NULL; return(0);}
    250:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);

    252:   n  = nx*ny;
    253:   hx = 1.0/nx;
    254:   hy = 1.0/ny;
    255:   PetscNew(&ports); *newports = ports;
    256:   ports->draw = draw;
    257:   ports->nports = n;
    258:   PetscObjectReference((PetscObject) draw);
    259:   /* save previous drawport of window */
    260:   PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);

    262:   PetscMalloc4(n,&xl,n,&xr,n,&yl,n,&yr);
    263:   ports->xr = xr;
    264:   ports->xl = xl;
    265:   ports->yl = yl;
    266:   ports->yr = yr;

    268:   PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);
    269:   PetscDrawCollectiveBegin(draw);
    270:   for (i = 0; i < nx; i++) {
    271:     for (j = 0; j < ny; j++) {
    272:       k = j*nx+i;

    274:       xl[k] = i*hx;
    275:       xr[k] = xl[k] + hx;
    276:       yl[k] = j*hy;
    277:       yr[k] = yl[k] + hy;

    279:       if (rank == 0) {
    280:         PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);
    281:         PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);
    282:         PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);
    283:         PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);
    284:       }

    286:       xl[k] += .05*hx;
    287:       xr[k] -= .05*hx;
    288:       yl[k] += .05*hy;
    289:       yr[k] -= .05*hy;
    290:     }
    291:   }
    292:   PetscDrawCollectiveEnd(draw);
    293:   PetscDrawFlush(draw);
    294:   return(0);
    295: }

    297: /*@C
    298:    PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object

    300:    Collective on PetscDraw inside PetscDrawViewPorts

    302:    Input Parameter:
    303: .  ports - the PetscDrawViewPorts object

    305:    Level: advanced

    307: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate()

    309: @*/
    310: PetscErrorCode  PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports)
    311: {

    315:   if (!ports) return(0);
    317:   /* reset Drawport of Window back to previous value */
    318:   PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);
    319:   PetscDrawDestroy(&ports->draw);
    320:   PetscFree4(ports->xl,ports->xr,ports->yl,ports->yr);
    321:   PetscFree(ports);
    322:   return(0);
    323: }

    325: /*@C
    326:    PetscDrawViewPortsSet - sets a draw object to use a particular subport

    328:    Logically Collective on PetscDraw inside PetscDrawViewPorts

    330:    Input Parameters:
    331: +  ports - the PetscDrawViewPorts object
    332: -  port - the port number, from 0 to nports-1

    334:    Level: advanced

    336: .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate()

    338: @*/
    339: PetscErrorCode  PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port)
    340: {

    344:   if (!ports) return(0);
    346:   if (port < 0 || port > ports->nports-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Port is out of range requested %d from 0 to %d\n",port,ports->nports-1);
    347:   PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);
    348:   return(0);
    349: }