Overview
Comment:Numerical solution of algebraic equations implemented for S-function target.

Equation solving requires the Matlab Optimization Toolbox to be installed.

Code has been changed from C++ to C to allow mex files to be built with LCC,
the compiler bundled with Matlab.

Parameters are now obtained from numpar.c instead of a dialogue box.

`mtt <sys> sfun zip` creates all necessary files for building the model mex files.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | origin/master | trunk
Files: files | file ages | folders
SHA3-256: 062029b187822b39851e505d09f272f96134572e888bb0a690899a8f846ed0fa
User & Date: geraint@users.sourceforge.net on 2002-05-19 13:01:22
Other Links: branch diff | manifest | tags
Context
2002-05-20
07:12:05
Trying to get oct files generated with -oct check-in: 039197b659 user: gawthrop@users.sourceforge.net tags: origin/master, trunk
2002-05-19
13:01:22
Numerical solution of algebraic equations implemented for S-function target.

Equation solving requires the Matlab Optimization Toolbox to be installed.

Code has been changed from C++ to C to allow mex files to be built with LCC,
the compiler bundled with Matlab.

Parameters are now obtained from numpar.c instead of a dialogue box.

`mtt <sys> sfun zip` creates all necessary files for building the model mex files. check-in: 062029b187 user: geraint@users.sourceforge.net tags: origin/master, trunk

2002-05-17
11:17:35
No longer uses df() if corresponding sensitivity parameter is 0. check-in: a29cbd4fd9 user: gawthrop@users.sourceforge.net tags: origin/master, trunk
Changes

Modified mttroot/mtt/bin/trans/mtt_header from [c5cc8a3a52] to [60dbd07829].

8
9
10
11
12
13
14








15
16
17
18
19
20
21
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29







+
+
+
+
+
+
+
+







# Copyright (C) 2000 by Peter J. Gawthrop

###############################################################
## Version control history
###############################################################
## $Id$
## $Log$
## Revision 1.50  2002/05/15 14:22:25  geraint
## Code for Simulink S-function target written direct to sfun.cc instead of
## calling .mexglx files. This eliminates the sfun dependency on Octave
## ColumnVectors. sys_sfun.cc should build directly on a MS Windows machine
## (can't test this yet).
##
## added sfun.zip target to create source code to export.
##
## Revision 1.49  2002/05/11 01:14:17  geraint
## Fix for [ 553218 ] simpar.oct and simpar.m different.
## Translation added between ColumnVector in base .cc and Octave_map in .oct.
##
## Revision 1.48  2002/05/08 14:51:03  geraint
## Moved matlab/octave data type conversion functions to a separate file.
##
206
207
208
209
210
211
212



213
214
215
216
217
218
219
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230







+
+
+







# Arguments
system=$1
rep=$2
language=$3
fun_name=${1}_${2}

other=$4 # Anything else eg stdin

insertor=\<\<			# help emacs sh-mode out with C++ lines


if [ -z "$system" ]; then
  echo 'Usage: mtt_header sys rep lang [stdin]'
  exit
fi


465
466
467
468
469
470
471
472
473
474
475




476
477
478
479
480
481
482
483
484
485
486
476
477
478
479
480
481
482




483
484
485
486
487
488


489
490
491
492
493
494
495







-
-
-
-
+
+
+
+


-
-







	oct_header=yes;
        constant_declaration="const double "
        var_declaration="double "
	minusone="-1"
	map="_map"
        declaredummies=yes
	;;
    sfun)
	modeline="// -*-c++-*- Put Emacs into c++-mode";
	Lc='//'
	Rc=''
    c)
	modeline="/* -*-c-*- Put Emacs into c-mode */";
	Lc='/*'
	Rc='*/'
	Lb='['
	Rb=']'
	start="## BEGIN Code"
	finish="## END Code"
	constant_declaration="const double "
	var_declaration="double "
	minusone="-1"
	;;
    *)
	echo Language $language not supported - sorry; exit 1
esac
849
850
851
852
853
854
855
856

857
858
859
860
861
862
863
864
865

866
867
868
869
870
871
872

873
874
875
876
877
878
879
858
859
860
861
862
863
864

865
866
867
868
869
870
871
872
873

874
875
876
877
878
879
880

881
882
883
884
885
886
887
888







-
+








-
+






