j-fu / voronoifvm.jl Goto Github PK
View Code? Open in Web Editor NEWSolution of nonlinear multiphysics partial differential equation systems using the Voronoi finite volume method
License: MIT License
Solution of nonlinear multiphysics partial differential equation systems using the Voronoi finite volume method
License: MIT License
As requested in #18
Hello Jürgen Fuhrmann,
I'm very interested in your package for the simulation of the coupled transport processes in a flow battery cell. For this I'd like to use internal jump conditions: For simplicity let's consider a one-dimensional Laplace equation with Dirichlet conditions at the domain boundaries. What is the recommended way to enforce a jump in the function value (for some prescribed value) at some location x* in the domain, whereas the left and right limits of the derivative at x* are identical?
Looking through the examples it seems that this could be achieved using a DiscontinuousQuantity. However, currently it is unclear to me how to interpret the resulting discretization and achieve a prescribed jump in the solution.
Thanks for developing this very nice package.
Setting react =0.0
in
turns the dspec
the DiscontinuousQuantity
in continuous one:
I'd expect to see some sort of a step function -- depending on the initial condition.
@j-fu @dilaraabdel is this behavior as intended?
I plan to drop support of Julia 1.6 for VoronoiFVM.jl and all related packages (e.g. ExtendableGrids etc.). The minimal Julia version to be supported will be 1.9 with its Extension mechanism.
Many other packages did this step, e.g. meanwhile, LinearSolve.jl (a dependency of VoronoiFVM) requires 1.10 as minimal version, which means that Pkg will resolve to older versions of LinearSolve.jl when a lower version is needed.
Probably, Julia 1.10 will become the new LTS (longtime support) release and replace 1.6 in this role.
In general, it is advisable to work with the current stable releases of Julia.
I would like to compute the steady-state of a particle density ρ
, that is moved under a velocity field v
and is produced at a rate s
.
-div(vρ) + s = 0
The boundary condition is that particles are free to leave the simulation volume at boundaries, but no particles can enter the simulation that way. (Does this boundary condition have a name?)
I tried
using VoronoiFVM
function flux!(f,u,edge)
v = 1.0
h = meas(edge)
f[1] = if v > 0
v*u[1, 1] * h
else
v*u[1, 2] * h
end
end
function source!(out, node)
out[1] = 1
end
physics=VoronoiFVM.Physics(num_species=1,
flux=flux!,
source=source!,
)
X = range(0, stop=1, length=5)
grid=VoronoiFVM.Grid(collect(X))
sys=VoronoiFVM.System(grid,physics)
ispec = 1
enable_species!(sys,ispec,[1])
boundary_neumann!(sys, ispec, 1, 0.0) # this should ensure no particles enter from the left
inival=unknowns(sys,inival=0)
solution=unknowns(sys)
solve!(solution,inival,sys)
But it errors:
ERROR: LoadError: LinearAlgebra.SingularException(0)
How to solve this problem with VoronoiFVM.jl
?
The above is a simplified example of an issue I face. Really I would like to simulate an ionization chamber. The equations are:
E = -grad(φ)
ε*div(E) = - ρₑ - ρ₋ + ρ₊
∂ₜρₑ = div(μₑ(E)*E*ρₑ) + Rₑ(E,ρₑ,ρ₋,ρ₊) + sₑ
∂ₜρ₋ = div(μ₋(E)*E*ρ₋) + R₋(E,ρₑ,ρ₋,ρ₊) + s₋
∂ₜρ₊ = -div(μ₊(E)*E*ρ₊) + R₊(E,ρₑ,ρ₋,ρ₊) + s₊
The unknowns are (φ, E, ρₑ, ρ₋, ρ₊ )
. The other functions/constants are known. I am interested in both time evolution and steady-state (∂ₜρᵢ = 0).
The boundary decomposes into parts that are conductive Γ₁ and parts that are not Γ₂:
∂Ω = Γ₁ ∪ Γ₂
The boundary condition for the charge carriers ρᵢ is:
I wanted to look at a range of parameters on the same system, so I tried using Threads.@threads
on the for loop, and I got the following error:
nested task error: Allocations in assembly loop: cells: 208, bfaces: 0
See the documentation of `check_allocs!` for more information
It runs just fine if I run it in series, but I thought I would try to speed up the process any way I could. Is this something VoronoiFVM cannot handle (yet), or did I fumble somewhere? Thank you!
In two functions in src/vfvm_assemblydata.jl the iparam
-for-loop to be moved into some other loops such that all used variables are defined.
line 337: @inline function assemble_res_jac(edge...
the iparam
-for-loop has to be inside the isnodespecies(system, ispec, K)
if-statement, otherwise idofL
is not defined.
line 400: @inline function assemble_res_jac(bedge...
the iparam
-for-loop has to be inside idofK
for-loop and the isnodespecies(system, ispec, K)
if-statement, otherwise idofK
and idofL
are not defined.
There have been issues with precompilation MacOS Intel getting stuck.
After some tests which showed no significant influence on loading time (1.10 beta, Linux) I switched off precompilation until I better understand what could be the issues and how much precompilation can help at all. See #80
Hi,
I would like to use your package to solve an equation of the form
d/dt P = d2/dx2 P + d/dx( F(x,y) P) + d/dy (G(x,y) P)
with Dirichlet BC. However, I am struggling writing the flux function mainly because the "Laplacian" only applies to the x variable. Can you give me a hint please?
Thank you
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
If you'd like for me to do this for you, comment TagBot fix
on this issue.
I'll open a PR within a few hours, please be patient!
The examples need some reformatting, such that the comments inside code (e.g. inside of module
s) are not becoming text (cf. fredrikekre/Literate.jl#37).
This hurts copy-pasteability a bit.
For some post processing purposes, it could be beneficial to provide a function which returns the nodal values
My suggestion would be to provide something like a bvals
function in vfvm_system.jl
.
A quick and dirty draft could look like this:
function bvalinds(system::VoronoiFVM.AbstractSystem{Tv,Ti}, regions::AbstractVector) where {Tv,Ti}
TA=Array{Ti}
bvals=Array{TA}(undef,length(regions))
grid=system.grid
for (i,ireg) in enumerate(regions)
catBFaces=findall(grid[BFaceRegions].==ireg)
catBFaceLeftNodes=grid[BFaceNodes][1,catBFaces]
catBFaceRightNodes=grid[BFaceNodes][2,catBFaces]
BNodes=union(catBFaceLeftNodes,catBFaceRightNodes)
bvals[i]=BNodes
end
return bvals
end
The user could then simply call a solution vector as indexed by the boundary face regions, e.g. if we want to extract the boundary values of a solution U
associated with a system system
on regions [1,3]
, we would simply execute
>bvals=bvalinds(system,[1,3]);
>U[1,bvals[1]] #boundary values for face region 1
>U[1,bvals[2]] #boundary values for face region 3
On the spot, I am not quite sure yet how we would extend that for arbitrary species and boundary species though and it might be worth thinking about if we should preserve some kind of ordering or orientation of the boundary nodes.
Hi,
I have a 2.5D (cylindrical axisymmetric) domain, over which I solve Laplace's equation for heat transfer. I have obtained the temperature gradient by doing:
∇T = nodeflux(sys, T)
, which returns a matrix with the same dimensions as T.
I would like to obtain the temperature gradient on the West boundary, but am unsure what indexing yields this. I have surmised that grid[BFaceNodes]
, grid[BFaceEdges]
or grid[BEdgeNodes]
contain the indices of all boundary nodes.
Further to this, once I have obtained ∇T_west
, would I be able to simply input this as a boundary condition to another PDE on the same domain? For example:
boundary_neumann!(f, p, bnode; species = 1, region = 4, value = ∇T_west)
I wanted to pass parameters with something like
data = (D=1.0,)
phys = VoronoiFVM.Physics(flux=flux!,data=data)
but I get an error
MethodError: no method matching isdata(::NamedTuple{(:D,), Tuple{Float64}})
Closest candidates are:
isdata(::VoronoiFVM.NoData) at /home/mjyshin/.julia/packages/VoronoiFVM/sd93r/src/vfvm_physics.jl:28
isdata(::VoronoiFVM.AbstractData) at /home/mjyshin/.julia/packages/VoronoiFVM/sd93r/src/vfvm_physics.jl:29
Stacktrace:
[1] VoronoiFVM.Physics(; num_species::Int64, data::NamedTuple{(:D,), Tuple{Float64}}, flux::Function, reaction::Function, storage::Function, source::Function, breaction::Function, bstorage::Function)
@ VoronoiFVM ~/.julia/packages/VoronoiFVM/sd93r/src/vfvm_physics.jl:121
[2] top-level scope
@ In[77]:1
[3] eval
@ ./boot.jl:360 [inlined]
[4] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1094
I have not gotten this error before, so I was wondering if there's something with a recent update that might have prompted it. Thank you in advance!
Could you please help to solve it in Julia with VoronoiFVM?
I can do it in ansys fluent , but I want learn Julia.
oscillating flow through pipe (2D)
it is a transient compressible, viscous 2D flow problem. also, conventional heat transfer considers from the pipe wall.
it is a convention diffusion problem. at both ends, there are porous heat exchangers.
Thank you
Hi,
I am really interested in using your package for solving McKean-Vlasov equations describing the distribution of mean field of particles. All examples I have in mind are like (say in 2d), x=(x1, x2)
For example F_1(x,p) = x1^2 + sum(lambda(x), p)
Let us skip the
p
dependency on the vector field for now.
However, I find there is quite some boilerplate to implement in order to use your package.
Most, if not all, your examples are nonlinear reaction diffusion equations like
du/dt = ∇(c(x,u) + d(x,u) ∇ NL(x,u)) + f(x, u)
c,d,NL,f
, the discretization (like upwind or other), the boundary conditions and return a problem that implement the discretization. Even if this is a subset of what your package can handle, I'd say it would be helpful.That you for your valuable tool
Hi, I am thinking of using VoronoiFVM.jl for solving a set of different PDEs governing the evolution of snow on the ground in 1D. In order to follow the ice-matrix in snow, it is usual to solve diffusion processes and water liquid percolation on a fix grid and then to update the grid (by moving nodes as snow settles) and iterate again on the new grid and so on.
I would like to know if according to you, VoronoiFVM could be applied in such a configuration.
Thank you by advance!
Should this be replaced with
ExtendableGrids.plot()
according to v0.8?
Unfortunately
Example120_ThreeRegions1D.main(;n=30,Plotter=Plots,plot_grid=false, verbose=false,unknown_storage=:sparse)
returns
MethodError: no method matching plot(::Module, ::ExtendableGrids.ExtendableGrid{Float64,Int32}; p=Plot{Plots.GRbackend() n=0})
for both VoronoiFVM.plot() and ExtendableGrids.plot() .
As of the last API update, all boundary condition specifications can be pooled into one function and passed to the System
constructor using the bcondition
keyword argument.
However, the old boundary condition handling using boundary_factor
and boundary_value
is of course still present not only in eval_and_assemble!
among
VoronoiFVM.jl/src/vfvm_solver.jl
Line 561 in 70739a1
_initialize!
e.g.VoronoiFVM.jl/src/vfvm_system.jl
Line 931 in 70739a1
solve!
call through eval_and_assemble!
.
It might be sensible to commit fully to the new boundary condition handling (which pleases me very much btw, thank you for that!) because fields like boundary_factor
which are assigned once within the System
construcutor can lead to problems for some narrow applications where grid-dependent boundary conditions are needed.
I want to evaluate a convection-diffusion system on a simple simplexgrid
, but set Neumann boundary conditions on one boundary face of one cell of the grid. If I want to cycle through different boundary faces in some loop, I would set up the system once where I assign a new bregion
, for a 2D rectangle say ibreg=5
, and specify my Neumann condition among others in some bcond
function:
function bconditions(y,u,bnode)
boundary_neumann!(y,u,bnode,species=1,region=5,value=1)
# some other bconds...
end
If I then make a solve!
call for this system somewhere else, VoronoiFVM
protests since boundary_factor
will be out of bounds, having been assigned fixed when the System
constructor was called.
I currently avoid this behaviour by simply setting one entry in grid[BFaceRegions]
to 5 before calling the constructor and resetting it afterward.
I am sure this is not how it is intended to be used. I have not tested this further, but if the _initialize!
functions were to simply invoke the breaction
, being an alias for bcondition
, and boundary_factor
, boundary_value
were made obsolete, that would at least avoid the bounds error here and make the code more consistent.
Apologies for the wall of text 🙃
Hi !
I am having a bit of trouble using the norm
function for time-dependent solutions.
For example VoronoiFVM.norm(sys, u(t), 2)
, where u
is a transient solution, gives out an error message (see below).
It might be useful for error and convergence analysis of parabolic problems.
Error Message :
MethodError: no method matching _initialize_inactive_dof!(::Vector{Float64}, ::VoronoiFVM.System{Float64, Float64, Int32, Int64, Matrix{Int32}, Matrix{Float64}})
We have no control about the generation of examples and notebooks via the switches with_notebooks
and with_examples
at the end of the file.
Hi,
I am new to VoronoiFVM.jl. After one week try, I found it is really fantastic at solving diffusion problems, it is faster than similar problem I solved in c++ using FEM. So, I decide to try further.
Currently I have the time-dependent mass diffusion equation (c) in 1D domain, and heat conduction equation (T) in a 2D domain. the top boundary of the 2D domain is actually the 1D domain where mass diffusion happens. The equation are coupled (mass diffusion coefficient depends on temperature e.g., D(T), mass diffusion also generate heat, e.g., Q(c)) .
+=============mass diffusion============+
+++++++++++++++++++++++++++++++++++++++
++++++++++++++ heat conduction+++++++++++
+++++++++++++++++++++++++++++++++++++++
I first solve the 2D heat equation and get temperature T, then I solve the mass diffusion equation and get generated heat Q, Can you tell me how can I pass the T, and Q to each other in VoronoiFVM.jl?
The use of Triangle in the various Julia packages needs to be consolidated.
We have TriangleMesh by @konsim83 and Triangle by @furio . Both hide the full functionality of Triangle behind their particular mesh structure.
In this package I need yet another particular mesh structure (I need triangles, triangle attributes, segments, segment markers). I was not able to access these data with either package.
I think there should be one module e.g. TriangleRaw which gives full Julianic access to Triangle which everyone can use. Based on @konsim83 's code (which has some good architectural ideas within this respect) I made a prototype for this which sits in the subdirectory src/triangle of this package. Before making yet another Triangle package out of this I suggest to try to have some consensus.
Same IMHO would be good for TetGen and possibly other mesh generators. CC to @SimonDanisch and @ChrisRackauckas .
Jürgen (Fuhrmann)
PS: What is the appropriate place for discussing this ? It is on the intersection of geometry and PDEs...
The interface to ODE solvers in DifferentialEquations.jl is fantastic.
What would be really great is to have an interface for DDE problems as well.
Is it feasible or too much to ask for? Thanks!
VoronoiFVM.jl/src/vfvm_quantities.jl
Line 292 in bf823b3
It should say
u[q[u.geom]], since f is not defined.
More dots in
...Hello, I had asked a question a while ago about time and space dependence in the flux and reaction terms. I'm not sure if that has been resolved, but I was also wondering how one would go about modeling a flux term like j = -D(u/K)ᵐ∇u
? This was my attempt (by averaging u[1,1]
and u[1,2]
), but I'm not sure about it:
function g!(g,u,∂ω,θ)
ū = (u[1,1]+u[1,2])/2
g[1] = -θ.D*(ū/θ.K)^θ.m*(u[1,2]-u[1,1])
end
Or more generally what would I do for j = -f(u)∇u
? Also, since j⋅n̂
is approximated by g(uₖ,uₗ)/|xₖ-xₗ|
, wouldn't we need to multiply the u
by something like (abs ∘ -)(∂ω.coord[1:2]...)
? Thank you in advance!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.