99# Get boundary conditions from an array
1010function get_bcs (bcs,tdomain,domain)
1111 lhs_deriv_depvars_bcs = Dict ()
12- no_bcs = size (bcs,1 )
13- for i = 1 : no_bcs
12+ num_bcs = size (bcs,1 )
13+ for i = 1 : num_bcs
1414 var = operation (bcs[i]. lhs)
1515 if var isa Sym
1616 var = var. name
@@ -69,10 +69,10 @@ function discretize_2(input,deriv_order,approx_order,dx,X,len,
6969 # input parameters of each derivative
7070 approx_order = 1
7171 L = UpwindDifference (deriv_order,approx_order,dx[i],len[i]- 2 ,- 1 )
72- expr = :(- 1 * ($ L* Q [$ j]* u[:,$ j]))
72+ expr = :(- 1 * ($ L* all_bcs [$ j]* u[:,$ j]))
7373 elseif deriv_order == 2
7474 L = CenteredDifference (deriv_order,approx_order,dx[i],len[i]- 2 )
75- expr = :($ L* Q [$ j]* u[:,$ j])
75+ expr = :($ L* all_bcs [$ j]* u[:,$ j])
7676 end
7777 end
7878 return expr
@@ -81,7 +81,6 @@ function discretize_2(input,deriv_order,approx_order,dx,X,len,
8181 push! (deriv_var,var)
8282 return discretize_2 (input. args[1 ],deriv_order+ 1 ,approx_order,dx,X,
8383 len,deriv_var,dep_var_idx,indep_var_idx)
84- pop! (deriv_var,var)
8584 else
8685 name = nameof (operation (input))
8786 if size (input. args,1 ) == 1
@@ -127,13 +126,13 @@ function DiffEqBase.discretize(pdesys::PDESystem,discretization::MOLFiniteDiffer
127126
128127 tdomain = 0.0
129128 indep_var_idx = Dict ()
130- no_indep_vars = size (pdesys. domain,1 )
131- domain = Array {Any} (undef,no_indep_vars )
132- dx = Array {Any} (undef,no_indep_vars )
133- X = Array {Any} (undef,no_indep_vars )
134- len = Array {Any} (undef,no_indep_vars )
129+ num_indep_vars = size (pdesys. domain,1 )
130+ domain = Array {Any} (undef,num_indep_vars )
131+ dx = Array {Any} (undef,num_indep_vars )
132+ X = Array {Any} (undef,num_indep_vars )
133+ len = Array {Any} (undef,num_indep_vars )
135134 k = 0
136- for i = 1 : no_indep_vars
135+ for i = 1 : num_indep_vars
137136 var = nameof (pdesys. domain[i]. variables)
138137 indep_var_idx[var] = i
139138 domain[i] = pdesys. domain[i]. domain
@@ -166,8 +165,8 @@ function DiffEqBase.discretize(pdesys::PDESystem,discretization::MOLFiniteDiffer
166165 else
167166 eqs = pdesys. eq
168167 end
169- no_dep_vars = size (eqs,1 )
170- for j = 1 : no_dep_vars
168+ num_dep_vars = size (eqs,1 )
169+ for j = 1 : num_dep_vars
171170 input = eqs[j]. lhs
172171 op = operation (input)
173172 if op isa Sym
@@ -181,49 +180,46 @@ function DiffEqBase.discretize(pdesys::PDESystem,discretization::MOLFiniteDiffer
181180 for (var,j) in dep_var_idx
182181 aux = discretize_2 ( eqs[j]. rhs,0 ,approx_order,dx,X,len,
183182 [],dep_var_idx,indep_var_idx)
184- # TODO : is there a better way to convert an Expr into a Function?
185- dep_var_disc[var] = @eval (Q,u,t) -> $ aux
183+ dep_var_disc[var] = @RuntimeGeneratedFunction (:((all_bcs,u,t) -> $ aux))
186184 end
187185
188186 # ## Declare and define boundary conditions ################################
189187
190188 # TODO : extend to Neumann BCs and Robin BCs
191189 lhs_deriv_depvars_bcs = get_bcs (pdesys. bcs,tdomain,domain[2 ])
192190 t = 0.0
193- u_t0 = Array {Float64} (undef,len[2 ]- 2 ,no_dep_vars )
194- u_x0 = Array {Any} (undef,no_dep_vars )
195- u_x1 = Array {Any} (undef,no_dep_vars )
196- Q = Array {RobinBC} (undef,no_dep_vars )
191+ u_ic = Array {Float64} (undef,len[2 ]- 2 ,num_dep_vars )
192+ u_left_bc = Array {Any} (undef,num_dep_vars )
193+ u_right_bc = Array {Any} (undef,num_dep_vars )
194+ all_bcs = Array {RobinBC} (undef,num_dep_vars )
197195
198196 for var in keys (dep_var_idx)
199197 j = dep_var_idx[var]
200198 bcs = lhs_deriv_depvars_bcs[var]
201199
202- g = eval (:((x,t) -> $ (bcs[1 ])))
203- u_t0 [:,j] = @eval $ g .( $ ( X[2 ][2 : len[2 ]- 1 ]), $ t)
200+ ic = @RuntimeGeneratedFunction (:((x,t) -> $ (bcs[1 ])))
201+ u_ic [:,j] = ic .( X[2 ][2 : len[2 ]- 1 ], t)
204202
205- u_x0[j] = @eval (x,t) -> $ (bcs[2 ])
206- u_x1[j] = @eval (x,t) -> $ (bcs[3 ])
207-
208- a = Base. invokelatest (u_x0[j],X[2 ][1 ],0.0 )
209- b = Base. invokelatest (u_x1[j],last (X[2 ]),0.0 )
210- Q[j] = DirichletBC (a,b)
203+ left_bc_fn = :((x, t) -> $ (bcs[2 ]))
204+ right_bc_fn = :((x, t) -> $ (bcs[3 ]))
205+ u_left_bc[j] = @RuntimeGeneratedFunction (left_bc_fn)
206+ u_right_bc[j] = @RuntimeGeneratedFunction (right_bc_fn)
211207 end
212208
213209 # ## Define the discretized PDE as an ODE function #########################
214210
215211 function f (du,u,p,t)
216212
217213 # Boundary conditions can vary with respect to time
218- for j in 1 : no_dep_vars
219- a = Base . invokelatest (u_x0 [j], X[2 ][1 ],t )
220- b = Base . invokelatest (u_x1 [j], last (X[2 ]),t )
221- Q [j] = DirichletBC (a,b )
214+ for j in 1 : num_dep_vars
215+ left_bc_eval = u_left_bc [j]( X[2 ][1 ],0.0 )
216+ right_bc_eval = u_right_bc [j]( last (X[2 ]),0.0 )
217+ all_bcs [j] = DirichletBC (left_bc_eval,right_bc_eval )
222218 end
223219
224220 for (var,disc) in dep_var_disc
225221 j = dep_var_idx[var]
226- res = Base . invokelatest ( disc,Q ,u,t)
222+ res = disc (all_bcs ,u,t)
227223 if haskey (lhs_deriv_depvars,var)
228224 du[:,j] = res
229225 else
@@ -234,5 +230,5 @@ function DiffEqBase.discretize(pdesys::PDESystem,discretization::MOLFiniteDiffer
234230 end
235231
236232 # Return problem ##########################################################
237- return PDEProblem (ODEProblem (f,u_t0 ,(tdomain. lower,tdomain. upper),nothing ),Q ,X)
233+ return PDEProblem (ODEProblem (f,u_ic ,(tdomain. lower,tdomain. upper),nothing ),all_bcs ,X)
238234end
0 commit comments