-
+







	    ColumnVector | Matrix | *)
		printf "  ${arg_type}\t${w}\t= args(${j}).%s ();\n" ${vector_value}
		;;
	esac
    done
}	

map_mex_inputs ()
map_mex_cc_inputs ()
{
    s=${1:-""}					# comma separated input list
    if [ -z ${s:-""} ];then return; fi
    c=`get_field ${s} 0`			# count of inputs
    i=0
    cat <<EOF
    if (${c} != nrhs)
     {
       std::cerr << "${fun_name} expected " << ${c} << " argument(s): ${s}" << std::endl;
       std::cerr $insertor "${fun_name} expected " $insertor ${c} $insertor " argument(s): ${s}" $insertor std::endl;
       return;
     }
EOF
    while [ ${i} -lt ${c} ]; do
	j=${i}
	i=`expr ${i} + 1`
	w=`get_field ${s} ${i}`		# argument name
        w=`get_field ${s} ${i}`		# argument name
	get_arg_specific_stuff ${w}
	case ${arg_type} in
	    "const double")
		printf "  ${arg_type}\t${w}\t= mtt_double (prhs [${j}]);\n"
		;;
	    ColumnVector | Matrix | *)
		printf "  ${arg_type}\t${w}\t= mtt_${arg_type} (prhs [${j}]);\n"
904
905
906
907
908
909
910
911

912
913
914
915
916
917
918
919
920
921
922
923
924
925

926
927
928
929
930
931
932
913
914
915
916
917
918
919

920
921
922
923
924
925
926
927
928
929
930
931
932
933

934
935
936
937
938
939
940
941







-
+













-
+







  return retval;
}
#endif // (CODEGENTARGET == OCTAVEDLD)

EOF
}

write_mex ()
write_mex_cc ()
{
    func=${1:-"<insert function name>"}
    args=${2:-""}
    cat <<EOF
#if (CODEGENTARGET == MATLABMEX)
#include <mtt_matlab_octave.hh>

extern "C"
{
  void mexFunction (int nlhs, mxArray *plhs[],
		    int nrhs, const mxArray *prhs[])
  {
EOF
  map_mex_inputs ${args}
  map_mex_cc_inputs ${args}
cat <<EOF
  plhs[0] = mtt_mxArray (${func} (${args}));
  }
}
#endif

EOF
951
952
953
954
955
956
957
958







959
960
961
962
963
964
965
960
961
962
963
964
965
966

967
968
969
970
971
972
973
974
975
976
977
978
979
980







-
+
+
+
+
+
+
+







if [ ${language} = "oct" ];then
# standalone
    write_cc_header
    array2constant
    write_cc_footer
# oct and mex code
    write_oct ${system}_${rep} ${args}
    write_mex ${system}_${rep} ${args}
    write_mex_cc ${system}_${rep} ${args}
elif [ $language = "c" ]; then
    array2constant
    cat <<EOF
/* BEGIN Code */
/* END Code */
EOF
else

if [ -n "$noglobals" ]; then
cat<<EOF

## Horrible fudge to make mtt_m2p work
global ...

Modified mttroot/mtt/cc/mtt_m2cc.sh from [7e5ae6afba] to [71ee6a40d1].

96
97
98
99
100
101
102


103
104




105
106



107
108
109
110
111
112
113
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110


111
112
113
114
115
116
117
118
119
120







+
+


+
+
+
+
-
-
+
+
+







	cat
	;;
esac
};

fix_comment_delimiter ()
{
    language=${1:-cc}
    case $language in
    # it would be preferable if we didn't use '%' as a delimiter
    # (a % b) gives the remainder of ((int)a / (int)b) in C/C++
	c)
	    sed 's/[%#]\(.*\)/\/* \1 *\//'
	    ;;
	cc | *)
    sed 's/[%#]/\/\//g' | sed 's/\/\/\/\//\/\//g'
    
	    sed 's/[%#]/\/\//g' | sed 's/\/\/\/\//\/\//g'
	    ;;
    esac
};

