# \[ANN\] Trixi.jl v0.3: SciML integration and a new modular approach for easy extension

**URL:** <https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419>\
**Category:** Package Announcements\
**Tags:** parallel, pde, numerics, physics, math\
**Created:** [November 19, 2020, 10:06am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419 "2020-11-19T10:06:42Z")\
**Posts on this page:** 20\
**Page:** 4

<div class="post-metadata">

**Author:** ![ziolai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ziolai/32/23422_2.png) [@ziolai](https://discourse.julialang.org/u/ziolai)\
**Post date:** [June 1, 2022, 8:33am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/62 "2022-06-01T08:33:15Z")

</div>

How about splitting second order in time into two coupled first order in time equations? Thx.

---

<div class="post-metadata">

**Author:** ![ranocha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ranocha/32/35588_2.png) [@ranocha](https://discourse.julialang.org/u/ranocha)\
**Post date:** [June 1, 2022, 10:08am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/63 "2022-06-01T10:08:40Z")

</div>

It’s second-order in space, not time, but the basic idea behind [Incorporate parabolic terms into `main` by jlchan · Pull Request #1149 · trixi-framework/Trixi.jl · GitHub](https://github.com/trixi-framework/Trixi.jl/pull/1149). We just need more time to polish it.

---

<div class="post-metadata">

**Author:** ![ziolai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ziolai/32/23422_2.png) [@ziolai](https://discourse.julialang.org/u/ziolai)\
**Post date:** [June 1, 2022, 11:25am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/64 "2022-06-01T11:25:51Z")

</div>

Expand second order in space as div ( grad() ) ?

---

<div class="post-metadata">

**Author:** ![ranocha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ranocha/32/35588_2.png) [@ranocha](https://discourse.julialang.org/u/ranocha)\
**Post date:** [June 1, 2022, 1:13pm UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/65 "2022-06-01T13:13:31Z")

</div>

Yes

---

<div class="post-metadata">

**Author:** ![Craig\_Hamel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/craig_hamel/32/202434_2.png) [@Craig\_Hamel](https://discourse.julialang.org/u/Craig_Hamel)\
**Post date:** [June 2, 2022, 2:42am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/66 "2022-06-02T02:42:26Z")

</div>

Is there currently or plans in the future for multi material support?

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [June 2, 2022, 3:58am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/67 "2022-06-02T03:58:14Z")

</div>

Do you mean multiphase, or multicomponent? Trixi already supports multiple components for the Euler equation (limited to an ideal gas EOS) [[ref](https://trixi-framework.github.io/Trixi.jl/stable/reference-trixi/#Trixi.CompressibleEulerMulticomponentEquations2D)]

---

<div class="post-metadata">

**Author:** ![Craig\_Hamel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/craig_hamel/32/202434_2.png) [@Craig\_Hamel](https://discourse.julialang.org/u/Craig_Hamel)\
**Post date:** [June 2, 2022, 12:46pm UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/68 "2022-06-02T12:46:12Z")

</div>

I meant multicomponent so thanks for the references!

---

<div class="post-metadata">

**Author:** ![corne00](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/corne00/32/36087_2.png) [@corne00](https://discourse.julialang.org/u/corne00)\
**Post date:** [June 7, 2022, 8:01am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/69 "2022-06-07T08:01:06Z")

</div>

Hey! Trixi uses `DifferentialEquations.jl` to solve the system of (semidiscretized) ODEs. We were wondering if Trixi also supports solving a PDE for steady state, using one of the Steady State Solvers which DifferentialEquations.jl offers ([see this page](https://diffeq.sciml.ai/stable/solvers/steady_state_solve/#Steady-State-Solvers)). Thanks in advance!

EDIT: just tried this and this seems to work. Now, suppose the steady state solver works and we want to solve the following transport equation with source term for steady state:

\partial\_t s + \partial\_x(s \, q\_1) + \partial\_y (s \, q\_2) = \frac{1}{f^2} + s(\partial\_x q\_1 + \partial\_y q\_2)

How would you advise on approximating the partial derivatives \partial\_x q\_1, \partial\_y q\_2 efficiently and how can we add the right hand side term as a source term in the `Trixi` environment?

---

<div class="post-metadata">

**Author:** ![ziolai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ziolai/32/23422_2.png) [@ziolai](https://discourse.julialang.org/u/ziolai)\
**Post date:** [June 7, 2022, 12:02pm UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/70 "2022-06-07T12:02:09Z")

</div>

What is required to extend InviscidBurgersEquation1D() to a 2D equivalent?

EDIT: a guide in defining UserDefinedEquation() would be valuable to have.

---

<div class="post-metadata">

**Author:** ![ranocha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ranocha/32/35588_2.png) [@ranocha](https://discourse.julialang.org/u/ranocha)\
**Post date:** [June 7, 2022, 3:33pm UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/71 "2022-06-07T15:33:14Z")

</div>

Depends on your `q1, q2`. If they are known analytically, just implement them like that. Otherwise, fake variable coefficients as in our tutorial [8 Adding a non-conservative equation · Trixi.jl](https://trixi-framework.github.io/Trixi.jl/stable/tutorials/adding_nonconservative_equation/).

---

<div class="post-metadata">

**Author:** ![ranocha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ranocha/32/35588_2.png) [@ranocha](https://discourse.julialang.org/u/ranocha)\
**Post date:** [June 7, 2022, 3:37pm UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/72 "2022-06-07T15:37:21Z")

</div>

The tutorial [7 Adding a new scalar conservation law · Trixi.jl](https://trixi-framework.github.io/Trixi.jl/stable/tutorials/adding_new_scalar_equations/) describes the 1D setting. If you go to 2D, you need to set the number of spatial dimensions in the subtyping appropriately. Then, you need to define

```julia
Trixi.flux(u, orientation, equations)

```

where `orientation == 1` for the x direction and `orientation == 1` for the y direction. See for example [Trixi.jl/elixir\_kpp.jl at main · trixi-framework/Trixi.jl · GitHub](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_dgsem/elixir_kpp.jl) (linked from the 1D tutorial).

Do you have specific suggestions for improving this part of our docs/tutorials? If so, could you please create a pull request (or open an issue)?

---

<div class="post-metadata">

**Author:** ![ziolai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ziolai/32/23422_2.png) [@ziolai](https://discourse.julialang.org/u/ziolai)\
**Post date:** [June 7, 2022, 4:21pm UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/73 "2022-06-07T16:21:33Z")

</div>

Thx! Will go over it and get back to you. Cheers.

---

<div class="post-metadata">

**Author:** ![corne00](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/corne00/32/36087_2.png) [@corne00](https://discourse.julialang.org/u/corne00)\
**Post date:** [June 8, 2022, 10:14am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/74 "2022-06-08T10:14:21Z")

</div>

> [@ranocha](#):
>
> Depends on your `q1, q2`. If they are known analytically, just implement them like that. Otherwise, fake variable coefficients as in our tutorial [8 Adding a non-conservative equation · Trixi.jl](https://trixi-framework.github.io/Trixi.jl/stable/tutorials/adding_nonconservative_equation/).

Thank you very much for your fast reaction and for your useful answers! Our `q1, q2` are not known analytically, we have to estimate them from the data. If we try implement the 2D Inviscid Burgers equations

\frac{\partial q\_1}{\partial t} + q\_1\frac{\partial q\_1}{\partial x} + q\_2 \frac{\partial q\_1}{\partial y} = 0

\frac{\partial q\_2}{\partial t} + q\_1\frac{\partial q\_2}{\partial x} + q\_2 \frac{\partial q\_2}{\partial y} = 0

following the implementation in tutorial 8, we get the following structure:

```julia
struct BurgersEquations2D <: AbstractEquations{2, 2} #(spatial dimensions, variables)
end

```

The conservative flux part in these equations is 0:

```julia
flux(u, orientation, equation::BurgersEquations2D) = zero(u)

```

and the non-conservative flux is defined as follows.

```julia
# This "nonconservative numerical flux" implements the nonconservative terms.
# In general, nonconservative terms can be written in the form
# g(u) ∂ₓ h(u)
# Thus, a discrete difference approximation of this nonconservative term needs
# - `u mine`: the value of `u` at the current position (for g(u))
# - `u_other`: the values of `u` in a neighborhood of the current position (for ∂ₓ h(u))

function flux_nonconservative(u_mine, u_other, orientation, equations::BurgersEquations2D)
    if orientation == 1
        q1_mine, q2_mine = u_mine
        q1_other, q2_other = u_other
        f = SVector(q1_mine * q1_other, q1_mine * q2_other)
    else orientation == 2 
        q1_mine, q2_mine = u_mine
        q1_other, q2_other = u_other
        f = SVector(q2_mine * q1_other, q2_mine * q2_other)
    end
    return f
end

```

We are not really certain about the definition of the non-conservative flux here: did we implement this in a correct way? Where in this code are the partial derivatives \partial\_x(q\_1) and \partial\_y(q\_2) estimated? Is this already done in the definition of `u_other`? Or should we do this ourselves in the definition of the non-conservative flux (and what would you recommend to do so)?

EDIT: we found out how to implement Dirichlet Boundary conditions, so removed that part of the question.

---

<div class="post-metadata">

**Author:** ![ranocha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ranocha/32/35588_2.png) [@ranocha](https://discourse.julialang.org/u/ranocha)\
**Post date:** [June 10, 2022, 4:01am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/75 "2022-06-10T04:01:45Z")

</div>

> [@corne00](#):
>
> We are not really certain about the definition of the non-conservative flux here: did we implement this in a correct way?

Looks good to me (but you should try it out with a toy example to be sure).

> [@corne00](#):
>
> Where in this code are the partial derivatives \partial\_x(q\_1) ∂x(q1)\partial\_x(q\_1) and \partial\_y(q\_2) ∂y(q2)\partial\_y(q\_2) estimated?

Not directly in this code, but it will be called in loops described in the tutorial:

```julia
du_m(D, u) = sum(D[m, l] * flux_nonconservative(u[m], u[l], 1, equations)) # orientation 1: x

```

Here, `D` is the derivative matrix. Thus, the derivative at index `m` is obtained by summing over `l` with fluxes where the first argument is fixed to `u[m]` and the second one varies with `u[l]`. Thus, the way you have written the non-conservative flux ensures that you take the derivatives of `q1_other` and `q2_other`.

---

<div class="post-metadata">

**Author:** ![SFJucelino](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@SFJucelino](https://discourse.julialang.org/u/SFJucelino)\
**Post date:** [June 18, 2022, 10:38am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/76 "2022-06-18T10:38:41Z")

</div>

Hey there, I am also one of ziolai’s student. We currently have insufficient information about the TreeMesh. I have two questions about it and I hope you guys can help me out/ point me to the right direction.

1. How do we extract/calculate the average solution over a quadrilateral element?
2. Once we know a new average over a quadrilateral element, how do we update the internal nodes?

Some more background information:  
For each timestep we currently modify our rhs before letting trixi do it’s magic. For this we first obtain the average density of crowds over each rectangular element by computing a 2D spline over the whole domain and then integrating over each rectangular element (our first mistake). Then we apply an algorithm to determine the direction of the crowd for each element. And lastly, we update the direction for each node used in our current mesh by interpolation and extrapolation (our second mistake).

We constructed our mesh as

> `TreeMesh((0, 0), (64, 64), initial_refinement_level=6, n_cells_max=10000, periodicity = false)`

which constructs a 64x64 uniform square mesh. However each square element contains 16 internal nodes and we do not know how to extract and import data to each of the internal nodes.

---

<div class="post-metadata">

**Author:** ![ranocha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ranocha/32/35588_2.png) [@ranocha](https://discourse.julialang.org/u/ranocha)\
**Post date:** [June 20, 2022, 9:24am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/77 "2022-06-20T09:24:37Z")

</div>

> [@SFJucelino](#):
>
> How do we extract/calculate the average solution over a quadrilateral element?

See for example

> <https://github.com/trixi-framework/Trixi.jl/blob/c7de88710b80d73fed6f181d1605eb897402908d/src/callbacks_stage/positivity_zhang_shu_dg2d.jl#L23-L30>

Note that this uses undocumented internal API, so be aware…

> [@SFJucelino](#):
>
> Once we know a new average over a quadrilateral element, how do we update the internal nodes?

You want to change the position of the integration nodes? You shouldn’t do that…

---

<div class="post-metadata">

**Author:** ![SFJucelino](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@SFJucelino](https://discourse.julialang.org/u/SFJucelino)\
**Post date:** [June 20, 2022, 10:01am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/78 "2022-06-20T10:01:07Z")

</div>

Thanks for your feedback. So I can calculate the average values now.

I absolutely do not want to change the position of the integration nodes. I want to update the values of the solution over a quadrilateral element, so I also need to update the values on the integration nodes.

---

<div class="post-metadata">

**Author:** ![ranocha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ranocha/32/35588_2.png) [@ranocha](https://discourse.julialang.org/u/ranocha)\
**Post date:** [June 20, 2022, 11:20am UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/79 "2022-06-20T11:20:16Z")

</div>

Ah, I see. Just scroll a bit further down in the code I linked above, to

> <https://github.com/trixi-framework/Trixi.jl/blob/c7de88710b80d73fed6f181d1605eb897402908d/src/callbacks_stage/positivity_zhang_shu_dg2d.jl#L36-L40>

This sets the nodal variables in the vector `u` at index `(i, j)` in the given `element` to `theta * u_node + (1-theta) * u_mean`, a convex combination of the current node variables and the mean value. I guess that should help you in your case?

---

<div class="post-metadata">

**Author:** ![SFJucelino](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@SFJucelino](https://discourse.julialang.org/u/SFJucelino)\
**Post date:** [June 20, 2022, 12:40pm UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/80 "2022-06-20T12:40:13Z")

</div>

Yes, this is exactly what I needed. Thanks!

---

<div class="post-metadata">

**Author:** ![ziolai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ziolai/32/23422_2.png) [@ziolai](https://discourse.julialang.org/u/ziolai)\
**Post date:** [June 20, 2022, 5:26pm UTC](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419/81 "2022-06-20T17:26:43Z")

</div>

Is there a way to obtain the spatial partial derivatives of a computed field in post-processing stage?

[Previous page](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419.md?page=3)

[Next page](https://discourse.julialang.org/t/ann-trixi-jl-v0-3-sciml-integration-and-a-new-modular-approach-for-easy-extension/50419.md?page=5)
