0001 function solve_file = dsGetSolveFile(model,studyinfo,varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 opts=[];
0030 if nargin<1
0031 error('first argument must be a DynaSim model structure.');
0032 end
0033 if nargin<2
0034 studyinfo=[];
0035 end
0036 if nargin<3
0037 varargin={};
0038 elseif isstruct(varargin{1})
0039 opts=varargin{1};
0040 fields=fieldnames(opts);
0041 varargin={};
0042 end
0043
0044 options=dsCheckOptions(varargin,{...
0045 'solver','rk4',{'euler','rk1','rk2','rk4','modified_euler','rungekutta','rk','ode23','ode45',...
0046 'ode1','ode2','ode3','ode4','ode5','ode8','ode113','ode15s','ode23s','ode23t','ode23tb'},...
0047 'matlab_solver_options',[],[],...
0048 'disk_flag',0,{0,1},...
0049 'solve_file',[],[],...
0050 'study_dir',[],[],...
0051 'verbose_flag',0,{0,1},...
0052 'parallel_flag',0,{0,1},...
0053 'compile_flag',0,{0,1},...
0054 'mex_dir_flag',1,{0,1},...
0055 'mex_dir',[],[],...
0056 'auto_gen_test_data_flag',0,{0,1},...
0057 'unit_test_flag',0,{0,1},...
0058 },false);
0059
0060 if ~isempty(opts)
0061
0062
0063 warning('off','catstruct:DuplicatesFound');
0064 options=catstruct(options,opts);
0065 options=orderfields(options,fields);
0066 end
0067
0068 if isempty(options.mex_dir)
0069 options.mex_dir = dsGetConfig('mex_path');
0070 end
0071
0072 if options.verbose_flag
0073 fprintf('\nPREPARING SOLVER:\n');
0074 end
0075
0076
0077 switch options.solver
0078 case {'euler','rk1','rk2','modified_euler','rk4','rungekutta','rk'}
0079 solver_type = 'dynasim';
0080 if ~isempty(options.matlab_solver_options)
0081 warning('matlab_solver_options are not used by DynaSim solvers. instead try ''ode23'' or ''ode45'' to use those options.');
0082 end
0083 case {'ode23','ode45'}
0084 solver_type = 'matlab';
0085 if options.disk_flag==1
0086 warning('using disk for real-time storage instead of memory is only available for DynaSim solvers. try using ''euler'',''rk2'', or ''rk4'' for real-time disk usage.');
0087 end
0088
0089 case {'ode113','ode15s','ode23s','ode23t','ode23tb'}
0090 solver_type = 'matlab_no_mex';
0091 if options.disk_flag==1
0092 warning('using disk for real-time storage instead of memory is only available for DynaSim solvers. try using ''euler'',''rk2'', or ''rk4'' for real-time disk usage.');
0093 end
0094 otherwise
0095 error('unrecognized solver type');
0096 end
0097
0098
0099 if ~strcmp(solver_type, 'dynasim') && options.disk_flag
0100 error('Disk_flag not supported with built-in matlab solvers')
0101 end
0102
0103 if ~isempty(options.solve_file)
0104
0105 solve_file=options.solve_file;
0106
0107 elseif isfield(studyinfo,'solve_file')
0108
0109 solve_file=studyinfo.solve_file;
0110 elseif options.auto_gen_test_data_flag || options.unit_test_flag
0111 solve_file='solve_ode.m';
0112 else
0113
0114 solve_file=['solve_ode_' datestr(now,'yyyymmddHHMMSS_FFF') '.m'];
0115 end
0116
0117 if ~strcmp(reportUI,'matlab') && ~strcmp(solve_file,'solve_ode.m')
0118 wrn_fnc = warning('query', 'Octave:function-name-clash');
0119 if strcmp(wrn_fnc.state,'on')
0120 fprintf('Switching off ''function-name-clash'' warnings because of solve_ode suffix.\n');
0121 warning('off', 'Octave:function-name-clash');
0122 end
0123 end
0124
0125 [fpath,fname,fext]=fileparts2(solve_file);
0126
0127 if isempty(fpath)
0128
0129 if ~isempty(options.sim_id)
0130 solve_file=fullfile(options.study_dir,'solve',['sim' num2str(options.sim_id)],[fname fext]);
0131 else
0132 solve_file=fullfile(options.study_dir,'solve',[fname fext]);
0133 end
0134
0135
0136 solve_file = getAbsolutePath(solve_file);
0137 end
0138 [fpath,fname,fext]=fileparts2(solve_file);
0139
0140
0141 if length(fname)>(63-4)
0142 fname=fname(1:(63-4));
0143 solve_file=fullfile(fpath,[fname fext]);
0144 end
0145
0146
0147 if ~isdir(fpath)
0148 if options.verbose_flag
0149 fprintf('Creating solver directory %s\n',fpath);
0150 end
0151 mkdir(fpath);
0152 end
0153 cwd=pwd;
0154
0155 if ~strcmp(cwd,fpath)
0156 if options.verbose_flag
0157 fprintf('Changing directory to %s\n',fpath);
0158 end
0159 cd(fpath);
0160 end
0161
0162
0163 if ~exist(solve_file,'file')
0164 keyvals = dsOptions2Keyval(options);
0165 switch solver_type
0166 case 'dynasim'
0167 solve_file_m = dsWriteDynaSimSolver(model,keyvals{:},'filename',solve_file);
0168 case {'matlab', 'matlab_no_mex'}
0169 solve_file_m = dsWriteMatlabSolver(model,keyvals{:},'filename',solve_file, 'solver_type',solver_type);
0170
0171
0172
0173
0174
0175
0176
0177
0178 end
0179 solve_file=dsCompareSolveFiles(solve_file_m);
0180 if options.compile_flag && options.mex_dir_flag
0181 solve_file=dsCompareSolveFiles(solve_file,options.mex_dir,options.verbose_flag);
0182 end
0183 else
0184 if options.verbose_flag
0185 fprintf('Using previous solver file: %s\n',solve_file);
0186 end
0187 end
0188
0189
0190
0191
0192
0193
0194
0195 if options.compile_flag && ~strcmp(solver_type,'matlab_no_mex')
0196 if options.one_solve_file_flag
0197 options.codegen_args = {0};
0198 end
0199 solve_file = dsPrepareMEX(solve_file, options);
0200 end
0201
0202
0203 if ~strcmp(cwd,fpath)
0204 if options.verbose_flag
0205 fprintf('Changing directory back to %s\n',cwd);
0206 end
0207 cd(cwd);
0208 end