decrement_indices ()
{    
    # first section appends '-1' to container indices
    # to convert from FORTRAN-type numbering to C-type numbering
    sed 's/mtta(\([0-9][0-9]*\),\([0-9][0-9]*\))/mtta[\1-1,\2-1]/g'	|\
168
169
170
171
172
173
174
175
176


177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
175
176
177
178
179
180
181


182
183

184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
211







-
-
+
+
-



-
+













-
+










    sed 's/\([0-9]*\)\(\.\)\{0,1\}\([0-9]*\)\^\([0-9]*\)\(\.\)\{0,1\}\([0-9]*\)/pow \(\1\2\3,\4\5\6\)/g'
};


echo Creating ${OUT}

case ${TARGET} in
    sfun)
	mtt_header ${SYS} ${REP} "sfun"	>  ${TMP}
    c)
	mtt_header ${SYS} ${REP} "c"	>  ${TMP}
	echo "## END Code"		>> ${TMP}
	find_code ${TMP} head		>  ${OUT}
	find_code ${IN} body		|\
	    decrement_indices		|\
	    fix_comment_delimiter	|\
	    fix_comment_delimiter c	|\
	    fix_pow			|\
	    strip_junk			|\
	    ${PARSER}			>> ${OUT}
	find_code ${TMP} foot		>> ${OUT}
	rm ${TMP}
	;;
    cc | *)
	mtt_header ${SYS} ${REP} "oct"	>  ${TMP}
	find_code ${TMP} head		>  ${OUT}
	rep_declarations		>> ${OUT}
	find_code ${IN} body   		|\
	    decrement_indices		|\
	    fortran_to_c_paren		|\
	    fix_comment_delimiter	|\
	    fix_comment_delimiter cc	|\
	    fix_pow			|\
	    strip_junk			|\
	    ${PARSER}			>> ${OUT}
	rep_footer			>> ${OUT}
	find_code ${TMP} foot		>> ${OUT}
	rm ${TMP}
	;;
esac


Modified mttroot/mtt/cc/sympar_txt2h.sh from [f951f86658] to [9a054e0600].

1
2
3




4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
11
12
13
14



+
+
+
+







#! /bin/sh
# $Id$
# $Log$
# Revision 1.5  2002/04/28 18:58:06  geraint
# Fixed [ 549658 ] awk should be gawk.
# Replaced calls to awk with call to gawk.
#
# Revision 1.4  2001/08/24 21:41:04  geraint
# Fixed problem with declaration when there are no numerical parameters.
#
# Revision 1.3  2001/03/19 02:28:53  geraint
# Branch merge: merging-ode2odes-exe back to MAIN.
#
# Revision 1.2.2.1  2001/03/16 03:56:54  geraint
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70







-
+







TMP_VAR_NAMES="mtt_tmp mtt_o $*"

IN=${SYS}_sympar.txt
OUT=${SYS}_sympar.h

declare_sys_param ()
{
cat ${IN} | gawk '(NF>0){printf ("static double %s MTT_UNUSED;\t// %s\n", tolower($1), $2)}'
cat ${IN} | gawk '(NF>0){printf ("static double %s MTT_UNUSED;\t/* %s\t*/\n", tolower($1), $2)}'
}

