-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Global mass conservation and diffusion equation #124
Comments
Hi, thanks for coming up with this. The subtle point is the following: the "mass" to be conserved on the continuous level is \int_\omega u dx. The discrete analogon of this integral is For an N-nodes grid with stepsize h we have |\omega_i|=h for all but i=1 and i=N. We have |\omega_1| = h/2 and |\omega_N|=h/2. So in the calculation with The proper way to work here would be to define e.g. mass(u)=integrate(sys,storage!,u)[1,1] and return EDIT: Note to self: make an example from this |
Thanks for your prompt reply! Regarding the following lines:
I was already looking this routine up, but didn't know how to correctly use it. Since the routine takes On another note (note #1, since there will be 2), I have tried implementing weighted averaging of the diffusion constants for the # Flux function which describes the flux
# between neighboring control volumes
function flux!(f, u, edge, data)#, data)
@inbounds begin
_D::Float64 = data.D
# correction to the standard diffusionfv
_k::Float64 = data.k
# get the corrected diffusion constants
# at nodes
d1::Float64 = _D * (1. + _k * u[1, 1])#_corrected_D(u[1, 1], _D, _k)
d2::Float64 = _D * (1. + _k * u[1, 2])#_corrected_D(u[1, 2], _D, _k)
# (d1, d2) = _corrected_D.(u[1, :], _D, _k)
# get the harmonic average of the diffusion constants
# df::Float64 = _harm_D(d1, d2)
if d1 == 0 || d2 == 0
df = 0.
elseif (d1 + d2) == 0
df = 0.
else
df::Float64 = 2. * d1 * d2 / (d1 + d2)
end
f[1] = df * (u[1, 1] - u[1, 2])
end
end However, if I tried to break the above code into smaller functions (which would improve readability in some more complex cases), allocation warnings in the assembly loop were prompted. Is there a way to go about this? I have read about the allocation warnings, but I am unsure about what the culprit would be in this case. My #note2 is actually related to the former one, since I would also like to implement inverse-distance weighting; using
I was able to obtain the node volumes outside the flux function. Then, inside the flux function, I call
which again prompts allocation warnings. Is there also a way to go about this? I've noticed that no allocation warnings were issued when I tested the tutorial on the generic operators which probably attempts to achieve something similar (in a sense that it accesses and indexes an eternal array). Thank you and best regards, Jan |
As for the flux function: After a short glance on the code, the only line where I would expect allocations |
As for nodevolumes, it is a bit unfortunate that in the moment, these data can be created after creating the system. |
Hello, I am following the code in Example 106, since I am interested in implementing the nonlinear diffusion case in 1D for some benchmarking purposes. However, upon running the code, I've noticed the mass is not conserved globally in the example.
If I understand the tutorials and Github issues correctly, if no boundary conditions are specified, the default are the homogenous Neumann boundary conditions and so the global mass of the system should remain conserved at all times. Already slightly increasing the final time of the simulation in the example and summing the solution vectors shows this is not the case. I am appending a slightly modified example below in which I changed the initial condition (it is a step function now) and am also simulating the standard linear diffusion equation for simplicity.
Given that the sums of the solution vector increase from$\approx 462$ to $\approx 462$ in a rather short time span, something is clearly not right; am I implementing the boundary conditions incorrectly (the same also happens if I explicitly specify them using
boundary_neumann!(...)
, is there an error in post-processing or perhaps I should impose stricter solver tolerances?Apart from this, is it possible there is a bug in the code that the tests do not catch?
Regards,
Jan
EDIT:
After some more tinkering and trying out different initial profiles, it looks as if I choose an initial profile that was too difficult for the solver to handle in the initial stages of relaxation. I will report back once I am convinced about that.
The text was updated successfully, but these errors were encountered: