/usr/lib/petscdir/3.7.7/x86_64-linux-gnu-complex/share/petsc/saws/js/drawDiagrams.js is in libpetsc-complex-3.7.7-dev 3.7.7+dfsg1-2build5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | //this recursive function should always be called on the root solver (endtag = "0").
//targetEndtag is the endtag of the solver option that is currently being asked. the reason we have this as a parameter is because there is simply not enough space to display a diagram of the ENTIRE solver. so, we only display a path to the current solver option
//x,y are the x and y coordinates of the upper lefthand corner of the svg (should initially be called with 0,0)
//this function returns a string that needs to be put into an svg in the html page
function drawDiagrams(data,endtag,targetEndtag,x,y) {
if(data["0"].x_extreme == undefined)
data["0"].x_extreme = 0;
if(data["0"].y_extreme == undefined)
data["0"].y_extreme = 0;
var numChildren = getNumChildren(data,endtag);
if(numChildren == 0) //base case. no children.
return "";
if(targetEndtag.indexOf(endtag) != 0) //base case. endtag is not on the path to targetEndtag.
return "";
var ret = "";
if(data[endtag].pc_type == "fieldsplit") {
if(x+400 > data["0"].x_extreme)
data["0"].x_extreme = x+400;
if(y+400 > data["0"].y_extreme)
data["0"].y_extreme = y+400;
}
else if(data[endtag].pc_type == "mg") {
var mg_levels = data[endtag].mg_levels;
var global_downshift = 141*mg_levels + 68*mg_levels;
if(x+465 > data["0"].x_extreme)
data["0"].x_extreme = x+465;
if(y+global_downshift > data["0"].y_extreme)
data["0"].y_extreme = y+global_downshift;
}
if(data[endtag].pc_type == "fieldsplit") { //draw fieldsplit diagram
var colors = ["green","blue","red"];
var layer = 0;
ret += "<polygon points=\""+x+","+y+" "+(x+400)+","+y+" "+(x+400)+","+(y+400)+" "+x+","+(y+400)+"\" style=\"fill:khaki;stroke:black;stroke-width:1\"></polygon>";
layer = 1;
function drawFieldsplit(data,endtag,level,targetEndtag,x,y,size) { //(x,y) is the upper lefthand corner. size is the size of one side of the parent square (in pixels)
//work = draw the children of the fieldsplit then call draw on each child
if(targetEndtag.indexOf(endtag) != 0)
return ""; //endtag is not on the path to the targetEndtag
var ret = "";
var numChildren = getNumChildren(data,endtag);
if(numChildren == 0)
return;
var colorNum = level;//the depth of the fieldsplit within other fieldsplits
for(var i=0; i<numChildren; i++) {
var side = size/(numChildren+1);//leave one extra block of space
var curr_x = x + i*side;
var curr_y = y + i*side;
ret += "<polygon points=\""+curr_x+","+curr_y+" "+(curr_x+side)+","+curr_y+" "+(curr_x+side)+","+(curr_y+side)+" "+curr_x+","+(curr_y+side)+"\" style=\"fill:"+colors[colorNum]+";stroke:black;stroke-width:1\"></polygon>";
var childEndtag = endtag + "_" + i;
//only draw if child is indeed a fieldsplit
if(data[childEndtag] != undefined && data[childEndtag].pc_type == "fieldsplit")
ret += drawFieldsplit(data,childEndtag, level+1, targetEndtag, curr_x, curr_y, size/numChildren);
//if child is mg, then it is time to switch drawing methods
else if(data[childEndtag] != undefined && data[childEndtag].pc_type == "mg") {
var possible = drawDiagrams(data,childEndtag,targetEndtag,x+size+20+146,y+i*side);
if(possible != "") {//don't draw the arrow if there is no diagram following
ret += "<image x=\""+(x+size+20)+"\" y=\""+(y+i*side+side/2-13)+"\" width=\"146\" height=\"26\" xlink:href=\"images/arrow.png\"></image>";
ret += possible;
}
}
}
var side = size/(numChildren+1);//side of the blank square
var blank_x = x + numChildren*side;
var blank_y = y + numChildren*side;
var inc = side/4;//the increment
for(var i=1; i<4; i++) { //add diagonal ellipsis
var x_coord = blank_x + i*inc;
var y_coord = blank_y + i*inc;
ret += "<circle cx=\""+x_coord+"\" cy=\"" + y_coord + "\" r=\"2\" stroke=\"black\" stroke-width=\"2\" fill=\"black\"></circle>";
}
return ret;
}
ret += drawFieldsplit(data,endtag,0,targetEndtag,x,y,400);
}
else if(data[endtag].pc_type == "mg") { //draw multigrid diagram. multigrid diagram doesn't use an inner recursive function because it's not that complex to draw.
var selectedChild = "";
//generate a parallelogram for each layer
for(var i=0; i<numChildren; i++) { //i represents the multigrid level (i=0 would be coarse)
var dim = 3+2*i;//dimxdim grid
var global_downshift = 141*i + 68*i;
ret += "<polygon points=\""+x+","+(y+141+global_downshift)+" "+ (x+141)+","+(y+global_downshift)+" "+(x+465)+","+(y+global_downshift)+" "+(x+324)+","+(y+141+global_downshift)+"\" style=\"fill:khaki;stroke:black;stroke-width:1\"> </polygon>";
for(var j=1; j<dim; j++) {//draw 'vertical' lines
var inc = 324/dim;//parallogram is 324 wide and 200 on the slant side (1.6x)
var shift = j*inc;
var top_shift = shift + 141;
ret += "<line x1=\""+(x+shift)+"\" y1=\""+(y+141+global_downshift)+"\" x2=\""+(x+top_shift)+"\" y2=\""+(y+global_downshift)+"\" style='stroke:black;stroke-width:1'></line>";
}
for(var j=1; j<dim; j++) {//draw horizonal lines
var inc = 141/dim;//parallelogram is 141 tall
var horiz_shift = (141/dim) * j;
var horiz_shift_end = horiz_shift + 324;
var shift = 141 - inc * j;
ret += "<line x1=\""+(x+horiz_shift)+"\" y1=\""+(y+shift+global_downshift) +"\" x2=\""+(x+horiz_shift_end)+"\" y2=\""+(y+shift+global_downshift)+"\" style='stroke:black;stroke-width:1'></line>";
}
if(i != numChildren-1)//add transition arrows image if there are more grids left
ret += "<image x=\""+x+"\" y=\""+(y+141+global_downshift)+"\" width=\"349\" height=\"68\" xlink:href=\"/images/transition.bmp\"/>"; //images in svg are handled differently. can't simply use <img>
//if the current child is the one that is on the path to the target, then record it
var childEndtag = endtag + "_" + i;
if(targetEndtag.indexOf(childEndtag) == 0) { //this can only happen with 1 child (the one that is on the path to the target)
selectedChild = i;
}
}
var new_x = x + 465;
var new_y = y + (selectedChild) * (141+68);//manipulate based on selectedChild
//recursively draw the rest of the path to targetEndtag
var possible = drawDiagrams(data,endtag+"_"+selectedChild,targetEndtag,new_x+146,new_y);
if(possible != "") {//only add the arrow if something was actually drawn
ret += "<image x=\""+(new_x-45)+"\" y=\""+(new_y+70)+"\" width=\"146\" height=\"26\" xlink:href=\"images/arrow.png\"></image>";
ret += possible;
}
}
return ret;
}
|