sciml / diffeqphysics.jl Goto Github PK
View Code? Open in Web Editor NEWA library for building differential equations arising from physical problems for physics-informed and scientific machine learning (SciML)
License: Other
A library for building differential equations arising from physical problems for physics-informed and scientific machine learning (SciML)
License: Other
Hello,
I tried the example script pendulum.jl on Linux and FreeBSD. On both platforms it crashes with the following error message:
ERROR: LoadError: MethodError: no method matching getindex(::Nothing, ::Int64)
Stacktrace:
[1] H(ℒ::Float64, θ::ForwardDiff.Dual{ForwardDiff.Tag{DiffEqPhysics.var"#10#18"{Float64, Nothing, typeof(H)}, Float64}, Float64, 1}, params::Nothing)
@ Main pendulum.jl:38
[2] (::DiffEqPhysics.var"#10#18"{Float64, Nothing, typeof(H)})(q::ForwardDiff.Dual{ForwardDiff.Tag{DiffEqPhysics.var"#10#18"{Float64, Nothing, typeof(H)}, Float64}, Float64, 1})
@ DiffEqPhysics ~/.julia/packages/DiffEqPhysics/SeVwO/src/hamiltonian.jl:56
[3] derivative(f::DiffEqPhysics.var"#10#18"{Float64, Nothing, typeof(H)}, x::Float64)
@ ForwardDiff ~/.julia/packages/ForwardDiff/QOqCN/src/derivative.jl:14
[4] generic_derivative(q0::Float64, hami::Function, x::Float64)
@ DiffEqPhysics ~/.julia/packages/DiffEqPhysics/SeVwO/src/hamiltonian.jl:40
[5] (::DiffEqPhysics.var"#9#17"{typeof(H), Float64})(p::Float64, q::Float64, param::Nothing, t::Float64)
@ DiffEqPhysics ~/.julia/packages/DiffEqPhysics/SeVwO/src/hamiltonian.jl:56
[6] (::ODEFunction{false, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing})(::Float64, ::Vararg{Any, N} where N)
@ SciMLBase ~/.julia/packages/SciMLBase/9EjAY/src/scimlfunctions.jl:334
[7] initialize!(integrator::OrdinaryDiffEq.ODEIntegrator{SofSpa10, false, ArrayPartition{Float64, Tuple{Float64, Float64}}, Nothing, Float64, Nothing, Float64, Float64, Float64, Vector{ArrayPartition{Float64, Tuple{Float64, Float64}}}, ODESolution{Float64, 2, Vector{ArrayPartition{Float64, Tuple{Float64, Float64}}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{ArrayPartition{Float64, Tuple{Float64, Float64}}}}, ODEProblem{ArrayPartition{Float64, Tuple{Float64, Float64}}, Tuple{Float64, Float64}, false, Nothing, DynamicalODEFunction{false, ODEFunction{false, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, ODEFunction{false, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Base.Iterators.Pairs{Symbol, Vector{Float64}, Tuple{Symbol}, NamedTuple{(:p,), Tuple{Vector{Float64}}}}, SciMLBase.StandardODEProblem}, SofSpa10, OrdinaryDiffEq.InterpolationData{DynamicalODEFunction{false, ODEFunction{false, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, ODEFunction{false, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{ArrayPartition{Float64, Tuple{Float64, Float64}}}, Vector{Float64}, Vector{Vector{ArrayPartition{Float64, Tuple{Float64, Float64}}}}, OrdinaryDiffEq.SofSpa10ConstantCache{Float64, Float64}}, DiffEqBase.DEStats}, DynamicalODEFunction{false, ODEFunction{false, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, ODEFunction{false, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, OrdinaryDiffEq.SofSpa10ConstantCache{Float64, Float64}, OrdinaryDiffEq.DEOptions{Float64, Float64, Float64, Float64, typeof(DiffEqBase.ODE_DEFAULT_NORM), typeof(LinearAlgebra.opnorm), Nothing, CallbackSet{Tuple{}, Tuple{}}, typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), DataStructures.BinaryMinHeap{Float64}, DataStructures.BinaryMinHeap{Float64}, Nothing, Nothing, Int64, Tuple{}, Tuple{}, Tuple{}}, ArrayPartition{Float64, Tuple{Float64, Float64}}, Float64, Nothing, OrdinaryDiffEq.DefaultInit}, cache::OrdinaryDiffEq.SofSpa10ConstantCache{Float64, Float64})
@ OrdinaryDiffEq ~/.julia/packages/OrdinaryDiffEq/IOPED/src/perform_step/symplectic_perform_step.jl:160
[8] __init(prob::ODEProblem{ArrayPartition{Float64, Tuple{Float64, Float64}}, Tuple{Float64, Float64}, false, Nothing, DynamicalODEFunction{false, ODEFunction{false, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, ODEFunction{false, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Base.Iterators.Pairs{Symbol, Vector{Float64}, Tuple{Symbol}, NamedTuple{(:p,), Tuple{Vector{Float64}}}}, SciMLBase.StandardODEProblem}, alg::SofSpa10, timeseries_init::Tuple{}, ts_init::Tuple{}, ks_init::Tuple{}, recompile::Type{Val{true}}; saveat::Tuple{}, tstops::Tuple{}, d_discontinuities::Tuple{}, save_idxs::Nothing, save_everystep::Bool, save_on::Bool, save_start::Bool, save_end::Nothing, callback::Nothing, dense::Bool, calck::Bool, dt::Float64, dtmin::Nothing, dtmax::Float64, force_dtmin::Bool, adaptive::Bool, gamma::Int64, abstol::Nothing, reltol::Nothing, qmin::Int64, qmax::Int64, qsteady_min::Int64, qsteady_max::Int64, qoldinit::Int64, fullnormalize::Bool, failfactor::Int64, beta1::Nothing, beta2::Nothing, maxiters::Int64, internalnorm::typeof(DiffEqBase.ODE_DEFAULT_NORM), internalopnorm::typeof(LinearAlgebra.opnorm), isoutofdomain::typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), unstable_check::typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), verbose::Bool, timeseries_errors::Bool, dense_errors::Bool, advance_to_tstop::Bool, stop_at_next_tstop::Bool, initialize_save::Bool, progress::Bool, progress_steps::Int64, progress_name::String, progress_message::typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), userdata::Nothing, allow_extrapolation::Bool, initialize_integrator::Bool, alias_u0::Bool, alias_du0::Bool, initializealg::OrdinaryDiffEq.DefaultInit, kwargs::Base.Iterators.Pairs{Symbol, Vector{Float64}, Tuple{Symbol}, NamedTuple{(:p,), Tuple{Vector{Float64}}}})
@ OrdinaryDiffEq ~/.julia/packages/OrdinaryDiffEq/IOPED/src/solve.jl:434
[9] #__solve#403
@ ~/.julia/packages/OrdinaryDiffEq/IOPED/src/solve.jl:4 [inlined]
[10] #solve_call#56
@ ~/.julia/packages/DiffEqBase/GmecW/src/solve.jl:61 [inlined]
[11] solve_up(prob::ODEProblem{ArrayPartition{Float64, Tuple{Float64, Float64}}, Tuple{Float64, Float64}, false, Nothing, DynamicalODEFunction{false, ODEFunction{false, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, ODEFunction{false, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Base.Iterators.Pairs{Symbol, Vector{Float64}, Tuple{Symbol}, NamedTuple{(:p,), Tuple{Vector{Float64}}}}, SciMLBase.StandardODEProblem}, sensealg::Nothing, u0::ArrayPartition{Float64, Tuple{Float64, Float64}}, p::Nothing, args::SofSpa10; kwargs::Base.Iterators.Pairs{Symbol, Float64, Tuple{Symbol}, NamedTuple{(:dt,), Tuple{Float64}}})
@ DiffEqBase ~/.julia/packages/DiffEqBase/GmecW/src/solve.jl:82
[12] #solve#57
@ ~/.julia/packages/DiffEqBase/GmecW/src/solve.jl:70 [inlined]
[13] top-level scope
@ pendulum.jl:53
[14] include(fname::String)
@ Base.MainInclude ./client.jl:444
[15] top-level scope
@ REPL[2]:1
in expression starting at pendulum.jl:53
It'll make it much faster.
When force field simulations are done in MD, many times the temperature needs to be controlled to make sure it's sampling from the right ensambles. Two methods for this are Nose-Hoover and Langivan.
The Nose-Hoover method modifies the resulting Hamiltonian:
https://en.wikipedia.org/wiki/Nos%C3%A9%E2%80%93Hoover_thermostat
This might be able to (?) be written directly as equations of motion modified by a parameter s
.
Langivan equations add thermal stochasticity directly to the equations of motion by using an SDE instead of an ODE:
https://en.wikipedia.org/wiki/Langevin_dynamics
This gives an additive SDE which can be simulated using the tools in StochasticDiffEq.jl.
Here methods for animating NBodyGravProblem
were developed using solutions to problems directly. The methods should be reworked implementing the iterator interface to allow one to create animations while callinganimate(solution)
.
One can compute Hamiltonian from Lagrangian via Legendre transformation, so I propose the following implementation.
function Legendre_transformation(F, w) # Legendre transformation for quadratic function
wv = a->ForwardDiff.gradient(F, a)
z = zeros(w)
M = ForwardDiff.jacobian(wv, z)
b = wv(z)
v = bkfact!(M)\(w-b)
w'v - F(v)
end
function Lagrangian2Hamiltonian(Lagrangian, t, q, p)
L = q̇ -> Lagrangian(t, q, q̇)
Legendre_transformation(L, p)
end
Finding the Legendre transformation of an arbitrary function is very hard numerically, but Lagrangian is quadratic in most of mechanics.
For the Euler–Lagrange equation, we need to move the generalized acceleration term into the LHS. I propose the following implementation.
using ForwardDiff
∂L∂q(L, t, q, q̇) = ForwardDiff.gradient(a->L(t,a,q̇), q)
∂L∂q̇(L, t, q, q̇) = ForwardDiff.gradient(a->L(t,q,a), q̇)
Dtq(L, t, q, q̇) = ForwardDiff.derivative(a->∂L∂q(L,a,q,q̇), t)
Dqq̇(L, t, q, q̇) = ForwardDiff.jacobian(a->∂L∂q̇(L,t,a,q̇), q)
Dq̇q̇(L, t, q, q̇) = ForwardDiff.hessian(a->L(t,q,a), q̇)
function generalized_acceleration(L, t, q, q̇)
F= ∂L∂q(L, t, q, q̇)
lhs = Dq̇q̇(L, t, q, q̇)
rhs = F - Dqq̇(L, t, q, q̇)*q̇ - Dtq(L, t, q, q̇)
bkfact!(lhs)\rhs # Using Bunch-Kaufman factorization since we can assume that for a physical system, the matrix will be symmetric
end
This implementation won't work until this issue is fixed.
From a Lagrangian, the Euler-Lagrange equations can be defined. It would nice to be able to just specify the Lagrangian, and have that specify the PDE that can be solved. This won't be useful until the PDE tools are created, so this may need to sit here for a bit.
The Lagrangian L(t,x,dx)
can be used to specify the equations of motion as well. My recall of this approach is quite hazy (I have always used Hamiltonians: is there a field where using Lagrangians directly is useful?). I'm not entirely sure how to do this without getting an implicit equation for the second derivative (this is easy to solve for usually symbolically, but how would it be done numerically?)
Solving a HamiltonianProblem
with time-dependent Hamiltonian triggers an exception:
using DiffEqPhysics
using DifferentialEquations
function H(p, q, params, t) # note the time argument, even though we do not use it in this MWE
p^2 + q^2
end
p0 = 1.0
q0 = 0.0
tspan = (0.0, 0.1)
HP = HamiltonianProblem(H, p0, q0, tspan)
sol = solve(HP)
Using DifferentialEquations 7.5.0 and DiffEqPhysics 3.9.0, solve(HP)
yields
ERROR: MethodError: no method matching H(::Float64, ::ForwardDiff.Dual{ForwardDiff.Tag{DiffEqPhysics.var"#10#18"{Float64, Nothing, typeof(H)}, Float64}, Float64, 1}, ::Nothing)
Closest candidates are:
H(::Any, ::Any, ::Any, ::Any) at c:\Users\user\Desktop\diff.jl:6
Stacktrace:
[1] (::DiffEqPhysics.var"#10#18"{Float64, Nothing, typeof(H)})(q::ForwardDiff.Dual{ForwardDiff.Tag{DiffEqPhysics.var"#10#18"{Float64, Nothing, typeof(H)}, Float64}, Float64, 1})
@ DiffEqPhysics C:\Users\user\.julia\packages\DiffEqPhysics\SeVwO\src\hamiltonian.jl:56
[2] derivative(f::DiffEqPhysics.var"#10#18"{Float64, Nothing, typeof(H)}, x::Float64)
@ ForwardDiff C:\Users\user\.julia\packages\ForwardDiff\pDtsf\src\derivative.jl:14
[3] generic_derivative(q0::Float64, hami::Function, x::Float64)
@ DiffEqPhysics C:\Users\user\.julia\packages\DiffEqPhysics\SeVwO\src\hamiltonian.jl:40
[4] (::DiffEqPhysics.var"#9#17"{typeof(H), Float64})(p::Float64, q::Float64, param::Nothing, t::Float64)
@ DiffEqPhysics C:\Users\user\.julia\packages\DiffEqPhysics\SeVwO\src\hamiltonian.jl:56
[5] (::ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing})(::Float64, ::Vararg{Any})
@ SciMLBase C:\Users\user\.julia\packages\SciMLBase\ZGRni\src\scimlfunctions.jl:1962
[6] (::DynamicalODEFunction{false, SciMLBase.FullSpecialize, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing})(u::ArrayPartition{Float64, Tuple{Float64, Float64}}, p::Nothing, t::Float64)
@ SciMLBase C:\Users\user\.julia\packages\SciMLBase\ZGRni\src\scimlfunctions.jl:1966
[7] initialize!(integrator::OrdinaryDiffEq.ODEIntegrator{Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, false, ArrayPartition{Float64, Tuple{Float64, Float64}}, Nothing, Float64, Nothing, Float64, Float64, Float64, Float64, Vector{ArrayPartition{Float64, Tuple{Float64, Float64}}}, ODESolution{Float64, 2, Vector{ArrayPartition{Float64, Tuple{Float64, Float64}}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{ArrayPartition{Float64, Tuple{Float64, Float64}}}}, ODEProblem{ArrayPartition{Float64, Tuple{Float64, Float64}}, Tuple{Float64, Float64}, false, Nothing, DynamicalODEFunction{false, SciMLBase.FullSpecialize, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing,
Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, OrdinaryDiffEq.InterpolationData{DynamicalODEFunction{false, SciMLBase.FullSpecialize, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Vector{ArrayPartition{Float64, Tuple{Float64, Float64}}}, Vector{Float64}, Vector{Vector{ArrayPartition{Float64, Tuple{Float64, Float64}}}}, OrdinaryDiffEq.Tsit5ConstantCache{Float64, Float64}}, DiffEqBase.DEStats}, DynamicalODEFunction{false, SciMLBase.FullSpecialize, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, OrdinaryDiffEq.Tsit5ConstantCache{Float64, Float64}, OrdinaryDiffEq.DEOptions{Float64, Float64, Float64, Float64, PIController{Rational{Int64}}, typeof(DiffEqBase.ODE_DEFAULT_NORM), typeof(LinearAlgebra.opnorm), Nothing, CallbackSet{Tuple{}, Tuple{}}, typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), DataStructures.BinaryHeap{Float64, DataStructures.FasterForward}, DataStructures.BinaryHeap{Float64, DataStructures.FasterForward}, Nothing, Nothing, Int64, Tuple{}, Tuple{}, Tuple{}}, ArrayPartition{Float64, Tuple{Float64, Float64}}, Float64, Nothing, OrdinaryDiffEq.DefaultInit}, cache::OrdinaryDiffEq.Tsit5ConstantCache{Float64, Float64})
@ OrdinaryDiffEq C:\Users\user\.julia\packages\OrdinaryDiffEq\l0xpb\src\perform_step\low_order_rk_perform_step.jl:672
[8] __init(prob::ODEProblem{ArrayPartition{Float64, Tuple{Float64, Float64}}, Tuple{Float64, Float64}, false, Nothing, DynamicalODEFunction{false, SciMLBase.FullSpecialize, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, alg::Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, timeseries_init::Tuple{}, ts_init::Tuple{}, ks_init::Tuple{}, recompile::Type{Val{true}}; saveat::Tuple{}, tstops::Tuple{}, d_discontinuities::Tuple{}, save_idxs::Nothing, save_everystep::Bool, save_on::Bool, save_start::Bool, save_end::Nothing, callback::Nothing, dense::Bool, calck::Bool, dt::Float64, dtmin::Nothing, dtmax::Float64, force_dtmin::Bool, adaptive::Bool, gamma::Rational{Int64}, abstol::Nothing, reltol::Nothing, qmin::Rational{Int64}, qmax::Int64, qsteady_min::Int64, qsteady_max::Int64, beta1::Nothing, beta2::Nothing, qoldinit::Rational{Int64}, controller::Nothing, fullnormalize::Bool, failfactor::Int64, maxiters::Int64, internalnorm::typeof(DiffEqBase.ODE_DEFAULT_NORM), internalopnorm::typeof(LinearAlgebra.opnorm), isoutofdomain::typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), unstable_check::typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), verbose::Bool, timeseries_errors::Bool, dense_errors::Bool, advance_to_tstop::Bool, stop_at_next_tstop::Bool, initialize_save::Bool, progress::Bool, progress_steps::Int64, progress_name::String, progress_message::typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), userdata::Nothing, allow_extrapolation::Bool, initialize_integrator::Bool, alias_u0::Bool, alias_du0::Bool, initializealg::OrdinaryDiffEq.DefaultInit, kwargs::Base.Pairs{Symbol, Bool, Tuple{Symbol, Symbol}, NamedTuple{(:default_set, :second_time), Tuple{Bool, Bool}}})
@ OrdinaryDiffEq C:\Users\user\.julia\packages\OrdinaryDiffEq\l0xpb\src\solve.jl:493
[9] __solve(::ODEProblem{ArrayPartition{Float64, Tuple{Float64, Float64}}, Tuple{Float64, Float64}, false, Nothing, DynamicalODEFunction{false, SciMLBase.FullSpecialize, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, ::Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}; kwargs::Base.Pairs{Symbol, Bool, Tuple{Symbol, Symbol}, NamedTuple{(:default_set, :second_time), Tuple{Bool, Bool}}})
@ OrdinaryDiffEq C:\Users\user\.julia\packages\OrdinaryDiffEq\l0xpb\src\solve.jl:5
[10] __solve(::ODEProblem{ArrayPartition{Float64, Tuple{Float64, Float64}}, Tuple{Float64, Float64}, false, Nothing, DynamicalODEFunction{false, SciMLBase.FullSpecialize, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, ::Nothing; default_set::Bool, kwargs::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:second_time,), Tuple{Bool}}})
@ DifferentialEquations C:\Users\user\.julia\packages\DifferentialEquations\fGVGw\src\default_solve.jl:9
[11] #__solve#50
@ C:\Users\user\.julia\packages\DiffEqBase\5U1Mr\src\solve.jl:1096 [inlined]
[12] __solve
@ C:\Users\user\.julia\packages\DiffEqBase\5U1Mr\src\solve.jl:1089 [inlined]
[13] #solve_call#26
@ C:\Users\user\.julia\packages\DiffEqBase\5U1Mr\src\solve.jl:472 [inlined]
[14] solve_call
@ C:\Users\user\.julia\packages\DiffEqBase\5U1Mr\src\solve.jl:442 [inlined]
[15] #solve_up#32
@ C:\Users\user\.julia\packages\DiffEqBase\5U1Mr\src\solve.jl:838 [inlined]
[16] solve_up
@ C:\Users\user\.julia\packages\DiffEqBase\5U1Mr\src\solve.jl:807 [inlined]
[17] solve(::ODEProblem{ArrayPartition{Float64, Tuple{Float64, Float64}}, Tuple{Float64, Float64}, false, Nothing, DynamicalODEFunction{false, SciMLBase.FullSpecialize, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing,
Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}; sensealg::Nothing, u0::Nothing, p::Nothing,
wrap::Val{true}, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ DiffEqBase C:\Users\user\.julia\packages\DiffEqBase\5U1Mr\src\solve.jl:801
[18] solve(::ODEProblem{ArrayPartition{Float64, Tuple{Float64, Float64}}, Tuple{Float64, Float64}, false, Nothing, DynamicalODEFunction{false, SciMLBase.FullSpecialize, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#9#17"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, ODEFunction{false, SciMLBase.FullSpecialize, DiffEqPhysics.var"#11#19"{typeof(H), Float64}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing,
Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem})
@ DiffEqBase C:\Users\user\.julia\packages\DiffEqBase\5U1Mr\src\solve.jl:791
[19] top-level scope
@ c:\Users\user\Desktop\diff.jl:14
Apparently, the call to DiffEqBase.numargs(H)
in DiffEqPhysics/hamiltonian.jl:51
does not work as expected, and execution proceeds to the wrong branch.
DiffEqPhysics.jl/src/hamiltonian.jl
Line 51 in 877d778
First, I want to apologize for being new to Julia and not knowing a lot of the basics.
Second, thanks for putting this together. It looks great!
Third, unfortunately, when I try adding the packing using the standard approach (as I understand it) Iget an error. See below for details. Could someone help me figure out what I am doing wrong?
julia> Pkg.add("DiffEqPhysics")
ERROR: unknown package DiffEqPhysics
macro expansion at ./pkg/entry.jl:53 [inlined]
(::Base.Pkg.Entry.##1#3{String,Base.Pkg.Types.VersionSet})() at ./task.jl:335
Stacktrace:
[1] sync_end() at ./task.jl:287
[2] macro expansion at ./task.jl:303 [inlined]
[3] add(::String, ::Base.Pkg.Types.VersionSet) at ./pkg/entry.jl:51
[4] (::Base.Pkg.Dir.##4#7{Array{Any,1},Base.Pkg.Entry.#add,Tuple{String}})() at ./pkg/dir.jl:36
[5] cd(::Base.Pkg.Dir.##4#7{Array{Any,1},Base.Pkg.Entry.#add,Tuple{String}}, ::String) at ./file.jl:70
[6] #cd#1(::Array{Any,1}, ::Function, ::Function, ::String, ::Vararg{String,N} where N) at ./pkg/dir.jl:36
[7] add(::String) at ./pkg/pkg.jl:117
https://github.com/JuliaDiffEq/DiffEqPhysics.jl/blob/master/src/nbody.jl
This looks like it should be using ArrayPartition
s to keep the x,y,z
in separate arrays for the DiffEq solver. This will also allow it to be compatible with GPUs.
Upon Pkg.update()
I got
INFO: Updating METADATA...
INFO: Updating Plots master...
INFO: Computing changes...
ERROR: AssertionError: verify_solution(sol, interface)
The solution resolved after I Pkg.free("Plots")
. Then it said:
INFO: Freeing Plots
ERROR: resolve is unable to satisfy package requirements.
The problem was detected when trying to find a feasible version
for package DiffEqPhysics.
After I Pkg.rm("DifferentialEquations")
it updated fine.
@JuliaRegistrator register()
Make these auto-generate PartitionedODEProblem
s.
What did I wrong?
Trying to solve one of the simplest dynamical systems using the Hamiltonian method with DiffEqPhysics
failed.
We have H(p, q) = p^2/20
(a inert body of 10 kg)
p0 = 1.0 (initial momentum = 1 kg * m / s)
q0 = 0.0 (initial speed = 0 m/s)
equations of motion:
dq/dt = ∂H/∂p = p / 10
dp/dt = - ∂H/∂q = 0
solutions:
p(t) = 1.0
q(t) = 0.1 * t
That should be reproducible using the package, but surprisingly delivers two wrong solutions with 2 different
solver algorithms.
julia> using DifferentialEquations
julia> H(p, q, param) = p^2/20
H (generic function with 1 method)
julia> p0, q0 = 1.0, 0.0;
julia> prob = HamiltonianProblem(H, p0, q0, (0., 1.))
ODEProblem with uType ArrayPartition{Float64,Tuple{Float64,Float64}} and tType Float64. In-place: false
timespan: (0.0, 1.0)
u0: 1.00.0
julia> sol = solve(prob, SofSpa10(), dt=0.001);
julia> sol(1.0)
(1.0, 0.13545807513475394)
julia> sol = solve(prob, dt=0.001);
julia> sol(1.0)
(1.0, 1.0)
@ChrisRackauckas, @dextorious I have made some notes regarding publishing a new package.
I suppose the project, which I am going to create, should be under JuliaDiffEq organization? In this case there might exist access rights issues for me.
As I understood from the docs, I need to generate a new package without using Project.toml file, but instead implementing standard structure including REQUIRE file. I faced with some problems using PkgDev
in v0.7 so, it seems like I will create the project structure manually.
Set up AppVeyor and Travis-ci testing for the N-body project.
Register/publish the package in METADATA.jl and create a pull request for that.
Tag and register v0.0.1 of the N-body package
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 enclosed config (https://github.com/JuliaDiffEq/DiffEqPhysics.jl/blob/master/src/hamiltonian.jl#L24-L36) may cause problems.
There are some common tooling which is used for analyzing the solution to force-field simulations. It would be nice to include functionality for calculating and plotting temperature and pressure over time from the simulation's solution. @dpsanders and @jiahao might have more details to give here.
@Mikhail-Vaganov some comments on the proposal someone gave me:
Periodic Boundary Condition (PBC)
Distance
The student says that for the Periodic Boundary condition appropriate particles copies will be generated when it leaves the periodic box. While a nice feature for analysis this does not the defining feature of a simulation with PBC. Rather he has to ensure that any calculated distance follows the minimum image convention (MIC). The MIC says that from any pair i,j in the simulation box and it’s infinite identical copies find to use the shortest distance. See wikipedia. For performance I recommend not using code that uses floor
to calculate the distance. Rather use a while loop.
while (x > box_x * .5) x -= box_x;
while (x < -box_x * .5) x += box_x;
The while loop will normally have only one invocation unless the particle jumps several images.
Electro / Magneto Statitics
For PBC simulations electro statics and other long range forces have to be treated specially. As correctly identified by the student one solution is Ewald summation. In simulation without Ewald summation or special screening terms to limit these forces to short-ranges the simulations will give physical wrong results. For PBC conditions if Ewald summation is a stretch goal so should be electro statics.
Thermostats
Nose Hoover Equation
The normal Nose Hoover thermostat does not reproduce the correct equilibrium distribution for a harmonic oscillator ([1] 4.10). One would instead need to use Nose Hoover chains ([1] 4.11). They are more complicated to implement and cannot be converted to a Hamiltonian system
[1] Statistical Mechanic Theory and Simulation
Anderson/Berendson Thermostat
Both only produce approximate results for very large systems and are typically used to equilibrate a system and not for production simulations.
Velocity Rescaling
This algorithm has become a standard thermostat in the MD community. It extends the ideas from Berendson and Anderson by coupling the distribution for selection of random velocities to a stochastic process. This thermostat tends to be relatively easy to implement and gives good results also for small systems. I recommend using it.
[1] Bussi et. al 2007
Langevin Thermostat
This thermostat is interesting for coarse grained simulations where I don’t want to simulate the solvent explicitly. But the random forces in the integrator violate detailed balance, eq 1, leading to different equilibrium distributions.
P(ij)ij=P(ji)ji (1)
A simple example when detailed balance is violated is using a linear increasing force F(j) > F(i) if j>i. Due to the force and the position independent random-force the probability to make a transition from i to j is not equal to the transition from j to i. The only way to minimise this error is to choose a sufficiently small timestep. This can be tested with a harmonic oscillator.
Another problem is the quick divergence of Langevin integrators for stiff potentials. For such a potential the timestep has to be chosen sufficiently small for the simulation not to diverge. Adaptive step size algorithms can help to still achieve good performance for stiff potentials.
An alternative are dynamic Monte-Carlo methods [1]-[3]. A large advantage of MC methods is that you do not need to calculate forces given a potential.
[1] Kotelyanskii et. al 1992
[2] Heyes et. al 1998
[3] Sanz et. al 2010
Particle Collision
Using continuous callbacks to simulate particle collisions sounds similar to a hard sphere simulation. Those can be solved explicitly with a variable timestep [1] Chap 14.2.
For flexibility I would leave this to potential function like the lennard jones potential.
[1] The Art Molecular Dynamics Simulation
Efficient Force/Potential Evaluations
A big problem of MD simulations is that a naiive approach scales as O(N^2) with N the number of particles. This is terrible scaling! We are lucky though that most intersting potential are only short ranged. This allows us to use a domain decomposition algorithm (also known as verlet lists). The idea is that we only need to calculate forces/energies up to a cutoff Rc and therefore only need to calculate distances for particles which are closer than Rc. This can be done by sub-dividing the simulation box into cubes of edge length Rc. Only particles in neighboring cells need to be considered for force/energy calculations. This results in a scaling of O(N). See [1] for an implementation of domain decomposition in python.
[1] CellGrid
Stretch Goals
Other possible interesting stretch goals
Multiple species with different forcefield parameters. (i.e. larger radius)
NPT ensemble simulations
Similar projects
Besides lammps and espresso other big MD engines are GROMACS, OpenMM, Amber, NAMD. The later are specifically optimized for proteins and other biological applications.
MDAnalysis is thinking about taking a student for efficient distance calculations. It might be worth it that both students share experiences for distance calculations in particular.
A good example for the force field simulator #3 would be to simulate a fluid approximated using the Lennard-Jones potential:
https://en.wikipedia.org/wiki/Lennard-Jones_potential
It's a simple and cheap way to approximate molecules in fluids and would be a good test.
While playing with a harmonic oscillator, I encountered the following interesting behaviour.
Somehow DPRKN6
ignores my hard coded mass in the hamiltonian and gives a solution as if the mass was one:
using OrdinaryDiffEq
using DiffEqPhysics
using Plots
function H(p,q, param)
m = 1000 # very heavy object, should oscillate slowly
k = 1.0
1/2*p^2/m + 1/2*k*q^2
end
p0 = 0.0
q0 = 1.0
tspan = (0, 2pi)
prob = HamiltonianProblem(H, p0, q0, tspan)
alg = McAte5() # works
alg = Tsit5() # works
alg = DPRKN6()
sol = solve(prob, alg)
plot(sol, fmt=:png)
The following notation is confusing to me and most likely to potential users.
function HamiltonianProblem{T}(H,p0,q0,tspan,p=nothing;kwargs...) where T
if T == false
if typeof(q0) <: Number
dp = function (v,x,p,t)
ForwardDiff.derivative(x->-H(v, x, p), x)
end
dq = function (v,x,p,t)
ForwardDiff.derivative(v->H(v, x, p), v)
end
A hamiltonian in physics, takes two parameters, p and q. In the above segment of code, we define the derivatives dp and dq using the following relation:
In the derivative, we use H(v,x,p) where
v is "p" which usually corresponds to momentum, the initial values are passed as p0
x is "q" which usually corresponds to position, the initial values are passed as q0
and p is p, which has nothing to do with the p associated with a hamiltonian (it's params).
Would there be any objections to me changing this a bit, so when a physicist looks at the code, it's obvious what is what? Maybe this doesn't need to be addressed, but I think it would help. I'd love to hear anyone's thoughts. Thanks!
Just specify positions, masses, and charges and let it make a SecondOrderODEProblem
.
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.