declare_temp_vars ()
{
for name in ${TMP_VAR_NAMES}
do
    echo ""

Modified mttroot/mtt/lib/rep/sfun_rep/Makefile from [f2177a72f4] to [506c1123b2].

1
2
3

4


5


6
7
8







9
10


11
12
13


14
15




16
17







18
19
20



21
22
23



24
25
26



27
28
29
1
2

3
4
5
6

7
8
9


10
11
12
13
14
15
16
17

18
19
20
21

22
23
24
25
26
27
28
29


30
31
32
33
34
35
36
37


38
39
40
41


42
43
44
45


46
47
48
49
50
51


-
+

+
+
-
+
+

-
-
+
+
+
+
+
+
+

-
+
+


-
+
+


+
+
+
+
-
-
+
+
+
+
+
+
+

-
-
+
+
+

-
-
+
+
+

-
-
+
+
+



#! /usr/bin/make -f

SRC = $(SYS)_sfun.cc $(SYS)_def.h $(SYS)_ae.sfun $(SYS)_ode.sfun $(SYS)_odeo.sfun $(SYS)_state.sfun
all: $(SYS)_sfun.mexglx

$(SYS)_sfun.mexglx: $(SYS)_sfun.c $(SYS)_def.h $(SYS)_sympar.h $(SYS)_numpar.c $(SYS)_ode.c $(SYS)_odeo.c $(SYS)_state.c $(SYS)_sfun_ae.mexglx 
	echo Creating $@
all: $(SYS)_sfun.mexglx
	mex $(SYS)_sfun.c
	cp *_sfun*mexglx ..

$(SYS)_sfun.mexglx: $(SRC)
	mex $(SYS)_sfun.cc
$(SYS)_sfun.c:: ${MTT_REP}/sfun_rep/sfun.c.tmpl
	echo Creating $@
	cat $^ | sed 's/<mtt_model_name>/$(SYS)/g' > $@

$(SYS)_sfun_ae.mexglx: $(SYS)_sfun_ae.c $(SYS)_def.h $(SYS)_ae.c
	echo Creating $@
	mex $(SYS)_sfun_ae.c

$(SYS)_sfun.cc:: ${MTT_REP}/sfun_rep/sfun.cc.tmpl
$(SYS)_sfun_ae.c:: ${MTT_REP}/sfun_rep/ae.c.tmpl
	echo Creating $@
	cat $^ | sed 's/<mtt_model_name>/$(SYS)/g' > $@

$(SYS)_sfun.zip: $(SRC)
$(SYS)_sfun.zip: $(SYS)_sfun.c $(SYS)_sfun_ae.c $(SYS)_def.h $(SYS)_sympar.h $(SYS)_ae.c $(SYS)_numpar.c $(SYS)_ode.c $(SYS)_odeo.c $(SYS)_state.c README
	echo Creating $@
	zip $@ $^

README:: ${MTT_REP}/sfun_rep/README.tmpl
	echo Creating $@
	cat $^ | sed 's/<mtt_model_name>/$(SYS)/g' > $@

$(SYS)_ae.sfun: $(SYS)_ae.m
	${MTT_CC}/mtt_m2cc.sh $(SYS) ae sfun cat 
$(SYS)_ae.c: $(SYS)_ae.m
	echo Creating $@
	${MTT_CC}/mtt_m2cc.sh $(SYS) ae c cat 

$(SYS)_numpar.c: $(SYS)_numpar.m
	echo Creating $@
	${MTT_CC}/mtt_m2cc.sh $(SYS) numpar c cat

$(SYS)_ode.sfun: $(SYS)_ode.m
	${MTT_CC}/mtt_m2cc.sh $(SYS) ode sfun cat
$(SYS)_ode.c: $(SYS)_ode.m
	echo Creating $@
	${MTT_CC}/mtt_m2cc.sh $(SYS) ode c cat

$(SYS)_odeo.sfun: $(SYS)_odeo.m
	${MTT_CC}/mtt_m2cc.sh $(SYS) odeo sfun cat
$(SYS)_odeo.c: $(SYS)_odeo.m
	echo Creating $@
	${MTT_CC}/mtt_m2cc.sh $(SYS) odeo c cat

$(SYS)_state.sfun: $(SYS)_state.m
	${MTT_CC}/mtt_m2cc.sh $(SYS) state sfun cat
$(SYS)_state.c: $(SYS)_state.m
	echo Creating $@
	${MTT_CC}/mtt_m2cc.sh $(SYS) state c cat

%::
	mtt -q $(OPTS) `echo $* | sed 's/\(.*\)_\(.*\)\.\(.*\)/\1 \2 \3/'`

Added mttroot/mtt/lib/rep/sfun_rep/README.tmpl version [7562840818].









1
2
3
4
5
6
7
8
+
+
+
+
+
+
+
+

To build a Simulink funtion of the <mtt_model_name> model without using MTT:

mex <mtt_model_name>_sfun.c

If numerical solution of algebraic equations is also required:

mex <mtt_model_name>_sfun_ae.c

Added mttroot/mtt/lib/rep/sfun_rep/ae.c.tmpl version [61cef996f8].











































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/* -*-c-*-	Put emacs into c-mode */

#include <stdio.h>
#include <stdlib.h>

#include <mex.h>
#include "<mtt_model_name>_def.h"

/* utility procedures */

double *
array_of_double (size_t n)
{
  void *p = calloc (n, sizeof (double));
  if (! p) {
    fprintf (stderr, "*** Error: failed to allocate memory\n");
  }
  return (double *) p;
}

/* system equations */

static double *
<mtt_model_name>_ae (double *mttyz,
		     const double *mttx,
		     const double *mttu,
		     const double mttt,
		     const double *mttpar)
{
#include "<mtt_model_name>_ae.c"
}

/* generic mex function */

#ifdef __cplusplus
extern "C" {
#endif

void
mexFunction (int nlhs, mxArray *plhs[],
	     int nrhs, const mxArray *prhs[])
{
  double *mttyz;		/* residuals */

  double *mttx;			/* states */
  double *mttu;			/* known + unknown inputs */
  double mttt;			/* time */
  double *mttpar;		/* parameters */

  unsigned int i;
  double *p;

  mttyz		= array_of_double (MTTNYZ);

  mttx		= array_of_double (MTTNX);
  mttu		= array_of_double (MTTNU + MTTNYZ);
  mttpar	= array_of_double (MTTNPAR);

  /* get trial values */
  p = mxGetPr (prhs[0]);
  for (i = 0; i < MTTNYZ; i++) {
    mttu[MTTNU + i] = p[i];
  }

  /* get states */
  p = mxGetPr (prhs[1]);
  for (i = 0; i < MTTNX; i++) {
    mttx[i] = p[i];
  }

  /* get known inputs */
  p = mxGetPr (prhs[2]);
  for (i = 0; i < MTTNU; i++) {
    mttu[i] = p[i];
  }

  /* get time */
  p = mxGetPr (prhs[3]);
  mttt = *p;

  /* get parameters */
  p = mxGetPr (prhs[4]);
  for (i = 0; i < MTTNPAR; i++) {
    mttpar[i] = p[i];
  }
  
  /* evaluate residuals */
  <mtt_model_name>_ae (mttyz, mttx, mttu, mttt, mttpar);
  
  /* return residuals */
  plhs[0] = mxCreateDoubleMatrix (MTTNYZ, 1, mxREAL);
  p = mxGetPr (plhs[0]);
  for (i = 0; i < MTTNYZ; i++) {
    p[i] = mttyz[i];
  }

  /* release memory */
  free (mttx);
  free (mttu);
  free (mttpar);
  free (mttyz);
}

#ifdef __cplusplus
}
#endif

Added mttroot/mtt/lib/rep/sfun_rep/sfun.c.tmpl version [3726daca35].




























































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/* -*-c-*-
 * <mtt_model_name>_sfun.c:
 * Matlab S-function simulation of <mtt_model_name>
 */

#define S_FUNCTION_NAME <mtt_model_name>_sfun
#define S_FUNCTION_LEVEL 2

#if (0)				/* DEBUG? */
#define PRINT_ENTER(f) fprintf (stderr, "Entered %s\n", f)
#define PRINT_LEAVE(f) fprintf (stderr, "Leaving %s\n", f)
#else
#define PRINT_ENTER(f)
#define PRINT_LEAVE(f)
#endif /* DEBUG? */

#include <stdio.h>
#include <stdlib.h>

#include "simstruc.h"
#include "<mtt_model_name>_def.h"

static double *mttdx;		/* pointer to rates */
static double *mttu;		/* pointer to inputs */
static double *mttpar;		/* pointer to parameters */
static double *mttx;		/* pointer to states */
static double *mtty;		/* pointer to outputs */
static double *mttyz;		/* pointer to residuals */
static double  mttt;		/* time */

static unsigned int i;		/* loop counter */

/* system equations */

static void
<mtt_model_name>_ae (void)
{
#include "<mtt_model_name>_ae.c"
}

static void
<mtt_model_name>_ode (void)
{
#include "<mtt_model_name>_ode.c"
}

static void
<mtt_model_name>_odeo (void)
{
#include "<mtt_model_name>_odeo.c"
}

static void
<mtt_model_name>_state (void)
{
#include "<mtt_model_name>_state.c"
}

/* utility procedures */

static double *
array_of_double (size_t n)
{
  void *p = calloc (n, sizeof (double));
  if (! p) {
    fprintf (stderr, "*** Error: failed to allocate memory\n");
  }
  return (double *) p;
}

static void
initialise_arrays (void)
{
  PRINT_ENTER("initialise_arrays");

  mttdx		= array_of_double (MTTNX);
  mttpar	= array_of_double (MTTNPAR);
  mttu		= array_of_double (MTTNU + MTTNYZ);
  mttx		= array_of_double (MTTNX);
  mtty		= array_of_double (MTTNY);
  mttyz		= array_of_double (MTTNYZ);

  PRINT_LEAVE("initialise_arrays");
}

static void
update_states_from_simulink (SimStruct *S)
{
  PRINT_ENTER("update_states_from_simulink");
  for (i = 0; i < MTTNX; i++) {
    mttx[i] = ssGetContStates (S)[i];
  }
  PRINT_LEAVE("update_states_from_simulink");
}

static void
update_inputs_from_simulink (SimStruct *S)
{
  PRINT_ENTER("update_inputs_from_simulink");
  for (i = 0; i < MTTNU; i++) {
    mttu[i] = *ssGetInputPortRealSignalPtrs (S, i)[0];
  }
  PRINT_LEAVE("update_inputs_from_simulink");
}

static void
update_inputs_from_solver (void)
{
  mxArray *MTT_MATLAB_P;
  mxArray *MTT_MATLAB_T;
  mxArray *MTT_MATLAB_U;
  mxArray *MTT_MATLAB_Ui;
  mxArray *MTT_MATLAB_X;

  double *p;

  PRINT_ENTER ("update_inputs_from_solver");

  /* starting value for solver - start with zero */
  MTT_MATLAB_Ui = mxCreateDoubleMatrix (MTTNYZ, 1, mxREAL);
  mxSetName (MTT_MATLAB_Ui, "MTT_Ui");
  p = mxGetPr (MTT_MATLAB_Ui);
  for (i = 0; i < MTTNYZ; i++) {
    p[i] = 0.0;
  }
  mexPutArray (MTT_MATLAB_Ui, "base");

  /* put states into matlab workspace */
  MTT_MATLAB_X = mxCreateDoubleMatrix (MTTNX, 1, mxREAL);
  mxSetName (MTT_MATLAB_X, "MTT_X");
  p = mxGetPr (MTT_MATLAB_X);
  for (i = 0; i < MTTNX; i++) {
    p[i] = mttx[i];
  }
  mexPutArray (MTT_MATLAB_X, "base");

  /* put known inputs into matlab workspace */
  MTT_MATLAB_U = mxCreateDoubleMatrix (MTTNU, 1, mxREAL);
  mxSetName (MTT_MATLAB_U, "MTT_U");
  p = mxGetPr (MTT_MATLAB_U);
  for (i = 0; i < MTTNU; i++) {
    p[i] = mttu[i];
  }
  mexPutArray (MTT_MATLAB_U, "base");

  /* put time into matlab workspace */
  MTT_MATLAB_T = mxCreateDoubleMatrix (1, 1, mxREAL);
  mxSetName (MTT_MATLAB_T, "MTT_T");
  *mxGetPr (MTT_MATLAB_T) = mttt;
  mexPutArray (MTT_MATLAB_T, "base");

  /* put parameters into matlab workspace */
  MTT_MATLAB_P = mxCreateDoubleMatrix (MTTNPAR, 1, mxREAL);
  mxSetName (MTT_MATLAB_P, "MTT_P");
  p = mxGetPr (MTT_MATLAB_P);
  for (i = 0; i < MTTNPAR; i++) {
    p[i] = mttpar[i];
  }
  mexPutArray (MTT_MATLAB_P, "base");

  /* call fsolve */
  mexEvalString ("MTT_Ui = fsolve (@<mtt_model_name>_sfun_ae, MTT_Ui, optimset('display','off'), MTT_X, MTT_U, MTT_T, MTT_P);");

  /* retrieve result */
  MTT_MATLAB_Ui = mexGetArray ("MTT_Ui", "base");
  p = mxGetPr (MTT_MATLAB_Ui);
  for (i = 0; i < MTTNYZ; i++) {
    mttu[MTTNU + i] = p[i];
  }

  /* free memory */
  mxDestroyArray (MTT_MATLAB_P);
  mxDestroyArray (MTT_MATLAB_T);
  mxDestroyArray (MTT_MATLAB_U);
  mxDestroyArray (MTT_MATLAB_Ui);
  mxDestroyArray (MTT_MATLAB_X);

  PRINT_LEAVE ("update_inputs_from_solver");
}

static void
update_simtime_from_simulink (SimStruct *S)
{
  PRINT_ENTER("update_simtime_from_simulink");
  mttt = ssGetT (S);
  PRINT_LEAVE("update_simtime_from_simulink");
}

/* S-function methods */

static void mdlInitializeSizes(SimStruct *S)
{
  PRINT_ENTER("mdlInitializeSizes");
  ssSetNumSFcnParams(S, 0); 
  if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
    PRINT_LEAVE("mdlInitializeSizes");
    return;
  }
  
  ssSetNumContStates(S, MTTNX);
  ssSetNumDiscStates(S, 0);
  
  if (!ssSetNumInputPorts(S, MTTNU)) return;
    for (i = 0; i < MTTNU; i++) {
      ssSetInputPortWidth(S, i, 1);
      ssSetInputPortDirectFeedThrough(S, i, 1);
    }
    
    if (!ssSetNumOutputPorts(S, MTTNY)) return;
    for (i = 0; i < MTTNY; i++) {
      ssSetOutputPortWidth(S, i, 1);
    }
    
    ssSetNumSampleTimes(S, 1);
    ssSetNumRWork(S, 0);
    ssSetNumIWork(S, 0);
    ssSetNumPWork(S, 0);
    ssSetNumModes(S, 0);
    ssSetNumNonsampledZCs(S, 0);
    
    ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
    
    initialise_arrays ();
    PRINT_LEAVE("mdlInitializeSizes");
}

