# How to make R, C, etc. parameters in Acausal Component-Based Model (ModelingToolkit example)

**URL:** <https://discourse.julialang.org/t/how-to-make-r-c-etc-parameters-in-acausal-component-based-model-modelingtoolkit-example/66115>\
**Category:** Modelling & Simulations\
**Tags:** modelingtoolkit\
**Created:** [August 10, 2021, 9:10am UTC](https://discourse.julialang.org/t/how-to-make-r-c-etc-parameters-in-acausal-component-based-model-modelingtoolkit-example/66115 "2021-08-10T09:10:31Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [August 10, 2021, 9:10am UTC](https://discourse.julialang.org/t/how-to-make-r-c-etc-parameters-in-acausal-component-based-model-modelingtoolkit-example/66115/1 "2021-08-10T09:10:31Z")

</div>

Hello,

I am trying to move my models to the new ModelingToolkit framework and so far everything works nicely and it creates the models nicely.

For simplicity I refer here to the example as outlined in [Acausal Component-Based Modeling the RC Circuit · ModelingToolkit.jl](https://mtk.sciml.ai/stable/tutorials/acausal_components/) - my model is similar enough (more complex network, and a driving function), but the issue arises in the tutorial case as well.

Obviously the first run takes longer due to compile time, and the second run will be blisteringly fast.

However, I have not found a way yet to change the parameters (R, C) and rerun the model without incurring a recompilation.

My optimisation problem will need to change the model parameters (R and C) and rerun the model many times, so I need to find a way to make these parameters act in a similar way than when I define the ODEs manually.

I hope that it’s just my lack of understanding of how the model generation works and it is a rather simple solution.

The driving function is defined as:

```julia
systcos(t) = sin(2pi * t) < 0 ? 0 : 1 - cos(2pi * t)^2
@register systcos(t)

```

and has a similar problem. If I change the function or one of the parameters, then I need to go through the `compose`, `structural_simplify`, and `ODAEProblem` steps, which means it will recompile the `solve` step.

Edit:  
The driving function component looks like this:

```julia
function DrivenCurrent(;name, I=1.0, fun)
    @named oneport = OnePort()
    @unpack i = oneport
    ps = @parameters I = I
    eqs = [
           i ~ - I * fun(t)
          ]
    extend(ODESystem(eqs, t, [], ps; name=name), oneport)
end

```

```julia
@named source = DrivenCurrent(I=I, fun=systcos)

```

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [August 10, 2021, 7:37pm UTC](https://discourse.julialang.org/t/how-to-make-r-c-etc-parameters-in-acausal-component-based-model-modelingtoolkit-example/66115/2 "2021-08-10T19:37:23Z")

</div>

Using the example from the documentation, you can get a list of parameters from the system object:

```julia
julia> parameters(sys)
3-element Vector{Sym{Real, Base.ImmutableDict{DataType, Any}}}:
 resistor₊R
 capacitor₊C
 source₊V

```

There is a helper in the FAQ to turn this name into an index in `prob.p`, [indexof](https://mtk.sciml.ai/stable/basics/FAQ/#Getting-the-index-for-a-symbol). Then you can do

```julia
params = copy(prob.p)
params[indexof(capacitor.C, parameters(sys))] = 2.0
newprob = remake(prob; p=params)

```

`newprob` is now a copy of prob with just the parameters changed, so it re-uses all the compilation done for prob.

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [August 10, 2021, 9:02pm UTC](https://discourse.julialang.org/t/how-to-make-r-c-etc-parameters-in-acausal-component-based-model-modelingtoolkit-example/66115/3 "2021-08-10T21:02:08Z")

</div>

Thanks a lot, this does work.

But is a bit awkward just to change a parameter, in the otherwise elegant ModelingToolkit.

The `varmap_to_vars` function on the same FAQ would be more elegant. However, it gives me a `varmap_to_vars not defined` error.

Is there an equivalent to `remake` that takes the variable map, rather than an array?

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [August 10, 2021, 11:48pm UTC](https://discourse.julialang.org/t/how-to-make-r-c-etc-parameters-in-acausal-component-based-model-modelingtoolkit-example/66115/4 "2021-08-10T23:48:02Z")

</div>

You need to import `varmap_to_vars` explicitly, it is not an exported function, then you could do this:

```julia
using ModelingToolkit
using ModelingToolkit: varmap_to_vars

function reparameterize(sys, prob, parameter_map)
    params = varmap_to_vars(parameter_map, parameters(sys))
    remake(prob; p=params)
end

```

Looking at the implementation of [remake](https://github.com/SciML/SciMLBase.jl/blob/master/src/remake.jl#L36) it seems like a version that accepted maps and only updated the mapped variables wouldn’t be too hard to implement.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 11, 2021, 1:15am UTC](https://discourse.julialang.org/t/how-to-make-r-c-etc-parameters-in-acausal-component-based-model-modelingtoolkit-example/66115/5 "2021-08-11T01:15:28Z")

</div>

> [@TS-CUBED](#):
>
> But is a bit awkward just to change a parameter, in the otherwise elegant ModelingToolkit.
> 
> The `varmap_to_vars` function on the same FAQ would be more elegant. However, it gives me a `varmap_to_vars not defined` error.
> 
> Is there an equivalent to `remake` that takes the variable map, rather than an array?

I completely agree with you and it’s an open issue to fix it. We need to handle it because it’s hacky to require users to ever have to deal with the index maps.

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [August 11, 2021, 8:57am UTC](https://discourse.julialang.org/t/how-to-make-r-c-etc-parameters-in-acausal-component-based-model-modelingtoolkit-example/66115/6 "2021-08-11T08:57:44Z")

</div>

Thanks a lot. I was just starting to write my own function. But this is a lot more elegant.

I assume there will be a `remake` soon that will take the parameter maps, but for the time being this will do nicely.

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [August 11, 2021, 9:04am UTC](https://discourse.julialang.org/t/how-to-make-r-c-etc-parameters-in-acausal-component-based-model-modelingtoolkit-example/66115/7 "2021-08-11T09:04:39Z")

</div>

I don’t necessarily mind hacky solutions 🙂

But in the otherwise very elegant toolkit, it seemed a bit off.

BTW. I just want to take the opportunity to thank you and the other developers for the amazing work you do on the whole scientific modelling ecosystem. It is mindblowing how much is already possible in Julia and how consistent and streamlined everything (well, almost everything) feels.

BTW2: Also amazing: My first acausal model produces an ODAE system that solves faster than the code you optimised in another thread on here\*. I was prepared for a penalty for not deriving the ODEs myself, but that did not materialise at all. To the contrary.

- I need to double check that, but without going through the old work in detail, it seems like the new code is about 25% faster (and about 4 times faster than my initial unoptimised code).
