1 |
#include <iostream> |
2 |
#include <stdexcept> |
3 |
#include <string> |
4 |
using namespace std; |
5 |
|
6 |
extern "C"{ |
7 |
#include <utilities/ascConfig.h> |
8 |
#include <utilities/ascSignal.h> |
9 |
#include <general/dstring.h> |
10 |
#include <compiler/instance_enum.h> |
11 |
#include <compiler/fractions.h> |
12 |
#include <compiler/compiler.h> |
13 |
#include <compiler/dimen.h> |
14 |
#include <compiler/symtab.h> |
15 |
#include <compiler/instance_io.h> |
16 |
#include <compiler/instantiate.h> |
17 |
#include <compiler/bintoken.h> |
18 |
#include <utilities/readln.h> |
19 |
#include <solver/mtx.h> |
20 |
#include <solver/slv_types.h> |
21 |
#include <solver/var.h> |
22 |
#include <solver/rel.h> |
23 |
#include <solver/discrete.h> |
24 |
#include <solver/conditional.h> |
25 |
#include <solver/logrel.h> |
26 |
#include <solver/bnd.h> |
27 |
#include <solver/calc.h> |
28 |
#include <solver/relman.h> |
29 |
#include <solver/slv_common.h> |
30 |
#include <solver/linsol.h> |
31 |
#include <solver/linsolqr.h> |
32 |
#include <solver/slv_client.h> |
33 |
#include <solver/system.h> |
34 |
#include <solver/slv_interface.h> |
35 |
#include <compiler/simlist.h> |
36 |
} |
37 |
|
38 |
#include "type.h" |
39 |
#include "simulation.h" |
40 |
#include "library.h" |
41 |
#include "dimensions.h" |
42 |
|
43 |
/** |
44 |
@TODO FIXME for some reason there are a lot of empty Type objects being created |
45 |
*/ |
46 |
Type::Type(){ |
47 |
//cerr << "CREATED EMPTY TYPE" << endl; |
48 |
// throw runtime_error("Type::Type: Can't create new Types via C++ interface"); |
49 |
} |
50 |
|
51 |
Type::Type(const TypeDescription *t) : t(t){ |
52 |
//cerr << "CREATED TYPE '" << getName() << "'" << endl; |
53 |
} |
54 |
|
55 |
const SymChar |
56 |
Type::getName() const{ |
57 |
if(t==NULL){ |
58 |
throw runtime_error("Type::getName: t is NULL"); |
59 |
} |
60 |
symchar *sym = GetName(t); |
61 |
if(sym==NULL){ |
62 |
throw runtime_error("Unnamed type"); |
63 |
} |
64 |
return SymChar(SCP(GetName(t))); |
65 |
} |
66 |
|
67 |
const int |
68 |
Type::getParameterCount() const{ |
69 |
return GetModelParameterCount(t); |
70 |
} |
71 |
|
72 |
const TypeDescription * |
73 |
Type::getInternalType() const{ |
74 |
return t; |
75 |
} |
76 |
|
77 |
const Dimensions |
78 |
Type::getDimensions() const{ |
79 |
if( isRefinedConstant() ){ |
80 |
return Dimensions( GetConstantDimens(getInternalType()) ); |
81 |
}else if( isRefinedReal() ){ |
82 |
return Dimensions( GetRealDimens(getInternalType()) ); |
83 |
}else{ |
84 |
if( !isRefinedAtom() )throw runtime_error("Type::getDimensions: called with non-atom type"); |
85 |
throw runtime_error("Type::getDimensions: unrecognised type"); |
86 |
} |
87 |
} |
88 |
|
89 |
const bool |
90 |
Type::isRefinedAtom() const{ |
91 |
return BaseTypeIsAtomic(t); |
92 |
} |
93 |
|
94 |
const bool |
95 |
Type::isRefinedReal() const{ |
96 |
return BaseTypeIsReal(t); |
97 |
} |
98 |
|
99 |
const bool |
100 |
Type::isRefinedConstant() const{ |
101 |
return BaseTypeIsConstant(t); |
102 |
} |
103 |
|
104 |
/** |
105 |
Instantiate a type. This expensive: it will compile your |
106 |
model as C-code and load a dynamic library with native |
107 |
machine-code versions of your equations. |
108 |
|
109 |
Once you have an instance of your model, you can start |
110 |
to eliminate variables and attempt to solve it, see Instanc. |
111 |
*/ |
112 |
Simulation |
113 |
Type::getSimulation(SymChar sym){ |
114 |
static bool have_bintoken_setup; |
115 |
static string bin_targetstem; |
116 |
static string bin_srcname; |
117 |
static string bin_objname; |
118 |
static string bin_libname; |
119 |
static string bin_cmd; |
120 |
static string bin_rm; |
121 |
|
122 |
cerr << "Type " << getName().toString() << ", getSimulation('" << sym.toString() << "')" << endl; |
123 |
|
124 |
// Tell ASCEND file locations and compiler commands: |
125 |
if(0 && !have_bintoken_setup){ |
126 |
cerr << "SETUP BINTOKENS..." << endl; |
127 |
|
128 |
bin_targetstem = ASCEND_TMPDIR "/asc_bintoken"; |
129 |
bin_srcname = bin_targetstem + ".c"; |
130 |
bin_objname = bin_targetstem + ".o"; |
131 |
bin_libname = bin_targetstem + ".so"; |
132 |
bin_rm = "/bin/rm"; |
133 |
#if 1 |
134 |
bin_cmd = "make -C " ASCEND_TMPDIR " -f " ASCEND_MAKEFILEDIR_1 "/Makefile.bt" \ |
135 |
" SO=" + bin_targetstem + " ASCEND_INCDIR=\"" ASCEND_INCDIR "\" ASCEND_LIBDIR=\"" ASCEND_LIBDIR "\""; |
136 |
|
137 |
cerr << "BINTOKEN COMMAND" << endl << "----" << bin_cmd << endl << "----" << endl; |
138 |
|
139 |
#else |
140 |
# define BTINCLUDES "-I" ASCEND_INCDIR |
141 |
bin_cmd = "cd " ASCEND_INCDIR " && make BTTARGET=" + bin_targetstem + " BTINCLUDES=" BTINCLUDES \ |
142 |
" -f " ASCEND_MAKEFILEDIR "/Makefile.bt " + bin_targetstem; |
143 |
#endif |
144 |
BinTokenSetOptions(bin_srcname.c_str(), bin_objname.c_str(), bin_libname.c_str() |
145 |
, bin_cmd.c_str(), bin_rm.c_str(), 1000, 1, 0); |
146 |
|
147 |
cerr << "...SETUP BINTOKENS" << endl; |
148 |
have_bintoken_setup = true; |
149 |
} |
150 |
|
151 |
cerr << "CREATING INSTANCE..." << endl; |
152 |
// Perform the instantiation (C compile etc): |
153 |
/*Instance *i = Instantiate(getInternalType()->name, sym.getInternalType(), |
154 |
0, SymChar("default_self").getInternalType()); */ |
155 |
Instance *i = SimsCreateInstance(getInternalType()->name, sym.getInternalType(), e_normal, SymChar("default_self").getInternalType()); |
156 |
|
157 |
if(i==NULL){ |
158 |
throw runtime_error("Failed to create instance"); |
159 |
} |
160 |
|
161 |
cerr << "CREATED INSTANCE " << sym << " OF " << getName() << endl; |
162 |
return Simulation(i,sym); |
163 |
} |
164 |
|
165 |
vector<Method> |
166 |
Type::getMethods() const{ |
167 |
vector<Method> v; |
168 |
struct gl_list_t *l = GetInitializationList(getInternalType()); |
169 |
if(l==NULL) return v; |
170 |
for(int i=1, end=gl_length(l); i<=end; ++i){ |
171 |
v.push_back(Method((struct InitProcedure *)gl_fetch(l,i))); |
172 |
} |
173 |
return v; |
174 |
} |
175 |
|
176 |
const bool |
177 |
Type::isRefinedSolverVar() const{ |
178 |
static const TypeDescription *solver_var_type; |
179 |
if(!solver_var_type){ |
180 |
Type t1 = Library().findType(SymChar("solver_var")); |
181 |
solver_var_type=t1.getInternalType(); |
182 |
} |
183 |
if(MoreRefined(t, solver_var_type)==t){ |
184 |
//cerr << getName() << " IS A REFINED SOLVER_VAR" << endl; |
185 |
return true; |
186 |
} |
187 |
//cerr << getName() << "IS *NOT* A REFINED SOLVER_VAR" << endl; |
188 |
return false; |
189 |
} |
190 |
|
191 |
|