static void mdlInitializeSampleTimes(SimStruct *S)
{
  PRINT_ENTER("mdlInitializeSampleTimes");
  ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
  ssSetOffsetTime(S, 0, 0.0);
  PRINT_LEAVE("mdlInitializeSampleTimes");
}

#define MDL_INITIALIZE_CONDITIONS
static void mdlInitializeConditions(SimStruct *S)
{
#include "<mtt_model_name>_sympar.h"

  PRINT_ENTER("mdlInitializeConditions");

#include "<mtt_model_name>_numpar.c"

  <mtt_model_name>_state ();

  for (i = 0; i < MTTNX; i++) {
    ssGetContStates (S)[i] = mttx[i];
  }

  PRINT_LEAVE("leaving mdlInitializeConditions");
}

static void mdlOutputs(SimStruct *S, int_T tid)
{
  PRINT_ENTER("entered mdlOutputs");

  update_states_from_simulink (S);
  update_inputs_from_simulink (S);
  if (MTTNYZ > 0) {
    update_inputs_from_solver ();
  }
  update_simtime_from_simulink (S);

  UNUSED_ARG(tid); /* not used in single tasking mode */

  <mtt_model_name>_odeo ();

  for (i = 0; i < MTTNY; i++) {
      ssGetOutputPortRealSignal (S,i)[0] = mtty[i];
  }

  PRINT_LEAVE("leaving mdlOutputs");
}

