Skip to content
This repository has been archived by the owner on Jul 19, 2023. It is now read-only.

Nonlinear Laplacian Handling in MOLFiniteDifference (issue #354) #371

Merged
merged 23 commits into from
May 4, 2021
Merged

Nonlinear Laplacian Handling in MOLFiniteDifference (issue #354) #371

merged 23 commits into from
May 4, 2021

Conversation

emmanuellujan
Copy link
Contributor

@emmanuellujan emmanuellujan commented Apr 13, 2021

Fixes part of #354

@emmanuellujan emmanuellujan changed the title [WIP] Advances regarding issue 354 [WIP] Nonlinear Laplacian Handling in MOLFiniteDifference (issue #354) Apr 14, 2021
@ChrisRackauckas
Copy link
Member

Is there a reason why this is commented?

@emmanuellujan
Copy link
Contributor Author

I am working with some test files in my computer that isolate the portion of code that performs this particular parsing. This code is not integrated to MOL_discretization.jl yet, first I need to solve some issues with the automatic generation of rules involving Differentials. Because I wanted to upload some progress, I added the portion of code of interest at about the place where it should be integrated, but as a comment.

@emmanuellujan
Copy link
Contributor Author

I added code to handle cases like the following:

  • Dt(u(t,x)) ~ Dx(u(t,x)^(-1) * Dx(u(t,x)))
  • Dt(u(t,x)) ~ Dx(u(t,x)^2 * Dx(u(t,x)))
  • Dt(u(t,x)) ~ Dx(1. / (1. + u(t,x)^2) * Dx(u(t,x)))
  • Dt(u(t,x)) ~ Dx(1. / (u(t,x)^2 - 1.) * Dx(u(t,x)))
  • Dt(u(t,x,y)) ~ Dx( (u(t,x,y)^2 / exp(x+y)^2 + sin(x+y+4t)^2)^0.5 * Dx(u(t,x,y))) +
                           Dy( (u(t,x,y)^2 / exp(x+y)^2 + sin(x+y+4t)^2)^0.5 * Dy(u(t,x,y)))

To do this I partially used the SymbolicUtils @rules.

Also, I added new test cases for all the examples above.

The function g  (see issue "#354") needs to be improved. Currently a basic approximation is implemented. I would like to solve this in another PR. Now I would like to address convection and convection-diffusion.

@emmanuellujan
Copy link
Contributor Author

@ChrisRackauckas if you agree, you can merge this PR.

@ChrisRackauckas
Copy link
Member

It's WIP and has merge conflicts?

Comment on lines 166 to 173
nonlinlap_rules = []
for t in vcat(lhs_arg,rhs_arg)
for r in rules
if r(t) != nothing
push!(nonlinlap_rules, t => r(t))
end
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this need to be done manually? @YingboMa @shashi don't the rules check the variations?

Copy link
Contributor Author

@emmanuellujan emmanuellujan Apr 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, I did not find a way to fully use SymbolicUtils to solve this issue. So I solved a part of it manually. An explanation of my issue can be found in the following document.: https://docs.google.com/document/d/1qbWokDYXuO5GV3ilI8R4fWWnvkBkrpQd3H6d7l9DrC4/edit

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YingboMa can you double check this?

@emmanuellujan
Copy link
Contributor Author

It's WIP and has merge conflicts?

I update my fork from time to time, I estimate that the conflicts were generated because of that. Unfortunately I do not see an option in github that allows me to resolve them. If there is such an option, and you could point me to it, I would be happy to resolve them.

@valentinsulzer
Copy link
Contributor

I think you need write access to resolve conflicts on github, but if you merge master into your local branch you will see them and be able to resolve them

@emmanuellujan
Copy link
Contributor Author

I think you need write access to resolve conflicts on github, but if you merge master into your local branch you will see them and be able to resolve them

Thanks for the advice. In summary this is what I did:

git clone https://github.com/emmanuellujan/DiffEqOperators.jl/
cd DiffEqOperators.jl
git remote add upstream https://github.com/SciML/DiffEqOperators.jl/
git fetch upstream
git checkout master
git merge upstream/master
git checkout fix-issue-354
git merge master
# Solve conflict in editor 
git add src/MOLFiniteDifference/MOL_discretization.jl
git push

@emmanuellujan emmanuellujan changed the title [WIP] Nonlinear Laplacian Handling in MOLFiniteDifference (issue #354) Nonlinear Laplacian Handling in MOLFiniteDifference (issue #354) Apr 29, 2021
@emmanuellujan
Copy link
Contributor Author

@ChrisRackauckas @tinosulzer

Copy link
Contributor

@valentinsulzer valentinsulzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ok merging this as something that works for now so we can move forward. But I am not sure this is the most accurate approach: currently we do D(u_i+1/2, x_i+1/2) (i.e. function of the average) but usually I have seen D_i+1/2 (i.e. average of the function). These can be quite different if D is nonlinear. Would need to dig more into the numerical analysis to be sure which is best

src/MOLFiniteDifference/MOL_discretization.jl Outdated Show resolved Hide resolved
src/MOLFiniteDifference/MOL_discretization.jl Outdated Show resolved Hide resolved
src/MOLFiniteDifference/MOL_discretization.jl Outdated Show resolved Hide resolved
@emmanuellujan emmanuellujan changed the base branch from master to upwind_operators April 29, 2021 22:59
@emmanuellujan emmanuellujan changed the base branch from upwind_operators to master April 29, 2021 22:59
@emmanuellujan
Copy link
Contributor Author

I am ok merging this as something that works for now so we can move forward. But I am not sure this is the most accurate approach: currently we do D(u_i+1/2, x_i+1/2) (i.e. function of the average) but usually I have seen D_i+1/2 (i.e. average of the function). These can be quite different if D is nonlinear. Would need to dig more into the numerical analysis to be sure which is best

Currently a basic approximation is implemented. I would like to solve this in another PR. In the first page of this draft you can find the definition of g based on a degree 2 polynomial in a 3D case. If this is the correct definition, I would need to know which stencil nodes should I use. The "cross" gives me 7, but I need 10 to fit the coefficients, I think that the crossed derivatives could be avoided to use just 7 nodes.

@ChrisRackauckas
Copy link
Member

Currently a basic approximation is implemented. I would like to solve this in another PR. In the first page of this draft you can find the definition of g based on a degree 2 polynomial in a 3D case. If this is the correct definition, I would need to know which stencil nodes should I use. The "cross" gives me 7, but I need 10 to fit the coefficients, I think that the crossed derivatives could be avoided to use just 7 nodes.

You split it to the 3 terms Del u = u_xx + u_yy + u_zz and then you have 2 unique coefficients per, + 1 for the middle. Otherwise you have to have the corner terms, which you could discretize to include the corners.

Comment on lines 127 to 130
# TODO: check central_neighbor_idxs. It does not work like the old implementation.
#I1 = oneunit(first(indices))
#Imin = first(indices) + I1 * (order÷2)
#Imax = last(indices) - I1 * (order÷2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just remove

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below

# Use max and min to apply buffers
central_neighbor_idxs(II,j) = stencil(j) .+ max(Imin,min(II,Imax))
# central_neighbor_idxs(II,j) = stencil(j) .+ max(Imin,min(II,Imax))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? just remove if there's a new definition

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's back to the old definition which ignores the discretization order (I think) i.e. breaks #365 but not enough to cause tests to fail

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you looking into this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can take a look tomorrow

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing that is broken with the stencil approach is "Test 00: Dt(u(t,x,y)) ~ Dxx(u(t,x,y)) + Dyy(u(t,x,y))" in the MOL_2D_Diffusion.jl test with orders 4 and 6. The test breaks because the solution is not accurate enough, not a syntax error. The reason it works with the old syntax is that it just ignores discretization.centered_order and pretends you're always asking for order 2. @emmanuellujan if you only test for order 2 in that test then you can use the syntax you commented out, and we should open an issue for the order 4 and 6 in 2D.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that it is better not to remove those comments for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually I'll just open a PR to your fork

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, we posted almost at the same time, I did not see your comment when I posted mine. I will check what you mention. Thank you :)

@ChrisRackauckas
Copy link
Member

I am ok merging this as something that works for now so we can move forward. But I am not sure this is the most accurate approach: currently we do D(u_i+1/2, x_i+1/2) (i.e. function of the average) but usually I have seen D_i+1/2 (i.e. average of the function). These can be quite different if D is nonlinear. Would need to dig more into the numerical analysis to be sure which is best

That would make the approximation O(dx) instead of O(dx^2), but that can be improved in a subsequent PR. Let's get an issue open for this.

@emmanuellujan
Copy link
Contributor Author

Currently a basic approximation is implemented. I would like to solve this in another PR. In the first page of this draft you can find the definition of g based on a degree 2 polynomial in a 3D case. If this is the correct definition, I would need to know which stencil nodes should I use. The "cross" gives me 7, but I need 10 to fit the coefficients, I think that the crossed derivatives could be avoided to use just 7 nodes.

You split it to the 3 terms Del u = u_xx + u_yy + u_zz and then you have 2 unique coefficients per, + 1 for the middle. Otherwise you have to have the corner terms, which you could discretize to include the corners.

I know, but if you want to fit a degree 2 polynomial in 3D you need 10 coefficients, ergo 10 nodes. If you use a typical stencil (without the corners), you have 7 nodes, ergo you need to neglect some terms of the polynomial. I think the cross derivative terms could be removed to this end. Another option is to use the corners. In this case, you have 15 nodes available, but you only need 10, so you need to chose which corners to use. Probably any choice in which the nodes are sufficiently distributed is enough.

@emmanuellujan
Copy link
Contributor Author

I am ok merging this as something that works for now so we can move forward. But I am not sure this is the most accurate approach: currently we do D(u_i+1/2, x_i+1/2) (i.e. function of the average) but usually I have seen D_i+1/2 (i.e. average of the function). These can be quite different if D is nonlinear. Would need to dig more into the numerical analysis to be sure which is best

That would make the approximation O(dx) instead of O(dx^2), but that can be improved in a subsequent PR. Let's get an issue open for this.

Okay, we need to wait until this PR is merged to post the new issue.

Note: currently issue #371 contains this "sub-issue".

@ChrisRackauckas
Copy link
Member

I know, but if you want to fit a degree 2 polynomial in 3D you need 10 coefficients, ergo 10 nodes. If you use a typical stencil (without the corners), you have 7 nodes, ergo you need to neglect some terms of the polynomial. I think the cross derivative terms could be removed to this end. Another option is to use the corners. In this case, you have 15 nodes available, but you only need 10, so you need to chose which corners to use. Probably any choice in which the nodes are sufficiently distributed is enough.

Yes, that is what I'm saying. The typical stencil is not a 2nd order 2D polynomial: it's the cross product of 2 1D polynomials. That's the derivation we should probably use.

Though the 9 coefficient 2D polynomial is used though. See the examples here:

https://en.wikipedia.org/wiki/Discrete_Laplace_operator#Implementation_via_operator_discretization

Generating the higher precision stencils wouldn't be a bad idea, given that it's easy (and doesn't impact the cache efficiency)

@ChrisRackauckas ChrisRackauckas merged commit c7ff691 into SciML:master May 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants