diff --git a/docs/Project.toml b/docs/Project.toml index 7cb65c49..efb87802 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -11,11 +11,12 @@ GSL = "92c85e6c-cbff-5e0c-80f7-495c94daaecd" Gmsh = "705231aa-382f-11e9-3f0c-b7cb4346fdeb" HMatrices = "8646bddf-ab1c-4fa7-9c51-ba187d647618" IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" +JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899" LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" Meshes = "eacbb407-ea5a-433e-ab97-5258b1ca43fa" +Pluto = "c3e4b0f8-55cb-11ea-2926-15256bba5781" PlutoSliderServer = "2fc8631c-6f24-4c5b-bca7-cbb509c42db4" -PlutoStaticHTML = "359b1769-a58e-495b-9770-312e911026ad" PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" diff --git a/docs/make.jl b/docs/make.jl index 53c7b2f5..81e1a8c5 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -2,7 +2,8 @@ using Inti using Documenter using DocumenterCitations using DocumenterInterLinks -using ExampleJuggler, Literate, PlutoStaticHTML, PlutoSliderServer +using ExampleJuggler, Literate, PlutoSliderServer +using Pluto, JuliaFormatter # packages needed for extensions using Gmsh using HMatrices @@ -11,65 +12,85 @@ using GLMakie using FMM2D using FMM3D -# Function to remove "begin #hide" and "end #hide" from a markdown file -function formatting_pluto(input_file::String, output_file::String) - # Read the contents of the file - file_content = read(input_file, String) - - # Replace the "begin #hide" and "end #hide" with an empty string - cleaned_content = replace(file_content, r"\b(end #hide)\b" => "") - cleaned_content = replace(cleaned_content, r"\b(end; #hide)\b" => "") - cleaned_content = replace(cleaned_content, r"\b(end;#hide)\b" => "") - cleaned_content = replace(cleaned_content, r"begin #hide\s*" => "") - cleaned_content = replace(cleaned_content, r"let #hide\s*" => "") - - # Write the modified content back to a new file - open(output_file, "w") do f - return write(f, cleaned_content) - end -end - -# Function to format the terminal output for the documentation -function formatting_terminal_output(input_file::String, output_file::String) - # Read the contents of the file - file_content = read(input_file, String) - - # Replace the plutouiterminal in the md file by plutouiterminal with padding and background color - cleaned_content = replace( - file_content, - r"\bplutouiterminal\b" => "plutouiterminal\" style=\"padding: 10px; background-color: white;", - ) - - # replace info macro (to keep?? or not use the macro) - cleaned_content = replace( - cleaned_content, - r"�\[36m�\[1m\[ �\[22m�\[39m�\[36m�\[1mInfo: �\[22m�\[39m" => "[ Info: ", - ) +cleanexamples() - # Write the modified content back to a new file - open(output_file, "w") do f - return write(f, cleaned_content) +# from https://github.com/fonsp/Pluto.jl/pull/2471 +function generate_plaintext( + notebook, + strmacrotrim::Union{String,Nothing} = nothing; + header::Function = _ -> nothing, + footer::Function = _ -> nothing, + textcomment::Function = identity, + codewrapper::Function, +) + cell_strings = String[] + header_content = header(notebook) + isnothing(header_content) || push!(cell_strings, header_content) + for cell_id in notebook.cell_order + cell = notebook.cells_dict[cell_id] + scode = strip(cell.code) + (raw, ltrim, rtrim) = if isnothing(strmacrotrim) + false, 0, 0 + elseif startswith(scode, string(strmacrotrim, '"'^3)) + true, length(strmacrotrim) + 3, 3 + elseif startswith(scode, string(strmacrotrim, '"')) + true, length(strmacrotrim) + 1, 1 + else + false, 0, 0 + end + push!( + cell_strings, + if raw + text = strip( + scode[nextind(scode, 1, ltrim):prevind(scode, end, rtrim)], + ['\n'], + ) + ifelse(Pluto.is_disabled(cell), textcomment, identity)(text) + else + codewrapper(cell, Pluto.is_disabled(cell)) + end, + ) end + footer_content = footer(notebook) + isnothing(footer_content) || push!(cell_strings, footer_content) + return join(cell_strings, "\n\n") end -# Function to format the note sections in the markdown file -function formatting_note_tip_md(input_file::String, output_file::String) - # Read the contents of the file - file_content = read(input_file, String) - - cleaned_content = - replace(file_content, r"\badmonition is-note\b" => "admonition is-info") - cleaned_content = - replace(cleaned_content, r"\badmonition is-tip\b" => "admonition is-success") - - # Write the modified content back to a new file - open(output_file, "w") do f - return write(f, cleaned_content) +function generate_md( + input; + output = replace(replace(input, r"..$" => "md"), "pluto-examples" => "module_examples"), +) + notebook = Pluto.load_notebook(input) + header = _ -> "" + fname = basename(input) + function codewrapper(cell, _) + # 1. Strips begin/end block + # 2. Reformats code using JuliaFormatter + # 3. Wraps all code in same ```@example``` block for documenter + code = strip(cell.code) + if startswith(code, "begin") && endswith(code, "end") + code = strip(code[6:end-4]) # Remove "begin" and "end" and strip spaces + # reformat code using JuliaFormatter + code = format_text(String(code)) + elseif startswith(code, "let") && endswith(code, "end") + code = strip(code[4:end-4]) # Remove "let" and "end" and strip spaces + # reformat code using JuliaFormatter + code = format_text(String(code)) + end + return if cell.code_folded + string("```@setup $fname\n", code, "\n```") + else + string("```@example $fname\n", code, "\n```") + end end + textcomment(text) = string("") + str = generate_plaintext(notebook, "md"; header, codewrapper, textcomment) + open(output, "w") do io + return write(io, str) + end + return output end -cleanexamples() - links = InterLinks( "Meshes" => "https://juliageometry.github.io/MeshesDocs/dev/objects.inv", "HMatrices" => "https://integralequations.github.io/HMatrices.jl/stable/objects.inv", @@ -97,26 +118,26 @@ end ## TO REMOVE if we decide to use Pluto Notebooks to generate documentation # Generate examples using Literate -const examples_dir = joinpath(Inti.PROJECT_ROOT, "docs", "src", "examples") +# const examples_dir = joinpath(Inti.PROJECT_ROOT, "docs", "src", "examples") const notebook_dir = joinpath(Inti.PROJECT_ROOT, "docs", "src", "pluto-examples") -const generated_dir = joinpath(Inti.PROJECT_ROOT, "docs", "src", "examples", "generated") -const examples = ["toy_example.jl", "helmholtz_scattering.jl"] -for t in examples - println("\n*** Generating $t example") - @time begin - src = joinpath(examples_dir, t) - Literate.markdown(src, generated_dir; mdstrings = true) - # if draft, skip creation of notebooks - Literate.notebook( - src, - generated_dir; - mdstrings = true, - preprocess = insert_setup, - # execute = ON_CI, - execute = false, - ) - end -end +# const generated_dir = joinpath(Inti.PROJECT_ROOT, "docs", "src", "examples", "generated") +# const examples = ["toy_example.jl", "helmholtz_scattering.jl"] +# for t in examples +# println("\n*** Generating $t example") +# @time begin +# src = joinpath(examples_dir, t) +# Literate.markdown(src, generated_dir; mdstrings = true) +# # if draft, skip creation of notebooks +# Literate.notebook( +# src, +# generated_dir; +# mdstrings = true, +# preprocess = insert_setup, +# # execute = ON_CI, +# execute = false, +# ) +# end +# end println("\n*** Generating documentation") @@ -137,22 +158,22 @@ notebooks = [ "Poisson problem" => "poisson.jl", ] -# Generate markdown versions of the notebooks for documentation using PlutoStaticHTML.jl -notebook_examples = @docplutonotebooks(notebook_dir, notebooks, iframe = false) -size_threshold_ignore = last.(notebook_examples) +mkdir(joinpath(Inti.PROJECT_ROOT, "docs", "src", "module_examples")) -# Formatting the markdown files +notebook_examples = Pair{String,String}[] for notebook in notebooks - get_md_files = replace(notebook[2], ".jl" => ".md") - file = - joinpath(Inti.PROJECT_ROOT, "docs", "src", "plutostatichtml_examples", get_md_files) - formatting_pluto(file, file) - formatting_terminal_output(file, file) - formatting_note_tip_md(file, file) + name, file = notebook + file_in = joinpath(notebook_dir, file) + file_out = generate_md(file_in) + push!( + notebook_examples, + name => joinpath("module_examples", replace(file, ".jl" => ".md")), + ) end +size_threshold_ignore = last.(notebook_examples) # Generate HTML versions of the notebooks using PlutoSliderServer.jl -notebook_examples_html = @docplutonotebooks(notebook_dir, notebooks, iframe = true) +# notebook_examples_html = @docplutonotebooks(notebook_dir, notebooks, iframe = true) makedocs(; modules = modules, @@ -178,23 +199,23 @@ makedocs(; "tutorials/correction_methods.md", "tutorials/solvers.md", ], - "Examples" => [ - "examples/generated/toy_example.md", - "examples/generated/helmholtz_scattering.md", - "examples/poisson.md", - # "examples/generated/lippmann_schwinger.md", - # "examples/generated/poisson.md", - # "examples/generated/stokes_drag.md", - ], + # "Examples" => [ + # "examples/generated/toy_example.md", + # "examples/generated/helmholtz_scattering.md", + # "examples/poisson.md", + # # "examples/generated/lippmann_schwinger.md", + # # "examples/generated/poisson.md", + # # "examples/generated/stokes_drag.md", + # ], "Notebooks" => notebook_examples, "References" => "references.md", "Docstrings" => "docstrings.md", ], - warnonly = ON_CI ? false : Documenter.except(:linkcheck_remotes), + warnonly = Documenter.except(:linkcheck_remotes), # ON_CI ? false : Documenter.except(:linkcheck_remotes), # warnonly = true, pagesonly = true, checkdocs = :none, - clean=false, + clean = false, draft, plugins = [bib, links], ) @@ -206,3 +227,5 @@ deploydocs(; devbranch = "main", push_preview = true, ) + +# GLMakie.closeall() diff --git a/docs/src/pluto-examples/helmholtz_scattering.jl b/docs/src/pluto-examples/helmholtz_scattering.jl index 82f507ab..c2c1b554 100644 --- a/docs/src/pluto-examples/helmholtz_scattering.jl +++ b/docs/src/pluto-examples/helmholtz_scattering.jl @@ -8,28 +8,28 @@ using InteractiveUtils begin import Pkg as _Pkg haskey(ENV, "PLUTO_PROJECT") && _Pkg.activate(ENV["PLUTO_PROJECT"]) - using PlutoUI: with_terminal, TableOfContents + using PlutoUI: TableOfContents end ; # ╔═╡ ef067551-aa44-4099-b32a-08debb81ee79 -begin #hide -using Inti -using LinearAlgebra -using StaticArrays -using Gmsh -using Meshes -using GLMakie -using SpecialFunctions -using GSL -using IterativeSolvers -using LinearMaps -end #hide +begin + using Inti + using LinearAlgebra + using StaticArrays + using Gmsh + using Meshes + using GLMakie + using SpecialFunctions + using GSL + using IterativeSolvers + using LinearMaps +end # ╔═╡ a6c80f87-ff47-496f-8925-1275b58b02e1 md""" # Helmholtz scattering -[![Pluto notebook](https://img.shields.io/badge/download-Pluto_notebook-blue)](../../pluto_examples/helmholtz_scattering.jl) $\hspace{0.2cm}$ [![nbviewer](https://img.shields.io/badge/show-nbviewer-blue.svg)](../../pluto_examples/helmholtz_scattering.html) +[![Pluto notebook](https://img.shields.io/badge/download-Pluto_notebook-blue)](../../pluto_examples/helmholtz_scattering.jl)$\hspace{5pt}$[![nbviewer](https://img.shields.io/badge/show-nbviewer-blue.svg)](../../pluto_examples/helmholtz_scattering.html) """ # ╔═╡ 1715d794-a33d-4faf-953c-b706a9ceea23 @@ -46,7 +46,7 @@ md""" md""" In this tutorial we will show how to solve an acoustic scattering problem in the context of Helmholtz equation. We will focus on a *smooth* sound-soft obstacle for simplicity, and introduce along the way the necessary techniques used to handle some difficulties encountered. We will use various packages throughout this example (including of course `Inti.jl`); if they are not on your environment, you can install them using `] add ` in the REPL. -In the [following section](@ref helmholtz-soundsoft), we will provide a brief mathematical description of the problem (valid in both $2$ and $3$ dimensions). We will tackle the [two-dimensional problem](@ref helmholtz-scattering-2d) first, for which we do not need to worry much about performance issues (e.g. compressing the integral operators). Finally, we present a [three-dimensional example](@ref helmholtz-scattering-3d), where we will use [`HMatrices.jl`](https://github.com/IntegralEquatins/HMatrices.jl) to compress the underlying integral operators. +In the [following section](#Sound-soft-problem), we will provide a brief mathematical description of the problem (valid in both $2$ and $3$ dimensions). We will tackle the [two-dimensional problem](#Two-dimensional-scattering) first, for which we do not need to worry much about performance issues (e.g. compressing the integral operators). Finally, we present a [three-dimensional example](#Three-dimensional-scattering), where we will use [`HMatrices.jl`](https://github.com/IntegralEquations/HMatrices.jl) to compress the underlying integral operators. """ # ╔═╡ 643919c5-762f-4fa6-ac26-6bf0abd94558 @@ -121,36 +121,40 @@ and setup some of the (global) problem parameters: """ # ╔═╡ 4cabe108-93c6-4fbf-b8ec-37277abbbda1 -begin #hide -k = 4π -λ = 2π / k -qorder = 4 # quadrature order -gorder = 2 # order of geometrical approximation -end; #hide +begin + k = 4π + λ = 2π / k + qorder = 4 # quadrature order + gorder = 2 # order of geometrical approximation + nothing #hide +end # ╔═╡ a33f066e-307c-42c4-836b-5b7d8236a893 md""" ## Two-dimensional scattering -We will use [Gmsh API](https://gmsh.info/doc/texinfo/gmsh.htmlGmsh-application-programming-interface) for creating `.msh` file containing the desired geometry and mesh. Here is a function to mesh the circle: +We will use [Gmsh API](https://gmsh.info/doc/texinfo/gmsh.html#Gmsh-application-programming-interface) for creating `.msh` file containing the desired geometry and mesh. Here is a function to mesh the circle: """ # ╔═╡ cb736b4d-bbd6-456c-9041-f69b2155a470 -function gmsh_circle(; name, meshsize, order = 1, radius = 1, center = (0, 0)) - try - gmsh.initialize() - gmsh.model.add("circle-mesh") - gmsh.option.setNumber("Mesh.MeshSizeMax", meshsize) - gmsh.option.setNumber("Mesh.MeshSizeMin", meshsize) - gmsh.model.occ.addDisk(center[1], center[2], 0, radius, radius) - gmsh.model.occ.synchronize() - gmsh.model.mesh.generate(1) - gmsh.model.mesh.setOrder(order) - gmsh.write(name) - finally - gmsh.finalize() - end -end; +begin + function gmsh_circle(; name, meshsize, order = 1, radius = 1, center = (0, 0)) + try + gmsh.initialize() + gmsh.model.add("circle-mesh") + gmsh.option.setNumber("Mesh.MeshSizeMax", meshsize) + gmsh.option.setNumber("Mesh.MeshSizeMin", meshsize) + gmsh.model.occ.addDisk(center[1], center[2], 0, radius, radius) + gmsh.model.occ.synchronize() + gmsh.model.mesh.generate(1) + gmsh.model.mesh.setOrder(order) + gmsh.write(name) + finally + gmsh.finalize() + end + end + nothing #hide +end # ╔═╡ 2ed4fd2d-b3c2-4211-bf3f-c551923e65cf md""" @@ -158,20 +162,10 @@ Let us now use `gmsh_circle` to create a `circle.msh` file. As customary in wave """ # ╔═╡ 12e20620-042c-4040-bd64-af01bd0f2ad9 -# ╠═╡ show_logs = false -begin #hide -name = joinpath(@__DIR__, "circle.msh") -meshsize = λ / 5 -gmsh_circle(; meshsize, order = gorder, name) -end #hide - -# ╔═╡ 867186cf-fd4c-484b-9ded-344573ccda4f -let # to render terminal output in the documentation - with_terminal() do - name = joinpath(@__DIR__, "circle.msh") - meshsize = λ / 5 - gmsh_circle(; meshsize, order = gorder, name) - end +begin + name = joinpath(@__DIR__, "circle.msh") + meshsize = λ / 5 + gmsh_circle(; meshsize, order = gorder, name) end # ╔═╡ 24454bd5-00cf-4282-926f-f1324141fe26 @@ -180,10 +174,11 @@ We can now import the file and parse the mesh and domain information into `Inti. """ # ╔═╡ ff73663c-7cf4-4b23-83b5-095dc66f711f -begin #hide -Inti.clear_entities!() # empty the entity cache -msh = Inti.import_mesh(name; dim = 2) -end #hide +# ╠═╡ show_logs = false +begin + Inti.clear_entities!() # empty the entity cache + msh = Inti.import_mesh(name; dim = 2) +end # ╔═╡ 176f1fef-f761-4ad0-8fea-982eab4fe24d md""" @@ -200,11 +195,12 @@ for: """ # ╔═╡ 09a785ae-7286-4a47-b103-1e90efa20167 -begin #hide -Γ = Inti.boundary(Ω) -Γ_msh = view(msh, Γ) -Q = Inti.Quadrature(Γ_msh; qorder) -end; #hide +begin + Γ = Inti.boundary(Ω) + Γ_msh = view(msh, Γ) + Q = Inti.Quadrature(Γ_msh; qorder) + nothing #hide +end # ╔═╡ 593216db-810e-47db-b6cb-aa6cf53e8590 md""" @@ -234,16 +230,17 @@ With the [`Quadrature`](@ref Inti.Quadrature) constructed, we now can define dis """ # ╔═╡ 9b37d163-15ca-44af-9e00-7410956fc16c -begin #hide -pde = Inti.Helmholtz(; k, dim = 2) -S, D = Inti.single_double_layer(; - pde, - target = Q, - source = Q, - compression = (method = :none,), - correction = (method = :dim,), -) -end; #hide +begin + pde = Inti.Helmholtz(; k, dim = 2) + S, D = Inti.single_double_layer(; + pde, + target = Q, + source = Q, + compression = (method = :none,), + correction = (method = :dim,), + ) + nothing #hide +end # ╔═╡ 061b7503-bad0-411e-b126-eea4b89feb03 md""" @@ -257,7 +254,10 @@ We can now combine `S` and `D` to form the combined-field operator: """ # ╔═╡ ebaf6ed5-8e01-4c5f-9d7f-8cdc32a68022 -L = I / 2 + D - im * k * S ; +begin + L = I / 2 + D - im * k * S + nothing #hide +end # ╔═╡ 8ba9aadc-5b34-41cb-adba-1ebdc65a741d md""" @@ -265,13 +265,14 @@ where `I` is the identity matrix. Assuming an incident field along the $x_1$ dir """ # ╔═╡ eaf2025e-1135-4ee6-9dea-25e2c0c09ec8 -begin #hide -uᵢ = x -> exp(im * k * x[1]) # plane-wave incident field -rhs = map(Q) do q - x = q.coords - return -uᵢ(x) +begin + uᵢ = x -> exp(im * k * x[1]) # plane-wave incident field + rhs = map(Q) do q + x = q.coords + return -uᵢ(x) + end + nothing #hide end -end; #hide # ╔═╡ 7fcd47c1-9d65-41e2-9363-141d53f0dbca md""" @@ -285,7 +286,10 @@ We can now solve the integral equation using e.g. the backslash operator: """ # ╔═╡ 2925e1a3-1051-4b09-bbd9-461c6a76a1e3 -σ = L \ rhs ; +begin + σ = L \ rhs + nothing #hide +end # ╔═╡ b26e0c64-b3f1-4b18-a6f5-8f789407a744 md""" @@ -293,10 +297,11 @@ The variable `σ` contains the value of the approximate density at the quadratur """ # ╔═╡ fd0f2cf4-1b18-4c56-84a9-2339b3dfc10a -begin #hide -𝒮, 𝒟 = Inti.single_double_layer_potential(; pde, source = Q) -uₛ = x -> 𝒟[σ](x) - im * k * 𝒮[σ](x) -end; #hide +begin + 𝒮, 𝒟 = Inti.single_double_layer_potential(; pde, source = Q) + uₛ = x -> 𝒟[σ](x) - im * k * 𝒮[σ](x) + nothing #hide +end # ╔═╡ 12b3c26a-96b3-440b-9771-4a945fe14ce7 md""" @@ -306,24 +311,27 @@ To assess the accuracy of the solution, we can compare it to the exact solution """ # ╔═╡ 185cfa1e-7c87-4243-8f5e-c5983932e135 -function circle_helmholtz_soundsoft(pt; radius = 1, k, θin) - x = pt[1] - y = pt[2] - r = sqrt(x^2 + y^2) - θ = atan(y, x) - u = 0.0 - r < radius && return u - c(n) = -exp(im * n * (π / 2 - θin)) * besselj(n, k * radius) / besselh(n, k * radius) - u = c(0) * besselh(0, k * r) - n = 1 - while (abs(c(n)) > 1e-12) - u += - c(n) * besselh(n, k * r) * exp(im * n * θ) + - c(-n) * besselh(-n, k * r) * exp(-im * n * θ) - n += 1 - end - return u -end; +begin + function circle_helmholtz_soundsoft(pt; radius = 1, k, θin) + x = pt[1] + y = pt[2] + r = sqrt(x^2 + y^2) + θ = atan(y, x) + u = 0.0 + r < radius && return u + c(n) = -exp(im * n * (π / 2 - θin)) * besselj(n, k * radius) / besselh(n, k * radius) + u = c(0) * besselh(0, k * r) + n = 1 + while (abs(c(n)) > 1e-12) + u += + c(n) * besselh(n, k * r) * exp(im * n * θ) + + c(-n) * besselh(-n, k * r) * exp(-im * n * θ) + n += 1 + end + return u + end + nothing #hide +end # ╔═╡ 4c37081c-4f68-48fe-be5b-bebf35f0c35e md""" @@ -331,24 +339,18 @@ Here is the maximum error on some points located on a circle of radius `2`: """ # ╔═╡ 1daa0518-a98b-448c-bddd-1147a0f7ed4d -# ╠═╡ show_logs = false -begin #hide -uₑ = x -> circle_helmholtz_soundsoft(x; k, radius = 1, θin = 0) # exact solution -er = maximum(0:0.01:2π) do θ - R = 2 - x = (R * cos(θ), R * sin(θ)) - return abs(uₛ(x) - uₑ(x)) +begin + uₑ = x -> circle_helmholtz_soundsoft(x; k, radius = 1, θin = 0) # exact solution + er = maximum(0:0.01:2π) do θ + R = 2 + x = (R * cos(θ), R * sin(θ)) + return abs(uₛ(x) - uₑ(x)) + end + @info "maximum error = $er" end -@info "maximum error = $er" -end #hide # ╔═╡ 3557cd23-43b2-4c79-a0e9-53c0d9650851 -let - @assert er < 1e-3 - with_terminal() do - @info "maximum error = $er" - end -end +@assert er < 1e-3 # ╔═╡ 42a42555-0c97-4a40-8865-38966983a9e7 md""" @@ -356,22 +358,22 @@ As we can see, the error is quite small! Let's use `Makie` to visualize the solu """ # ╔═╡ 56350a37-b2d8-463e-934f-e8a4fbf72c67 -begin #hide -xx = yy = range(-4; stop = 4, length = 200) -vals = - map(pt -> Inti.isinside(pt, Q) ? NaN : real(uₛ(pt) + uᵢ(pt)), Iterators.product(xx, yy)) -fig, ax, hm = heatmap( - xx, - yy, - vals; - colormap = :inferno, - interpolate = true, - axis = (aspect = DataAspect(), xgridvisible = false, ygridvisible = false), -) -viz!(Γ_msh; color = :white, segmentsize = 5) -Colorbar(fig[1, 2], hm) -fig -end #hide +begin + xx = yy = range(-4; stop = 4, length = 200) + vals = + map(pt -> Inti.isinside(pt, Q) ? NaN : real(uₛ(pt) + uᵢ(pt)), Iterators.product(xx, yy)) + fig, ax, hm = heatmap( + xx, + yy, + vals; + colormap = :inferno, + interpolate = true, + axis = (aspect = DataAspect(), xgridvisible = false, ygridvisible = false), + ) + viz!(Γ_msh; color = :white, segmentsize = 5) + Colorbar(fig[1, 2], hm) + fig +end # ╔═╡ 471a5475-1ef5-4f40-bb45-a3e29ae5c0a8 md""" @@ -381,45 +383,45 @@ Before moving on to the 3D example let us simply mention that, besides the fact """ # ╔═╡ 3f3f4794-f2bf-4171-a1b4-70fd38c01fc3 -let #hide -# vertices of an equilateral triangle centered at the origin with a vertex at (0,1) -a, b, c = SVector(0, 1), SVector(sqrt(3) / 2, -1 / 2), SVector(-sqrt(3) / 2, -1 / 2) -circle_f(center, radius) = s -> center + radius * SVector(cospi(2 * s[1]), sinpi(2 * s[1])) -disk1 = Inti.parametric_curve(circle_f(a, 1 / 2), 0, 1) -disk2 = Inti.parametric_curve(circle_f(b, 1 / 2), 0, 1) -disk3 = Inti.parametric_curve(circle_f(c, 1 / 2), 0, 1) -Γ = disk1 ∪ disk2 ∪ disk3 -msh = Inti.meshgen(Γ; meshsize) -Γ_msh = view(msh, Γ) -Q = Inti.Quadrature(Γ_msh; qorder) -S, D = Inti.single_double_layer(; - pde, - target = Q, - source = Q, - compression = (method = :none,), - correction = (method = :dim,), -) -L = I / 2 + D - im * k * S -rhs = map(q -> -uᵢ(q.coords), Q) -σ = L \ rhs -𝒮, 𝒟 = Inti.single_double_layer_potential(; pde, source = Q) -uₛ = x -> 𝒟[σ](x) - im * k * 𝒮[σ](x) -vals = - map(pt -> Inti.isinside(pt, Q) ? NaN : real(uₛ(pt) + uᵢ(pt)), Iterators.product(xx, yy)) -colorrange = (-2, 2) -fig, ax, hm = heatmap( - xx, - yy, - vals; - colormap = :inferno, - colorrange, - interpolate = true, - axis = (aspect = DataAspect(), xgridvisible = false, ygridvisible = false), -) -viz!(Γ_msh; color = :black, segmentsize = 4) -Colorbar(fig[1, 2], hm) -fig -end #hide +let + # vertices of an equilateral triangle centered at the origin with a vertex at (0,1) + a, b, c = SVector(0, 1), SVector(sqrt(3) / 2, -1 / 2), SVector(-sqrt(3) / 2, -1 / 2) + circle_f(center, radius) = s -> center + radius * SVector(cospi(2 * s[1]), sinpi(2 * s[1])) + disk1 = Inti.parametric_curve(circle_f(a, 1 / 2), 0, 1) + disk2 = Inti.parametric_curve(circle_f(b, 1 / 2), 0, 1) + disk3 = Inti.parametric_curve(circle_f(c, 1 / 2), 0, 1) + Γ = disk1 ∪ disk2 ∪ disk3 + msh = Inti.meshgen(Γ; meshsize) + Γ_msh = view(msh, Γ) + Q = Inti.Quadrature(Γ_msh; qorder) + S, D = Inti.single_double_layer(; + pde, + target = Q, + source = Q, + compression = (method = :none,), + correction = (method = :dim,), + ) + L = I / 2 + D - im * k * S + rhs = map(q -> -uᵢ(q.coords), Q) + σ = L \ rhs + 𝒮, 𝒟 = Inti.single_double_layer_potential(; pde, source = Q) + uₛ = x -> 𝒟[σ](x) - im * k * 𝒮[σ](x) + vals = + map(pt -> Inti.isinside(pt, Q) ? NaN : real(uₛ(pt) + uᵢ(pt)), Iterators.product(xx, yy)) + colorrange = (-2, 2) + fig, ax, hm = heatmap( + xx, + yy, + vals; + colormap = :inferno, + colorrange, + interpolate = true, + axis = (aspect = DataAspect(), xgridvisible = false, ygridvisible = false), + ) + viz!(Γ_msh; color = :black, segmentsize = 4) + Colorbar(fig[1, 2], hm) + fig +end # ╔═╡ b8fd284a-3865-4762-9602-6bc1eba464a4 md""" @@ -437,27 +439,30 @@ The visualization is also more involved, and we will use the `Gmsh` API to creat """ # ╔═╡ b02fbb5b-ce97-48e7-ab2b-a8db6ca7c8d3 -function gmsh_sphere(; meshsize, order = gorder, radius = 1, visualize = false, name) - gmsh.initialize() - gmsh.model.add("sphere-scattering") - gmsh.option.setNumber("Mesh.MeshSizeMax", meshsize) - gmsh.option.setNumber("Mesh.MeshSizeMin", meshsize) - sphere_tag = gmsh.model.occ.addSphere(0, 0, 0, radius) - xl, yl, zl = -2 * radius, -2 * radius, 0 - Δx, Δy = 4 * radius, 4 * radius - rectangle_tag = gmsh.model.occ.addRectangle(xl, yl, zl, Δx, Δy) - outDimTags, _ = - gmsh.model.occ.cut([(2, rectangle_tag)], [(3, sphere_tag)], -1, true, false) - gmsh.model.occ.synchronize() - gmsh.model.addPhysicalGroup(3, [sphere_tag], -1, "omega") - gmsh.model.addPhysicalGroup(2, [dt[2] for dt in outDimTags], -1, "sigma") - gmsh.model.mesh.generate(2) - gmsh.model.mesh.setOrder(order) - visualize && gmsh.fltk.run() - gmsh.option.setNumber("Mesh.SaveAll", 1) # otherwise only the physical groups are saved - gmsh.write(name) - return gmsh.finalize() -end; +begin + function gmsh_sphere(; meshsize, order = gorder, radius = 1, visualize = false, name) + gmsh.initialize() + gmsh.model.add("sphere-scattering") + gmsh.option.setNumber("Mesh.MeshSizeMax", meshsize) + gmsh.option.setNumber("Mesh.MeshSizeMin", meshsize) + sphere_tag = gmsh.model.occ.addSphere(0, 0, 0, radius) + xl, yl, zl = -2 * radius, -2 * radius, 0 + Δx, Δy = 4 * radius, 4 * radius + rectangle_tag = gmsh.model.occ.addRectangle(xl, yl, zl, Δx, Δy) + outDimTags, _ = + gmsh.model.occ.cut([(2, rectangle_tag)], [(3, sphere_tag)], -1, true, false) + gmsh.model.occ.synchronize() + gmsh.model.addPhysicalGroup(3, [sphere_tag], -1, "omega") + gmsh.model.addPhysicalGroup(2, [dt[2] for dt in outDimTags], -1, "sigma") + gmsh.model.mesh.generate(2) + gmsh.model.mesh.setOrder(order) + visualize && gmsh.fltk.run() + gmsh.option.setNumber("Mesh.SaveAll", 1) # otherwise only the physical groups are saved + gmsh.write(name) + return gmsh.finalize() + end + nothing #hide +end # ╔═╡ 49f0edcd-9cb8-4722-ae56-b17ee48f8336 md""" @@ -465,11 +470,12 @@ As before, lets write a file with our mesh, and import it into `Inti.jl`: """ # ╔═╡ a18b8726-fa97-4388-bb8b-53965a5d433b -begin #hide -name_sphere = joinpath(@__DIR__, "sphere.msh") -gmsh_sphere(; meshsize=(λ / 5), order = gorder, name=name_sphere, visualize = false) -msh_3d = Inti.import_mesh(name_sphere; dim = 3) -end #hide +# ╠═╡ show_logs = false +begin + name_sphere = joinpath(@__DIR__, "sphere.msh") + gmsh_sphere(; meshsize=(λ / 5), order = gorder, name=name_sphere, visualize = false) + msh_3d = Inti.import_mesh(name_sphere; dim = 3) +end # ╔═╡ 063e3185-8714-4955-b985-5413420a889b md""" @@ -483,11 +489,12 @@ Since we created physical groups in `Gmsh`, we can use them to extract the relev """ # ╔═╡ 631328d5-c961-41e1-ac0e-181c3bb75112 -begin #hide -Ω_3d = Inti.Domain(e -> "omega" ∈ Inti.labels(e), Inti.entities(msh_3d)) -Σ_3d = Inti.Domain(e -> "sigma" ∈ Inti.labels(e), Inti.entities(msh_3d)) -Γ_3d = Inti.boundary(Ω_3d) -end; #hide +begin + Ω_3d = Inti.Domain(e -> "omega" ∈ Inti.labels(e), Inti.entities(msh_3d)) + Σ_3d = Inti.Domain(e -> "sigma" ∈ Inti.labels(e), Inti.entities(msh_3d)) + Γ_3d = Inti.boundary(Ω_3d) + nothing #hide +end # ╔═╡ dbd6d298-0fbf-420f-9622-d1db1d550cc5 md""" @@ -495,23 +502,25 @@ We can now create a quadrature as before """ # ╔═╡ 6096328b-e1af-4ec5-b72b-cd381c166cb7 -begin #hide -Γ_msh_3d = view(msh_3d, Γ_3d) -Q_3d = Inti.Quadrature(Γ_msh_3d; qorder) -end; #hide +begin + Γ_msh_3d = view(msh_3d, Γ_3d) + Q_3d = Inti.Quadrature(Γ_msh_3d; qorder) + nothing #hide +end # ╔═╡ 498fa575-5cf7-4a7e-8d3b-c50d605aa57c -begin #hide -using HMatrices -pde_3d = Inti.Helmholtz(; k, dim = 3) -S_3d, D_3d = Inti.single_double_layer(; - pde = pde_3d, - target = Q_3d, - source = Q_3d, - compression = (method = :hmatrix, tol = 1e-4), - correction = (method = :dim,), -) -end; #hide +begin + using HMatrices + pde_3d = Inti.Helmholtz(; k, dim = 3) + S_3d, D_3d = Inti.single_double_layer(; + pde = pde_3d, + target = Q_3d, + source = Q_3d, + compression = (method = :hmatrix, tol = 1e-4), + correction = (method = :dim,), + ) + nothing #hide +end # ╔═╡ b6cad085-eb74-4152-8850-226ed837febd md""" @@ -530,17 +539,9 @@ Here is how much memory it would take to store the dense representation of these """ # ╔═╡ 54f07c21-339b-44c3-9ac2-22af163d55ae -# ╠═╡ show_logs = false -begin #hide -mem = 2 * length(S_3d) * 16 / 1e9 # 16 bytes per complex number, 1e9 bytes per GB, two matrices -println("memory required to store S and D: $(mem) GB") -end #hide - -# ╔═╡ baea69b3-028b-4617-83f1-1ab9e2ca7115 -let # to render terminal output in the documentation - with_terminal() do - println("memory required to store S and D: $(mem) GB") - end +begin + mem = 2 * length(S_3d) * 16 / 1e9 # 16 bytes per complex number, 1e9 bytes per GB, two matrices + println("memory required to store S and D: $(mem) GB") end # ╔═╡ 915d3636-70bd-4001-857f-3aae11eb2d2e @@ -560,7 +561,10 @@ We will use the generalized minimal residual (GMRES) iterative solver, for the l """ # ╔═╡ a2ddce1e-440e-49e2-8c3e-ec6960ff83f0 -L_3d = I / 2 + LinearMap(D_3d) - im * k * LinearMap(S_3d) ; +begin + L_3d = I / 2 + LinearMap(D_3d) - im * k * LinearMap(S_3d) + nothing #hide +end # ╔═╡ f148c58a-50d3-4ac2-a1da-148563d533e7 md""" @@ -569,15 +573,15 @@ We can now solve the linear system using GMRES solver: # ╔═╡ dcf006a3-5332-442a-9771-f427cd7189a5 # ╠═╡ show_logs = false -begin #hide -rhs_3d = map(Q_3d) do q - x = q.coords - return -uᵢ(x) +begin + rhs_3d = map(Q_3d) do q + x = q.coords + return -uᵢ(x) + end + σ_3d, hist = + gmres(L_3d, rhs_3d; log = true, abstol = 1e-6, verbose = false, restart = 100, maxiter = 100) + @show hist end -σ_3d, hist = - gmres(L_3d, rhs_3d; log = true, abstol = 1e-6, verbose = false, restart = 100, maxiter = 100) -@show hist -end #hide # ╔═╡ 215677a6-af7b-4e5d-863f-aabdfb4a1400 md""" @@ -585,10 +589,11 @@ As before, let us represent the solution using `IntegralPotential`s: """ # ╔═╡ 14a549ad-e23f-40a4-b7fa-ef31354805a9 -begin #hide -𝒮_3d, 𝒟_3d = Inti.single_double_layer_potential(; pde=pde_3d, source = Q_3d) -uₛ_3d = x -> 𝒟_3d[σ_3d](x) - im * k * 𝒮_3d[σ_3d](x) -end; #hide +begin + 𝒮_3d, 𝒟_3d = Inti.single_double_layer_potential(; pde=pde_3d, source = Q_3d) + uₛ_3d = x -> 𝒟_3d[σ_3d](x) - im * k * 𝒮_3d[σ_3d](x) + nothing #hide +end # ╔═╡ 832858dc-2475-4f6a-a820-a557b2883f0c md""" @@ -596,32 +601,33 @@ To check the result, we compare against the exact solution obtained through a se """ # ╔═╡ e00c4d90-aa3b-41f9-b65e-7e9ace89a295 -begin #hide -sphbesselj(l, r) = sqrt(π / (2r)) * besselj(l + 1 / 2, r) -sphbesselh(l, r) = sqrt(π / (2r)) * besselh(l + 1 / 2, r) -sphharmonic(l, m, θ, ϕ) = GSL.sf_legendre_sphPlm(l, abs(m), cos(θ)) * exp(im * m * ϕ) -function sphere_helmholtz_soundsoft(xobs; radius = 1, k = 1, θin = 0, ϕin = 0) - x = xobs[1] - y = xobs[2] - z = xobs[3] - r = sqrt(x^2 + y^2 + z^2) - θ = acos(z / r) - ϕ = atan(y, x) - u = 0.0 - r < radius && return u - function c(l, m) - return -4π * im^l * sphharmonic(l, -m, θin, ϕin) * sphbesselj(l, k * radius) / sphbesselh(l, k * radius) - end - l = 0 - for l in 0:60 - for m in -l:l - u += c(l, m) * sphbesselh(l, k * r) * sphharmonic(l, m, θ, ϕ) - end - l += 1 - end - return u +begin + sphbesselj(l, r) = sqrt(π / (2r)) * besselj(l + 1 / 2, r) + sphbesselh(l, r) = sqrt(π / (2r)) * besselh(l + 1 / 2, r) + sphharmonic(l, m, θ, ϕ) = GSL.sf_legendre_sphPlm(l, abs(m), cos(θ)) * exp(im * m * ϕ) + function sphere_helmholtz_soundsoft(xobs; radius = 1, k = 1, θin = 0, ϕin = 0) + x = xobs[1] + y = xobs[2] + z = xobs[3] + r = sqrt(x^2 + y^2 + z^2) + θ = acos(z / r) + ϕ = atan(y, x) + u = 0.0 + r < radius && return u + function c(l, m) + return -4π * im^l * sphharmonic(l, -m, θin, ϕin) * sphbesselj(l, k * radius) / sphbesselh(l, k * radius) + end + l = 0 + for l in 0:60 + for m in -l:l + u += c(l, m) * sphbesselh(l, k * r) * sphharmonic(l, m, θ, ϕ) + end + l += 1 + end + return u + end + nothing #hide end -end; #hide # ╔═╡ bb87f66d-5e68-49c5-9167-bdbab60109e5 md""" @@ -629,24 +635,18 @@ We will compute the error on some point on the sphere of radius `2`: """ # ╔═╡ 3848717e-0c30-4c0b-82ec-b504c9210483 -# ╠═╡ show_logs = false -begin #hide -uₑ_3d = (x) -> sphere_helmholtz_soundsoft(x; radius = 1, k = k, θin = π / 2, ϕin = 0) -er_3d = maximum(1:100) do _ - x̂ = rand(Inti.Point3D) |> normalize # an SVector of unit norm - x = 2 * x̂ - return abs(uₛ_3d(x) - uₑ_3d(x)) +begin + uₑ_3d = (x) -> sphere_helmholtz_soundsoft(x; radius = 1, k = k, θin = π / 2, ϕin = 0) + er_3d = maximum(1:100) do _ + x̂ = rand(Inti.Point3D) |> normalize # an SVector of unit norm + x = 2 * x̂ + return abs(uₛ_3d(x) - uₑ_3d(x)) + end + @info "error with correction = $er_3d" end -@info "error with correction = $er_3d" -end #hide # ╔═╡ 36ddb3be-7103-429f-9011-99c27c655de5 -let # Render terminal output in documentation - with_terminal() do - @assert er_3d < 1e-3 #hide - @info "error with correction = $er_3d" - end -end +@assert er_3d < 1e-3 # ╔═╡ 386046f6-6909-4e9e-bb90-80c32df59f70 md""" @@ -654,23 +654,24 @@ We see that, once again, the approximation is quite accurate. Let us now visuali """ # ╔═╡ b2b31b38-4c2f-4763-9273-971749c40d5c -begin #hide -Σ_msh = view(msh_3d, Σ_3d) -target = Inti.nodes(Σ_msh) - -S_viz, D_viz = Inti.single_double_layer(; - pde = pde_3d, - target, - source = Q_3d, - compression = (method = :hmatrix, tol = 1e-4), - # correction for the nearfield (for visual purposes, set to `:none` to disable) - correction = (method = :dim, maxdist = meshsize, target_location = :outside), -) - -ui_eval_msh = uᵢ.(target) -us_eval_msh = D_viz * σ_3d - im * k * S_viz * σ_3d -u_eval_msh = ui_eval_msh + us_eval_msh -end; #hide +begin + Σ_msh = view(msh_3d, Σ_3d) + target = Inti.nodes(Σ_msh) + + S_viz, D_viz = Inti.single_double_layer(; + pde = pde_3d, + target, + source = Q_3d, + compression = (method = :hmatrix, tol = 1e-4), + # correction for the nearfield (for visual purposes, set to `:none` to disable) + correction = (method = :dim, maxdist = meshsize, target_location = :outside), + ) + + ui_eval_msh = uᵢ.(target) + us_eval_msh = D_viz * σ_3d - im * k * S_viz * σ_3d + u_eval_msh = ui_eval_msh + us_eval_msh + nothing #hide +end # ╔═╡ 0cec09b1-8806-4aee-970d-cc0b1e4b841c md""" @@ -678,19 +679,17 @@ Finalize, we use [`Meshes.viz`](@extref) to visualize the scattered field: """ # ╔═╡ dab9a19c-977e-4ab1-a3d9-f9970af69642 -begin #hide -nv = length(Inti.nodes(Γ_msh_3d)) -colorrange = extrema(real(u_eval_msh)) -colormap = :inferno -fig_3d = Figure(; size = (800, 500)) -ax_3d = Axis3(fig_3d[1, 1]; aspect = :data) -viz!(Γ_msh_3d; colorrange, colormap, color = zeros(nv), interpolate = true) -viz!(Σ_msh; colorrange, colormap, color = real(u_eval_msh)) -cb = Colorbar(fig_3d[1, 2]; label = "real(u)", colormap, colorrange) -end; #hide - -# ╔═╡ 0c1114d1-256c-44e3-bbd4-9b5077fc7ee8 -fig_3d +begin + nv = length(Inti.nodes(Γ_msh_3d)) + colorrange = extrema(real(u_eval_msh)) + colormap = :inferno + fig_3d = Figure(; size = (800, 500)) + ax_3d = Axis3(fig_3d[1, 1]; aspect = :data) + viz!(Γ_msh_3d; colorrange, colormap, color = zeros(nv), interpolate = true) + viz!(Σ_msh; colorrange, colormap, color = real(u_eval_msh)) + cb = Colorbar(fig_3d[1, 2]; label = "real(u)", colormap, colorrange) + fig_3d #hide +end # ╔═╡ 765e46fc-dac3-439a-ab07-2865298aed45 TableOfContents() @@ -2766,7 +2765,6 @@ version = "1.4.1+1" # ╠═cb736b4d-bbd6-456c-9041-f69b2155a470 # ╟─2ed4fd2d-b3c2-4211-bf3f-c551923e65cf # ╠═12e20620-042c-4040-bd64-af01bd0f2ad9 -# ╟─867186cf-fd4c-484b-9ded-344573ccda4f # ╟─24454bd5-00cf-4282-926f-f1324141fe26 # ╠═ff73663c-7cf4-4b23-83b5-095dc66f711f # ╟─176f1fef-f761-4ad0-8fea-982eab4fe24d @@ -2812,7 +2810,6 @@ version = "1.4.1+1" # ╠═498fa575-5cf7-4a7e-8d3b-c50d605aa57c # ╟─ba95db2c-979a-41f2-9705-92d3cedd0160 # ╠═54f07c21-339b-44c3-9ac2-22af163d55ae -# ╟─baea69b3-028b-4617-83f1-1ab9e2ca7115 # ╟─915d3636-70bd-4001-857f-3aae11eb2d2e # ╟─bc09986a-5378-4d0b-a2b2-df9245f3f9cf # ╟─b9e36a69-a3d1-41c8-8951-01f92acf0806 @@ -2830,7 +2827,6 @@ version = "1.4.1+1" # ╠═b2b31b38-4c2f-4763-9273-971749c40d5c # ╟─0cec09b1-8806-4aee-970d-cc0b1e4b841c # ╠═dab9a19c-977e-4ab1-a3d9-f9970af69642 -# ╟─0c1114d1-256c-44e3-bbd4-9b5077fc7ee8 # ╟─765e46fc-dac3-439a-ab07-2865298aed45 # ╟─00000000-0000-0000-0000-000000000001 # ╟─00000000-0000-0000-0000-000000000002 diff --git a/docs/src/pluto-examples/poisson.jl b/docs/src/pluto-examples/poisson.jl index 62bb262a..ece579b9 100644 --- a/docs/src/pluto-examples/poisson.jl +++ b/docs/src/pluto-examples/poisson.jl @@ -8,34 +8,33 @@ using InteractiveUtils begin import Pkg as _Pkg haskey(ENV, "PLUTO_PROJECT") && _Pkg.activate(ENV["PLUTO_PROJECT"]) - using PlutoUI: with_terminal + using PlutoUI: TableOfContents end ; # ╔═╡ 332bd3bb-c720-454e-80af-89ad65041773 -# ╠═╡ show_logs = false -begin #hide -using Inti, Gmsh -meshsize = 0.1 -gmsh.initialize() -jellyfish = Inti.gmsh_curve(0, 2π; meshsize) do s - r = 1 + 0.3*cos(4*s + 2*sin(s)) - return r*Inti.Point2D(cos(s), sin(s)) +begin + using Inti, Gmsh + meshsize = 0.1 + gmsh.initialize() + jellyfish = Inti.gmsh_curve(0, 2π; meshsize) do s + r = 1 + 0.3*cos(4*s + 2*sin(s)) + return r*Inti.Point2D(cos(s), sin(s)) + end + cl = gmsh.model.occ.addCurveLoop([jellyfish]) + surf = gmsh.model.occ.addPlaneSurface([cl]) + gmsh.model.occ.synchronize() + gmsh.option.setNumber("Mesh.MeshSizeMax", meshsize) + gmsh.model.mesh.generate(2) + gmsh.model.mesh.setOrder(2) + msh = Inti.import_mesh(; dim = 2) + gmsh.finalize() end -cl = gmsh.model.occ.addCurveLoop([jellyfish]) -surf = gmsh.model.occ.addPlaneSurface([cl]) -gmsh.model.occ.synchronize() -gmsh.option.setNumber("Mesh.MeshSizeMax", meshsize) -gmsh.model.mesh.generate(2) -gmsh.model.mesh.setOrder(2) -msh = Inti.import_mesh(; dim = 2) -gmsh.finalize() -end #hide # ╔═╡ aca57c74-d084-40e7-9760-edf988a64915 md""" # Poisson Problem -[![Pluto notebook](https://img.shields.io/badge/download-Pluto_notebook-blue)](../../pluto_examples/poisson.jl) $\hspace{0.2cm}$ [![nbviewer](https://img.shields.io/badge/show-nbviewer-blue.svg)](../../pluto_examples/poisson.html) +[![Pluto notebook](https://img.shields.io/badge/download-Pluto_notebook-blue)](../../pluto_examples/poisson.jl)$\hspace{5pt}$[![nbviewer](https://img.shields.io/badge/show-nbviewer-blue.svg)](../../pluto_examples/poisson.html) """ # ╔═╡ 4160cbc1-3e98-4919-a8b5-bfbc65077b53 @@ -110,26 +109,6 @@ We use the *Gmsh API* to create a jellyfish-shaped domain and to generate a second order mesh of its interior and boundary: """ -# ╔═╡ 546966b1-58c2-44e6-ac2c-578094251fce -let # For the output in the documentation -with_terminal() do - meshsize = 0.1 -gmsh.initialize() -jellyfish = Inti.gmsh_curve(0, 2π; meshsize) do s - r = 1 + 0.3*cos(4*s + 2*sin(s)) - return r*Inti.Point2D(cos(s), sin(s)) -end -cl = gmsh.model.occ.addCurveLoop([jellyfish]) -surf = gmsh.model.occ.addPlaneSurface([cl]) -gmsh.model.occ.synchronize() -gmsh.option.setNumber("Mesh.MeshSizeMax", meshsize) -gmsh.model.mesh.generate(2) -gmsh.model.mesh.setOrder(2) -msh_output = Inti.import_mesh(; dim = 2) -gmsh.finalize() -end -end - # ╔═╡ 1609838c-67ec-4d67-9c9b-993b1bd01fb6 md""" We can now extract components of the mesh corresponding to the ``\Omega`` and @@ -137,28 +116,27 @@ We can now extract components of the mesh corresponding to the ``\Omega`` and """ # ╔═╡ 4e580f9f-6e22-4160-b262-ca941b6bfb8f -begin #hide -Ω = Inti.Domain(e -> Inti.geometric_dimension(e) == 2, msh) -Γ = Inti.boundary(Ω) -Ω_msh = view(msh, Ω) -Γ_msh = view(msh, Γ) -end; #hide +begin + Ω = Inti.Domain(e -> Inti.geometric_dimension(e) == 2, msh) + Γ = Inti.boundary(Ω) + Ω_msh = view(msh, Ω) + Γ_msh = view(msh, Γ) + nothing #hide +end # ╔═╡ 2c4bace3-ef35-4500-829f-2f5ae6725249 -begin #hide -using Meshes, GLMakie -viz(Ω_msh; showsegments=true) -viz!(Γ_msh; color=:red) -end; #hide +begin + using Meshes, GLMakie + viz(Ω_msh; showsegments=true) + viz!(Γ_msh; color=:red) + Makie.current_figure() #hide +end # ╔═╡ 901578c3-b7aa-4023-bb99-769cf5805f57 md""" and visualize them: """ -# ╔═╡ 1bb0a7a4-8fab-4744-9cf1-94619bde5395 -Makie.current_figure() - # ╔═╡ b142b298-26a8-4373-934d-3bc8448a8fda md""" To conclude the geometric setup, we need a quadrature for the volume and @@ -166,28 +144,29 @@ boundary: """ # ╔═╡ 85ce61fc-086d-4661-8f03-6a6ae4d55511 -begin #hide -Ω_quad = Inti.Quadrature(Ω_msh; qorder = 4) -Γ_quad = Inti.Quadrature(Γ_msh; qorder = 6) -end; #hide +begin + Ω_quad = Inti.Quadrature(Ω_msh; qorder = 4) + Γ_quad = Inti.Quadrature(Γ_msh; qorder = 6) + nothing #hide +end # ╔═╡ 6e3ea607-2b70-485d-94f0-5626bab4f832 -begin #hide -using FMM2D #to accelerate the maps -pde = Inti.Laplace(; dim = 2) -# Newtonian potential mapping domain to boundary -V_d2b = Inti.volume_potential(; - pde, - target = Γ_quad, - source = Ω_quad, - compression = (method = :fmm, tol = 1e-12), - correction = ( - method = :dim, - maxdist = 5 * meshsize, - target_location = :on, - ), -) -end #hide +begin + using FMM2D #to accelerate the maps + pde = Inti.Laplace(; dim = 2) + # Newtonian potential mapping domain to boundary + V_d2b = Inti.volume_potential(; + pde, + target = Γ_quad, + source = Ω_quad, + compression = (method = :fmm, tol = 1e-12), + correction = ( + method = :dim, + maxdist = 5 * meshsize, + target_location = :on, + ), + ) +end # ╔═╡ 731d9ae8-33a8-4f03-8cbc-5e40972996a2 md""" @@ -234,13 +213,14 @@ instead a manufactured solution ``u_e`` from which we will derive the functions """ # ╔═╡ 975b7c01-8147-44f8-a693-1185e7b8d63b -begin #hide -# Create a manufactured solution -uₑ = (x) -> cos(2 * x[1]) * sin(2 * x[2]) -fₑ = (x) -> 8 * cos(2 * x[1]) * sin(2 * x[2]) # -Δuₑ -g = map(q -> uₑ(q.coords), Γ_quad) -f = map(q -> fₑ(q.coords), Ω_quad) -end; #hide +begin + # Create a manufactured solution + uₑ = (x) -> cos(2 * x[1]) * sin(2 * x[2]) + fₑ = (x) -> 8 * cos(2 * x[1]) * sin(2 * x[2]) # -Δuₑ + g = map(q -> uₑ(q.coords), Γ_quad) + f = map(q -> fₑ(q.coords), Ω_quad) + nothing #hide +end # ╔═╡ 700cfbbc-970a-466b-9f8c-748f7ff0bc6e md""" @@ -249,41 +229,36 @@ homogeneous part of the solution: """ # ╔═╡ 6db682e4-e641-4272-ba90-1f10b2ff1150 -rhs = g - V_d2b*f ; +begin + rhs = g - V_d2b*f + nothing #hide +end # ╔═╡ 6eb1d813-e792-4148-8d30-975c49e9dbc6 -# ╠═╡ show_logs = false -begin #hide -using IterativeSolvers, LinearAlgebra -σ = gmres(-I/2 + D_b2b, rhs; abstol = 1e-8, verbose = true, restart = 1000) -end; #hide +begin + using IterativeSolvers, LinearAlgebra + σ = gmres(-I/2 + D_b2b, rhs; abstol = 1e-8, verbose = true, restart = 1000) + nothing #hide +end # ╔═╡ b21911c7-7276-44cb-a15f-64db3430a896 md""" and solve the integral equation for the integral density function ``σ``: """ -# ╔═╡ b5c4b1a6-c13d-416e-b820-02c9bfc1fdca -let # To Render in the Documentation - with_terminal() do - σ = gmres(-I/2 + D_b2b, rhs; abstol = 1e-8, verbose = true, restart = 1000) ; - nothing - end -end - # ╔═╡ 1357bb0a-bf56-4f56-bb2c-65dfe2a78c0c md""" With the density function at hand, we can now reconstruct our approximate solution: """ # ╔═╡ e0e1fa9c-7a43-45b1-ad45-2510533e1aed -begin #hide -G = Inti.SingleLayerKernel(pde) -dG = Inti.DoubleLayerKernel(pde) -𝒱 = Inti.IntegralPotential(G, Ω_quad) -𝒟 = Inti.IntegralPotential(dG, Γ_quad) -u = (x) -> 𝒱[f](x) + 𝒟[σ](x) -end #hide +begin + G = Inti.SingleLayerKernel(pde) + dG = Inti.DoubleLayerKernel(pde) + 𝒱 = Inti.IntegralPotential(G, Ω_quad) + 𝒟 = Inti.IntegralPotential(dG, Γ_quad) + u = (x) -> 𝒱[f](x) + 𝒟[σ](x) +end # ╔═╡ 2c2c943b-30ed-4244-a40c-f061050ca7b8 md""" @@ -291,17 +266,9 @@ and evaluate it at any point in the domain: """ # ╔═╡ 2faa4311-59d9-4b85-b585-937391e94568 -# ╠═╡ show_logs = false -begin #hide -x = Inti.Point2D(0.1,0.4) -println("error at $x: ", u(x)-uₑ(x)) -end #hide - -# ╔═╡ f3495025-ac97-415d-a398-ee5280c2d714 -let # Render for Documentation -with_terminal() do -println("error at $x: ", u(x)-uₑ(x)) -end +begin + x = Inti.Point2D(0.1,0.4) + println("error at $x: ", u(x)-uₑ(x)) end # ╔═╡ f3ee21f2-99e7-4be3-a2cc-930b6c4487f1 @@ -352,46 +319,40 @@ manufactured: """ # ╔═╡ 5be59f68-cf21-4e7e-ac23-7bffd690dc03 -# ╠═╡ show_logs = false -begin #hide -u_quad = V_d2d*f + D_b2d*σ -er_quad = u_quad - map(q -> uₑ(q.coords), Ω_quad) -println("maximum error at all quadrature nodes: ", norm(er_quad, Inf)) -end; #hide - -# ╔═╡ 41f97844-3c86-46b8-9fbb-0632bdcee0f6 -let # render for documentation - with_terminal() do - println("maximum error at all quadrature nodes: ", norm(er_quad, Inf)) - end +begin + u_quad = V_d2d*f + D_b2d*σ + er_quad = u_quad - map(q -> uₑ(q.coords), Ω_quad) + println("maximum error at all quadrature nodes: ", norm(er_quad, Inf)) + nothing #hide end # ╔═╡ a61f336e-15ee-4bb3-a071-1115ac6f1be1 md""" -Lastly, let us visualize the solution and the error on the mesh nodes using [`quadrature_to_node_vals`](@ref): +Lastly, let us visualize the solution and the error on the mesh nodes using [`quadrature_to_node_vals`](@ref Inti.quadrature_to_node_vals): """ # ╔═╡ ce03f9b7-c91c-4f53-bcda-49261a4bdcc2 -begin #hide -nodes = Inti.nodes(Ω_msh) -u_nodes = Inti.quadrature_to_node_vals(Ω_quad, u_quad) -er = u_nodes - map(uₑ, nodes) -colorrange = extrema(u_nodes) -fig = Figure(; size = (800, 300)) -ax = Axis(fig[1, 1]; aspect = DataAspect()) -viz!(Ω_msh; colorrange, color = u_nodes, interpolate = true) -cb = Colorbar(fig[1, 2]; label = "u", colorrange) -# plot error -log_er = log10.(abs.(er)) -colorrange = extrema(log_er) -colormap = :inferno -ax = Axis(fig[1, 3]; aspect = DataAspect()) -viz!(Ω_msh; colorrange, colormap, color = log_er, interpolate = true) -cb = Colorbar(fig[1, 4]; label = "log₁₀|u - uₑ|", colormap, colorrange) -end; #hide - -# ╔═╡ e46f76d5-074b-49ac-b976-9f782df9307d -fig +begin + nodes = Inti.nodes(Ω_msh) + u_nodes = Inti.quadrature_to_node_vals(Ω_quad, u_quad) + er = u_nodes - map(uₑ, nodes) + colorrange = extrema(u_nodes) + fig = Figure(; size = (800, 300)) + ax = Axis(fig[1, 1]; aspect = DataAspect()) + viz!(Ω_msh; colorrange, color = u_nodes, interpolate = true) + cb = Colorbar(fig[1, 2]; label = "u", colorrange) + # plot error + log_er = log10.(abs.(er)) + colorrange = extrema(log_er) + colormap = :inferno + ax = Axis(fig[1, 3]; aspect = DataAspect()) + viz!(Ω_msh; colorrange, colormap, color = log_er, interpolate = true) + cb = Colorbar(fig[1, 4]; label = "log₁₀|u - uₑ|", colormap, colorrange) + fig #hide +end + +# ╔═╡ e63c776b-6b52-4e6e-aca8-3d67cd9a9c3f +TableOfContents() # ╔═╡ 00000000-0000-0000-0000-000000000001 PLUTO_PROJECT_TOML_CONTENTS = """ @@ -2443,12 +2404,10 @@ version = "1.4.1+1" # ╟─b287d01b-7d13-414e-9f22-36e8a3a8ca62 # ╟─1d3720bb-c113-44d3-ac0d-275f80e87237 # ╠═332bd3bb-c720-454e-80af-89ad65041773 -# ╟─546966b1-58c2-44e6-ac2c-578094251fce # ╟─1609838c-67ec-4d67-9c9b-993b1bd01fb6 # ╠═4e580f9f-6e22-4160-b262-ca941b6bfb8f # ╟─901578c3-b7aa-4023-bb99-769cf5805f57 # ╠═2c4bace3-ef35-4500-829f-2f5ae6725249 -# ╟─1bb0a7a4-8fab-4744-9cf1-94619bde5395 # ╟─b142b298-26a8-4373-934d-3bc8448a8fda # ╠═85ce61fc-086d-4661-8f03-6a6ae4d55511 # ╟─731d9ae8-33a8-4f03-8cbc-5e40972996a2 @@ -2462,21 +2421,18 @@ version = "1.4.1+1" # ╠═6db682e4-e641-4272-ba90-1f10b2ff1150 # ╟─b21911c7-7276-44cb-a15f-64db3430a896 # ╠═6eb1d813-e792-4148-8d30-975c49e9dbc6 -# ╟─b5c4b1a6-c13d-416e-b820-02c9bfc1fdca # ╟─1357bb0a-bf56-4f56-bb2c-65dfe2a78c0c # ╠═e0e1fa9c-7a43-45b1-ad45-2510533e1aed # ╟─2c2c943b-30ed-4244-a40c-f061050ca7b8 # ╠═2faa4311-59d9-4b85-b585-937391e94568 -# ╟─f3495025-ac97-415d-a398-ee5280c2d714 # ╟─f3ee21f2-99e7-4be3-a2cc-930b6c4487f1 # ╠═fccb6992-32c4-4bd2-a742-fb36906fb62a # ╟─6489d40d-fdd3-488d-ae5d-4e4e489b669f # ╟─66a7946c-a601-4fc8-94a0-429d41b564ac # ╟─a5c7fcd0-1966-49fe-b5bf-7d3c1d9f4aa7 # ╠═5be59f68-cf21-4e7e-ac23-7bffd690dc03 -# ╟─41f97844-3c86-46b8-9fbb-0632bdcee0f6 # ╟─a61f336e-15ee-4bb3-a071-1115ac6f1be1 # ╠═ce03f9b7-c91c-4f53-bcda-49261a4bdcc2 -# ╟─e46f76d5-074b-49ac-b976-9f782df9307d +# ╟─e63c776b-6b52-4e6e-aca8-3d67cd9a9c3f # ╟─00000000-0000-0000-0000-000000000001 # ╟─00000000-0000-0000-0000-000000000002 diff --git a/docs/src/pluto-examples/toy_example.jl b/docs/src/pluto-examples/toy_example.jl index e9acae6f..81fc763a 100644 --- a/docs/src/pluto-examples/toy_example.jl +++ b/docs/src/pluto-examples/toy_example.jl @@ -4,26 +4,25 @@ using Markdown using InteractiveUtils +# ╔═╡ d027657d-4f16-40fd-b7c3-8ea9e51c0a98 +using Inti + # ╔═╡ 3f5a1750-7cd7-11ef-2223-4f3db029916b begin import Pkg as _Pkg - haskey(ENV, "PLUTO_PROJECT") && _Pkg.activate(ENV["PLUTO_PROJECT"]) - using PlutoUI: with_terminal + haskey(ENV, "PLUTO_PROJECT") && _Pkg.activate(ENV["PLUTO_PROJECT"]) end ; -# ╔═╡ d027657d-4f16-40fd-b7c3-8ea9e51c0a98 -using Inti - # ╔═╡ 854743f0-8556-4495-ba16-52514c85922a md""" # Toy example -[![Pluto notebook](https://img.shields.io/badge/download-Pluto_notebook-blue)](../../pluto_examples/toy_example.jl) $\hspace{0.2cm}$ [![nbviewer](https://img.shields.io/badge/show-nbviewer-blue.svg)](../../pluto_examples/toy_example.html) +[![Pluto notebook](https://img.shields.io/badge/download-Pluto_notebook-blue)](../../pluto_examples/toy_example.jl)$\hspace{5pt}$[![nbviewer](https://img.shields.io/badge/show-nbviewer-blue.svg)](../../pluto_examples/toy_example.html) """ # ╔═╡ 09c0bfc0-1c65-4fad-b486-b6a61ca580e8 md""" -All examples in Inti.jl are autogenerated by executing the `make.jl` script in the `docs` folder. The workflow uses [PlutoStaticHTML.jl](https://plutostatichtml.huijzer.xyz/stable/) and [PlutoSliderServer.jl](https://github.com/JuliaPluto/PlutoSliderServer.jl) via the intermediate of [ExampleJuggler.jl](https://github.com/j-fu/ExampleJuggler.jl) to generate (i) markdown files passed to Documenter.jl, and (ii) pluto notebook files downloadable from the example's page. +All examples in Inti.jl are autogenerated by executing the `make.jl` script in the `docs` folder. The workflow uses [Pluto.jl](https://plutojl.org), [JuliaFormatter](https://domluna.github.io/JuliaFormatter.jl/stable/), and [PlutoSliderServer.jl](https://github.com/JuliaPluto/PlutoSliderServer.jl) (via the intermediate of [ExampleJuggler.jl](https://github.com/j-fu/ExampleJuggler.jl)) to generate (i) markdown files passed to Documenter.jl, and (ii) pluto notebook files downloadable from the example's page. """ # ╔═╡ 00000000-0000-0000-0000-000000000001 @@ -31,11 +30,9 @@ PLUTO_PROJECT_TOML_CONTENTS = """ [deps] Inti = "fb74042b-437e-4c5b-88cf-d4e2beb394d5" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" [compat] Inti = "~0.1.1" -PlutoUI = "~0.7.60" """ # ╔═╡ 00000000-0000-0000-0000-000000000002 @@ -44,13 +41,7 @@ PLUTO_MANIFEST_TOML_CONTENTS = """ julia_version = "1.10.5" manifest_format = "2.0" -project_hash = "03506df29ac423a8c891aed43b1dcb6697268bfc" - -[[deps.AbstractPlutoDingetjes]] -deps = ["Pkg"] -git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" -uuid = "6e696c72-6542-2067-7265-42206c756150" -version = "1.3.2" +project_hash = "e35f19cc8ab3426fd7cbf4d4e2049a8aee789a0a" [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" @@ -62,12 +53,6 @@ uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" -[[deps.ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.5" - [[deps.CommonSubexpressions]] deps = ["MacroTools"] git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" @@ -145,12 +130,6 @@ version = "0.2.2" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" -[[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" - [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" @@ -161,24 +140,6 @@ weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] ForwardDiffStaticArraysExt = "StaticArrays" -[[deps.Hyperscript]] -deps = ["Test"] -git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" -uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" -version = "0.0.5" - -[[deps.HypertextLiteral]] -deps = ["Tricks"] -git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" -uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" -version = "0.9.5" - -[[deps.IOCapture]] -deps = ["Logging", "Random"] -git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" -uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.5" - [[deps.InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" @@ -217,12 +178,6 @@ git-tree-sha1 = "f389674c99bfcde17dc57454011aa44d5a260a40" uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" version = "1.6.0" -[[deps.JSON]] -deps = ["Dates", "Mmap", "Parsers", "Unicode"] -git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.21.4" - [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" @@ -289,11 +244,6 @@ version = "0.3.28" [[deps.Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" -[[deps.MIMEs]] -git-tree-sha1 = "65f28ad4b594aebe22157d6fac869786a255b7eb" -uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" -version = "0.1.4" - [[deps.MacroTools]] deps = ["Markdown", "Random"] git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" @@ -309,9 +259,6 @@ deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" version = "2.28.2+1" -[[deps.Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" version = "2023.1.10" @@ -353,23 +300,11 @@ git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.6.3" -[[deps.Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.1" - [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" version = "1.10.0" -[[deps.PlutoUI]] -deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] -git-tree-sha1 = "eba4810d5e6a01f612b948c9fa94f905b49087b0" -uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" -version = "0.7.60" - [[deps.PrecompileTools]] deps = ["Preferences"] git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" @@ -394,11 +329,6 @@ uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" deps = ["SHA"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" version = "0.7.0" @@ -477,20 +407,6 @@ deps = ["ArgTools", "SHA"] uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" version = "1.10.0" -[[deps.Test]] -deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.Tricks]] -git-tree-sha1 = "7822b97e99a1672bfb1b49b668a6d46d58d8cbcb" -uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" -version = "0.1.9" - -[[deps.URIs]] -git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" -uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.5.1" - [[deps.UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"