#define MDL_DERIVATIVES
static void mdlDerivatives(SimStruct *S)
{
  PRINT_ENTER("entered mdlDerivatives\n");
    
  update_states_from_simulink (S);
  update_inputs_from_simulink (S);
  if (MTTNYZ > 0) {
    update_inputs_from_solver ();
  } 
  update_simtime_from_simulink (S);

  <mtt_model_name>_ode ();

  for (i = 0; i < MTTNX; i++) {
    ssGetdX (S)[i] = mttdx[i];
  }

  PRINT_LEAVE("leaving mdlDerivatives");
}

static void mdlTerminate(SimStruct *S)
{
  PRINT_ENTER("entered mdlTerminate");
  UNUSED_ARG(S);

  free (mttdx);
  free (mttpar);
  free (mttu);
  free (mttx);
  free (mtty);
  free (mttyz);

  PRINT_LEAVE("leaving mdlTerminate");
}

#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
#include "simulink.c"      /* MEX-file interface mechanism */
#else
#include "cg_sfun.h"       /* Code generation registration function */
#endif

Deleted mttroot/mtt/lib/rep/sfun_rep/sfun.cc.tmpl version [cc87f430f2].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150






















































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
// -*-c++-*-
// <mtt_model_name>_sfun.c:
// Matlab S-function simulation of <mtt_model_name>

