1D Nonlinear Poisson equation with one species

1D Nonlinear Poisson equation with one species

Solve the nonlinear Poisson equation

\[-\nabla \varepsilon \nabla u^2 + u^2 = 0.0001x\]

in $\Omega=(0,1)$ with boundary condition $u(0)=1$ and $u(1)=0.5$.

# We wrap this example and all later ones
# into a module structure. This allows to load
# all of them at once into the REPL without name
# clashes. We shouldn't forget the corresponding end
# statement.
module OneSpeciesNonlinearPoisson

# This gives us he @printf macro (c-like output)
using Printf

# That's the thing we want to do
using TwoPointFluxFVM

# Allow plotting
if isinteractive()
    using PyPlot
end



#
# Structure containing  userdata information
#
# We choose a mutable struct which allows to overwrite
# fields later.
mutable struct Physics
    flux::Function      # flux function, mandatory
    source::Function    # source function, optional
    reaction::Function  # reaction term, optional
    storage::Function   # storage term, mandatory
    eps::Real           # Example for "user data" passed to the callback

    Physics()=new() # Provide inner constructor resulting in uninitialized struct
end



#Main function for user interaction from REPL and
#for testimg. Default physics need to generate correct
#test value.
function main(;n=10,pyplot=false,verbose=false)
    h=1.0/convert(Float64,n)
    grid=TwoPointFluxFVM.Grid(collect(0:h:1))
    
    
    physics=Physics()
    physics.eps=1.0e-2

    physics.flux=function(physics,edge,f,uk,ul)
        f[1]=physics.eps*(uk[1]^2-ul[1]^2)
    end 

    physics.source=function(physics,node,f)
        f[1]=1.0e-4*node.coord[1]
    end 

    physics.storage=function(physics,node, f,u)
        f[1]=u[1]
    end

    physics.reaction=function(physics,node,f,u)
        f[1]=u[1]^2
    end
    
    sys=TwoPointFluxFVM.System(grid,physics,1)
    add_species(sys,1,[1])
    sys.boundary_values[1,1]=1.0
    sys.boundary_values[1,2]=0.5
    
    sys.boundary_factors[1,1]=TwoPointFluxFVM.Dirichlet
    sys.boundary_factors[1,2]=TwoPointFluxFVM.Dirichlet
    
    inival=unknowns(sys)
    inival.=0.5


    control=TwoPointFluxFVM.NewtonControl()
    control.verbose=verbose
    tstep=1.0e-2
    times=collect(0.0:tstep:1.0)
    test_result=0
    for it=2:length(times)
        U=solve(sys,inival,control=control,tstep=tstep)
        test_result=U[5]
        inival.=U
        if verbose
            @printf("time=%g\n",times[it])
        end
        if pyplot
            PyPlot.clf()
            PyPlot.grid()
            plot(grid.coord[1,:],U[1,:])
            pause(1.0e-10)
        end
    end
    return test_result
end


end # Yes, this is *that* end (of the module...)