Skip to content

Commit

Permalink
Fixed stuff for modpar
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@1736 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Peter Aronsson committed Apr 28, 2005
1 parent 7ceb05f commit a6d507e
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 5 deletions.
187 changes: 187 additions & 0 deletions modeq/TaskGraph.rml
Expand Up @@ -136,6 +136,7 @@ with "DAE.rml"
with "Ceval.rml"
with "Values.rml"
with "Print.rml"
with "VarTransform.rml"

relation build_taskgraph: (DAELow.DAELow, int vector, int vector, int list list) => () =

Expand Down Expand Up @@ -356,11 +357,197 @@ relation build_equation:(DAELow.DAELow, int vector, int vector, int) => () =
--------------------------------
build_equation(DAELow.DAELOW(DAELow.VARIABLES(_,vararr,_,_),_,eqns,_,_,_),ass1,ass2,e) => fail

rule (* state nonlinear *)
int_sub(e,1) => e' &
DAELow.equation_nth(eqns,e') => DAELow.EQUATION(e1,e2) &
vector_nth(ass2,e') => v &
(* v == variable no solved in this equation *)
int_sub(v,1) => v' &
DAELow.var_list(vars) => varlst &
list_nth(varlst,v') => DAELow.VAR(cr,DAELow.STATE,_,_,_,_,_,_,indx,origname,_,dae_var_attr,_) &
int_string(indx) => indxs &
Util.string_append_list(["xd[",indxs,"]"]) => id &
let cr' = Exp.CREF_IDENT(id,[]) &
let varexp = Exp.CREF(cr',Exp.REAL) &
not Exp.solve(e1,e2,varexp) => _ &
build_nonlinear_equations([varexp],[Exp.BINARY(e1,Exp.SUB(Exp.REAL),e2)])
--------------------------------
build_equation(DAELow.DAELOW(vars,_,eqns,_,_,_),ass1,ass2,e)

rule print "-build_equation failed\n"
--------------------------------
build_equation(_,_,_,_) => fail
end

(** relation: build_nonlinear_equations
** builds task graph for solving non-linear equations
**)

relation build_nonlinear_equations: (Exp.Exp list, (* variables *)
Exp.Exp list) (* residuals *)
=> () =

rule list_length(vars) => size &
int_string(size) => size_str &
build_residual_code(vars,residuals) => taskname &
TaskGraphExt.new_task(taskname) => tid &
TaskGraphExt.set_tasktype(tid,3) & (* See TaskType in TaskGraph.hpp *)
build_nonlinear_equations2(tid,vars,residuals) &
Util.list_map(vars,Exp.print_exp_str) => varnames &
store_multiple_results(varnames,tid)
---------------------------------------------
build_nonlinear_equations(vars,residuals) => ()

rule print "build_nonlinear_equatins failed\n"
-----------------------------------------
build_nonlinear_equations(vars,residuals) => fail
end

(** relation: build_residual_code
** This relation takes a list of expressions and builds code for
** calculating the residuals as a string. Used for e.g. solving non-linear equations.
**)
relation build_residual_code:(Exp.Exp list, (* vars *)
Exp.Exp list) (* residuals *)
=> string =

rule make_residual_replacements(vars) => repl &
build_residual_code2(es,0,repl) => res
-------------------
build_residual_code(vars,es) => res

rule print "build_residual_code failed\n"
--------------------------
build_residual_code(_,_) => fail
end

(** relation: make_residual_replacements
** This relation makes replacement rules for variables occuring in a
** nonlinear equation system. They should be replaced by x[index], i.e.
** an unique index in the x vector.
**)
relation make_residual_replacements:(Exp.Exp list) =>
VarTransform.VariableReplacements =

rule VarTransform.empty_replacements() => repl &
make_residual_replacements2(repl,expl,0) => repl'
---------------------
make_residual_replacements(expl) => repl'
end

relation make_residual_replacements2:(VarTransform.VariableReplacements,
Exp.Exp list,
int) =>
VarTransform.VariableReplacements =
axiom make_residual_replacements2(repl,[],_) => repl

rule int_string(pos) => pstr &
Util.string_append_list(["xloc[",pstr,"]"]) => str &
VarTransform.add_replacement(repl,cr,Exp.CREF_IDENT(str,[])) => repl' &
pos + 1 => pos' &
make_residual_replacements2(repl',es,pos') => repl''
------------------------------
make_residual_replacements2(repl,Exp.CREF(cr,_)::es,pos) => repl''
end


relation build_residual_code2:(Exp.Exp list,
int,
VarTransform.VariableReplacements)
=> string =

axiom build_residual_code2([],_,_) => ""

rule VarTransform.replace_exp(e,repl) => e' &
Exp.print_exp_str(e') => s1 &
pos + 1 => pos' &
build_residual_code2(es,pos',repl) => s2 &
int_string(pos) => pstr &
Util.string_append_list(["res[",pstr,"]=",s1,";\n",s2]) => res
-------------------------
build_residual_code2(e::es,pos,repl) => res

rule print "build_residual_code2 failed\n"
-------------------------
build_residual_code2(_,_,_) => fail
end

(** relation store_multiple_results
** When a task calculates several values, this relation is used.
** It collects the names of the values into one string, separated by semicolons
** and uses that as the resultstring.
**)
relation store_multiple_results: (string list, (* var names*)
int (* task id*)
)
=> () =

rule Util.string_delimit_list(varnames,";") => result_str &
TaskGraphExt.store_result(result_str,tid,true,result_str)
-----------------------------------------
store_multiple_results(varnames,tid) => ()

rule print "store_multiple_results failed\n"
-----------------------
store_multiple_results(_,_) => fail
end


relation build_nonlinear_equations2: (int, (*task id *)
Exp.Exp list, (* vars *)
Exp.Exp list) (* residuals *)
=> () =

axiom build_nonlinear_equations2(tid,_,[]) => ()

rule (* Collect all variables and construct
a string for the residual, that can be directly used in codegen.*)
Exp.get_cref_from_exp(res) => vars1 &
Util.list_map(vars,Exp.get_cref_from_exp) => vars' &
Util.list_flatten(vars') => vars2 &
(* No duplicate elements *)
Util.list_union_p(vars1,vars2,Exp.cref_equal) => vars1' &
Util.list_setdifference_p(vars1',vars2,Exp.cref_equal) => vars &
add_edges_from_vars(vars,tid,0)
--------------------------------
build_nonlinear_equations2(tid,vars,res::residuals) => ()

rule print "build_nonlinear_equations2 failed\n" &
Exp.print_exp_str e => es & print "first residual :" &
print es & print "\n"
----------------------------
build_nonlinear_equations2(_,_,e::_) => fail
end

(** relation: add_edges_from_vars
** Adds an edge between the tasks where the variables are defined and the tasks
** given as second argument.
**)
relation add_edges_from_vars: (Exp.ComponentRef list,
int (* task *),
int (* priority*)) => () =

axiom add_edges_from_vars([],_,_) => ()

rule Exp.cref_str(v) => v_str &
TaskGraphExt.get_task(v_str) => predt &
TaskGraphExt.add_edge(predt,tid,v_str,prio) &
prio + 1 => prio' &
add_edges_from_vars(vs,tid,prio')
------------------------------
add_edges_from_vars(v::vs,tid,prio)

rule Exp.cref_str(v) => v_str &
not TaskGraphExt.get_task(v_str) => _ &
print "task " & print v_str & print " not found\n"
------------------------------------------------
add_edges_from_vars(v::vs,_,_) => fail

rule print "add_edges_from_vars failed\n"
----------------------
add_edges_from_vars(_,_,_) => fail
end

(* Build task graph for a system of equations *)
relation build_system:(DAELow.DAELow, int vector, int vector, int list) => () =

Expand Down
13 changes: 8 additions & 5 deletions modeq/modpar/Codegen.cpp
Expand Up @@ -373,7 +373,9 @@ void Codegen::generateNonLinearResidualFunc(VertexID task)
int n = out_degree(task,*m_tg);
int lr = (n*(n+1))/2;
m_cstream << TAB <<"{ double nls_x[" << n <<"];" << endl;
m_cstream << TAB <<"double nls_fvec[" << n <<"];" << endl;
m_cstream << TAB <<"double nls_diag[" << n <<"];" << endl;
m_cstream << TAB <<"double nls_r[" << lr << "];" << endl;
m_cstream << TAB <<"double nls_qtf[" << n << "];" << endl;
m_cstream << TAB <<"double nls_wa1[" << n << "];" << endl;
m_cstream << TAB <<"double nls_wa2[" << n << "];" << endl;
Expand All @@ -389,10 +391,10 @@ void Codegen::generateNonLinearResidualFunc(VertexID task)
m_cstream << TAB << "nls_x[" << i << "] = " << s.top() << ";\n" << endl;
}

m_cstream << TAB << "hybrd(residualFunc" << tasknumber << "," << n << ", &nls_x, 1e-6,"
<< "2000, " << n-1 << ", " << n-1 << ", 1e-6, &nls_diag, 1, 100.0,"
<< " -1, &info, &nfev, &nls_fjac, "<< n <<", " << lr
<<", &nls_qtf, &nls_wa1, &nls_wa2, &nls_wa3, &nls_wa4);" << endl;
m_cstream << TAB << "hybrd(residualFunc" << tasknumber << "," << n << ", nls_x, nls_fvec,1e-6,"
<< "2000, " << n-1 << ", " << n-1 << ", 1e-6, nls_diag, 1, 100.0,"
<< " -1, &info, &nfev, nls_fjac, nls_r, 1," << lr
<<", nls_qtf, nls_wa1, nls_wa2, nls_wa3, nls_wa4);" << endl;
m_cstream << TAB << "if (info == 0) { printf(\"improper input parameters to nonlinear system nuber " << tasknumber << "\");" << endl;
m_cstream << TAB << "exit(-3);" << endl;
m_cstream << TAB << " }"<< endl;
Expand Down Expand Up @@ -525,6 +527,7 @@ void Codegen::generateParallelMPIHeaders()
m_cstreamFunc << "#define BARRIER MPI_Barrier(MPI_COMM_WORLD)" << endl;

m_cstreamFunc << "#define abs(x) fabs(x)" << endl;
m_cstreamFunc << "#define hybrd hybrd_" << endl;

}

Expand All @@ -541,7 +544,7 @@ void Codegen::generateParallelMPIGlobals()
m_cstreamFunc << "void hybrd_(void (int, double *, double*, int)," << endl
<< "int, double*,double*,double,int, " << endl
<< "int,int,double,double*,int,double, " << endl
<< "int,int,int*,double *,int,double*, " << endl
<< "int,int*,int*,double *,int,double*, " << endl
<< "int, double*,double*,double*,double*,double*);" << endl;
m_cstream << "/* MPI Global variables */" << endl;
m_cstream << "MPI_Status status;" << endl;
Expand Down

0 comments on commit a6d507e

Please sign in to comment.