# A small "API" I made for ModelingToolkit/MoL, need feedback on the general API structure

**URL:** https://discourse.julialang.org/t/a-small-api-i-made-for-modelingtoolkit-mol-need-feedback-on-the-general-api-structure/107039
**Category:** Modelling & Simulations
**Tags:** question, package, sciml
**Created:** [December 2, 2023, 10:37am UTC](https://discourse.julialang.org/t/a-small-api-i-made-for-modelingtoolkit-mol-need-feedback-on-the-general-api-structure/107039 "2023-12-02T10:37:57Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Qfl3x](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/qfl3x/32/16227_2.png) [@Qfl3x](https://discourse.julialang.org/u/Qfl3x)
#### Post date: [December 2, 2023, 10:37am UTC](https://discourse.julialang.org/t/a-small-api-i-made-for-modelingtoolkit-mol-need-feedback-on-the-general-api-structure/107039/1 "2023-12-02T10:37:57Z")

</div>

> **[GitHub - Qfl3x/ModelDefiner.jl](https://github.com/Qfl3x/ModelDefiner.jl/tree/main)**
>
> main

Essentially the API is “functional”, where parameterized functions are defined which give the variables, parameters, equations…etc of the model. The goal is to have a nice easy way to do experiments that involve changing the model itself including parameter, eqs…etc based on a descriptor object.

It’s very simple and small, only consisting of this block:

```julia
struct Model
    variables::Any
    parameters::Any
    dep_vars::Any
    equations::Any
    bcs::Any
    domain::Any
    discretizer::Any
end

function (m::Model)(global_parameters, return_sys=false)
    variables = m.variables(global_parameters)
    params = m.parameters(global_parameters)
    dep_vars = m.dep_vars(global_parameters)
    equations = m.equations(global_parameters)
    bcs = m.bcs(global_parameters)
    domain = m.domain(global_parameters)
    discretizer = m.discretizer(global_parameters)

    default_params = [param => getdefault(param) for param in params]
    @named pdesys = PDESystem(equations, bcs, domain, variables, dep_vars, default_params)
    prob = discretizer(pdesys)
    if return_sys
        prob, pdesys
    else
        prob
    end
end

```

A small example below (using MoL), I used a float as the descriptor:

```julia
	using OrdinaryDiffEq
using ModelingToolkit
using MethodOfLines
using DomainSets
using Plots
using ModelDefiner

# Parameters, variables, and derivatives
@parameters t x
@variables u(..)
Dt = Differential(t)
Dxx = Differential(x)^2

function construct_eqs(i)
	function coeff(t, x)
		return i
	end
	return [Dt(u(t, x)) ~ coeff(t,x) * Dxx(u(t, x))]
end
function construct_bcs(i)
	[u(0, x) ~ cos(x),
	u(t, 0) ~ exp(-t),
	u(t, 1) ~ exp(-t) * cos(1)]
end
function construct_variables(i)
	[t, x]
end
function construct_domains(i)
	[t ∈ Interval(0.0, 1.0),
	x ∈ Interval(0.0, 1.0)]
end
function construct_depvars(i)
	return [u(t, x)]
end
function construct_discretizer(i)
	dx = 0.1
	order = 2
	discretization = MOLFiniteDifference([x => dx], t)
	
	# Convert the PDE problem into an ODE problem
	discretizer(pdesys) = discretize(pdesys,discretization)
	return discretizer
end
function construct_parameters(i)
	return []
end

m = Model(construct_variables, construct_parameters, construct_depvars, construct_eqs,
	construct_bcs, construct_domains, construct_discretizer)

prob = m(1.)
sol = solve(prob, Tsit5(), saveat=0.2)

# Plot results and compare with exact solution
discrete_x = sol[x]
discrete_t = sol[t]
solu = sol[u(t, x)]

plt = plot()

for i in eachindex(discrete_t)
	plot!(discrete_x, solu[i, :], label="Numerical, t=$(discrete_t[i])")
end
plt

```

---

<div class="post-metadata">

### Author: ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)
#### Post date: [December 2, 2023, 2:09pm UTC](https://discourse.julialang.org/t/a-small-api-i-made-for-modelingtoolkit-mol-need-feedback-on-the-general-api-structure/107039/2 "2023-12-02T14:09:16Z")

</div>

I admit I do not see or understand the usefulness of it. It is wrapping basic code in a type and function. Why not just call the code directly…?

---

<div class="post-metadata">

### Author: ![Qfl3x](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/qfl3x/32/16227_2.png) [@Qfl3x](https://discourse.julialang.org/u/Qfl3x)
#### Post date: [December 2, 2023, 2:14pm UTC](https://discourse.julialang.org/t/a-small-api-i-made-for-modelingtoolkit-mol-need-feedback-on-the-general-api-structure/107039/3 "2023-12-02T14:14:06Z")

</div>

I wanted a way to programmatically change a large PDE system. I only write the core equations, then create a struct with which I can define several systems by changing the core system; I may change the equations and thus have to add new parameters for example.

---

<div class="post-metadata">

### Author: ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)
#### Post date: [December 2, 2023, 2:21pm UTC](https://discourse.julialang.org/t/a-small-api-i-made-for-modelingtoolkit-mol-need-feedback-on-the-general-api-structure/107039/4 "2023-12-02T14:21:56Z")

</div>

I understand that, but I hardly see any “API”, much less the need for a package for that. As far as I can tell you just need the function

```julia
function some_name(i, return_sys=false)

```

as all of your constructors depend only on `i` (which itself is already extremely specific).

---

<div class="post-metadata">

### Author: ![Qfl3x](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/qfl3x/32/16227_2.png) [@Qfl3x](https://discourse.julialang.org/u/Qfl3x)
#### Post date: [December 2, 2023, 2:28pm UTC](https://discourse.julialang.org/t/a-small-api-i-made-for-modelingtoolkit-mol-need-feedback-on-the-general-api-structure/107039/5 "2023-12-02T14:28:03Z")

</div>

Thought of it more as a “wrapper” than an API.

```julia
function some_name(i, return_sys=false)

```

That’s what I’m doing (kinda) at the moment. Thought I’d make it general. I agree a package is not needed for this. I’m working on something else where I need the parameters explicitly written, so I just wrote this quickly as a wrapper.

Though you’re confirming my suspicion that this is “overdone”.