#define S_FUNCTION_NAME <mtt_model_name>_sfun
#define S_FUNCTION_LEVEL 2

#include "simstruc.h"
#include "<mtt_model_name>_def.h"

static mxArray *dX		= mxCreateDoubleMatrix (MTTNX	, 1, mxREAL);
static mxArray *P		= mxCreateDoubleMatrix (MTTNPAR	, 1, mxREAL);
static mxArray *T		= mxCreateDoubleMatrix (1	, 1, mxREAL);
static mxArray *U		= mxCreateDoubleMatrix (MTTNU	, 1, mxREAL);
static mxArray *X		= mxCreateDoubleMatrix (MTTNX	, 1, mxREAL);
static mxArray *Y		= mxCreateDoubleMatrix (MTTNY	, 1, mxREAL);
static mxArray *YZ		= mxCreateDoubleMatrix (MTTNYZ	, 1, mxREAL);

static double *mttdx		= mxGetPr (dX);
static double *mttu		= mxGetPr (U);
static double *mttpar		= mxGetPr (P);
static double *mttx		= mxGetPr (X);
static double *mtty		= mxGetPr (Y);
static double *mttyz		= mxGetPr (YZ);
static double *mtttp		= mxGetPr (T);

void
update_parameters_from_simulink (SimStruct *S)
{
  for (int i = 0; i < MTTNPAR; i++) {
    mttpar [i] = *mxGetPr (ssGetSFcnParam (S, i));
  }
}

