Home > functions > internal > dsGetSolveFile.m

dsGetSolveFile

PURPOSE ^

GETSOLVEFILE - helper function that creates or retrieves the desired solver file.

SYNOPSIS ^

function solve_file = dsGetSolveFile(model,studyinfo,varargin)

DESCRIPTION ^

GETSOLVEFILE - helper function that creates or retrieves the desired solver file.

 Usage:
   solve_file = dsGetSolveFile(model,studyinfo,options)

 Inputs:
   - model: DynaSim model structure (see dsGenerateModel)
   - studyinfo (optional): DynaSim studyinfo structure (see dsCheckStudyinfo)
   - options (optional): cell array of key/value pairs or Matlab structure with options
     'solver'      : solver for numerical integration (see dsGetSolveFile)
                     {'euler','rk2','rk4'} (default: 'rk4')
     'disk_flag'   : whether to write to disk during simulation instead of
                     storing in memory {0 or 1} (default: 0)
     'study_dir'   : relative or absolute path to output directory (default:
                     current directory)
     'verbose_flag': whether to display informative messages/logs (default: 0)

 Output:
   - solver_file: full file name of file solving the system in model

 See also: dsWriteDynaSimSolver, dsCompareSolveFiles, dsPrepareMEX,
           dsSimulate, dsCreateBatch

 Author: Jason Sherfey, PhD <jssherfey@gmail.com>
 Copyright (C) 2016 Jason Sherfey, Boston University, USA

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function solve_file = dsGetSolveFile(model,studyinfo,varargin)
0002 %GETSOLVEFILE - helper function that creates or retrieves the desired solver file.
0003 %
0004 % Usage:
0005 %   solve_file = dsGetSolveFile(model,studyinfo,options)
0006 %
0007 % Inputs:
0008 %   - model: DynaSim model structure (see dsGenerateModel)
0009 %   - studyinfo (optional): DynaSim studyinfo structure (see dsCheckStudyinfo)
0010 %   - options (optional): cell array of key/value pairs or Matlab structure with options
0011 %     'solver'      : solver for numerical integration (see dsGetSolveFile)
0012 %                     {'euler','rk2','rk4'} (default: 'rk4')
0013 %     'disk_flag'   : whether to write to disk during simulation instead of
0014 %                     storing in memory {0 or 1} (default: 0)
0015 %     'study_dir'   : relative or absolute path to output directory (default:
0016 %                     current directory)
0017 %     'verbose_flag': whether to display informative messages/logs (default: 0)
0018 %
0019 % Output:
0020 %   - solver_file: full file name of file solving the system in model
0021 %
0022 % See also: dsWriteDynaSimSolver, dsCompareSolveFiles, dsPrepareMEX,
0023 %           dsSimulate, dsCreateBatch
0024 %
0025 % Author: Jason Sherfey, PhD <jssherfey@gmail.com>
0026 % Copyright (C) 2016 Jason Sherfey, Boston University, USA
0027 
0028 % Check inputs
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}) % user provided an options structure
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'},... % DynaSim and built-in Matlab solvers
0047   'matlab_solver_options',[],[],... % options from odeset for use with built-in Matlab solvers
0048   'disk_flag',0,{0,1},...            % whether to write to disk during simulation instead of storing in memory
0049   'solve_file',[],[],... % m- or mex-file solving the system
0050   'study_dir',[],[],... % study directory
0051   'verbose_flag',0,{0,1},...
0052   'parallel_flag',0,{0,1},...     % whether to run simulations in parallel (using parfor)
0053   'compile_flag',0,{0,1},... % exist('codegen')==6, whether to compile using coder instead of interpreting Matlab
0054   'mex_dir_flag',1,{0,1},... % Flag to tell whether or not to search in mex_dir for pre-compiled solve files (solve*_mex*).
0055   'mex_dir',[],[],... % Directory to search for pre-compiled mex files. Can be relative to 'study_dir' or absolute path.
0056   'auto_gen_test_data_flag',0,{0,1},...
0057   'unit_test_flag',0,{0,1},...
0058   },false);
0059 
0060 if ~isempty(opts)
0061   % combine default options and user-supplied options w/ the latter
0062   % overriding the former
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 % check solver options
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'} % note: only ode23 and ode45 are supported by codegen (see: http://www.mathworks.com/help/coder/ug/functions-supported-for-code-generation--alphabetical-list.html)
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 %   case {'ode1','ode2','ode3','ode4','ode5','ode8','ode113','ode15s','ode23s','ode23t','ode23tb'} % not mex supported
0089   case {'ode113','ode15s','ode23s','ode23t','ode23tb'} % not mex supported
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 %check type of solver against disk_flag
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   % use user-provided solve_file
0105   solve_file=options.solve_file;
0106   % note: options.solve_file is used by cluster sim jobs (see dsCreateBatch())
0107 elseif isfield(studyinfo,'solve_file')
0108   % use study-associated solve_file
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   % set default solve_file name
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   % add path to solve_file name
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   % convert relative path to absolute path
0136   solve_file = getAbsolutePath(solve_file);
0137 end
0138 [fpath,fname,fext]=fileparts2(solve_file);
0139 
0140 % check that solve file name is less than max function name allwoed by matlab
0141 if length(fname)>(63-4) % subtract 4 to allow suffix '_mex'
0142   fname=fname(1:(63-4));
0143   solve_file=fullfile(fpath,[fname fext]);
0144 end
0145 
0146 % create directory for solve_file if it doesn't exist
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 % create solve_file if it doesn't exist
0163 if ~exist(solve_file,'file')
0164   keyvals = dsOptions2Keyval(options);
0165   switch solver_type
0166     case 'dynasim'  % write DynaSim solver function (solve_ode.m)
0167       solve_file_m = dsWriteDynaSimSolver(model,keyvals{:},'filename',solve_file); % create DynaSim solver m-file
0168     case {'matlab', 'matlab_no_mex'} % prepare model function handle etc for built-in solver (@odefun)
0169       solve_file_m = dsWriteMatlabSolver(model,keyvals{:},'filename',solve_file, 'solver_type',solver_type); % create Matlab solver m-file
0170                 % design: dsWriteMatlabSolver should be very similar to
0171                 % dsWriteDynaSimSolver except have a subfunction with an odefun
0172                 % format variation and main function that calls odeset and
0173                 % feval.
0174                 % DynaSimToOdefun(): a function called outside of
0175                 % dsSimulate. it should evaluate fixed_variables and
0176                 % return @odefun with all substitutions. dsSimulate
0177                 % should be able to handle: dsSimulate(@odefun,'tspan',tspan,'ic',ic)
0178   end
0179   solve_file=dsCompareSolveFiles(solve_file_m);               % First search in local solve folder...
0180   if options.compile_flag && options.mex_dir_flag
0181     solve_file=dsCompareSolveFiles(solve_file,options.mex_dir,options.verbose_flag); % Then search in mex_dir (if it exists and if compile_flag==1).
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 %% MEX Compilation
0190 % create MEX file if desired and doesn't exist
0191 
0192 % NOTE: if using stiff built-in solver, it should only compile the odefun, not
0193 %   the dynasim solve file. this is called from dsWriteMatlabSolver
0194 
0195 if options.compile_flag && ~strcmp(solver_type,'matlab_no_mex') % compile solver function
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

Generated on Tue 12-Dec-2017 11:32:10 by m2html © 2005