| [22880] | 1 | function solve(md, solutionstring) {//{{{ | 
|---|
| [22831] | 2 | /** | 
|---|
|  | 3 | * SOLVE - apply solution sequence for this model | 
|---|
|  | 4 | * | 
|---|
|  | 5 | *      Usage: | 
|---|
|  | 6 | *              solve(md, solutionstring, varargin); | 
|---|
|  | 7 | *              where varargin is a list of paired arguments of string OR enums | 
|---|
|  | 8 | * | 
|---|
|  | 9 | *      solution types available comprise: | 
|---|
|  | 10 | *              - 'Stressbalance'               or 'sb' | 
|---|
|  | 11 | *              - 'Masstransport'               or 'mt' | 
|---|
|  | 12 | *              - 'Thermal'                             or 'th' | 
|---|
|  | 13 | *              - 'Steadystate'                 or 'ss' | 
|---|
|  | 14 | *              - 'Transient'                   or 'tr' | 
|---|
|  | 15 | *              - 'Balancethickness'    or 'mc' | 
|---|
|  | 16 | *              - 'Balancevelocity'             or 'bv' | 
|---|
|  | 17 | *              - 'BedSlope'                    or 'bsl' | 
|---|
|  | 18 | *              - 'SurfaceSlope'                or 'ssl' | 
|---|
|  | 19 | *              - 'Hydrology'                   or 'hy' | 
|---|
|  | 20 | *              - 'DamageEvolution'             or 'da' | 
|---|
|  | 21 | *              - 'Gia'                                 or 'gia' | 
|---|
|  | 22 | *              - 'Sealevelrise'                or 'slr' | 
|---|
|  | 23 | * | 
|---|
|  | 24 | *      extra options: | 
|---|
|  | 25 | *              - loadonly              : do not solve, only load results | 
|---|
|  | 26 | *              - runtimename           : true or false (default is true), makes name unique | 
|---|
|  | 27 | *              - checkconsistency      : 'yes' or 'no' (default is 'yes'), ensures checks on consistency of model | 
|---|
|  | 28 | *              - restart                       : directory name (relative to the execution directory) where the restart file is located | 
|---|
|  | 29 | *              - successCallback       : callback function to be called on success | 
|---|
|  | 30 | *              - errorCallback         : callback function to be called on error | 
|---|
|  | 31 | * | 
|---|
|  | 32 | *      reporting: | 
|---|
|  | 33 | *              With no optional arguments for reporting, progress and error reporting is written to the DOM element with ID 'solve-button'. | 
|---|
|  | 34 | *              - solveButtonId         : overrides default solve button ID | 
|---|
|  | 35 | *              - callout                       : Callout to report progress/errors to; overrides reporting to solve button | 
|---|
|  | 36 | *              - withProgressBar       : reports progress of certain solution stages with a progress bar; will not display if a Callout has not been provided | 
|---|
|  | 37 | * | 
|---|
|  | 38 | *      Examples: | 
|---|
|  | 39 | *              md = solve(md, 'Stressbalance'); | 
|---|
|  | 40 | *              md = solve(md, 'sb'); | 
|---|
|  | 41 | */ | 
|---|
|  | 42 | if (typeof solutionstring !== 'string') { | 
|---|
| [21139] | 43 | throw Error(sprintf("%s\n", "ISSM's solve function only accepts strings for solution sequences. Type help solve to get a list of supported solutions.")); | 
|---|
| [21065] | 44 | } | 
|---|
|  | 45 |  | 
|---|
| [19780] | 46 | //recover and process solve options | 
|---|
| [22880] | 47 | let solutionStringLowerCase = solutionstring.toLowerCase(); | 
|---|
|  | 48 |  | 
|---|
|  | 49 | if ((solutionStringLowerCase === 'sb') || (solutionStringLowerCase === 'stressbalance')) { | 
|---|
| [21065] | 50 | solutionstring = 'StressbalanceSolution'; | 
|---|
| [22880] | 51 | } else if ((solutionStringLowerCase === 'mt') || (solutionStringLowerCase === 'masstransport')) { | 
|---|
| [21065] | 52 | solutionstring = 'MasstransportSolution'; | 
|---|
| [22880] | 53 | } else if ((solutionStringLowerCase === 'th') || (solutionStringLowerCase === 'thermal')) { | 
|---|
| [21065] | 54 | solutionstring = 'ThermalSolution'; | 
|---|
| [22880] | 55 | } else if ((solutionStringLowerCase === 'st') || (solutionStringLowerCase === 'steadystate')) { | 
|---|
| [21065] | 56 | solutionstring = 'SteadystateSolution'; | 
|---|
| [22880] | 57 | } else if ((solutionStringLowerCase === 'tr') || (solutionStringLowerCase === 'transient')) { | 
|---|
| [21065] | 58 | solutionstring = 'TransientSolution'; | 
|---|
| [22880] | 59 | } else if ((solutionStringLowerCase === 'mc') || (solutionStringLowerCase === 'balancethickness')) { | 
|---|
| [21065] | 60 | solutionstring = 'BalancethicknessSolution'; | 
|---|
| [22880] | 61 | } else if ((solutionStringLowerCase === 'bv') || (solutionStringLowerCase === 'balancevelocity')) { | 
|---|
| [21065] | 62 | solutionstring = 'BalancevelocitySolution'; | 
|---|
| [22880] | 63 | } else if ((solutionStringLowerCase === 'bsl') || (solutionStringLowerCase === 'bedslope')) { | 
|---|
| [21065] | 64 | solutionstring = 'BedSlopeSolution'; | 
|---|
| [22880] | 65 | } else if ((solutionStringLowerCase === 'ssl') || (solutionStringLowerCase === 'surfaceslope')) { | 
|---|
| [21065] | 66 | solutionstring = 'SurfaceSlopeSolution'; | 
|---|
| [22880] | 67 | } else if ((solutionStringLowerCase === 'hy') || (solutionStringLowerCase === 'hydrology')) { | 
|---|
| [21065] | 68 | solutionstring = 'HydrologySolution'; | 
|---|
| [22880] | 69 | } else if ((solutionStringLowerCase === 'da') || (solutionStringLowerCase === 'damageevolution')) { | 
|---|
| [21065] | 70 | solutionstring = 'DamageEvolutionSolution'; | 
|---|
| [22880] | 71 | } else if ((solutionStringLowerCase === 'gia') || (solutionStringLowerCase === 'gia')) { | 
|---|
| [21584] | 72 | solutionstring = 'GiaSolution'; | 
|---|
| [22880] | 73 | } else if ((solutionStringLowerCase === 'slr') || (solutionStringLowerCase === 'sealevelrise')) { | 
|---|
| [21065] | 74 | solutionstring = 'SealevelriseSolution'; | 
|---|
| [22831] | 75 | } else { | 
|---|
| [21065] | 76 | throw Error(sprintf("%s%s%s\n",'solutionstring ',solutionstring,' not supported!')); | 
|---|
| [19780] | 77 | } | 
|---|
|  | 78 |  | 
|---|
| [22880] | 79 | // Process options | 
|---|
|  | 80 | let args        = Array.prototype.slice.call(arguments); | 
|---|
|  | 81 | let options = new pairoptions(args.slice(2, args.length)); | 
|---|
|  | 82 | options.addfield('solutionstring', solutionstring); | 
|---|
| [19780] | 83 |  | 
|---|
| [22880] | 84 | // recover some fields | 
|---|
|  | 85 | md.priv.solution        = solutionstring; | 
|---|
|  | 86 | cluster                         = md.cluster; | 
|---|
| [19780] | 87 |  | 
|---|
|  | 88 | //check model consistency | 
|---|
| [22880] | 89 | if (options.getfieldvalue('checkconsistency', 'yes') === 'yes') { | 
|---|
|  | 90 | if (md.verbose.solution) { | 
|---|
| [19780] | 91 | console.log('checking model consistency'); | 
|---|
|  | 92 | } | 
|---|
| [22880] | 93 |  | 
|---|
| [21097] | 94 | ismodelselfconsistent(md); | 
|---|
| [19780] | 95 | } | 
|---|
|  | 96 |  | 
|---|
| [22880] | 97 | // If we are restarting, actually use the provided runtime name: | 
|---|
|  | 98 | restart = options.getfieldvalue('restart', ''); | 
|---|
| [20269] | 99 |  | 
|---|
| [22880] | 100 | // First, build a runtime name that is unique | 
|---|
|  | 101 | if (restart === 1 ) { | 
|---|
|  | 102 | // Leave the runtimename as is | 
|---|
|  | 103 | } else { | 
|---|
|  | 104 | if (!(restart === '')) { | 
|---|
| [19824] | 105 | md.priv.runtimename=restart; | 
|---|
| [22880] | 106 | } else if (options.getfieldvalue('runtimename',true)) { | 
|---|
|  | 107 | let c = new Date().getTime(); | 
|---|
|  | 108 | md.priv.runtimename = sprintf('%s-%g', md.miscellaneous.name, c); | 
|---|
|  | 109 | } else { | 
|---|
|  | 110 | md.priv.runtimename = md.miscellaneous.name; | 
|---|
| [19780] | 111 | } | 
|---|
|  | 112 | } | 
|---|
|  | 113 |  | 
|---|
| [22880] | 114 | // If running qmu analysis, some preprocessing of dakota files using models fields needs to be carried out | 
|---|
|  | 115 | if (md.qmu.isdakota) { | 
|---|
| [19780] | 116 | throw Error("solve error message: qmu runs not supported yet!"); | 
|---|
|  | 117 | //md.preqmu(options); | 
|---|
|  | 118 | } | 
|---|
|  | 119 |  | 
|---|
| [22880] | 120 | // Do we load results only? | 
|---|
|  | 121 | if (options.getfieldvalue('loadonly', false)){ | 
|---|
| [19780] | 122 | loadresultsfromcluster(md); | 
|---|
|  | 123 | return; | 
|---|
|  | 124 | } | 
|---|
|  | 125 |  | 
|---|
| [22880] | 126 | // Marshall into a binary array (fid) all the fields of model | 
|---|
|  | 127 | let fid = marshall(md); // bin file | 
|---|
| [20269] | 128 |  | 
|---|
|  | 129 | //deal with toolkits options: | 
|---|
| [22880] | 130 | toolkitsstring = md.toolkits.ToolkitsFile(md.miscellaneous.name + '.toolkits'); // toolkits file | 
|---|
| [19780] | 131 |  | 
|---|
| [22824] | 132 |  | 
|---|
|  | 133 | /* | 
|---|
|  | 134 | Set success callback function | 
|---|
| [22880] | 135 |  | 
|---|
|  | 136 | Default: do nothing if no success callback function requested | 
|---|
| [22824] | 137 | */ | 
|---|
|  | 138 | //{{{ | 
|---|
| [22831] | 139 | function successCallbackDefault() { | 
|---|
| [22824] | 140 | solving = false; | 
|---|
|  | 141 | }; | 
|---|
|  | 142 |  | 
|---|
| [22831] | 143 | let successCallback = options.getfieldvalue('successCallback', successCallbackDefault); | 
|---|
| [22824] | 144 | //}}} | 
|---|
| [20823] | 145 |  | 
|---|
| [22824] | 146 |  | 
|---|
|  | 147 | /* | 
|---|
|  | 148 | Set error callback function | 
|---|
| [22880] | 149 |  | 
|---|
|  | 150 | Default: do nothing if no error callback function requested | 
|---|
| [22824] | 151 | */ | 
|---|
| [22880] | 152 | //{{{ | 
|---|
| [22831] | 153 | function errorCallbackDefault() { | 
|---|
| [22824] | 154 | solving = false; | 
|---|
|  | 155 | }; | 
|---|
|  | 156 |  | 
|---|
| [22831] | 157 | let errorCallback = options.getfieldvalue('errorCallback', errorCallbackDefault); | 
|---|
| [22824] | 158 | //}}} | 
|---|
| [20995] | 159 |  | 
|---|
| [22824] | 160 |  | 
|---|
|  | 161 | /* | 
|---|
|  | 162 | Set solve button ID | 
|---|
| [22880] | 163 |  | 
|---|
|  | 164 | Default: update #solve-button element with progress updates | 
|---|
| [22824] | 165 | */ | 
|---|
|  | 166 | //{{{ | 
|---|
| [22831] | 167 | let solveButtonId = options.getfieldvalue('solveButtonId', '#solve-button'); | 
|---|
|  | 168 | //}}} | 
|---|
| [22824] | 169 |  | 
|---|
| [22831] | 170 |  | 
|---|
|  | 171 | /* | 
|---|
|  | 172 | Set Callout | 
|---|
|  | 173 | */ | 
|---|
|  | 174 | //{{{ | 
|---|
|  | 175 | var callout = {}; | 
|---|
|  | 176 |  | 
|---|
|  | 177 | // Default: Callout is an empty object | 
|---|
|  | 178 | callout = options.getfieldvalue('callout', {}); | 
|---|
| [22824] | 179 | //}}} | 
|---|
| [22831] | 180 |  | 
|---|
|  | 181 |  | 
|---|
|  | 182 | /* | 
|---|
|  | 183 | Set progress bar display boolean | 
|---|
| [22880] | 184 |  | 
|---|
|  | 185 | Default: no progress bar | 
|---|
|  | 186 |  | 
|---|
|  | 187 | NOTE: must have supplied a callout for progress bar to display | 
|---|
| [22831] | 188 | */ | 
|---|
|  | 189 | //{{{ | 
|---|
|  | 190 | let withProgressBar = options.getfieldvalue('withProgressBar', false); | 
|---|
|  | 191 | //}}} | 
|---|
| [19793] | 192 |  | 
|---|
|  | 193 |  | 
|---|
| [22880] | 194 | if (cluster.classname() === 'local') {//{{{ | 
|---|
| [22831] | 195 |  | 
|---|
| [22880] | 196 | // We are running locally on the machine, using the issm module | 
|---|
| [19793] | 197 | console.log('running issm locally'); | 
|---|
|  | 198 |  | 
|---|
| [22880] | 199 | // Call issm | 
|---|
|  | 200 | let outputs = issm(fid, toolkitsstring, solutionstring, md.miscellaneous.name); | 
|---|
| [19816] | 201 |  | 
|---|
| [22880] | 202 | // Recover output arguments: | 
|---|
|  | 203 | let outputbuffer                = outputs[0]; | 
|---|
|  | 204 | let outputbuffersize    = outputs[1]; | 
|---|
| [19816] | 205 |  | 
|---|
| [22880] | 206 | // Load results | 
|---|
| [22831] | 207 | md = loadresultsfrombuffer(md, outputbuffer, outputbuffersize); | 
|---|
| [20269] | 208 |  | 
|---|
| [22824] | 209 | // Call success callback | 
|---|
|  | 210 | successCallback(); | 
|---|
| [20270] | 211 |  | 
|---|
| [20269] | 212 | return md; | 
|---|
| [22831] | 213 | //}}} | 
|---|
| [22880] | 214 | } else {//{{{ | 
|---|
| [22831] | 215 | // We are running somewhere else on a computational server. Send the buffer to that server and retrieve output. | 
|---|
| [22716] | 216 | console.log('running issm remotely'); | 
|---|
| [22831] | 217 |  | 
|---|
|  | 218 | cluster.UploadAndRun( | 
|---|
|  | 219 | md, | 
|---|
|  | 220 | fid, | 
|---|
|  | 221 | toolkitsstring, | 
|---|
|  | 222 | solutionstring, | 
|---|
|  | 223 | md.miscellaneous.name, | 
|---|
|  | 224 | md.priv.runtimename, | 
|---|
|  | 225 | successCallback, | 
|---|
|  | 226 | errorCallback, | 
|---|
|  | 227 | solveButtonId, | 
|---|
|  | 228 | callout, | 
|---|
|  | 229 | withProgressBar | 
|---|
|  | 230 | ); | 
|---|
| [20269] | 231 |  | 
|---|
|  | 232 | return md; | 
|---|
| [22880] | 233 | }//}}} | 
|---|
|  | 234 | }//}}} | 
|---|