Skip to content

Commit

Permalink
Fixed bugs with external functions in simulation code. Fixed undercon…
Browse files Browse the repository at this point in the history
…strained initial equations, etc.

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@1887 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Peter Aronsson committed Aug 31, 2005
1 parent 8e34775 commit 29bab25
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 44 deletions.
5 changes: 3 additions & 2 deletions Compiler/Ceval.rml
Expand Up @@ -1197,7 +1197,7 @@ end
DAELow.lower(dae) => dlow &
DAELow.incidence_matrix(dlow) => m &
DAELow.transpose_matrix(m) => mT &
DAELow.matching_algorithm(dlow,m,mT,DAELow.INDEX_REDUCTION)
DAELow.matching_algorithm(dlow,m,mT,(DAELow.INDEX_REDUCTION,DAELow.EXACT))
=> (ass1,ass2,dlow',m,mT) &
DAELow.strong_components(m,mT,ass1,ass2) => (comps) &
DAELow.translate_dae (dlow') => indexed_dlow &
Expand Down Expand Up @@ -1241,7 +1241,7 @@ end
DAELow.lower(dae) => dlow &
DAELow.incidence_matrix(dlow) => m &
DAELow.transpose_matrix(m) => mT &
DAELow.matching_algorithm(dlow,m,mT,DAELow.INDEX_REDUCTION)
DAELow.matching_algorithm(dlow,m,mT,(DAELow.INDEX_REDUCTION,DAELow.EXACT))
=> (ass1,ass2,dlow',m,mT) &
DAELow.strong_components(m,mT,ass1,ass2) => (comps) &
DAELow.translate_dae (dlow') => indexed_dlow &
Expand Down Expand Up @@ -2629,6 +2629,7 @@ relation ceval_generate_function : (Env.Env, Absyn.Path) => () =
Print.print_buf "{\n\n if (argc != 3)\n" &
Print.print_buf "{\n fprintf(stderr,\"# Incorrect number of arguments\\n\");\n" &
Print.print_buf "return 1;\n }\n" &
Print.print_buf "_" &
Print.print_buf pathstr &
Print.print_buf "_read_call_write(argv[1],argv[2]);\n return 0;\n}\n" &
(*
Expand Down
88 changes: 73 additions & 15 deletions Compiler/Codegen.rml
Expand Up @@ -623,6 +623,7 @@ relation generate_function : DAE.Element => CFunction list =

(* Modelica functions *)
rule generate_function_name fpath => fn_name_str &
string_append("_",fn_name_str) => fn_name_str &
Debug.fprintl ("cgtr", ["generating function ", fn_name_str, "\n"]) &

Debug.fprintln ("cgtrdumpdae3", "Dumping DAE:") &
Expand Down Expand Up @@ -650,6 +651,7 @@ relation generate_function : DAE.Element => CFunction list =

(* External functions *)
rule generate_function_name fpath => fn_name_str &
string_append("_",fn_name_str) => fn_name_str &
Debug.fprintl ("cgtr", ["generating external function ", fn_name_str, "\n"]) &
let DAE.EXTERNALDECL(extfnname,extargs,extretarg,lang) = extdecl &

Expand All @@ -668,13 +670,14 @@ relation generate_function : DAE.Element => CFunction list =
generate_ext_function_name (extfnname, lang) => extfnname' &
generate_ext_function_args (extargs, lang) => arg_strs &
c_make_function_decl(retstr,extfnname',struct_strs,arg_strs) => func_decl &
generate_read_call_write_external(fn_name_str,outvars,retstructtype,invars,extdecl,bivars) => rcw_fn
generate_read_call_write_external(fn_name_str,outvars,retstructtype,invars,extdecl,bivars) => rcw_fn &
generate_external_wrapper_call(fn_name_str,outvars,retstructtype,invars,extdecl,bivars,tp) => ext_decl
-----------------------------------------------------------------------
generate_function DAE.EXTFUNCTION(fpath,
DAE.DAE(orgdae),
(Types.T_FUNCTION(args,restype),_),
tp as (Types.T_FUNCTION(args,restype),_),
extdecl)
=> [func_decl,rcw_fn]
=> [func_decl,rcw_fn,ext_decl]

rule generate_functions_elist daelist => cfns
----------------------
Expand Down Expand Up @@ -1190,8 +1193,12 @@ relation generate_ext_function_arg : DAE.ExtArg => string =
rule generate_type_external ty => res
-----------------------------------
generate_ext_function_arg DAE.EXTARGEXP(exp, ty) => res

axiom generate_ext_function_arg DAE.EXTARGSIZE(_,_,_,_) => "size_t"

rule comp_ref_cstr cr => (name,_) &
Exp.print_exp_str exp => e_str &
Util.string_append_list(["size_t ",name,"_",e_str]) => res
--------------------------------
generate_ext_function_arg DAE.EXTARGSIZE(cr,_,_,exp) => res

rule Print.print_buf "#-- generate_ext_function_arg failed\n"
----------------------------------------------------
Expand Down Expand Up @@ -2294,7 +2301,7 @@ relation generate_expression : (Exp.Exp, int) => (CFunction,string,int) =
c_add_variables(cfn1,[tdecl]) => cfn2 &

Util.string_delimit_list(vars1,", ") => args_str &
Util.string_append_list([tvar," = ",fn_name,"(", args_str,");"])
Util.string_append_list([tvar," = _",fn_name,"(", args_str,");"])
=> stmt &

c_add_statements(cfn2,[stmt]) => cfn &
Expand All @@ -2312,7 +2319,7 @@ relation generate_expression : (Exp.Exp, int) => (CFunction,string,int) =
c_add_variables(cfn1,[tdecl]) => cfn2 &

Util.string_delimit_list(vars1,", ") => args_str &
Util.string_append_list([tvar," = ",fn_name,"(", args_str,");"]) => stmt &
Util.string_append_list([tvar," = _",fn_name,"(", args_str,");"]) => stmt &

c_add_statements(cfn2,[stmt]) => cfn
-------------------------
Expand Down Expand Up @@ -3405,9 +3412,9 @@ end
** and writing result to file.
**)

relation generate_read_call_write : (string,
relation generate_read_call_write : (string, (* external function name *)
DAE.Element list,
string,
string, (* return type *)
DAE.Element list)
=> CFunction =

Expand Down Expand Up @@ -3445,18 +3452,69 @@ relation generate_read_call_write : (string,

end

(** relation: generate_external_wrapper_call
**
** This relation generates the wrapper function for external functions
** when used in e.g. simulation code.
**)

relation generate_external_wrapper_call:(string, (* function name *)
DAE.Element list, (* output variables *)
string, (* return type *)
DAE.Element list, (* input variables*)
DAE.ExternalDecl, (* external declaration*)
DAE.Element list, (* bidirectional vars *)
Types.Type) (* function type *)
=> CFunction =
rule let tnr = 1 &
Util.list_map(args,generate_function_arg) => arg_strs &

c_make_function(retstr,fnname,[],
arg_strs) => cfn1 &
Util.string_append_list([retstr," out;"]) => out_decl &

c_add_variables(cfn1, [out_decl]) => cfn1' &
generate_var_decls(invars,is_rcw_input,tnr)
=> (cfn31,tnr_invars1) &
generate_var_inits(invars,is_rcw_input,tnr_invars1,"")
=> (cfn32,tnr_invars) &
generate_var_decls(bivars,is_rcw_bidir,tnr_invars)
=> (cfn33, tnr_bivars1) &
generate_var_inits(bivars,is_rcw_bidir,tnr_bivars1,"")
=> (cfn34, tnr_bivars) &

c_merge_fns([cfn1',cfn31, cfn32, cfn33, cfn34]) => cfn3 &

list_append (invars, outvars) => vars' &
list_append (vars', bivars) => vars &

generate_ext_call (vars, extdecl, tnr_bivars) => (extcall, tnr_extcall) &

c_merge_fns([cfn1',extcall]) => cfn' &

c_add_cleanups(cfn', ["return out;"]) => cfn
------------------------------------------------------
generate_external_wrapper_call(fnname,outvars,retstr,invars,
extdecl as DAE.EXTERNALDECL(extfnname,extargs,extretarg,lang),bivars,(Types.T_FUNCTION(args,restype),_)) => cfn

rule Print.print_buf "#-- generate_external_wrapper_call failed\n"
----------------------------------------------------------------
generate_external_wrapper_call (_,_,_,_,_,_,_) => fail

end

(** relation: generate_read_call_write_external
**
** Generates code for reading input parameters from file, executing function
** and writing result to file fo external functions.
**)

relation generate_read_call_write_external : (string,
DAE.Element list,
string,
DAE.Element list,
DAE.ExternalDecl,
DAE.Element list)
relation generate_read_call_write_external : (string, (* function name *)
DAE.Element list, (* output variables *)
string, (* return type *)
DAE.Element list, (* input variables*)
DAE.ExternalDecl, (* external declaration*)
DAE.Element list) (* bidirectional vars *)
=> CFunction =


Expand Down
4 changes: 4 additions & 0 deletions Compiler/DAE.rml
Expand Up @@ -2606,6 +2606,10 @@ relation get_named_function : (Absyn.Path, Element list) => Element list =
-----------------------------------------
get_named_function (path, (el as FUNCTION(elpath, _, _))::rest) => [el]

rule ModUtil.path_equal (path, elpath) => true
-----------------------------------------
get_named_function (path, (el as EXTFUNCTION(elpath, _, _,_))::rest) => [el]

rule get_named_function (path, rest) => res
-----------------------------------------
get_named_function (path, el::rest) => res
Expand Down
49 changes: 33 additions & 16 deletions Compiler/DAELow.rml
Expand Up @@ -262,7 +262,16 @@ datatype EquationArray = EQUATION_ARRAY of int * (* no. elements *)
* means that a nonlinear system of equations needs to be
* solved *)

datatype IndexReduction = INDEX_REDUCTION | NO_INDEX_REDUCTION
datatype IndexReduction = INDEX_REDUCTION (* Use index reduction during matching*)
| NO_INDEX_REDUCTION (* do not use index reduction during matching *)

datatype EquationConstraints = ALLOW_UNDERCONSTRAINED (* for e.g. initial eqns.
where not all variables
have a solution *)
| EXACT (*exact as many equations
as variables *)

type MatchingOptions = (IndexReduction*EquationConstraints)

relation dump: DAELow => ()
relation dump_vars: Var list => ()
Expand All @@ -284,7 +293,7 @@ datatype IndexReduction = INDEX_REDUCTION | NO_INDEX_REDUCTION

relation dump_matching: (int vector) => ()

relation matching_algorithm: (DAELow,IncidenceMatrix, IncidenceMatrixT,IndexReduction)
relation matching_algorithm: (DAELow,IncidenceMatrix, IncidenceMatrixT,MatchingOptions)
=> (int vector,(* var solved in eqn*)
int vector, (* eqn solves var *)
DAELow,
Expand Down Expand Up @@ -3345,29 +3354,33 @@ end
** assignments is returned as a vector of variable indices, as well as its
** inverse, i.e. which equation a variable is solved in as a vector of
** equation indices.
** MatchingOptions contain options given to the algorithm.
** - if index reduction should be used or not.
** - if the equation system is allowed to be under constrained or not
** which is used when generating code for initial equations.
**)

relation matching_algorithm: (DAELow,IncidenceMatrix, IncidenceMatrixT,
IndexReduction)
MatchingOptions)
=> (int vector(* vector of equation indices*) ,
int vector (* vector of variable indices*),
DAELow,IncidenceMatrix, IncidenceMatrixT) =

rule check_matching(dae) &
rule check_matching(dae,match_opts) &
array_length(m) => nvars &
array_length(mt) => neqns &
int_gt(nvars,0) => true &
int_gt(neqns,0) => true &
int_add(nvars,nvars) => memsize &
assignments_create(nvars,memsize,0) => assign1 &
assignments_create(nvars,memsize,0) => assign2 &
matching_algorithm2(dae,m,mt,nvars,neqns,1,assign1,assign2,indx_red)
matching_algorithm2(dae,m,mt,nvars,neqns,1,assign1,assign2,match_opts)
=> (ass1, ass2,dae,m,mt) &

assignments_vector(ass1) => vec1 &
assignments_vector(ass2) => vec2
--------------------------
matching_algorithm(dae,m,mt,indx_red) => (vec1,vec2,dae,m,mt)
matching_algorithm(dae,m,mt,match_opts) => (vec1,vec2,dae,m,mt)

rule (*Print.print_error_buf "#Error, matching failed\n" &*)
list_vector([]) => v1 &
Expand All @@ -3383,13 +3396,16 @@ end
** Checks that the matching is correct, i.e. that the number of variables
** is the same as the number of equations. If not, the relation fails and
** prints an error message.
** If matching options indicate that underconstrained systems are ok, no
** check is performed.
**)
relation check_matching : (DAELow) => () =
relation check_matching : (DAELow,MatchingOptions) => () =
axiom check_matching(_,(_,ALLOW_UNDERCONSTRAINED)) => ()

rule equation_size(eqns) => esize &
int_eq(esize,vars_size) => true
------------------
check_matching(DAELOW(VARIABLES(_,_,_,_,vars_size),_,eqns,_,_,_,_))
check_matching(DAELOW(VARIABLES(_,_,_,_,vars_size),_,eqns,_,_,_,_),_)
=> ()

rule equation_size(eqns) => esize &
Expand All @@ -3401,7 +3417,7 @@ relation check_matching : (DAELow) => () =
Print.print_error_buf " variables and " & Print.print_error_buf esize_str &
Print.print_error_buf " equations\n"
------------------
check_matching(DAELOW(VARIABLES(_,_,_,_,vars_size),_,eqns,_,_,_,_))
check_matching(DAELOW(VARIABLES(_,_,_,_,vars_size),_,eqns,_,_,_,_),_)
=> fail

rule equation_size(eqns) => esize &
Expand All @@ -3413,11 +3429,11 @@ relation check_matching : (DAELow) => () =
Print.print_error_buf " variables and " & Print.print_error_buf esize_str &
Print.print_error_buf " equations\n"
------------------
check_matching(DAELOW(VARIABLES(_,_,_,_,vars_size),_,eqns,_,_,_,_)) => fail
check_matching(DAELOW(VARIABLES(_,_,_,_,vars_size),_,eqns,_,_,_,_),_) => fail

rule Debug.fprint("failtrace", "-check_matching failed\n")
--------------------
check_matching(_) => fail
check_matching(_,_) => fail
end

(** relation: assignments_vector
Expand Down Expand Up @@ -3542,7 +3558,7 @@ relation matching_algorithm2: (DAELow,IncidenceMatrix, IncidenceMatrixT
,int (* current var*)
,Assignments(*assignments, array of eqn indices*)
,Assignments,(*assignments, array of var indices*)
IndexReduction) (* index reduction or not*)
MatchingOptions) (* options for matching alg.*)
=> (Assignments, (* assignments, array of equation indices*)
Assignments, (* assignments, list of variable indices *)
DAELow,
Expand All @@ -3559,10 +3575,10 @@ relation matching_algorithm2: (DAELow,IncidenceMatrix, IncidenceMatrixT
rule int_add(i,1) => i' &
DAEEXT.init_marks(nv,nf) &(* eMark(i)=vMark(i)=false *)
path_found(m,mt,i,ass1,ass2) => (ass1',ass2') &
matching_algorithm2(dae,m,mt,nv,nf,i',ass1',ass2',index_red)
matching_algorithm2(dae,m,mt,nv,nf,i',ass1',ass2',match_opts)
=> (ass1'',ass2'',dae,m,mt)
----------------------------------------------------------------
matching_algorithm2(dae,m,mt,nv,nf,i,ass1,ass2,index_red)
matching_algorithm2(dae,m,mt,nv,nf,i,ass1,ass2,match_opts)
=> (ass1'',ass2'',dae,m,mt)

rule (* path_found failed, Try index reduction using dummy derivatives.
Expand Down Expand Up @@ -3594,10 +3610,11 @@ relation matching_algorithm2: (DAELow,IncidenceMatrix, IncidenceMatrixT
int_sub(nv',nv) => nvd &
assignments_expand(ass1,nvd) => ass1' &
assignments_expand(ass2,nvd) => ass2' &
matching_algorithm2(dae,m,mt,nv',nf',i,ass1',ass2',INDEX_REDUCTION)
matching_algorithm2(dae,m,mt,nv',nf',i,ass1',ass2',
(INDEX_REDUCTION,eq_cons))
=> (ass1'',ass2'',dae,m,mt)
------------------------
matching_algorithm2(dae,m,mt,nv,nf,i,ass1,ass2,INDEX_REDUCTION)
matching_algorithm2(dae,m,mt,nv,nf,i,ass1,ass2,(INDEX_REDUCTION,eq_cons))
=> (ass1'',ass2'',dae,m,mt)

rule (* When index reduction also fails, the model is structurally
Expand Down
2 changes: 0 additions & 2 deletions Compiler/Inst.rml
Expand Up @@ -473,10 +473,8 @@ relation instantiate_class_implicit : (SCode.Program, SCode.Path)
inst_class_decls(env,cdecls,path)=> (env',_) &
Lookup.lookup_class(env',path,true)
=> (cdef as SCode.CLASS(n,_,_,_,_), env'') &
print "found class to instantiate implicit\n" &
implicit_instantiation(env'',Types.NOMOD,Prefix.NOPRE,[],cdef,[],false)
=> (env,dae)
& print "instantiated class\n"
--------------------------------------------
instantiate_class_implicit(cdecls as _::_, path as Absyn.QUALIFIED(name,_))
=> (DAE.DAE(dae),env)
Expand Down
2 changes: 1 addition & 1 deletion Compiler/Main.rml
Expand Up @@ -468,7 +468,7 @@ relation optimize_dae: (SCode.Program, DAE.DAElist, DAE.DAElist, Absyn.Path) =>
& DAELow.transpose_matrix(m) => mT
& Debug.fcall("bltdump", DAELow.dump_incidence_matrix, m)
& Debug.fcall("bltdump", DAELow.dump_incidence_matrix_t, mT)
& DAELow.matching_algorithm(dlow,m,mT,DAELow.INDEX_REDUCTION)
& DAELow.matching_algorithm(dlow,m,mT,(DAELow.INDEX_REDUCTION,DAELow.EXACT))
=> (v1,v2,dlow',m,mT)
& Debug.fcall("bltdump", DAELow.dump_incidence_matrix, m)
& Debug.fcall("bltdump", DAELow.dump_incidence_matrix_t, mT)
Expand Down

0 comments on commit 29bab25

Please sign in to comment.