source: issm/trunk-jpl/src/m/solve/solve.js

Last change on this file was 26300, checked in by dlcheng, 4 years ago

CHG (JS): Large update of JS classes in for solid earth/sea level solver.

File size: 8.6 KB
RevLine 
[26300]1async function solve(md, solutionstring, ...varargin) { //{{{
2/*
3SOLVE - apply solution sequence for this model
4
5Usage:
6 solve(md, solutionstring[, ...]);
7
8where varargin is a list of paired arguments of string OR enums
9
10Solution types available comprise:
11- 'Stressbalance' or 'sb'
12- 'Masstransport' or 'mt'
13- 'Oceantransport' or 'oceant'
14- 'Thermal' or 'th'
15- 'Steadystate' or 'ss'
16- 'Transient' or 'tr'
17- 'Balancethickness' or 'mc'
18- 'BalancethicknessSoft' or 'mcsoft'
19- 'Balancevelocity' or 'bv'
20- 'BedSlope' or 'bsl'
21- 'SurfaceSlope' or 'ssl'
22- 'Hydrology' or 'hy'
23- 'DamageEvolution' or 'da'
24- 'Gia' or 'gia'
25- 'Love' or 'lv'
26- 'Esa' or 'esa'
27- 'Sampling' or 'smp'
28- 'Gmsh'
29
30Extra options (these all need to be passed in via the third parameter, which is
31a rest parameter):
32- loadonly : do not solve, only load results
33- runtimename : true or false (default is true); makes name unique
34- checkconsistency : true or false (default is true); checks consistency of model
35- restart : directory name (relative to the execution directory) where the restart file is located
36
37Examples:
38 md = solve(md, 'Stressbalance');
39 md = solve(md, 'sb');
40
41NOTE:
42- We do not strictly need to return md as objects are passed by reference in
43JavaScript, but we do so to mirror MATLAB and Python APIs.
44
45TODO:
46- Refactor UI reporting structure so we do not have to check if it is defined
47*/
48
49/*
50 // Check that md exists and that it is a model
51 if (md === null || md === undefined || md.constructor.name !== 'model') {
52 throw new Error('md needs to be an instance of the model class');
53 }
54*/
55
56 if (typeof(solutionstring) !== 'string') {
57 throw new Error('ISSM\'s solve function only accepts strings for solution sequences. Type help solve to get a list of supported solutions.');
[21065]58 }
59
[26300]60 // Recover and process solve options
61 if (vesl.strings.strcmpi(solutionstring, 'sb') || vesl.strings.strcmpi(solutionstring, 'Stressbalance')) {
[21065]62 solutionstring = 'StressbalanceSolution';
[26300]63 } else if (vesl.strings.strcmpi(solutionstring, 'mt') || vesl.strings.strcmpi(solutionstring, 'Masstransport')) {
[21065]64 solutionstring = 'MasstransportSolution';
[26300]65 } else if (vesl.strings.strcmpi(solutionstring, 'oceant') || vesl.strings.strcmpi(solutionstring, 'Oceantransport')) {
66 solutionstring = 'OceantransportSolution';
67 } else if (vesl.strings.strcmpi(solutionstring, 'th') || vesl.strings.strcmpi(solutionstring, 'Thermal')) {
[21065]68 solutionstring = 'ThermalSolution';
[26300]69 } else if (vesl.strings.strcmpi(solutionstring, 'st') || vesl.strings.strcmpi(solutionstring, 'Steadystate')) {
[21065]70 solutionstring = 'SteadystateSolution';
[26300]71 } else if (vesl.strings.strcmpi(solutionstring, 'tr') || vesl.strings.strcmpi(solutionstring, 'Transient')) {
[21065]72 solutionstring = 'TransientSolution';
[26300]73 } else if (vesl.strings.strcmpi(solutionstring, 'mc') || vesl.strings.strcmpi(solutionstring, 'Balancethickness')) {
[21065]74 solutionstring = 'BalancethicknessSolution';
[26300]75 } else if (vesl.strings.strcmpi(solutionstring, 'mcsoft') || vesl.strings.strcmpi(solutionstring, 'BalancethicknessSoft')) {
76 solutionstring = 'BalancethicknessSoftSolution';
77 } else if (vesl.strings.strcmpi(solutionstring, 'bv') || vesl.strings.strcmpi(solutionstring, 'Balancevelocity')) {
[21065]78 solutionstring = 'BalancevelocitySolution';
[26300]79 } else if (vesl.strings.strcmpi(solutionstring, 'bsl') || vesl.strings.strcmpi(solutionstring, 'BedSlope')) {
[21065]80 solutionstring = 'BedSlopeSolution';
[26300]81 } else if (vesl.strings.strcmpi(solutionstring, 'ssl') || vesl.strings.strcmpi(solutionstring, 'SurfaceSlope')) {
[21065]82 solutionstring = 'SurfaceSlopeSolution';
[26300]83 } else if (vesl.strings.strcmpi(solutionstring, 'hy') || vesl.strings.strcmpi(solutionstring, 'Hydrology')) {
[21065]84 solutionstring = 'HydrologySolution';
[26300]85 } else if (vesl.strings.strcmpi(solutionstring, 'da') || vesl.strings.strcmpi(solutionstring, 'DamageEvolution')) {
[21065]86 solutionstring = 'DamageEvolutionSolution';
[26300]87 } else if (vesl.strings.strcmpi(solutionstring, 'gia') || vesl.strings.strcmpi(solutionstring, 'Gia')) {
[21584]88 solutionstring = 'GiaSolution';
[26300]89 } else if (vesl.strings.strcmpi(solutionstring, 'lv') || vesl.strings.strcmpi(solutionstring, 'Love')) {
90 solutionstring = 'LoveSolution';
91 } else if (vesl.strings.strcmpi(solutionstring, 'Esa')) {
92 solutionstring = 'EsaSolution';
93 } else if (vesl.strings.strcmpi(solutionstring, 'smp') || vesl.strings.strcmpi(solutionstring, 'Sampling')) {
94 solutionstring = 'SamplingSolution';
95 } else if (vesl.strings.strcmpi(solutionstring, 'gmsh')) {
96 solutionstring = 'GmshSolution';
97 } else if (vesl.strings.strcmpi(solutionstring, 'gmt')) {
98 solutionstring = 'GmtSolution';
[22831]99 } else {
[26300]100 throw new Error('solutionstring ' + solutionstring + ' not supported!');
[19780]101 }
[26300]102 let options = new pairoptions(varargin, 'solutionstring', solutionstring);
[19780]103
[26300]104 // Recover some fields
[22880]105 md.priv.solution = solutionstring;
[26300]106 let cluster = md.cluster;
107
108 // NOTE: Batch scripts are not currently implemented
109 let batch = 0;
110 if (options.getfieldvalue('batch', 'no') === 'yes') {
111 batch = 1;
112 }
113
114 // Check model consistency
[22880]115 if (options.getfieldvalue('checkconsistency', 'yes') === 'yes') {
116 if (md.verbose.solution) {
[19780]117 console.log('checking model consistency');
118 }
[22880]119
[21097]120 ismodelselfconsistent(md);
[19780]121 }
[26300]122
[22880]123 // If we are restarting, actually use the provided runtime name:
124 restart = options.getfieldvalue('restart', '');
[20269]125
[22880]126 // First, build a runtime name that is unique
[26300]127 if (restart === 1) {
[22880]128 // Leave the runtimename as is
129 } else {
[26300]130 if (restart !== '') {
131 md.priv.runtimename = restart;
[22880]132 } else {
[26300]133 if (options.getfieldvalue('runtimename', true)) {
134 let c = new Date().getTime();
135 md.priv.runtimename = sprintf('%s-%g', md.miscellaneous.name, c);
136 } else {
137 md.priv.runtimename = md.miscellaneous.name;
138 }
[19780]139 }
140 }
141
[26300]142 // If running QMU analysis, some preprocessing of Dakota files using model fields needs to be carried out
[22880]143 if (md.qmu.isdakota) {
[26300]144 throw new Error("QMU not supported yet!");
145 //md = preqmu(md, options);
[19780]146 }
[26300]147
[22880]148 // Do we load results only?
149 if (options.getfieldvalue('loadonly', false)){
[19780]150 loadresultsfromcluster(md);
151 return;
152 }
153
[22824]154 /*
[26300]155 Write all input arrays (as opposed to, under MATLAB/Python, input binary
156 files)
[22824]157
[26300]158 NOTE: The JavaScript implementation diverges significantly from the
159 MATLAB/Python APIs here.
[22824]160 */
[26300]161 let fid = null; // bin file equivalent
162 //TODO: FIND A BETTER WAY TO DO THIS! (IE, SYNC UP WRITEDATA AND HAVE A FULL DEMARSHALL/READMODEL IN PYTHON
163 if (solutionstring === 'GmshSolution') {
164 //open file for binary writing
165 fid = new fileptr('mode','w');
166 } else if (solutionstring === 'GmtSolution') {
167 //open file for binary writing
168 fid = new fileptr('mode','w');
169 let prefix='md.mesh';
170 WriteData(fid,prefix,'object',md.mesh,'fieldname','lat','format','DoubleMat','mattype',1);
171 WriteData(fid,prefix,'object',md.mesh,'fieldname','long','format','DoubleMat','mattype',1);
172 } else {
173 // Marshall into a binary array (fid) all the fields of model
174 fid = marshall(md); // bin file
175 }
176 let toolkitsstring = md.toolkits.ToolkitsFile(md.miscellaneous.name + '.toolkits'); // toolkits file equivalent
[19793]177
[22880]178 if (cluster.classname() === 'local') {//{{{
[22831]179
[26300]180 // We are running locally on the machine, using the ISSM module
[19793]181 console.log('running issm locally');
182
[26300]183 // Call ISSM
[22880]184 let outputs = issm(fid, toolkitsstring, solutionstring, md.miscellaneous.name);
[19816]185
[26300]186 // Recover output
[22880]187 let outputbuffer = outputs[0];
188 let outputbuffersize = outputs[1];
[19816]189
[22880]190 // Load results
[26300]191 md = loadresultsfrombuffer(md, outputbuffer, outputbuffersize); // TODO: Pass reporting construct to loadresultsfrombuffer
[20269]192
[26300]193 // Call success callback
194 if (vesl.helpers.isFunction(vesl.ui.reporting.success_callback)) {
195 vesl.ui.reporting.success_callback();
196 }
[22831]197 //}}}
[26300]198 } else { //{{{
[22831]199 // We are running somewhere else on a computational server. Send the buffer to that server and retrieve output.
[22716]200 console.log('running issm remotely');
[22831]201
[26300]202 await cluster.uploadandrun(
[22831]203 md,
204 fid,
205 toolkitsstring,
206 solutionstring,
207 md.miscellaneous.name,
208 md.priv.runtimename,
[26300]209 options
210 );/*
211.catch(function(e) {
212 if (vesl.helpers.isDefined(vesl.ui) && vesl.helpers.isDefined(vesl.ui.reporting) && vesl.helpers.isFunction(vesl.ui.reporting.error_callback)) {
213 vesl.ui.reporting.error_callback(e);
214 }
215 }).catch(function(e) {
216 // Handle unexpected errors (source: http://thecodebarbarian.com/async-await-error-handling-in-javascript.html)
217 console.log(e);
218 });
219
220 if (vesl.helpers.isDefined(vesl.ui) && vesl.helpers.isDefined(vesl.ui.reporting) && vesl.helpers.isFunction(vesl.ui.reporting.success_callback)) {
221 vesl.ui.reporting.success_callback(md);
222 }
223*/
224
225 // Why is md undefined at vesl.ui.reporting.success_callback(md)? See issm-refactor
226
[20269]227 return md;
[26300]228 } //}}}
229} //}}}
Note: See TracBrowser for help on using the repository browser.