1/* 2 This function is called when a pc_type option is changed (new options may need to be displayed and/or old ones removed 3*/ 4 5$(document).on("change","select[id^='pc_type']",function() { 6 7 //get the pc option 8 var pcValue = $(this).val(); 9 var id = $(this).attr("id"); //really should not be used in this method. there are better ways of getting information 10 var endtag = id.substring(id.indexOf("0"),id.length); 11 var parentDiv = "solver" + endtag; 12 13 removeAllChildren(endtag); //this function also changes matInfo as needed 14 15 //record pc_type in matInfo 16 matInfo[endtag].pc_type = pcValue; 17 18 if (pcValue == "mg") { 19 var defaults = getDefaults("mg",matInfo[endtag].symm, matInfo[endtag].posdef, matInfo[endtag].logstruc); 20 var defaultMgLevels = defaults.pc_mg_levels; 21 22 matInfo[endtag].pc_mg_levels = defaultMgLevels; 23 matInfo[endtag].pc_mg_type = defaults.pc_mg_type; 24 25 //first add options related to multigrid (pc_mg_type and pc_mg_levels) 26 $("#" + parentDiv).append("<br><b>MG Type </b><select id=\"pc_mg_type" + endtag + "\"></select>"); 27 $("#" + parentDiv).append("<br><b>MG Levels </b><input type='text' id=\'pc_mg_levels" + endtag + "\' maxlength='4'>"); 28 29 populateList("mg",endtag); 30 31 $("#pc_mg_levels" + endtag).val(defaultMgLevels); 32 $("#pc_mg_type" + endtag).val(defaults.pc_mg_type); 33 34 //display options for each level 35 for(var i=defaultMgLevels-1; i>=0; i--) { 36 var childEndtag = endtag + "_" + i; 37 38 matInfo[childEndtag] = { 39 pc_type : defaults.sub_pc_type, 40 ksp_type: defaults.sub_ksp_type, 41 symm: matInfo[endtag].symm, //inherit !! 42 posdef: matInfo[endtag].posdef, 43 logstruc: matInfo[endtag].logstruc 44 }; 45 46 var margin = 30 * getNumUnderscores(childEndtag); //indent based on the level of the solver (number of underscores) 47 48 $("#" + parentDiv).after("<div id=\"solver" + childEndtag + "\" style=\"margin-left:" + margin + "px;\"></div>"); 49 if(i == 0) //coarse grid solver (level 0) 50 $("#solver" + childEndtag).append("<br><b>Coarse Grid Solver (Level 0) </b>"); 51 else 52 $("#solver" + childEndtag).append("<br><b>Smoothing (Level " + i + ") </b>"); 53 54 $("#solver" + childEndtag).append("<br><b>KSP </b><select id=\"ksp_type" + childEndtag + "\"></select>"); 55 $("#solver" + childEndtag).append("<br><b>PC </b><select id=\"pc_type" + childEndtag + "\"></select>"); 56 57 populateList("ksp",childEndtag); 58 populateList("pc",childEndtag); 59 60 //set defaults 61 $("#ksp_type" + childEndtag).val(defaults.sub_ksp_type); 62 $("#pc_type" + childEndtag).val(defaults.sub_pc_type); 63 //trigger both to add additional options 64 $("#ksp_type" + childEndtag).trigger("change"); 65 $("#pc_type" + childEndtag).trigger("change"); 66 } 67 68 } 69 70 else if(pcValue == "gamg") { 71 var defaults = getDefaults("gamg",matInfo[endtag].symm, matInfo[endtag].posdef, matInfo[endtag].logstruc); 72 var defaultGamgLevels = defaults.pc_gamg_levels; 73 74 matInfo[endtag].pc_gamg_levels = defaultGamgLevels; 75 matInfo[endtag].pc_gamg_type = defaults.pc_gamg_type; 76 77 //first add options related to multigrid (pc_gamg_type and pc_gamg_levels) 78 $("#" + parentDiv).append("<br><b>GAMG Type </b><select id=\"pc_gamg_type" + endtag + "\"></select>"); 79 $("#" + parentDiv).append("<br><b>GAMG Levels </b><input type='text' id=\'pc_gamg_levels" + endtag + "\' maxlength='4'>"); 80 81 populateList("gamg",endtag); 82 83 $("#pc_gamg_levels" + endtag).val(defaultGamgLevels); 84 $("#pc_gamg_type" + endtag).val(defaults.pc_gamg_type); 85 86 //display options for each level 87 for(var i=defaultGamgLevels-1; i>=0; i--) { 88 var childEndtag = endtag + "_" + i; 89 90 matInfo[childEndtag] = { 91 pc_type : defaults.sub_pc_type, 92 ksp_type: defaults.sub_ksp_type, 93 symm: matInfo[endtag].symm, //inherit !! 94 posdef: matInfo[endtag].posdef, 95 logstruc: matInfo[endtag].logstruc 96 }; 97 98 var margin = 30 * getNumUnderscores(childEndtag); //indent based on the level of the solver (number of underscores) 99 100 $("#" + parentDiv).after("<div id=\"solver" + childEndtag + "\" style=\"margin-left:" + margin + "px;\"></div>"); 101 if(i == 0) //coarse grid solver (level 0) 102 $("#solver" + childEndtag).append("<br><b>Coarse Grid Solver (Level 0) </b>"); 103 else 104 $("#solver" + childEndtag).append("<br><b>Smoothing (Level " + i + ") </b>"); 105 106 $("#solver" + childEndtag).append("<br><b>KSP </b><select id=\"ksp_type" + childEndtag + "\"></select>"); 107 $("#solver" + childEndtag).append("<br><b>PC </b><select id=\"pc_type" + childEndtag + "\"></select>"); 108 109 populateList("ksp",childEndtag); 110 populateList("pc",childEndtag); 111 112 //set defaults 113 $("#ksp_type" + childEndtag).val(defaults.sub_ksp_type); 114 $("#pc_type" + childEndtag).val(defaults.sub_pc_type); 115 //trigger both to add additional options 116 $("#ksp_type" + childEndtag).trigger("change"); 117 $("#pc_type" + childEndtag).trigger("change"); 118 } 119 120 } 121 122 else if (pcValue == "redundant") { 123 var defaults = getDefaults("redundant",matInfo[endtag].symm,matInfo[endtag].posdef,matInfo[endtag].logstruc); 124 var defaultRedundantNumber = defaults.pc_redundant_number; 125 var childEndtag = endtag + "_0"; 126 127 matInfo[endtag].pc_redundant_number = defaultRedundantNumber; 128 129 //first add options related to redundant (pc_redundant_number) 130 $("#" + parentDiv).append("<br><b>Redundant Number </b><input type='text' id=\'pc_redundant_number" + endtag + "\' maxlength='4'>"); 131 $("#pc_redundant_number" + endtag).val(defaultRedundantNumber); 132 133 matInfo[childEndtag] = { 134 pc_type : defaults.sub_pc_type, 135 ksp_type: defaults.sub_ksp_type, 136 symm: matInfo[endtag].symm, //inherit!! 137 posdef: matInfo[endtag].posdef, 138 logstruc: matInfo[endtag].logstruc 139 }; 140 141 var margin = 30 * getNumUnderscores(childEndtag); //indent based on the level of the solver (number of underscores) 142 $("#" + parentDiv).after("<div id=\"solver" + childEndtag + "\" style=\"margin-left:" + margin + "px;\"></div>"); 143 $("#solver" + childEndtag).append("<br><b>Redundant Solver Options </b>"); 144 $("#solver" + childEndtag).append("<br><b>KSP </b><select id=\"ksp_type" + childEndtag + "\"></select>"); 145 $("#solver" + childEndtag).append("<br><b>PC </b><select id=\"pc_type" + childEndtag + "\"></select>"); 146 147 populateList("ksp",childEndtag); 148 populateList("pc",childEndtag); 149 150 //set defaults 151 $("#ksp_type" + childEndtag).val(defaults.sub_ksp_type); 152 $("#pc_type" + childEndtag).val(defaults.sub_pc_type); 153 //trigger both to add additional options 154 $("#ksp_type" + childEndtag).trigger("change"); 155 $("#pc_type" + childEndtag).trigger("change"); 156 } 157 158 else if (pcValue == "bjacobi") { 159 var defaults = getDefaults("bjacobi",matInfo[endtag].symm,matInfo[endtag].posdef,matInfo[endtag].logstruc); 160 var defaultBjacobiBlocks = defaults.pc_bjacobi_blocks; 161 var childEndtag = endtag + "_0"; 162 163 matInfo[endtag].pc_bjacobi_blocks = defaultBjacobiBlocks; 164 165 //first add options related to bjacobi (pc_bjacobi_blocks) 166 $("#" + parentDiv).append("<br><b>Bjacobi Blocks </b><input type='text' id=\'pc_bjacobi_blocks" + endtag + "\' maxlength='4'>"); 167 $("#pc_bjacobi_blocks" + endtag).val(defaultBjacobiBlocks); 168 169 matInfo[childEndtag] = { 170 pc_type : defaults.sub_pc_type, 171 ksp_type: defaults.sub_ksp_type, 172 symm: matInfo[endtag].symm, //inherit!! 173 posdef: matInfo[endtag].posdef, 174 logstruc: matInfo[endtag].logstruc 175 }; 176 177 var margin = 30 * getNumUnderscores(childEndtag); //indent based on the level of the solver (number of underscores) 178 179 $("#" + parentDiv).after("<div id=\"solver" + childEndtag + "\" style=\"margin-left:" + margin + "px;\"></div>"); 180 181 $("#solver" + childEndtag).append("<br><b>Bjacobi Solver Options </b>"); 182 $("#solver" + childEndtag).append("<br><b>KSP </b><select id=\"ksp_type" + childEndtag + "\"></select>"); 183 $("#solver" + childEndtag).append("<br><b>PC </b><select id=\"pc_type" + childEndtag + "\"></select>"); 184 185 populateList("ksp",childEndtag); 186 populateList("pc",childEndtag); 187 188 //set defaults 189 $("#ksp_type" + childEndtag).val(defaults.sub_ksp_type); 190 $("#pc_type" + childEndtag).val(defaults.sub_pc_type); 191 //trigger both to add additional options 192 $("#ksp_type" + childEndtag).trigger("change"); 193 $("#pc_type" + childEndtag).trigger("change"); 194 } 195 196 else if (pcValue == "asm") { 197 var defaults = getDefaults("asm",matInfo[endtag].symm,matInfo[endtag].posdef,matInfo[endtag].logstruc); 198 199 var defaultAsmBlocks = defaults.pc_asm_blocks; 200 var defaultAsmOverlap = defaults.pc_asm_overlap; 201 var childEndtag = endtag + "_0"; 202 203 matInfo[endtag].pc_asm_blocks = defaultAsmBlocks; 204 matInfo[endtag].pc_asm_overlap = defaultAsmOverlap; 205 206 //first add options related to ASM 207 $("#" + parentDiv).append("<br><b>ASM blocks </b><input type='text' id=\"pc_asm_blocks" + endtag + "\" maxlength='4'>"); 208 $("#" + parentDiv).append("<br><b>ASM overlap </b><input type='text' id=\"pc_asm_overlap" + endtag + "\" maxlength='4'>"); 209 $("#pc_asm_blocks" + endtag).val(defaultAsmBlocks); 210 $("#pc_asm_overlap" + endtag).val(defaultAsmOverlap); 211 212 matInfo[childEndtag] = { 213 pc_type : defaults.sub_pc_type, 214 ksp_type: defaults.sub_ksp_type, 215 symm: matInfo[endtag].symm, //inherit!! 216 posdef: matInfo[endtag].posdef, 217 logstruc: matInfo[endtag].logstruc 218 }; 219 220 var margin = 30 * getNumUnderscores(childEndtag); //indent based on the level of the solver (number of underscores) 221 222 $("#" + parentDiv).after("<div id=\"solver" + childEndtag + "\" style=\"margin-left:" + margin + "px;\"></div>"); 223 224 $("#solver" + childEndtag).append("<br><b>ASM Solver Options </b>"); 225 $("#solver" + childEndtag).append("<br><b>KSP </b><select id=\"ksp_type" + childEndtag + "\"></select>"); 226 $("#solver" + childEndtag).append("<br><b>PC </b><select id=\"pc_type" + childEndtag + "\"></select>"); 227 228 populateList("ksp",childEndtag); 229 populateList("pc",childEndtag); 230 231 //set defaults 232 $("#ksp_type" + childEndtag).val(defaults.sub_ksp_type); 233 $("#pc_type" + childEndtag).val(defaults.sub_pc_type); 234 //trigger both to add additional options 235 $("#ksp_type" + childEndtag).trigger("change"); 236 $("#pc_type" + childEndtag).trigger("change"); 237 } 238 239 else if (pcValue == "ksp") { 240 var defaults = getDefaults("ksp",matInfo[endtag].symm,matInfo[endtag].posdef,matInfo[endtag].logstruc); 241 var childEndtag = endtag + "_0"; 242 243 matInfo[childEndtag] = { 244 pc_type : defaults.sub_pc_type, 245 ksp_type: defaults.sub_ksp_type, 246 symm: matInfo[endtag].symm, //inherit!! 247 posdef: matInfo[endtag].posdef, 248 logstruc: matInfo[endtag].logstruc 249 }; 250 251 var margin = 30 * getNumUnderscores(childEndtag); //indent based on the level of the solver (number of underscores) 252 253 $("#" + parentDiv).after("<div id=\"solver" + childEndtag + "\" style=\"margin-left:" + margin + "px;\"></div>"); 254 255 $("#solver" + childEndtag).append("<br><b>KSP Solver Options </b>"); 256 $("#solver" + childEndtag).append("<br><b>KSP </b><select id=\"ksp_type" + childEndtag + "\"></select>"); 257 $("#solver" + childEndtag).append("<br><b>PC </b><select id=\"pc_type" + childEndtag + "\"></select>"); 258 259 populateList("ksp",childEndtag); 260 populateList("pc",childEndtag); 261 262 //set defaults 263 $("#ksp_type" + childEndtag).val(defaults.sub_ksp_type); 264 $("#pc_type" + childEndtag).val(defaults.sub_pc_type); 265 //trigger both to add additional options 266 $("#ksp_type" + childEndtag).trigger("change"); 267 $("#pc_type" + childEndtag).trigger("change"); 268 } 269 270 else if (pcValue == "fieldsplit") { 271 /*if(!matInfo[endtag].logstruc) {//do nothing if not logstruc 272 alert("Error: Fieldsplit can only be used on logically block-structured matrix!"); 273 return; 274 }*/ 275 var defaults = getDefaults("fieldsplit",matInfo[endtag].symm,matInfo[endtag].posdef,matInfo[endtag].logstruc); 276 var defaultFieldsplitBlocks = defaults.pc_fieldsplit_blocks; 277 278 matInfo[endtag].pc_fieldsplit_type = defaults.pc_fieldsplit_type; 279 matInfo[endtag].pc_fieldsplit_blocks = defaults.pc_fieldsplit_blocks; 280 281 //first add options related to fieldsplit (pc_fieldsplit_type and pc_fieldsplit_blocks) 282 $("#" + parentDiv).append("<br><b>Fieldsplit Type </b><select id=\"pc_fieldsplit_type" + endtag + "\"></select>"); 283 $("#" + parentDiv).append("<br><b>Fieldsplit Blocks </b><input type='text' id=\"pc_fieldsplit_blocks" + endtag + "\" maxlength='4'>"); 284 285 populateList("fieldsplit",endtag); 286 287 $("#pc_fieldsplit_blocks" + endtag).val(defaultFieldsplitBlocks); 288 $("#pc_fieldsplit_type" + endtag).val(defaults.pc_fieldsplit_type); 289 290 for(var i=defaultFieldsplitBlocks-1; i>=0; i--) { 291 var childEndtag = endtag + "_" + i; 292 293 matInfo[childEndtag] = { 294 pc_type : defaults.sub_pc_type, 295 ksp_type: defaults.sub_ksp_type, 296 symm: matInfo[endtag].symm, //inherit!! 297 posdef: matInfo[endtag].posdef, 298 logstruc: false //this one is false to prevent infinite recursion 299 }; 300 301 var margin = 30 * getNumUnderscores(childEndtag); //indent based on the level of the solver (number of underscores) 302 303 $("#" + parentDiv).after("<div id=\"solver" + childEndtag + "\" style=\"margin-left:" + margin + "px;\"></div>"); 304 $("#solver" + childEndtag).append("<br><b>Fieldsplit " + i + " Options (Matrix is <input type=\"checkbox\" id=\"symm" + childEndtag + "\">symmetric, <input type=\"checkbox\" id=\"posdef" + childEndtag + "\">positive definite, <input type=\"checkbox\" id=\"logstruc" + childEndtag + "\">block structured)</b>"); 305 306 //special for fieldsplit 307 if(matInfo[childEndtag].symm) 308 $("#symm" + childEndtag).attr("checked",true); 309 if(matInfo[childEndtag].posdef) 310 $("#posdef" + childEndtag).attr("checked",true); 311 if(matInfo[childEndtag].logstruc) 312 $("#logstruc" + childEndtag).attr("checked",true); 313 314 if(matInfo[endtag].symm) 315 $("#symm" + childEndtag).attr("disabled",true); 316 if(matInfo[endtag].posdef) 317 $("#posdef" + childEndtag).attr("disabled",true); 318 if(!matInfo[endtag].symm) 319 $("#posdef" + childEndtag).attr("disabled",true); 320 321 $("#solver" + childEndtag).append("<br><b>KSP </b><select id=\"ksp_type" + childEndtag + "\"></select>"); 322 $("#solver" + childEndtag).append("<br><b>PC </b><select id=\"pc_type" + childEndtag + "\"></select>"); 323 324 populateList("ksp",childEndtag); 325 populateList("pc",childEndtag); 326 327 //set defaults 328 $("#ksp_type" + childEndtag).val(defaults.sub_ksp_type); 329 $("#pc_type" + childEndtag).val(defaults.sub_pc_type); 330 //trigger both to add additional options 331 $("#ksp_type" + childEndtag).trigger("change"); 332 $("#pc_type" + childEndtag).trigger("change"); 333 } 334 } 335 refresh(); //refresh diagrams after any change in pc 336}); 337 338//called when a ksp option is changed 339//simply adjust ksp_type in matInfo 340$(document).on("change","select[id^='ksp_type']",function() { 341 342 var kspValue = $(this).val(); 343 var id = $(this).attr("id");//really should not be used in this method. there are better ways of getting information 344 var endtag = id.substring(id.indexOf("0"),id.length); 345 346 matInfo[endtag].ksp_type = kspValue; 347 refresh(); //refresh diagrams after any change in ksp 348}); 349 350//need to add a bunch of methods here for changing each variable: pc_fieldsplit_blocks, pc_asm_blocks, pc_redundant_number, etc 351//these methods seem incredibly redundant. perhaps there is a better way to write these. 352$(document).on("change","select[id^='pc_mg_type']",function() { 353 354 var mgType = $(this).val(); 355 var id = $(this).attr("id"); //really should not be used in this method. there are better ways of getting information 356 var endtag = id.substring(id.indexOf("0"),id.length); 357 358 matInfo[endtag].pc_mg_type = mgType; 359 refresh(); 360}); 361 362$(document).on("change","select[id^='pc_gamg_type']",function() { 363 364 var gamgType = $(this).val(); 365 var id = $(this).attr("id"); //really should not be used in this method. there are better ways of getting information 366 var endtag = id.substring(id.indexOf("0"),id.length); 367 368 matInfo[endtag].pc_gamg_type = gamgType; 369 refresh(); 370}); 371 372$(document).on("change","select[id^='pc_fieldsplit_type']",function() { 373 374 var fieldsplitType = $(this).val(); 375 var id = $(this).attr("id"); //really should not be used in this method. there are better ways of getting information 376 var endtag = id.substring(id.indexOf("0"),id.length); 377 378 matInfo[endtag].pc_fieldsplit_type = fieldsplitType; 379 refresh(); 380}); 381 382$(document).on("keyup","input[id^='pc_asm_blocks']",function() { 383 384 if($(this).val().match(/[^0-9]/) || $(this).val()<1) //return on invalid input 385 return; 386 387 var id = this.id; 388 var endtag = id.substring(id.indexOf(0),id.length); 389 var val = $(this).val(); 390 391 matInfo[endtag].pc_asm_blocks = val; 392 refresh(); //refresh diagrams 393}); 394 395$(document).on("keyup","input[id^='pc_asm_overlap']",function() { 396 397 if($(this).val().match(/[^0-9]/) || $(this).val()<1) //return on invalid input 398 return; 399 400 var id = this.id; 401 var endtag = id.substring(id.indexOf(0),id.length); 402 var val = $(this).val(); 403 404 matInfo[endtag].pc_asm_overlap = val; 405 refresh(); 406}); 407 408$(document).on("keyup","input[id^='pc_bjacobi_blocks']",function() { 409 410 if($(this).val().match(/[^0-9]/) || $(this).val()<1) //return on invalid input 411 return; 412 413 var id = this.id; 414 var endtag = id.substring(id.indexOf(0),id.length); 415 var val = $(this).val(); 416 417 matInfo[endtag].pc_bjacobi_blocks = val; 418 refresh(); //refresh diagrams 419}); 420 421$(document).on("keyup","input[id^='pc_redundant_number']",function() { 422 423 if($(this).val().match(/[^0-9]/) || $(this).val()<1) //return on invalid input 424 return; 425 426 var id = this.id; 427 var endtag = id.substring(id.indexOf(0),id.length); 428 var val = $(this).val(); 429 430 matInfo[endtag].pc_redundant_number = val; 431 refresh(); 432}); 433 434 435//input: endtag of the parent 436function removeAllChildren(endtag) { 437 438 var numChildren = getNumChildren(matInfo, endtag); 439 440 for(var i=0; i<numChildren; i++) { 441 var childEndtag = endtag + "_" + i; 442 443 if(getNumChildren(matInfo, childEndtag) > 0)//this child has more children 444 { 445 removeAllChildren(childEndtag);//recursive call to remove all children of that child 446 } 447 delete matInfo[childEndtag]; //make sure this location is never accessed again. 448 449 $("#solver" + childEndtag).remove();//remove that child itself 450 } 451 452 //adjust variables in matInfo 453 if(matInfo[endtag].pc_type == "mg") { 454 matInfo[endtag].pc_mg_levels = 0; 455 } 456 else if(matInfo[endtag].pc_type == "fieldsplit") { 457 matInfo[endtag].pc_fieldsplit_blocks = 0; 458 } 459 460 $("#pc_type" + endtag).nextAll().remove();//remove the options in the same level solver 461 462} 463 464//called when text input for pc_fieldsplit_blocks is changed 465$(document).on('keyup', "input[id^='pc_fieldsplit_blocks']", function() { 466 467 if($(this).val().match(/[^0-9]/) || $(this).val()<1) //return on invalid input 468 return; 469 470 var id = this.id; 471 var endtag = id.substring(id.indexOf(0),id.length); 472 var val = $(this).val(); 473 474 // this next part is a bit tricky...there are 2 cases 475 476 //case 1: we need to remove some divs 477 if(val < matInfo[endtag].pc_fieldsplit_blocks) { 478 for(var i=val; i<matInfo[endtag].pc_fieldsplit_blocks; i++) { 479 var childEndtag = endtag + "_" + i; 480 removeAllChildren(childEndtag); //remove grandchildren (if any) 481 delete matInfo[childEndtag]; 482 $("#solver" + childEndtag).remove(); //remove the divs 483 } 484 matInfo[endtag].pc_fieldsplit_blocks = val; 485 } 486 487 //case 2: we need to add some divs 488 else if(val > matInfo[endtag].pc_fieldsplit_blocks) { 489 490 var defaults = getDefaults("fieldsplit",matInfo[endtag].symm,matInfo[endtag].posdef,matInfo[endtag].logstruc); 491 492 for(var i = matInfo[endtag].pc_fieldsplit_blocks; i < val; i++) { 493 494 //add divs and write matInfo 495 var childEndtag = endtag + "_" + i; 496 var margin = getNumUnderscores(childEndtag) * 30; 497 498 //this is the trickiest part: need to find exactly where to insert the new divs 499 //find the first div that doesn't begin with endtag 500 501 var currentDiv = $(this).parent().get(0); 502 503 while($(currentDiv).next().length > 0) { //while has next 504 var nextDiv = $(currentDiv).next().get(0); 505 var nextId = nextDiv.id; 506 var nextEndtag = nextDiv.id.substring(nextId.indexOf("0"),nextId.length); 507 508 if(nextEndtag.indexOf(endtag) == 0) { 509 currentDiv = nextDiv; 510 } 511 else 512 break; 513 } 514 515 //append new stuff immediately after current div 516 matInfo[childEndtag] = { 517 pc_type : defaults.sub_pc_type, 518 ksp_type: defaults.sub_ksp_type, 519 symm: matInfo[endtag].symm, //inherit!! 520 posdef: matInfo[endtag].posdef, 521 logstruc: false 522 }; 523 524 var margin = 30 * getNumUnderscores(childEndtag); //indent based on the level of the solver (number of underscores) 525 $(currentDiv).after("<div id=\"solver" + childEndtag + "\" style=\"margin-left:" + margin + "px;\"></div>"); 526 $("#solver" + childEndtag).append("<br><b>Fieldsplit " + i + " Options (Matrix is <input type=\"checkbox\" id=\"symm" + childEndtag + "\">symmetric, <input type=\"checkbox\" id=\"posdef" + childEndtag + "\">positive definite, <input type=\"checkbox\" id=\"logstruc" + childEndtag + "\">block structured)</b>"); 527 528 //special for fieldsplit 529 if(matInfo[childEndtag].symm) 530 $("#symm" + childEndtag).attr("checked",true); 531 if(matInfo[childEndtag].posdef) 532 $("#posdef" + childEndtag).attr("checked",true); 533 if(matInfo[childEndtag].logstruc) 534 $("#logstruc" + childEndtag).attr("checked",true); 535 536 if(matInfo[endtag].symm) 537 $("#symm" + childEndtag).attr("disabled",true); 538 if(matInfo[endtag].posdef) 539 $("#posdef" + childEndtag).attr("disabled",true); 540 if(!matInfo[endtag].symm) 541 $("#posdef" + childEndtag).attr("disabled",true); 542 543 $("#solver" + childEndtag).append("<br><b>KSP </b><select id=\"ksp_type" + childEndtag + "\"></select>"); 544 $("#solver" + childEndtag).append("<br><b>PC </b><select id=\"pc_type" + childEndtag + "\"></select>"); 545 546 populateList("ksp",childEndtag); 547 populateList("pc",childEndtag); 548 549 //set defaults 550 $("#ksp_type" + childEndtag).val(defaults.sub_ksp_type); 551 $("#pc_type" + childEndtag).val(defaults.sub_pc_type); 552 //trigger both to add additional options 553 $("#ksp_type" + childEndtag).trigger("change"); 554 $("#pc_type" + childEndtag).trigger("change"); 555 } 556 matInfo[endtag].pc_fieldsplit_blocks = val; 557 } 558 refresh(); //refresh diagrams 559}); 560 561/* 562 This function is called when the text input "MG Levels" is changed 563*/ 564$(document).on('keyup', "input[id^='pc_mg_levels']", function() 565{ 566 if($(this).val().match(/[^0-9]/) || $(this).val()<1) //return on invalid input 567 return; 568 569 var id = this.id; 570 var endtag = id.substring(id.indexOf(0),id.length); 571 var val = $(this).val(); 572 573 // this next part is a bit tricky...there are 2 cases 574 575 //case 1: we need to remove some divs 576 if(val < matInfo[endtag].pc_mg_levels) { 577 for(var i=val; i<matInfo[endtag].pc_mg_levels; i++) { 578 var childEndtag = endtag + "_" + i; 579 removeAllChildren(childEndtag); //remove grandchildren (if any) 580 delete matInfo[childEndtag]; 581 $("#solver" + childEndtag).remove(); //remove the divs 582 } 583 matInfo[endtag].pc_mg_levels = val; 584 } 585 586 //case 2: we need to add some divs 587 else if(val > matInfo[endtag].pc_mg_levels) { 588 589 var defaults = getDefaults("mg",matInfo[endtag].symm,matInfo[endtag].posdef,matInfo[endtag].logstruc); 590 591 for(var i = matInfo[endtag].pc_mg_levels; i < val; i++) { 592 var childEndtag = endtag + "_" + i; 593 var margin = getNumUnderscores(childEndtag) * 30; 594 595 //this is the trickiest part: need to find exactly where to insert the new divs 596 //find the first div that doesn't begin with endtag 597 598 var currentDiv = $(this).parent().get(0); 599 600 while($(currentDiv).next().length > 0) { //while has next 601 var nextDiv = $(currentDiv).next().get(0); 602 var nextId = nextDiv.id; 603 var nextEndtag = nextDiv.id.substring(nextId.indexOf("0"),nextId.length); 604 605 if(nextEndtag.indexOf(endtag) == 0) { 606 currentDiv = nextDiv; 607 } 608 else 609 break; 610 } 611 612 //append new stuff immediately after current div 613 matInfo[childEndtag] = { 614 pc_type : defaults.sub_pc_type, 615 ksp_type: defaults.sub_ksp_type, 616 symm: matInfo[endtag].symm, //inherit!! 617 posdef: matInfo[endtag].posdef, 618 logstruc: matInfo[endtag].logstruc 619 }; 620 621 var margin = 30 * getNumUnderscores(childEndtag); //indent based on the level of the solver (number of underscores) 622 $(currentDiv).after("<div id=\"solver" + childEndtag + "\" style=\"margin-left:" + margin + "px;\"></div>"); 623 if(i == 0) //coarse grid solver (level 0) 624 $("#solver" + childEndtag).append("<br><b>Coarse Grid Solver (Level 0) </b>"); 625 else 626 $("#solver" + childEndtag).append("<br><b>Smoothing (Level " + i + ") </b>"); 627 628 $("#solver" + childEndtag).append("<br><b>KSP </b><select id=\"ksp_type" + childEndtag + "\"></select>"); 629 $("#solver" + childEndtag).append("<br><b>PC </b><select id=\"pc_type" + childEndtag + "\"></select>"); 630 631 populateList("ksp",childEndtag); 632 populateList("pc",childEndtag); 633 634 //set defaults 635 $("#ksp_type" + childEndtag).val(defaults.sub_ksp_type); 636 $("#pc_type" + childEndtag).val(defaults.sub_pc_type); 637 //trigger both to add additional options 638 $("#ksp_type" + childEndtag).trigger("change"); 639 $("#pc_type" + childEndtag).trigger("change"); 640 } 641 matInfo[endtag].pc_mg_levels = val; 642 } 643 refresh(); //refresh diagrams 644}); 645 646$(document).on('keyup', "input[id^='pc_gamg_levels']", function() 647{ 648 if($(this).val().match(/[^0-9]/) || $(this).val()<1) //return on invalid input 649 return; 650 651 var id = this.id; 652 var endtag = id.substring(id.indexOf(0),id.length); 653 var val = $(this).val(); 654 655 // this next part is a bit tricky...there are 2 cases 656 657 //case 1: we need to remove some divs 658 if(val < matInfo[endtag].pc_gamg_levels) { 659 for(var i=val; i<matInfo[endtag].pc_gamg_levels; i++) { 660 var childEndtag = endtag + "_" + i; 661 removeAllChildren(childEndtag); //remove grandchildren (if any) 662 delete matInfo[childEndtag]; 663 $("#solver" + childEndtag).remove(); //remove the divs 664 } 665 matInfo[endtag].pc_gamg_levels = val; 666 } 667 668 //case 2: we need to add some divs 669 else if(val > matInfo[endtag].pc_gamg_levels) { 670 671 var defaults = getDefaults("gamg",matInfo[endtag].symm,matInfo[endtag].posdef,matInfo[endtag].logstruc); 672 673 for(var i = matInfo[endtag].pc_gamg_levels; i < val; i++) { 674 var childEndtag = endtag + "_" + i; 675 var margin = getNumUnderscores(childEndtag) * 30; 676 677 //this is the trickiest part: need to find exactly where to insert the new divs 678 //find the first div that doesn't begin with endtag 679 680 var currentDiv = $(this).parent().get(0); 681 682 while($(currentDiv).next().length > 0) { //while has next 683 var nextDiv = $(currentDiv).next().get(0); 684 var nextId = nextDiv.id; 685 var nextEndtag = nextDiv.id.substring(nextId.indexOf("0"),nextId.length); 686 687 if(nextEndtag.indexOf(endtag) == 0) { 688 currentDiv = nextDiv; 689 } 690 else 691 break; 692 } 693 694 //append new stuff immediately after current div 695 matInfo[childEndtag] = { 696 pc_type : defaults.sub_pc_type, 697 ksp_type: defaults.sub_ksp_type, 698 symm: matInfo[endtag].symm, //inherit!! 699 posdef: matInfo[endtag].posdef, 700 logstruc: matInfo[endtag].logstruc 701 }; 702 703 var margin = 30 * getNumUnderscores(childEndtag); //indent based on the level of the solver (number of underscores) 704 $(currentDiv).after("<div id=\"solver" + childEndtag + "\" style=\"margin-left:" + margin + "px;\"></div>"); 705 if(i == 0) //coarse grid solver (level 0) 706 $("#solver" + childEndtag).append("<br><b>Coarse Grid Solver (Level 0) </b>"); 707 else 708 $("#solver" + childEndtag).append("<br><b>Smoothing (Level " + i + ") </b>"); 709 710 $("#solver" + childEndtag).append("<br><b>KSP </b><select id=\"ksp_type" + childEndtag + "\"></select>"); 711 $("#solver" + childEndtag).append("<br><b>PC </b><select id=\"pc_type" + childEndtag + "\"></select>"); 712 713 populateList("ksp",childEndtag); 714 populateList("pc",childEndtag); 715 716 //set defaults 717 $("#ksp_type" + childEndtag).val(defaults.sub_ksp_type); 718 $("#pc_type" + childEndtag).val(defaults.sub_pc_type); 719 //trigger both to add additional options 720 $("#ksp_type" + childEndtag).trigger("change"); 721 $("#pc_type" + childEndtag).trigger("change"); 722 } 723 matInfo[endtag].pc_gamg_levels = val; 724 } 725 refresh(); //refresh diagrams 726}); 727