void
update_states_from_simulink (SimStruct *S)
{
  static double *x;
  x = ssGetContStates (S);
  for (int i = 0; i < MTTNX; i++) {
    mttx [i] = x [i];
  }
}

void
update_inputs_from_simulink (SimStruct *S)
{
  for (int i = 0; i < MTTNU; i++) {
    mttu [i] = *ssGetInputPortRealSignalPtrs (S, i)[0];
  }
}

void
update_simtime_from_simulink (SimStruct *S)
{
  mtttp [0] = ssGetT (S);
}

// S-function methods

static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, MTTNPAR); 
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        return;
    }

    ssSetNumContStates(S, MTTNX);
    ssSetNumDiscStates(S, 0);

    if (!ssSetNumInputPorts(S, MTTNU)) return;
    for (int i = 0; i < MTTNU; i++) {
      ssSetInputPortWidth(S, i, 1);
      ssSetInputPortDirectFeedThrough(S, i, 1);
    }

    if (!ssSetNumOutputPorts(S, MTTNY)) return;
    for (int i = 0; i < MTTNY; i++) {
      ssSetOutputPortWidth(S, i, 1);
    }

    ssSetNumSampleTimes(S, 1);
    ssSetNumRWork(S, 0);
    ssSetNumIWork(S, 0);
    ssSetNumPWork(S, 0);
    ssSetNumModes(S, 0);
    ssSetNumNonsampledZCs(S, 0);

    ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}

static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, 0.0);
}

#define MDL_INITIALIZE_CONDITIONS
static void mdlInitializeConditions(SimStruct *S)
{
  update_parameters_from_simulink (S);

#include "<mtt_model_name>_state.sfun"

  for (int i = 0; i < MTTNX; i++) {
    ssGetContStates (S)[i] = mttx [i];
  }
}

static void mdlOutputs(SimStruct *S, int_T tid)
{
  update_states_from_simulink (S);
  update_inputs_from_simulink (S);
  update_simtime_from_simulink (S);
  update_parameters_from_simulink (S);

  UNUSED_ARG(tid); // not used in single tasking mode

#include "<mtt_model_name>_odeo.sfun"

  for (int i = 0; i < MTTNY; i++) {
      ssGetOutputPortRealSignal (S,i)[0] = mtty [i];
  }
}

#define MDL_DERIVATIVES
static void mdlDerivatives(SimStruct *S)
{
  update_states_from_simulink (S);
  update_inputs_from_simulink (S);
  update_simtime_from_simulink (S);
  update_parameters_from_simulink (S);

#include "<mtt_model_name>_ode.sfun"

  for (int i = 0; i < MTTNX; i++) {
    ssGetdX (S)[i] = mttdx [i];
  }
}

static void mdlTerminate(SimStruct *S)
{
    UNUSED_ARG(S);
}

#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
#include "simulink.c"      /* MEX-file interface mechanism */
#else
#include "cg_sfun.h"       /* Code generation registration function */
#endif


MTT: Model Transformation Tools
GitHub | SourceHut | Sourceforge | Fossil RSS ]