From 0ed96696fa0ef71ce44acdc0a14d7924f23dfb74 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 7 Sep 2023 11:30:04 +0200 Subject: [PATCH 001/110] gitignore aangepast --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b879feb5..715a5a38 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ dev/ profile/ /Manifest.toml /envs/ +programs/ +results/ From 9a6e0dac56ff12c8a9374c3e21fe61ef87beacd6 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 14 Sep 2023 10:44:12 +0200 Subject: [PATCH 002/110] MWncrossn implemented --- src/maxwell/maxwell.jl | 5 +++++ src/maxwell/mwops.jl | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/maxwell/maxwell.jl b/src/maxwell/maxwell.jl index 6e114c74..5d7b47c0 100644 --- a/src/maxwell/maxwell.jl +++ b/src/maxwell/maxwell.jl @@ -75,4 +75,9 @@ module Maxwell3D farfield(; wavenumber = error("missing argument: `wavenumber`")) = Mod.MWFarField3D(wavenumber=wavenumber) + + function ncrossn() + Mod.MWncrossn() + end + end diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index 5f034de6..318e13e7 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -41,6 +41,12 @@ struct MWSingleLayer3D{T,U} <: MaxwellOperator3D{T,U} β::U end +struct MWncrossn{T,U} <: MaxwellOperator3D{T,U} + gamma::T + α::U +end + + scalartype(op::MWSingleLayer3D{T,U}) where {T,U} = promote_type(T,U) sign_upon_permutation(op::MWSingleLayer3D, I, J) = 1 @@ -332,6 +338,23 @@ function (igd::Integrand{<:MWDoubleLayer3DReg})(x,y,f,g) return _krondot(fvalue, G) end +function (igd::{Integrand{<:MWncrossn}})(x,y,f,g) + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + γR = γ*R + iR = 1/R + expo = exp(-γR) + green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) + n = normal(x) + n' = normal(y) + fvalue = getvalue(f) + gvalue = getvalue(g) + t = cross(n,n')*green + t2 = Ref(t).*gvalue + return _krondot(fvalue,t2) +end ################################################################################ # # Handling of operator parameters (Helmholtz and Maxwell) From 790738e946aa645a40763efdb33841eddfc11f68 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 14 Sep 2023 11:38:30 +0200 Subject: [PATCH 003/110] all operators implemented but not tested --- src/maxwell/maxwell.jl | 176 ++++++++++++++++++++++++++++++++++++++++- src/maxwell/mwops.jl | 98 +++++++++++++++++++++-- 2 files changed, 266 insertions(+), 8 deletions(-) diff --git a/src/maxwell/maxwell.jl b/src/maxwell/maxwell.jl index 5d7b47c0..6194fde5 100644 --- a/src/maxwell/maxwell.jl +++ b/src/maxwell/maxwell.jl @@ -64,7 +64,35 @@ module Maxwell3D Mod.MWDoubleLayer3D(gamma) end + """ + ndoublelayer(;gamma) + ndoublelaher(;wavenumber) + + Bilinear form given by: + + ```math + α ∬_{Γ^2} k(x) ⋅ (∇G_γ(x-y) × n_y j(y)) + ``` + + with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + """ + function ndoublelayer(; + alpha=nothing, + gamma=nothing, + wavenumber=nothing) + + gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + if alpha === nothing + if gamma !== nothing + alpha = one(gamma) + else + alpha = 1.0 # Default to double precision + end + end + Mod.MWnDoubleLayer3D(gamma) + end planewave(; direction = error("missing arguement `direction`"), polarization = error("missing arguement `polarization`"), @@ -76,8 +104,150 @@ module Maxwell3D wavenumber = error("missing argument: `wavenumber`")) = Mod.MWFarField3D(wavenumber=wavenumber) - function ncrossn() - Mod.MWncrossn() + + """ + ngreenint(;gamma) + ngreenint(;wavenumber) + + Bilinear form given by: + + ```math + α ∬_{Γ^2} k(x) ⋅ n_y (G_γ(x-y)j(y)) + ``` + + with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + """ + function ngreenint(; + alpha=nothing, + gamma=nothing, + wavenumber=nothing) + + gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + if alpha === nothing + if gamma !== nothing + alpha = one(gamma) + else + alpha = 1.0 # Default to double precision + end + end + Mod.MWngreenint(gamma,alpha) end - + + """ + greenint(;gamma) + greenint(;wavenumber) + + Bilinear form given by: + + ```math + α ∬_{Γ^2} k(x) ⋅ G_γ(x-y) j(y) + ``` + + with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + """ + function greenint(; + alpha=nothing, + gamma=nothing, + wavenumber=nothing) + + gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + if alpha === nothing + if gamma !== nothing + alpha = one(gamma) + else + alpha = 1.0 # Default to double precision + end + end + Mod.MWgreenint(gamma,alpha) + end + + """ + greenint(;gamma) + greenint(;wavenumber) + + Bilinear form given by: + + ```math + α ∬_{Γ^2} k(x) ⋅ G_γ(x-y) j(y) + ``` + + with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + """ + function greenint(; + alpha=nothing, + gamma=nothing, + wavenumber=nothing) + + gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + if alpha === nothing + if gamma !== nothing + alpha = one(gamma) + else + alpha = 1.0 # Default to double precision + end + end + Mod.MWgreenint(gamma,alpha) + end + """ + gradgreenint(;gamma) + gradgreenint(;wavenumber) + + Bilinear form given by: + + ```math + α ∬_{Γ^2} k(x) ⋅∇G_γ(x-y) j(y) + ``` + or + ```math + α ∬_{Γ^2} k(x) ∇G_γ(x-y) ⋅ j(y) + ``` + with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + """ + function gradgreenint(; + alpha=nothing, + gamma=nothing, + wavenumber=nothing) + + gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + if alpha === nothing + if gamma !== nothing + alpha = one(gamma) + else + alpha = 1.0 # Default to double precision + end + end + Mod.MWgradgreenint(gamma,alpha) + end + """ + ngradgreenint(;gamma) + ngradgreenint(;wavenumber) + + Bilinear form given by: + + ```math + α ∬_{Γ^2} k(x) ⋅∇G_γ(x-y)n_y j(y) + ``` + with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + """ + function ngradgreenint(; + alpha=nothing, + gamma=nothing, + wavenumber=nothing) + + gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + if alpha === nothing + if gamma !== nothing + alpha = one(gamma) + else + alpha = 1.0 # Default to double precision + end + end + Mod.MWngradgreenint(gamma,alpha) + end + end diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index 318e13e7..52ac4dbe 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -41,12 +41,23 @@ struct MWSingleLayer3D{T,U} <: MaxwellOperator3D{T,U} β::U end -struct MWncrossn{T,U} <: MaxwellOperator3D{T,U} +struct MWngreenint{T,U} <: MaxwellOperator3D{T,U} gamma::T α::U end - +struct MWgreenint{T,U} <: MaxwellOperator3D{T,U} + gamma::T + α::U +end +struct MWgradgreenint{T,U} <: MaxwellOperator3D{T,U} + gamma::T + α::U +end +struct MWngradgreenint{T,U} <: MaxwellOperator3D{T,U} + gamma::T + α::U +end scalartype(op::MWSingleLayer3D{T,U}) where {T,U} = promote_type(T,U) sign_upon_permutation(op::MWSingleLayer3D, I, J) = 1 @@ -107,6 +118,11 @@ struct MWDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} gamma::K end +struct MWnDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} + alpha::T + gamma::K +end + sign_upon_permutation(op::MWDoubleLayer3D, I, J) = 1 struct MWDoubleLayer3DSng{T,K} <: MaxwellOperator3D{T,K} @@ -320,6 +336,23 @@ function (igd::Integrand{<:MWDoubleLayer3D})(x,y,f,g) end +function (igd::Integrand{<:MWnDoubleLayer3D})(x,y,f,g) + + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + n' = normal(y) + fvalue = getvalue(f) + gvalue = getvalue(g) + t1 = Ref(n').*gvalue + G = cross.(Ref(gradgreen), t1) + return _krondot(fvalue, G) +end + function (igd::Integrand{<:MWDoubleLayer3DReg})(x,y,f,g) γ = igd.operator.gamma @@ -338,7 +371,7 @@ function (igd::Integrand{<:MWDoubleLayer3DReg})(x,y,f,g) return _krondot(fvalue, G) end -function (igd::{Integrand{<:MWncrossn}})(x,y,f,g) +function (igd::{Integrand{<:MWngreenint}})(x,y,f,g) γ = igd.operator.gamma r = cartesian(x) - cartesian(y) @@ -347,14 +380,69 @@ function (igd::{Integrand{<:MWncrossn}})(x,y,f,g) iR = 1/R expo = exp(-γR) green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) - n = normal(x) + n' = normal(y) fvalue = getvalue(f) gvalue = getvalue(g) - t = cross(n,n')*green + t = n'*green t2 = Ref(t).*gvalue return _krondot(fvalue,t2) end + +function (igd::{Integrand{<:MWgreenint}})(x,y,f,g) + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + γR = γ*R + iR = 1/R + expo = exp(-γR) + green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) + + fvalue = getvalue(f) + gvalue = getvalue(g) + + t2 = green*gvalue + return _krondot(fvalue,t2) +end + +function (igd::{Integrand{<:MWgradgreenint}})(x,y,f,g) + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + γR = γ*R + iR = 1/R + expo = exp(-γR) + green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) + gradgreen = ( -(γR + 1)*expo + (1 - 0.5*γR^2) ) * (i4pi*iR^3) * r + + fvalue = getvalue(f) + gvalue = getvalue(g) + + t2 = dot.(gvalue,Ref(gradgreen)) + + return _krondot(fvalue,t2) +end +function (igd::{Integrand{<:MWgradgreenint}})(x,y,f,g) + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + γR = γ*R + iR = 1/R + expo = exp(-γR) + green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) + gradgreen = ( -(γR + 1)*expo + (1 - 0.5*γR^2) ) * (i4pi*iR^3) * r + + fvalue = getvalue(f) + gvalue = getvalue(g) + n' = normal(y) + t1 = Ref(n').*gvalue + t2 = dot.(t1,Ref(gradgreen)) + + return _krondot(fvalue,t2) +end ################################################################################ # # Handling of operator parameters (Helmholtz and Maxwell) From e6aa9858fb567764d431564bdd634add9ac50100 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 14 Sep 2023 17:20:01 +0200 Subject: [PATCH 004/110] ToDo: add all limits of the operators and write test compare by taking limit (use two triangles) --- src/bases/trace.jl | 3 ++- src/maxwell/mwops.jl | 23 +++++++++++++++++++++-- src/operator.jl | 40 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/bases/trace.jl b/src/bases/trace.jl index ea52a307..f0ef8ce4 100644 --- a/src/bases/trace.jl +++ b/src/bases/trace.jl @@ -17,7 +17,7 @@ function strace(X::DirectProductSpace{T}, γ) where T return DirectProductSpace(x) end - +struct SameBase end function ntrace(X::Space, γ) @@ -193,6 +193,7 @@ currently not working! # # ttrace(X, Σ, fns) # end +ttrace(X::Space, y::SameBase)=X function ttrace(X::Space, γ) diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index 52ac4dbe..10c7a85a 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -298,6 +298,8 @@ function (igd::Integrand{<:MWSingleLayer3D})(x,y,f,g) αG * dot(fi.value, gj.value) + βG * dot(fi.divergence, gj.divergence) end end +ttrace(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), SameBase() +strace(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), mesh function (igd::Integrand{<:MWSingleLayer3DReg})(x,y,f,g) α = igd.operator.α @@ -334,7 +336,10 @@ function (igd::Integrand{<:MWDoubleLayer3D})(x,y,f,g) G = cross.(Ref(gradgreen), gvalue) return _krondot(fvalue, G) end - +ttrace(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), SameBase() +strace(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), SameBase() +ttrace(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), SameBase() +strace(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), SameBase() function (igd::Integrand{<:MWnDoubleLayer3D})(x,y,f,g) @@ -353,6 +358,9 @@ function (igd::Integrand{<:MWnDoubleLayer3D})(x,y,f,g) return _krondot(fvalue, G) end +ttrace(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), SameBase() +strace(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), mesh + function (igd::Integrand{<:MWDoubleLayer3DReg})(x,y,f,g) γ = igd.operator.gamma @@ -389,6 +397,11 @@ function (igd::{Integrand{<:MWngreenint}})(x,y,f,g) return _krondot(fvalue,t2) end +ttrace(op::MWngreenint, mesh, or) = ZeroOperator(), SameBase() +strace(op::MWngreenint, mesh, or) = ZeroOperator(), mesh + + + function (igd::{Integrand{<:MWgreenint}})(x,y,f,g) γ = igd.operator.gamma @@ -406,6 +419,9 @@ function (igd::{Integrand{<:MWgreenint}})(x,y,f,g) return _krondot(fvalue,t2) end +ttrace(op::MWgreenint, mesh, or) = ZeroOperator(), SameBase() +strace(op::MWgreenint, mesh, or) = ZeroOperator(), mesh + function (igd::{Integrand{<:MWgradgreenint}})(x,y,f,g) γ = igd.operator.gamma @@ -424,7 +440,10 @@ function (igd::{Integrand{<:MWgradgreenint}})(x,y,f,g) return _krondot(fvalue,t2) end -function (igd::{Integrand{<:MWgradgreenint}})(x,y,f,g) + + + +function (igd::{Integrand{<:MWngradgreenint}})(x,y,f,g) γ = igd.operator.gamma r = cartesian(x) - cartesian(y) diff --git a/src/operator.jl b/src/operator.jl index 71c815e2..4fe89616 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -3,7 +3,7 @@ using .LinearSpace struct LongDelays{T} end struct Threading{T} end -import Base: transpose, +, -, * +import Base: transpose, +, -, *, zero abstract type AbstractOperator end @@ -220,7 +220,19 @@ function assemble!(op::LinearCombinationOfOperators, tfs::AbstractSpace, bfs::Ab assemble!(A, tfs, bfs, store1, threading; quadstrat=qs) end end +function assemble!(op::Ttrace, tfs::AbstractSpace, bfs::AbstractSpace, + store, threading = Threading{:multi}; + quadstrat=defaultquadstrat(op, tfs, bfs)) + pvterm, mesh = ttrace(op.op,tfs.geo) + assemble!(pvterm+op.op,ttrace(tfs,mesh),bfs,store) +end +function assemble!(op::Strace, tfs::AbstractSpace, bfs::AbstractSpace, + store, threading = Threading{:multi}; + quadstrat=defaultquadstrat(op, tfs, bfs)) + pvterm, mesh = strace(op.op,tfs.geo) + assemble!(-pvterm-op.op,strace(tfs,mesh),bfs,store) +end # Support for direct product spaces function assemble!(op::AbstractOperator, tfs::DirectProductSpace, bfs::Space, @@ -321,3 +333,29 @@ function assemble!(op::BlockFullOperators, U::DirectProductSpace, V::DirectProdu end end end + +abstract type TraceOperator <: Operator end + +struct Strace <: TraceOperator + op + MeshInformation + orientation +end + +struct Ttrace <: TraceOperator + op + MeshInformation + orientation +end + +strace(op::Operator,minof,orientation) = Strace(op,minfo,orientation) +ttrace(op::Operator,minfo,orientation) = Ttrace(op,minfo,orientation) + +struct ZeroOperator <: AbstractOperator end + +Base.zero(op::AbstractOperator) = ZeroOperator() ++(a::AbstractOperator,b::ZeroOperator) = a ++(a::ZeroOperator,b::ZeroOperator) = a ++(a::ZeroOperator,b::AbstractOperator) = b+a +*(a::Number,b::ZeroOperator) = b + From a892426ff41393dfe8e4a3e2d6679e8b5355a6c3 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 14 Sep 2023 18:18:53 +0200 Subject: [PATCH 005/110] last update 14 sept --- src/maxwell/mwops.jl | 8 ++++++-- src/operator.jl | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index 10c7a85a..cac0baa8 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -421,6 +421,7 @@ end ttrace(op::MWgreenint, mesh, or) = ZeroOperator(), SameBase() strace(op::MWgreenint, mesh, or) = ZeroOperator(), mesh +ntrace(op::MWgreenint, mesh, or) = ZeroOperator(), mesh function (igd::{Integrand{<:MWgradgreenint}})(x,y,f,g) γ = igd.operator.gamma @@ -440,8 +441,9 @@ function (igd::{Integrand{<:MWgradgreenint}})(x,y,f,g) return _krondot(fvalue,t2) end - - +ttrace(op::MWgradgreenint, mesh, or) = ZeroOperator(), SameBase() +strace(op::MWgradgreenint, mesh, or) = ZeroOperator(), mesh +ntrace(op::MWgradgreenint, mesh, or) = 1/2*Identity(), mesh function (igd::{Integrand{<:MWngradgreenint}})(x,y,f,g) γ = igd.operator.gamma @@ -462,6 +464,8 @@ function (igd::{Integrand{<:MWngradgreenint}})(x,y,f,g) return _krondot(fvalue,t2) end + +scallartrace(op::MWngradgreenint, mesh, or) = 1/2*Identity(), SameBase() ################################################################################ # # Handling of operator parameters (Helmholtz and Maxwell) diff --git a/src/operator.jl b/src/operator.jl index 4fe89616..bf6163a1 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -352,6 +352,8 @@ strace(op::Operator,minof,orientation) = Strace(op,minfo,orientation) ttrace(op::Operator,minfo,orientation) = Ttrace(op,minfo,orientation) struct ZeroOperator <: AbstractOperator end +struct Inside end +struct Outside end Base.zero(op::AbstractOperator) = ZeroOperator() +(a::AbstractOperator,b::ZeroOperator) = a From d25271ef7da54d49bf134fb4c9a8b988105569a0 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 15 Sep 2023 10:25:13 +0200 Subject: [PATCH 006/110] update not working --- src/BEAST.jl | 1 + src/operator.jl | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/BEAST.jl b/src/BEAST.jl index 227362c0..800b87c5 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -26,6 +26,7 @@ import SharedArrays: sdata export dot export planewave +export inside, outside export RefSpace, numfunctions, coordtype, scalartype, assemblydata, geometry, refspace, valuetype export lagrangecxd0, lagrangec0d1, duallagrangec0d1 export duallagrangecxd0 diff --git a/src/operator.jl b/src/operator.jl index bf6163a1..f1f476a5 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -354,6 +354,9 @@ ttrace(op::Operator,minfo,orientation) = Ttrace(op,minfo,orientation) struct ZeroOperator <: AbstractOperator end struct Inside end struct Outside end +inside() = Inside() +outside() = Outside() + Base.zero(op::AbstractOperator) = ZeroOperator() +(a::AbstractOperator,b::ZeroOperator) = a From 70dbfde59506508411682655e397932a75902873 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 15 Sep 2023 10:52:57 +0200 Subject: [PATCH 007/110] update --- src/operator.jl | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/operator.jl b/src/operator.jl index f1f476a5..1048c5eb 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -2,6 +2,20 @@ using .LinearSpace struct LongDelays{T} end struct Threading{T} end +abstract type TraceOperator <: Operator end + +struct Strace <: TraceOperator + op + MeshInformation + orientation +end + +struct Ttrace <: TraceOperator + op + MeshInformation + orientation +end + import Base: transpose, +, -, *, zero @@ -334,19 +348,6 @@ function assemble!(op::BlockFullOperators, U::DirectProductSpace, V::DirectProdu end end -abstract type TraceOperator <: Operator end - -struct Strace <: TraceOperator - op - MeshInformation - orientation -end - -struct Ttrace <: TraceOperator - op - MeshInformation - orientation -end strace(op::Operator,minof,orientation) = Strace(op,minfo,orientation) ttrace(op::Operator,minfo,orientation) = Ttrace(op,minfo,orientation) From c566821b280c86ee369f985b67622ceaede95254 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 15 Sep 2023 16:27:56 +0200 Subject: [PATCH 008/110] implemented operators, not tested --- src/maxwell/maxwell.jl | 312 +++++++++++++++------------- src/maxwell/mwops.jl | 416 +++++++++++++++++++++++++++++++------- src/maxwell/nxdbllayer.jl | 1 + src/operator.jl | 57 +++--- 4 files changed, 545 insertions(+), 241 deletions(-) diff --git a/src/maxwell/maxwell.jl b/src/maxwell/maxwell.jl index 6194fde5..f89abfbf 100644 --- a/src/maxwell/maxwell.jl +++ b/src/maxwell/maxwell.jl @@ -1,5 +1,16 @@ module Maxwell3D + """ + naming of operators: + ∇ + n_x normal test function + n_y normal basis function + G greens function + X cross product + d inner product/scallar product + t test function + b basis function + """ using ..BEAST Mod = BEAST @@ -64,35 +75,35 @@ module Maxwell3D Mod.MWDoubleLayer3D(gamma) end - """ - ndoublelayer(;gamma) - ndoublelaher(;wavenumber) - - Bilinear form given by: - - ```math - α ∬_{Γ^2} k(x) ⋅ (∇G_γ(x-y) × n_y j(y)) - ``` - - with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - """ - function ndoublelayer(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end - end - - Mod.MWnDoubleLayer3D(gamma) - end + # """ + # ndoublelayer(;gamma) + # ndoublelaher(;wavenumber) + + # Bilinear form given by: + + # ```math + # α ∬_{Γ^2} k(x) ⋅ (∇G_γ(x-y) × n_y j(y)) + # ``` + + # with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + # """ + # function td∇GXn_ydb(; + # alpha=nothing, + # gamma=nothing, + # wavenumber=nothing) + + # gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + # if alpha === nothing + # if gamma !== nothing + # alpha = one(gamma) + # else + # alpha = 1.0 # Default to double precision + # end + # end + + # Mod.Td∇GXn_ydb(gamma) + # end planewave(; direction = error("missing arguement `direction`"), polarization = error("missing arguement `polarization`"), @@ -105,34 +116,63 @@ module Maxwell3D Mod.MWFarField3D(wavenumber=wavenumber) - """ - ngreenint(;gamma) - ngreenint(;wavenumber) - - Bilinear form given by: - - ```math - α ∬_{Γ^2} k(x) ⋅ n_y (G_γ(x-y)j(y)) - ``` - - with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - """ - function ngreenint(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end - end - Mod.MWngreenint(gamma,alpha) - end + # """ + # ngreenint(;gamma) + # ngreenint(;wavenumber) + + # Bilinear form given by: + + # ```math + # α ∬_{Γ^2} k(x) ⋅ n_y (G_γ(x-y)j(y)) + # ``` + + # with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + # """ + # function tdGdn_ydj(; + # alpha=nothing, + # gamma=nothing, + # wavenumber=nothing) + + # gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + # if alpha === nothing + # if gamma !== nothing + # alpha = one(gamma) + # else + # alpha = 1.0 # Default to double precision + # end + # end + # Mod.TdGdn_ydj(gamma,alpha) + # end + + # """ + # greenint(;gamma) + # greenint(;wavenumber) + + # Bilinear form given by: + + # ```math + # α ∬_{Γ^2} k(x) ⋅ G_γ(x-y) j(y) + # ``` + + # with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + # """ + # function greenint(; + # alpha=nothing, + # gamma=nothing, + # wavenumber=nothing) + + # gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + # if alpha === nothing + # if gamma !== nothing + # alpha = one(gamma) + # else + # alpha = 1.0 # Default to double precision + # end + # end + # Mod.MWgreenint(gamma,alpha) + # end """ greenint(;gamma) @@ -162,92 +202,80 @@ module Maxwell3D end Mod.MWgreenint(gamma,alpha) end - - """ - greenint(;gamma) - greenint(;wavenumber) - - Bilinear form given by: - - ```math - α ∬_{Γ^2} k(x) ⋅ G_γ(x-y) j(y) - ``` - - with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - """ - function greenint(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end + # """ + # gradgreenint(;gamma) + # gradgreenint(;wavenumber) + + # Bilinear form given by: + + # ```math + # α ∬_{Γ^2} k(x) ⋅∇G_γ(x-y) j(y) + # ``` + # or + # ```math + # α ∬_{Γ^2} k(x) ∇G_γ(x-y) ⋅ j(y) + # ``` + # with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + # """ + # function gradgreenint(; + # alpha=nothing, + # gamma=nothing, + # wavenumber=nothing) + + # gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + # if alpha === nothing + # if gamma !== nothing + # alpha = one(gamma) + # else + # alpha = 1.0 # Default to double precision + # end + # end + # Mod.MWgradgreenint(gamma,alpha) + # end + # """ + # ngradgreenint(;gamma) + # ngradgreenint(;wavenumber) + + # Bilinear form given by: + + # ```math + # α ∬_{Γ^2} k(x) ⋅∇G_γ(x-y)n_y j(y) + # ``` + # with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + # """ + # function ngradgreenint(; + # alpha=nothing, + # gamma=nothing, + # wavenumber=nothing) + + # gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + # if alpha === nothing + # if gamma !== nothing + # alpha = one(gamma) + # else + # alpha = 1.0 # Default to double precision + # end + # end + # Mod.MWngradgreenint(gamma,alpha) + # end + + function gradgreendot(; + alpha=nothing, + gamma=nothing, + wavenumber=nothing) + + gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + if alpha === nothing + if gamma !== nothing + alpha = one(gamma) + else + alpha = 1.0 # Default to double precision end - Mod.MWgreenint(gamma,alpha) - end - """ - gradgreenint(;gamma) - gradgreenint(;wavenumber) - - Bilinear form given by: - - ```math - α ∬_{Γ^2} k(x) ⋅∇G_γ(x-y) j(y) - ``` - or - ```math - α ∬_{Γ^2} k(x) ∇G_γ(x-y) ⋅ j(y) - ``` - with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - """ - function gradgreenint(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end - end - Mod.MWgradgreenint(gamma,alpha) - end - """ - ngradgreenint(;gamma) - ngradgreenint(;wavenumber) - - Bilinear form given by: - - ```math - α ∬_{Γ^2} k(x) ⋅∇G_γ(x-y)n_y j(y) - ``` - with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - """ - function ngradgreenint(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end - end - Mod.MWngradgreenint(gamma,alpha) end + Mod.MWngradgreendot(gamma,alpha) +end end diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index cac0baa8..ec7361c9 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -1,6 +1,8 @@ abstract type MaxwellOperator3D{T,K} <: IntegralOperator end abstract type MaxwellOperator3DReg{T,K} <: MaxwellOperator3D{T,K} end +import base: ×, ⋅ + scalartype(op::MaxwellOperator3D{T,K}) where {T, K <: Nothing} = T scalartype(op::MaxwellOperator3D{T,K}) where {T, K} = promote_type(T, K) @@ -33,7 +35,10 @@ function kernelvals(biop::MaxwellOperator3D, p, q) KernelValsMaxwell3D(γ, r, R, green, gradgreen) end - +struct MWDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} + alpha::T + gamma::K +end struct MWSingleLayer3D{T,U} <: MaxwellOperator3D{T,U} gamma::T @@ -41,23 +46,94 @@ struct MWSingleLayer3D{T,U} <: MaxwellOperator3D{T,U} β::U end -struct MWngreenint{T,U} <: MaxwellOperator3D{T,U} +# struct TdGdn_ydj{T,U} <: MaxwellOperator3D{T,U} +# gamma::T +# α::U +# end + +struct MWgreenint{T,U} <: MaxwellOperator3D{T,U}#check + gamma::T + α::U +end +struct MWgradgreendot{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end -struct MWgreenint{T,U} <: MaxwellOperator3D{T,U} +struct nXMWgreenint{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end -struct MWgradgreenint{T,U} <: MaxwellOperator3D{T,U} + +struct nXdoublelayer{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end -struct MWngradgreenint{T,U} <: MaxwellOperator3D{T,U} + +struct MWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +struct nXMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check + gamma::T + α::U +end +struct nXMWgradgreendot{T,U}<: MaxwellOperator3D{T,U}#check + gamma::T + α::U +end +struct MWgradgreendotn{T,U}<: MaxwellOperator3D{T,U}#check + gamma::T + α::U +end +struct MWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check + gamma::T + α::U +end +struct nXMWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check haakjes rechts + gamma::T + α::U +end +struct ndotMWdoublelayer{T,U}<: MaxwellOperator3D{T,U}#check + gamma::T + α::U +end +struct ndotMWgreenint{T,U}<: MaxwellOperator3D{T,U}#cehck + gamma::T + α::U +end +struct ndotMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check + gamma::T + α::U +end +struct ndotMWgradgreen{T,U}<: MaxwellOperator3D{T,U}#check + gamma::T + α::U +end + +×(n::NormalVector,op::MWgreenint) = nXMWgreenint(op.gamma,op.α) +×(n::NormalVector,op::MWDoubleLayer3D) = nXdoublelayer(op.gamma,op.α) +⋅(op::MWgreenint,n::NormalVector) = MWgreenintdotn(op.gamma,op.α) +⋅(op::nXMWgreenint,n::NormalVector) = nXMWgreenintdotn(op.gamma,op.α) +×(n::NormalVector,op::MWgreenintdotn) = nXMWgreenintdotn(op.gamma,op.α) +×(n::NormalVector,op::MWgradgreendot) = nXMWgradgreendot(op.gamma,op.α) +⋅(op::MWgradgreendot,n::NormalVector) = MWgradgreendotn(op.gamma,op.α) +×(op::MWDoubleLayer3D,n::NormalVector) = MWdoublelayerXn(op.gamma,op.α) +×(n::NormalVector,op::MWdoublelayerXn) = nXMWdoublelayerXn(op.gamma,op.α) +⋅(n::NormalVector,op::MWDoubleLayer3D) = ndotMWdoublelayer(op.gamma,op.α) +⋅(n::NormalVector,op::MWgreenint) = ndotMWgreenint(op.gamma,op.α) +⋅(n::NormalVector,op::MWgreenintdotn) = ndotMWgreenintdotn(op.gamma,op.α) +⋅(op::ndotMWgreenint,n::NormalVector)= ndotMWgreenintdotn(op.gamma,op.α) +⋅(n::NormalVector,op::MWgradgreen) = ndotMWgradgreen(op.gamma,op.α) + +# struct MWgradgreenint{T,U} <: MaxwellOperator3D{T,U} +# gamma::T +# α::U +# end +# struct MWngradgreenint{T,U} <: MaxwellOperator3D{T,U} +# gamma::T +# α::U +# end scalartype(op::MWSingleLayer3D{T,U}) where {T,U} = promote_type(T,U) sign_upon_permutation(op::MWSingleLayer3D, I, J) = 1 @@ -113,15 +189,12 @@ function quaddata(op::MaxwellOperator3D, return (tpoints=tqd, bpoints=bqd, gausslegendre=leg) end -struct MWDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} - alpha::T - gamma::K -end -struct MWnDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} - alpha::T - gamma::K -end + +# struct MWnDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} +# alpha::T +# gamma::K +# end sign_upon_permutation(op::MWDoubleLayer3D, I, J) = 1 @@ -136,6 +209,7 @@ struct MWDoubleLayer3DReg{T,K} <: MaxwellOperator3DReg{T,K} end MWDoubleLayer3D(gamma) = MWDoubleLayer3D(1.0, gamma) # For legacy purposes +MWnDoubleLayer3D(gamma) = MWnDoubleLayer3D(1.0, gamma) # For legacy purposes regularpart(op::MWDoubleLayer3D) = MWDoubleLayer3DReg(op.alpha, op.gamma) singularpart(op::MWDoubleLayer3D) = MWDoubleLayer3DSng(op.alpha, op.gamma) @@ -154,14 +228,15 @@ function quadrule(op::MaxwellOperator3D, g::RTRefSpace, f::RTRefSpace, i, τ, j hits += (d2 < dtol) end end - + hits == 3 && return SauterSchwabQuadrature.CommonFace(qd.gausslegendre[3]) hits == 2 && return SauterSchwabQuadrature.CommonEdge(qd.gausslegendre[2]) hits == 1 && return SauterSchwabQuadrature.CommonVertex(qd.gausslegendre[1]) h2 = volume(σ) - xtol2 = 0.2 * 0.2 + xtol2 = 0.2 * 0.2 k2 = abs2(gamma(op)) + println(max(dmin2*k2, dmin2/16h2) < xtol2) max(dmin2*k2, dmin2/16h2) < xtol2 && return WiltonSERule( qd.tpoints[2,i], DoubleQuadRule( @@ -298,8 +373,8 @@ function (igd::Integrand{<:MWSingleLayer3D})(x,y,f,g) αG * dot(fi.value, gj.value) + βG * dot(fi.divergence, gj.divergence) end end -ttrace(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), SameBase() -strace(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), mesh +ttrace!(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), SameBase() +strace!(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), mesh function (igd::Integrand{<:MWSingleLayer3DReg})(x,y,f,g) α = igd.operator.α @@ -336,12 +411,53 @@ function (igd::Integrand{<:MWDoubleLayer3D})(x,y,f,g) G = cross.(Ref(gradgreen), gvalue) return _krondot(fvalue, G) end -ttrace(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), SameBase() -strace(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), SameBase() -ttrace(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), SameBase() -strace(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), SameBase() +function (igd::Integrand{<:ndotMWdoublelayer})(x,y,f,g) + + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + nx = normal(x) + fvalue = getvalue(f) + gvalue = getvalue(g) + G = dot.(Ref(nx),cross.(Ref(gradgreen), gvalue)) + return _krondot(fvalue, G) +end +function (igd::Integrand{<:MWdoublelayerXn})(x,y,f,g) + + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + ny = normal(y) + fvalue = getvalue(f) + gvalue = getvalue(g) + G = cross.(Ref(cross(gradgreen,n)), gvalue) + return _krondot(fvalue, G) +end + +function (igd::Integrand{<:nXdoublelayer})(x,y,f,g) + + γ = igd.operator.gamma -function (igd::Integrand{<:MWnDoubleLayer3D})(x,y,f,g) + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + nx = normal(x) + fvalue = getvalue(f) + gvalue = getvalue(g) + G = cross.(Ref(cross(nx,gradgreen)), gvalue) + return _krondot(fvalue, G) +end +function (igd::Integrand{<:nXMWdoublelayerXn})(x,y,f,g) γ = igd.operator.gamma @@ -350,16 +466,37 @@ function (igd::Integrand{<:MWnDoubleLayer3D})(x,y,f,g) iR = 1/R green = exp(-γ*R)*(iR*i4pi) gradgreen = -(γ + iR) * green * (iR * r) - n' = normal(y) + nx = normal(x) + ny = normal(y) fvalue = getvalue(f) gvalue = getvalue(g) - t1 = Ref(n').*gvalue - G = cross.(Ref(gradgreen), t1) + G = Ref(cross(nx,cross(gradgreen,ny))).* gvalue return _krondot(fvalue, G) end +# ttrace!(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), SameBase() +# strace!(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), mesh +# ttrace!(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), SameBase() +# strace!(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), mesh -ttrace(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), SameBase() -strace(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), mesh +# function (igd::Integrand{<:MWnDoubleLayer3D})(x,y,f,g) + +# γ = igd.operator.gamma + +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# normaly = normal(y) +# fvalue = getvalue(f) +# gvalue = getvalue(g) +# t1 = Ref(normaly).*gvalue +# G = cross.(Ref(gradgreen), t1) +# return _krondot(fvalue, G) +# end + +# ttrace!(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), SameBase() +# strace!(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), mesh function (igd::Integrand{<:MWDoubleLayer3DReg})(x,y,f,g) @@ -379,38 +516,37 @@ function (igd::Integrand{<:MWDoubleLayer3DReg})(x,y,f,g) return _krondot(fvalue, G) end -function (igd::{Integrand{<:MWngreenint}})(x,y,f,g) - γ = igd.operator.gamma +# function (igd::Integrand{<:MWngreenint})(x,y,f,g) +# γ = igd.operator.gamma - r = cartesian(x) - cartesian(y) - R = norm(r) - γR = γ*R - iR = 1/R - expo = exp(-γR) - green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# γR = γ*R +# iR = 1/R +# expo = exp(-γR) +# green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) - n' = normal(y) - fvalue = getvalue(f) - gvalue = getvalue(g) - t = n'*green - t2 = Ref(t).*gvalue - return _krondot(fvalue,t2) -end +# normaly = normal(y) +# fvalue = getvalue(f) +# gvalue = getvalue(g) +# t = normaly*green +# t2 = Ref(t).*gvalue +# return _krondot(fvalue,t2) +# end -ttrace(op::MWngreenint, mesh, or) = ZeroOperator(), SameBase() -strace(op::MWngreenint, mesh, or) = ZeroOperator(), mesh +# ttrace!(op::MWngreenint, mesh, or) = ZeroOperator(), SameBase() +# strace!(op::MWngreenint, mesh, or) = ZeroOperator(), mesh -function (igd::{Integrand{<:MWgreenint}})(x,y,f,g) +function (igd::Integrand{<:MWgreenint})(x,y,f,g) γ = igd.operator.gamma r = cartesian(x) - cartesian(y) R = norm(r) - γR = γ*R iR = 1/R - expo = exp(-γR) - green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) fvalue = getvalue(f) gvalue = getvalue(g) @@ -418,54 +554,194 @@ function (igd::{Integrand{<:MWgreenint}})(x,y,f,g) t2 = green*gvalue return _krondot(fvalue,t2) end +function (igd::Integrand{<:ndotMWgreenint})(x,y,f,g) + γ = igd.operator.gamma -ttrace(op::MWgreenint, mesh, or) = ZeroOperator(), SameBase() -strace(op::MWgreenint, mesh, or) = ZeroOperator(), mesh -ntrace(op::MWgreenint, mesh, or) = ZeroOperator(), mesh + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + nx = normal(x) + fvalue = getvalue(f) + gvalue = getvalue(g) -function (igd::{Integrand{<:MWgradgreenint}})(x,y,f,g) + t2 = dot.(Ref(nx),green*gvalue) + return _krondot(fvalue,t2) +end +function (igd::Integrand{<:ndotMWgreenintdotn})(x,y,f,g) γ = igd.operator.gamma r = cartesian(x) - cartesian(y) R = norm(r) - γR = γ*R iR = 1/R - expo = exp(-γR) - green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) - gradgreen = ( -(γR + 1)*expo + (1 - 0.5*γR^2) ) * (i4pi*iR^3) * r - + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + nx = normal(x) + ny = normal(y) + fvalue = getvalue(f) + gvalue = getvalue(g) + + t2 = dot.(Ref(nx),Ref(ny))*green*gvalue + return _krondot(fvalue,t2) +end +function (igd::Integrand{<:MWgreenintdotn})(x,y,f,g) + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + ny = normal(y) + fvalue = getvalue(f) + gvalue = getvalue(g) + + t2 = green*gvalue.*Ref(ny) + return _krondot(fvalue,t2) +end +function (igd::Integrand{<:nXMWgreenintdotn})(x,y,f,g) + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + ny = normal(y) + nx = normal(x) + fvalue = getvalue(f) + gvalue = getvalue(g) + t1 = green*gvalue.*Ref(ny) + t2 = cross.(Ref(nx),t1) + return _krondot(fvalue,t2) +end + +function (igd::Integrand{<:nXMWgreenint})(x,y,f,g) + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + nx = normal(x) + fvalue = getvalue(f) + gvalue = getvalue(g) + + t2 = cross.(Ref(nx),green*gvalue) + return _krondot(fvalue,t2) +end + +function (igd::Integrand{<:MWgradgreendot})(x,y,f,g) + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + fvalue = getvalue(f) gvalue = getvalue(g) t2 = dot.(gvalue,Ref(gradgreen)) + return _krondot(fvalue,t2) +end +function (igd::Integrand{<:ndotMWgradgreen})(x,y,f,g) + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + nx = normal(x) + fvalue = getvalue(f) + gvalue = getvalue(g) + t2 = gvalue*dot(nx,gradgreen) return _krondot(fvalue,t2) end -ttrace(op::MWgradgreenint, mesh, or) = ZeroOperator(), SameBase() -strace(op::MWgradgreenint, mesh, or) = ZeroOperator(), mesh -ntrace(op::MWgradgreenint, mesh, or) = 1/2*Identity(), mesh -function (igd::{Integrand{<:MWngradgreenint}})(x,y,f,g) +function (igd::Integrand{<:MWgradgreendotn})(x,y,f,g) γ = igd.operator.gamma r = cartesian(x) - cartesian(y) R = norm(r) - γR = γ*R iR = 1/R - expo = exp(-γR) - green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) - gradgreen = ( -(γR + 1)*expo + (1 - 0.5*γR^2) ) * (i4pi*iR^3) * r - + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + + fvalue = getvalue(f) + gvalue = getvalue(g) + ny = normal(y) + t2 = gvalue * dot(ny,Ref(gradgreen)) + return _krondot(fvalue,t2) +end +function (igd::Integrand{<:nXMWgradgreendot})(x,y,f,g) + γ = igd.operator.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-γ*R)*(iR*i4pi) + gradgreen = -(γ + iR) * green * (iR * r) + nx = normal(x) fvalue = getvalue(f) gvalue = getvalue(g) - n' = normal(y) - t1 = Ref(n').*gvalue - t2 = dot.(t1,Ref(gradgreen)) + t2 = gvalue.*Ref(cross(nx,gradgreen)) return _krondot(fvalue,t2) end -scallartrace(op::MWngradgreenint, mesh, or) = 1/2*Identity(), SameBase() +# ttrace!(op::MWgreenint, mesh, or) = ZeroOperator(), SameBase() +# strace!(op::MWgreenint, mesh, or) = ZeroOperator(), mesh +# ntrace!(op::MWgreenint, mesh, or) = ZeroOperator(), mesh + +# function (igd::Integrand{<:MWgradgreenint})(x,y,f,g) +# γ = igd.operator.gamma + +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# γR = γ*R +# iR = 1/R +# expo = exp(-γR) +# green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) +# gradgreen = ( -(γR + 1)*expo + (1 - 0.5*γR^2) ) * (i4pi*iR^3) * r + +# fvalue = getvalue(f) +# gvalue = getvalue(g) + +# t2 = dot.(gvalue,Ref(gradgreen)) + +# return _krondot(fvalue,t2) +# end +# ttrace!(op::MWgradgreenint, mesh, or) = ZeroOperator(), SameBase() +# strace!(op::MWgradgreenint, mesh, or) = ZeroOperator(), mesh +# ntrace!(op::MWgradgreenint, mesh, or) = 1/2*Identity(), mesh + +# function (igd::Integrand{<:MWngradgreenint})(x,y,f,g) +# γ = igd.operator.gamma + +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# γR = γ*R +# iR = 1/R +# expo = exp(-γR) +# green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) +# gradgreen = ( -(γR + 1)*expo + (1 - 0.5*γR^2) ) * (i4pi*iR^3) * r + +# fvalue = getvalue(f) +# gvalue = getvalue(g) +# normaly = normal(y) +# t1 = Ref(normaly).*gvalue +# t2 = dot.(t1,Ref(gradgreen)) + +# return _krondot(fvalue,t2) +# end + +# scallartrace!(op::MWngradgreenint, mesh, or) = 1/2*Identity(), SameBase() ################################################################################ # # Handling of operator parameters (Helmholtz and Maxwell) diff --git a/src/maxwell/nxdbllayer.jl b/src/maxwell/nxdbllayer.jl index 5343d986..054683ca 100644 --- a/src/maxwell/nxdbllayer.jl +++ b/src/maxwell/nxdbllayer.jl @@ -41,6 +41,7 @@ function quadrule(op::DoubleLayerRotatedMW3D, g::RTRefSpace, f::RTRefSpace, i, hits = 0 dtol = 1.0e3 * eps(eltype(eltype(τ.vertices))) + dmin2 = floatmax(eltype(eltype(τ.vertices))) for t in τ.vertices for s in σ.vertices diff --git a/src/operator.jl b/src/operator.jl index 1048c5eb..6e274c12 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -2,19 +2,7 @@ using .LinearSpace struct LongDelays{T} end struct Threading{T} end -abstract type TraceOperator <: Operator end -struct Strace <: TraceOperator - op - MeshInformation - orientation -end - -struct Ttrace <: TraceOperator - op - MeshInformation - orientation -end import Base: transpose, +, -, *, zero @@ -28,6 +16,26 @@ abstract type AbstractOperator end """ abstract type Operator <: AbstractOperator end +abstract type TraceOperator <: Operator end + +struct Strace <: TraceOperator + op + orientation +end + +struct Ttrace <: TraceOperator + op + orientation +end + +struct ZeroOperator <: AbstractOperator end +abstract type Orientation end +struct Inside <: Orientation end +struct Outside <: Orientation end +inside() = Inside() +outside() = Outside() + + mutable struct TransposedOperator <: AbstractOperator op::AbstractOperator end @@ -234,18 +242,14 @@ function assemble!(op::LinearCombinationOfOperators, tfs::AbstractSpace, bfs::Ab assemble!(A, tfs, bfs, store1, threading; quadstrat=qs) end end -function assemble!(op::Ttrace, tfs::AbstractSpace, bfs::AbstractSpace, - store, threading = Threading{:multi}; - quadstrat=defaultquadstrat(op, tfs, bfs)) - pvterm, mesh = ttrace(op.op,tfs.geo) - assemble!(pvterm+op.op,ttrace(tfs,mesh),bfs,store) +function assemble(op::Ttrace, tfs::AbstractSpace, bfs::AbstractSpace) + pvterm, mesh = ttrace!(op.op,tfs.geo,op.orientation) + assemble(pvterm+op.op,ttrace(tfs,mesh),bfs) end -function assemble!(op::Strace, tfs::AbstractSpace, bfs::AbstractSpace, - store, threading = Threading{:multi}; - quadstrat=defaultquadstrat(op, tfs, bfs)) - pvterm, mesh = strace(op.op,tfs.geo) - assemble!(-pvterm-op.op,strace(tfs,mesh),bfs,store) +function assemble(op::Strace, tfs::AbstractSpace, bfs::AbstractSpace) + pvterm, mesh = strace!(op.op,tfs.geo,op.orientation) + assemble(-pvterm-op.op,strace(tfs,mesh),bfs) end # Support for direct product spaces @@ -349,14 +353,9 @@ function assemble!(op::BlockFullOperators, U::DirectProductSpace, V::DirectProdu end -strace(op::Operator,minof,orientation) = Strace(op,minfo,orientation) -ttrace(op::Operator,minfo,orientation) = Ttrace(op,minfo,orientation) +strace(op::Operator,orientation::Orientation) = Strace(op,orientation) +ttrace(op::Operator,orientation::Orientation) = Ttrace(op,orientation) -struct ZeroOperator <: AbstractOperator end -struct Inside end -struct Outside end -inside() = Inside() -outside() = Outside() Base.zero(op::AbstractOperator) = ZeroOperator() From 2fc48396d2c9c3ffb02412aed6f790a0fff11f51 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 18 Sep 2023 09:32:41 +0200 Subject: [PATCH 009/110] traces implemented, not tested --- src/maxwell/mwops.jl | 23 +++++++++++++++++--- src/operator.jl | 50 ++++++++++++++++++++++---------------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index ec7361c9..81826a26 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -39,65 +39,80 @@ struct MWDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} alpha::T gamma::K end +trace(op::MWDoubleLayer3D, or::Inside) = op+1/2*NCross() +trace(op::MWDoubleLayer3D, or::Outside) = op-1/2*Ncross() struct MWSingleLayer3D{T,U} <: MaxwellOperator3D{T,U} gamma::T α::U β::U end +trace(op::MWSingleLayer3D,or::Orientation) = op # struct TdGdn_ydj{T,U} <: MaxwellOperator3D{T,U} # gamma::T # α::U # end +# TODO generalize traces for different normal combinations (see trace nXdoublelayer) +# TODO what if base and trial functions are not tangential + struct MWgreenint{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end +trace(op::MWgreenint,or::Orientation) = op struct MWgradgreendot{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end - +trace(op::MWgradgreendot,or::Orientation) = op struct nXMWgreenint{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end - +trace(op::nXMWgreenint,or::Orientation) = op struct nXdoublelayer{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end - +trace(op::nXdoublelayer,or::Orientation) = op-1/2*Identity() struct MWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +trace(op::MWgreenintdotn,or::Orientation) = op struct nXMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +trace(op::nXMWgreenintdotn,or::Orientation) = op struct nXMWgradgreendot{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +trace(op::nXMWgradgreendot,or::Orientation) = op struct MWgradgreendotn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +trace(op::MWgradgreendotn, or::Inside) = op+1/2*Identity() +trace(op::MWgradgreendotn, or::Outside) = op-1/2*Identity() struct MWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +trace(op::MWdoublelayerXn,or::Orientation) = op struct nXMWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check haakjes rechts gamma::T α::U end +trace(op::nXMWdoublelayerXn,or::Orientation) = op struct ndotMWdoublelayer{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +trace(op::ndotMWdoublelayer,or::Orientation) = op struct ndotMWgreenint{T,U}<: MaxwellOperator3D{T,U}#cehck gamma::T α::U @@ -106,10 +121,12 @@ struct ndotMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +trace(op::ndotMWgreenintdotn,or::Orientation) = op struct ndotMWgradgreen{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +trace(op::ndotMWgradgreen,or::Orientation) = op+1/2*Identity() ×(n::NormalVector,op::MWgreenint) = nXMWgreenint(op.gamma,op.α) ×(n::NormalVector,op::MWDoubleLayer3D) = nXdoublelayer(op.gamma,op.α) diff --git a/src/operator.jl b/src/operator.jl index 6e274c12..41e3c82d 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -16,19 +16,19 @@ abstract type AbstractOperator end """ abstract type Operator <: AbstractOperator end -abstract type TraceOperator <: Operator end +# abstract type TraceOperator <: Operator end -struct Strace <: TraceOperator - op - orientation -end +# struct Strace <: TraceOperator +# op +# orientation +# end -struct Ttrace <: TraceOperator - op - orientation -end +# struct Ttrace <: TraceOperator +# op +# orientation +# end -struct ZeroOperator <: AbstractOperator end +# struct ZeroOperator <: AbstractOperator end abstract type Orientation end struct Inside <: Orientation end struct Outside <: Orientation end @@ -242,15 +242,15 @@ function assemble!(op::LinearCombinationOfOperators, tfs::AbstractSpace, bfs::Ab assemble!(A, tfs, bfs, store1, threading; quadstrat=qs) end end -function assemble(op::Ttrace, tfs::AbstractSpace, bfs::AbstractSpace) - pvterm, mesh = ttrace!(op.op,tfs.geo,op.orientation) - assemble(pvterm+op.op,ttrace(tfs,mesh),bfs) -end +# function assemble(op::Ttrace, tfs::AbstractSpace, bfs::AbstractSpace) +# pvterm, mesh = ttrace!(op.op,tfs.geo,op.orientation) +# assemble(pvterm+op.op,ttrace(tfs,mesh),bfs) +# end -function assemble(op::Strace, tfs::AbstractSpace, bfs::AbstractSpace) - pvterm, mesh = strace!(op.op,tfs.geo,op.orientation) - assemble(-pvterm-op.op,strace(tfs,mesh),bfs) -end +# function assemble(op::Strace, tfs::AbstractSpace, bfs::AbstractSpace) +# pvterm, mesh = strace!(op.op,tfs.geo,op.orientation) +# assemble(-pvterm-op.op,strace(tfs,mesh),bfs) +# end # Support for direct product spaces function assemble!(op::AbstractOperator, tfs::DirectProductSpace, bfs::Space, @@ -353,14 +353,14 @@ function assemble!(op::BlockFullOperators, U::DirectProductSpace, V::DirectProdu end -strace(op::Operator,orientation::Orientation) = Strace(op,orientation) -ttrace(op::Operator,orientation::Orientation) = Ttrace(op,orientation) +# strace(op::Operator,orientation::Orientation) = Strace(op,orientation) +# ttrace(op::Operator,orientation::Orientation) = Ttrace(op,orientation) -Base.zero(op::AbstractOperator) = ZeroOperator() -+(a::AbstractOperator,b::ZeroOperator) = a -+(a::ZeroOperator,b::ZeroOperator) = a -+(a::ZeroOperator,b::AbstractOperator) = b+a -*(a::Number,b::ZeroOperator) = b +# Base.zero(op::AbstractOperator) = ZeroOperator() +# +(a::AbstractOperator,b::ZeroOperator) = a +# +(a::ZeroOperator,b::ZeroOperator) = a +# +(a::ZeroOperator,b::AbstractOperator) = b+a +# *(a::Number,b::ZeroOperator) = b From cab394bf23b0e2bd8282e71206772f4a01217f1f Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 19 Sep 2023 09:30:17 +0200 Subject: [PATCH 010/110] implemented operators and trace in a first manner a more general trace describtion is needed --- src/bases/basis.jl | 1 + src/maxwell/mwops.jl | 62 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/bases/basis.jl b/src/bases/basis.jl index 40ddedf0..6acbc810 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -2,6 +2,7 @@ abstract type RefSpace{T,D} end abstract type AbstractSpace end abstract type Space{T} <: AbstractSpace end + Base.length(s::AbstractSpace) = numfunctions(s) Base.in(x, s::AbstractSpace) = (x => s) diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index 81826a26..491bd77a 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -1,7 +1,7 @@ abstract type MaxwellOperator3D{T,K} <: IntegralOperator end abstract type MaxwellOperator3DReg{T,K} <: MaxwellOperator3D{T,K} end -import base: ×, ⋅ + scalartype(op::MaxwellOperator3D{T,K}) where {T, K <: Nothing} = T scalartype(op::MaxwellOperator3D{T,K}) where {T, K} = promote_type(T, K) @@ -40,7 +40,7 @@ struct MWDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} gamma::K end trace(op::MWDoubleLayer3D, or::Inside) = op+1/2*NCross() -trace(op::MWDoubleLayer3D, or::Outside) = op-1/2*Ncross() +trace(op::MWDoubleLayer3D, or::Outside) = op-1/2*(-1)*NCross() #extra -1 because of normal is chosen with respect to test function in localop.jl fix this. struct MWSingleLayer3D{T,U} <: MaxwellOperator3D{T,U} gamma::T @@ -61,87 +61,129 @@ struct MWgreenint{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end + trace(op::MWgreenint,or::Orientation) = op +sign_upon_permutation(op::MWgreenint, I, J) = 1 + struct MWgradgreendot{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end trace(op::MWgradgreendot,or::Orientation) = op +sign_upon_permutation(op::MWgradgreendot, I, J) = 1 + + struct nXMWgreenint{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end +sign_upon_permutation(op::nXMWgreenint, I, J) = Combinatorics.levicivita(I) trace(op::nXMWgreenint,or::Orientation) = op + + struct nXdoublelayer{T,U} <: MaxwellOperator3D{T,U}#check gamma::T α::U end +sign_upon_permutation(op::nXdoublelayer, I, J) = Combinatorics.levicivita(I) trace(op::nXdoublelayer,or::Orientation) = op-1/2*Identity() + + + struct MWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +sign_upon_permutation(op::MWgreenintdotn, I, J) = Combinatorics.levicivita(J) trace(op::MWgreenintdotn,or::Orientation) = op + + struct nXMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +sign_upon_permutation(op::nXMWgreenintdotn, I, J) = Combinatorics.levicivita(J)*Combinatorics.levicivita(I) trace(op::nXMWgreenintdotn,or::Orientation) = op + + struct nXMWgradgreendot{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +sign_upon_permutation(op::nXMWgradgreendot, I, J) = Combinatorics.levicivita(I) trace(op::nXMWgradgreendot,or::Orientation) = op + + struct MWgradgreendotn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +sign_upon_permutation(op::MWgradgreendotn, I, J) = Combinatorics.levicivita(J) trace(op::MWgradgreendotn, or::Inside) = op+1/2*Identity() trace(op::MWgradgreendotn, or::Outside) = op-1/2*Identity() + + struct MWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +sign_upon_permutation(op::MWdoublelayerXn, I, J) = Combinatorics.levicivita(J) trace(op::MWdoublelayerXn,or::Orientation) = op + + struct nXMWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check haakjes rechts gamma::T α::U end +sign_upon_permutation(op::nXMWdoublelayerXn, I, J) = Combinatorics.levicivita(I)*Combinatorics.levicivita(J) trace(op::nXMWdoublelayerXn,or::Orientation) = op + + struct ndotMWdoublelayer{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +sign_upon_permutation(op::ndotMWdoublelayer, I, J) = Combinatorics.levicivita(I) trace(op::ndotMWdoublelayer,or::Orientation) = op + + struct ndotMWgreenint{T,U}<: MaxwellOperator3D{T,U}#cehck gamma::T α::U end +sign_upon_permutation(op::ndotMWgreenint, I, J) = Combinatorics.levicivita(I) +trace(op::ndotMWgreenint,or::Orientation) = op + struct ndotMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +sign_upon_permutation(op::ndotMWgreenintdotn, I, J) = Combinatorics.levicivita(J)*Combinatorics.levicivita(I) trace(op::ndotMWgreenintdotn,or::Orientation) = op + + struct ndotMWgradgreen{T,U}<: MaxwellOperator3D{T,U}#check gamma::T α::U end +sign_upon_permutation(op::ndotMWgradgreen, I, J) = Combinatorics.levicivita(I) trace(op::ndotMWgradgreen,or::Orientation) = op+1/2*Identity() ×(n::NormalVector,op::MWgreenint) = nXMWgreenint(op.gamma,op.α) -×(n::NormalVector,op::MWDoubleLayer3D) = nXdoublelayer(op.gamma,op.α) +×(n::NormalVector,op::MWDoubleLayer3D) = nXdoublelayer(op.gamma,op.alpha) ⋅(op::MWgreenint,n::NormalVector) = MWgreenintdotn(op.gamma,op.α) ⋅(op::nXMWgreenint,n::NormalVector) = nXMWgreenintdotn(op.gamma,op.α) ×(n::NormalVector,op::MWgreenintdotn) = nXMWgreenintdotn(op.gamma,op.α) ×(n::NormalVector,op::MWgradgreendot) = nXMWgradgreendot(op.gamma,op.α) ⋅(op::MWgradgreendot,n::NormalVector) = MWgradgreendotn(op.gamma,op.α) -×(op::MWDoubleLayer3D,n::NormalVector) = MWdoublelayerXn(op.gamma,op.α) +×(op::MWgradgreendot,n::NormalVector) = MWdoublelayerXn(op.gamma,op.α) +×(op::MWDoubleLayer3D,n::NormalVector) = MWdoublelayerXn(op.gamma,op.alpha) ×(n::NormalVector,op::MWdoublelayerXn) = nXMWdoublelayerXn(op.gamma,op.α) -⋅(n::NormalVector,op::MWDoubleLayer3D) = ndotMWdoublelayer(op.gamma,op.α) +⋅(n::NormalVector,op::MWDoubleLayer3D) = ndotMWdoublelayer(op.gamma,op.alpha) ⋅(n::NormalVector,op::MWgreenint) = ndotMWgreenint(op.gamma,op.α) ⋅(n::NormalVector,op::MWgreenintdotn) = ndotMWgreenintdotn(op.gamma,op.α) ⋅(op::ndotMWgreenint,n::NormalVector)= ndotMWgreenintdotn(op.gamma,op.α) -⋅(n::NormalVector,op::MWgradgreen) = ndotMWgradgreen(op.gamma,op.α) +⋅(n::NormalVector,op::MWgradgreendot) = ndotMWgradgreen(op.gamma,op.α) # struct MWgradgreenint{T,U} <: MaxwellOperator3D{T,U} # gamma::T @@ -185,8 +227,8 @@ function _legendre(n,a,b) collect(zip(x,w)) end -defaultquadstrat(op::MaxwellOperator3D, tfs::Space, bfs::Space) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) -defaultquadstrat(op::MaxwellOperator3D, tfs::RefSpace, bfs::RefSpace) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) +# defaultquadstrat(op::MaxwellOperator3D, tfs::Space, bfs::Space) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) +# defaultquadstrat(op::MaxwellOperator3D, tfs::RefSpace, bfs::RefSpace) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) function quaddata(op::MaxwellOperator3D, @@ -390,8 +432,8 @@ function (igd::Integrand{<:MWSingleLayer3D})(x,y,f,g) αG * dot(fi.value, gj.value) + βG * dot(fi.divergence, gj.divergence) end end -ttrace!(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), SameBase() -strace!(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), mesh +# ttrace!(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), SameBase() +# strace!(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), mesh function (igd::Integrand{<:MWSingleLayer3DReg})(x,y,f,g) α = igd.operator.α From 1335e2e72e91eca43505130d843df32ba4813629 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 19 Sep 2023 09:31:01 +0200 Subject: [PATCH 011/110] implemented operators and trace, more general description needed --- src/BEAST.jl | 3 +++ src/integralop.jl | 1 - src/maxwell/maxwell.jl | 14 +------------- src/maxwell/nxdbllayer.jl | 2 +- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/BEAST.jl b/src/BEAST.jl index 800b87c5..5aeb4b83 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -25,6 +25,9 @@ import SharedArrays: sdata export dot +export ⋅ +export trace +export MWgradgreendot, MWgreenint export planewave export inside, outside export RefSpace, numfunctions, coordtype, scalartype, assemblydata, geometry, refspace, valuetype diff --git a/src/integralop.jl b/src/integralop.jl index f4a61320..7aa2fa45 100644 --- a/src/integralop.jl +++ b/src/integralop.jl @@ -115,7 +115,6 @@ function assemblechunk_body!(biop, todo, done, pctg = length(test_elements), 0, 0 for (p,tcell) in enumerate(test_elements) for (q,bcell) in enumerate(trial_elements) - fill!(zlocal, 0) qrule = quadrule(biop, test_shapes, trial_shapes, p, tcell, q, bcell, qd, quadstrat) momintegrals!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, qrule) diff --git a/src/maxwell/maxwell.jl b/src/maxwell/maxwell.jl index f89abfbf..e999c4bf 100644 --- a/src/maxwell/maxwell.jl +++ b/src/maxwell/maxwell.jl @@ -1,16 +1,4 @@ module Maxwell3D - """ - naming of operators: - ∇ - n_x normal test function - n_y normal basis function - G greens function - X cross product - d inner product/scallar product - t test function - b basis function - - """ using ..BEAST Mod = BEAST @@ -275,7 +263,7 @@ module Maxwell3D alpha = 1.0 # Default to double precision end end - Mod.MWngradgreendot(gamma,alpha) + Mod.MWgradgreendot(gamma,alpha) end end diff --git a/src/maxwell/nxdbllayer.jl b/src/maxwell/nxdbllayer.jl index 054683ca..5ad1719c 100644 --- a/src/maxwell/nxdbllayer.jl +++ b/src/maxwell/nxdbllayer.jl @@ -6,7 +6,7 @@ mutable struct DoubleLayerRotatedMW3D{T,K} <: MaxwellOperator3D{T,K} gamma::K end -LinearAlgebra.cross(::NormalVector, a::MWDoubleLayer3D) = DoubleLayerRotatedMW3D(a.alpha, a.gamma) +#LinearAlgebra.cross(::NormalVector, a::MWDoubleLayer3D) = DoubleLayerRotatedMW3D(a.alpha, a.gamma) # defaultquadstrat(::DoubleLayerRotatedMW3D, tfs, bfs) = DoubleNumQStrat(2,3) From 3cfb1d45be3673e8c8febb936353732133401061 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 19 Sep 2023 10:31:01 +0200 Subject: [PATCH 012/110] types of bases changed --- src/bases/basis.jl | 10 +++++++++- src/bases/bdm3dspace.jl | 2 +- src/bases/bdmdiv.jl | 2 +- src/bases/lagrange.jl | 2 +- src/bases/ncrossbdmspace.jl | 2 +- src/bases/ndlccspace.jl | 2 +- src/bases/ndlcdspace.jl | 2 +- src/bases/ndspace.jl | 2 +- src/bases/rtspace.jl | 2 +- src/maxwell/mwops.jl | 4 ++-- src/quadrature/quadstrats.jl | 5 ++++- 11 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/bases/basis.jl b/src/bases/basis.jl index 6acbc810..c3d69ca5 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -1,7 +1,15 @@ abstract type RefSpace{T,D} end abstract type AbstractSpace end abstract type Space{T} <: AbstractSpace end - +abstract type ScalarSpace{T} <: Space{T} end +abstract type VectorSpace{T} <: Space{T} end +abstract type ScalarSurfaceSpace{T} <: ScalarSpace{T} end +abstract type ScalarVolumeSpace{T} <: ScalarSpace{T} end +abstract type VectorSurfaceSpace{T} <: VectorSpace{T} end +abstract type VectorVolumeSpace{T} <: VectorSpace{T} end + +VolumeSpace = Union{ScalarVolumeSpace,VectorVolumeSpace} +SurfaceSpace = Union{ScalarSurfaceSpace,VectorSurfaceSpace} Base.length(s::AbstractSpace) = numfunctions(s) Base.in(x, s::AbstractSpace) = (x => s) diff --git a/src/bases/bdm3dspace.jl b/src/bases/bdm3dspace.jl index cabb8774..8cdc2414 100644 --- a/src/bases/bdm3dspace.jl +++ b/src/bases/bdm3dspace.jl @@ -1,4 +1,4 @@ -mutable struct BDM3DBasis{T,M,P} <: Space{T} +mutable struct BDM3DBasis{T,M,P} <: VectorVolumeSpace{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/bdmdiv.jl b/src/bases/bdmdiv.jl index 7865825d..72cc11c7 100644 --- a/src/bases/bdmdiv.jl +++ b/src/bases/bdmdiv.jl @@ -1,4 +1,4 @@ -struct BDMBasis{T,M,P} <: Space{T} +struct BDMBasis{T,M,P} <: VectorSurfaceSpace{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/lagrange.jl b/src/bases/lagrange.jl index 790492e3..36403089 100644 --- a/src/bases/lagrange.jl +++ b/src/bases/lagrange.jl @@ -11,7 +11,7 @@ function lagdimension end # M: mesh type # T: field type # NF: number of local shape functions -mutable struct LagrangeBasis{D,C,M,T,NF,P} <: Space{T} +mutable struct LagrangeBasis{D,C,M,T,NF,P} <: ScalarSpace{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/ncrossbdmspace.jl b/src/bases/ncrossbdmspace.jl index c5ed0364..efda3646 100644 --- a/src/bases/ncrossbdmspace.jl +++ b/src/bases/ncrossbdmspace.jl @@ -1,4 +1,4 @@ -struct NCrossBDMBasis{T,M,P} <: Space{T} +struct NCrossBDMBasis{T,M,P} <: VectorSurfaceSpace{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/ndlccspace.jl b/src/bases/ndlccspace.jl index aabea3e6..5fce51a9 100644 --- a/src/bases/ndlccspace.jl +++ b/src/bases/ndlccspace.jl @@ -1,4 +1,4 @@ -mutable struct NDLCCBasis{T,M,P} <: Space{T} +mutable struct NDLCCBasis{T,M,P} <: VectorVolumeSpace{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/ndlcdspace.jl b/src/bases/ndlcdspace.jl index 11d43b81..d9ea5828 100644 --- a/src/bases/ndlcdspace.jl +++ b/src/bases/ndlcdspace.jl @@ -1,4 +1,4 @@ -mutable struct NDLCDBasis{T,M,P} <: Space{T} +mutable struct NDLCDBasis{T,M,P} <: VectorVolumeSpace{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/ndspace.jl b/src/bases/ndspace.jl index 0393e5bb..6bcc1815 100644 --- a/src/bases/ndspace.jl +++ b/src/bases/ndspace.jl @@ -1,4 +1,4 @@ -struct NDBasis{T,M,P} <: Space{T} +struct NDBasis{T,M,P} <: VectorSurfaceSpace{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/rtspace.jl b/src/bases/rtspace.jl index b6a280a6..933e48cd 100644 --- a/src/bases/rtspace.jl +++ b/src/bases/rtspace.jl @@ -1,6 +1,6 @@ -mutable struct RTBasis{T,M,P} <: Space{T} +mutable struct RTBasis{T,M,P} <: VectorSurfaceSpace{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index 491bd77a..aa7163b1 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -227,8 +227,8 @@ function _legendre(n,a,b) collect(zip(x,w)) end -# defaultquadstrat(op::MaxwellOperator3D, tfs::Space, bfs::Space) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) -# defaultquadstrat(op::MaxwellOperator3D, tfs::RefSpace, bfs::RefSpace) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) +#defaultquadstrat(op::MaxwellOperator3D, tfs::Space, bfs::Space) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) +#defaultquadstrat(op::MaxwellOperator3D, tfs::RefSpace, bfs::RefSpace) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) function quaddata(op::MaxwellOperator3D, diff --git a/src/quadrature/quadstrats.jl b/src/quadrature/quadstrats.jl index 40d4bddb..40c9a994 100644 --- a/src/quadrature/quadstrats.jl +++ b/src/quadrature/quadstrats.jl @@ -39,7 +39,10 @@ struct OuterNumInnerAnalyticQStrat{R} end -defaultquadstrat(op, tfs, bfs) = defaultquadstrat(op, refspace(tfs), refspace(bfs)) +function defaultquadstrat(op, tfs, bfs) + @warn "made use of general defaultquadstrat routine which cals defaultquadstrat on refspaces" + defaultquadstrat(op, refspace(tfs), refspace(bfs)) +end macro defaultquadstrat(dop, body) @assert dop.head == :tuple @assert length(dop.args) == 3 From f8cb0a0e0e964d957ce369f98e03baf9d5acb029 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 19 Sep 2023 14:46:03 +0200 Subject: [PATCH 013/110] implemented operators in a general way --- src/Helmholtzhodge/helmholtzhodge.jl | 53 +++++++ src/Helmholtzhodge/hhhop.jl | 210 +++++++++++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 src/Helmholtzhodge/helmholtzhodge.jl create mode 100644 src/Helmholtzhodge/hhhop.jl diff --git a/src/Helmholtzhodge/helmholtzhodge.jl b/src/Helmholtzhodge/helmholtzhodge.jl new file mode 100644 index 00000000..0695d078 --- /dev/null +++ b/src/Helmholtzhodge/helmholtzhodge.jl @@ -0,0 +1,53 @@ +module Maxwell3D + using ..BEAST + Mod = BEAST + + + + """ + green(;gamma) + green(;wavenumber) + + Bilinear form given by: + + ```math + α ∬_{Γ^2} k(x) ⋅ G_γ(x-y) j(y) + ``` + + with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` + """ + function green(; + alpha=nothing, + gamma=nothing, + wavenumber=nothing) + + gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + if alpha === nothing + if gamma !== nothing + alpha = one(gamma) + else + alpha = 1.0 # Default to double precision + end + end + Mod.HHHgreen(gamma,alpha) + end + + function gradgreen(; + alpha=nothing, + gamma=nothing, + wavenumber=nothing) + + gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) + + if alpha === nothing + if gamma !== nothing + alpha = one(gamma) + else + alpha = 1.0 # Default to double precision + end + end + Mod.HHHgradgreen(gamma,alpha) +end + +end \ No newline at end of file diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl new file mode 100644 index 00000000..c7e8a463 --- /dev/null +++ b/src/Helmholtzhodge/hhhop.jl @@ -0,0 +1,210 @@ +import LinearAlgebra: ×, ⋅ +abstract type HHHOperator{T,K} <: IntegralOperator end +abstract type HHHtestOperator{T,K} <: HHHOperator{T,K} end +abstract type HHHbasisOperator{T,K} <: HHHOperator{T,K} end +abstract type HHHkernelOperator{T,K} <: HHHOperator{T,K} end +scalartype(op::HHHOperator3D{T,K}) where {T, K <: Nothing} = T +scalartype(op::HHHOperator3D{T,K}) where {T, K} = promote_type(T, K) + +const i4pi = 1 / (4pi) +struct HHHgreen{T,K} <: HHHkernelOperator{T,K} + α::K + γ::T + op::HHHOperator +end + +struct HHHgradgreen{T,K} <: HHHkernelOperator{T,K} + α::K + γ::T + op::HHHOperator +end + +struct HHHgradgreenCross{T,K} <: HHHkernelOperator{T,K} + α::K + γ::T + op::HHHOperator +end + +# struct HHHgreenNproj{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct HHHgradgreenCrossNproj{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct HHHgradgreenNproj{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct StraceHHHgreen{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct NtraceHHHgreen{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct StraceHHHgradgreen{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct NtraceHHHgradgreen{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct StraceHHHgradgreenCross{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct NtraceHHHgradgreenCross{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct StraceHHHgreenNproj{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct NtraceHHHgreenNproj{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct StraceHHHgradgreenCrossNproj{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end + +# struct NtraceHHHgradgreenCrossNproj{T,K} <: HHHOperator{T,K} +# α::K +# γ::T +# end +abstract type HHHdata end +struct HHHvector <:HHHdata end +struct HHHscalar <:HHHdata end +VectorToVector = Union{HHHNtestCross,HHHNbasisCross,HHHgradgreenCross,HHHgreen} +ScalarToVector = Union{HHHNbasisnormal,HHHgradgreen} +VectorToScalar = Union{HHHNtestDot,HHHgradgreen} +ScalarToScalar = Union{HHHgreen} + +struct HHHNtestCross{T,K} <: HHHtestOperator{T,K} + op::HHHOperator{T,K} +end +inversemap(op::VectorToVector,::HHHVector) = inversemap(op.op,HHHvector()) +inversemap(op::ScalarToVector,::HHHvector) = inversemap(op.op,HHHscalar()) +inversemap(op::VectorToScalar,::HHHscalar) = inversemap(op.op,HHHvector()) +inversemap(op::ScalarToScalar,::HHHscalar) = HHHscalar() +inversemap(::HHHOperator,::HHHdata) = @error "trying to convert scalar to vector or vector to scalar" +inversemap(::HHHIdentity,data::HHHdata) = data + +struct HHHNbasisCross <: HHHbasisOperator{T,K} + op::HHHOperator{T,K} +end + +struct HHHNtestDot{T,K} <: HHHtestOperator{T,K} + op::HHHOperator{T,K} +end + +struct HHHNbasisnormal{T,K} <: HHHbasisOperator{T,K} + op::HHHOperator{T,K} +end + +struct HHHIdentity{T,K} <: HHHbasisOperator{T,K} +end + +struct BasisFunction end +basisfunction() = BasisFunction() +export basisfunction + +##### Operator building + +strace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestCross(op) +ntrace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestDot(op) +×(op::HHHgradgreen,::Nothing) = HHHgradgreenCross(op.α,op.γ,op.op) +×(op::HHHgradgreen,::NormalVector) = HHHgradgreenCross(op.α,op.γ,op.op)(HHHNbasisnormal(HHHIdentity)) +×(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = strace(op) +⋅(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = ntrace(op) +*(::NormalVector,::BasisFunction) = HHHNbasisnormal(HHHIdentity()) +×(::NormalVector,::BasisFunction) = HHHNbasisCross(HHHIdentity()) +(op::HHHkernelOperator)(Basisop::HHHbasisOperator) = op.op=Basisop + + + +function (op::HHHOperator)(BasisOperator::HHHbasisOperator) + op.op = BasisOperator +end + + +##### Integrand definitions +function (igd::Integrand{<:HHHOperator})(x,y,f,g) + op = igd.operator + +test = getvalue(f) +_krondot(test,op(x,y,g)) +end +function (op::HHHNtestCross)(x,y,g) + nx = normal(x) + cross.(Ref(nx),op.op(x,y,g)) +end +function (op::HHHNtestDot)(x,y,g) + nx = normal(x) + dot.(Ref(nx),op.op(x,y,g)) +end +function (op::HHHNbasisnormal)(x,y,g) + ny = normal(y) + Ref(ny).*op.op(x.y.g) +end +function (op::HHHNbasisCross)(x,y,g) + ny = normal(y) + cross.(Ref(ny),op.op(x,y,g)) +end +function (op::HHHIdentity)(x,y,g) + getvalue(g) +end +function (op::HHHgreen)(x,y,g) + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-op.γ*R)*(iR*i4pi) + green*op.op(x,y,g) +end +mydot.(a::Vector{Vector},b::Base.RefValue) = dot.(a,b) +mydot.(a::Vector,b::Base.RefValue) = a.*b +function (op::HHHgradgreen)(x,y,g) + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-op.γ*R)*(iR*i4pi) + gradgreen = -(op.γ + iR) * green * (iR * r) + mydot.(op.op(x,y,g),Ref(gradgreen)) +end + +function (op::HHHgradgreenCross)(x,y,g) + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-op.γ*R)*(iR*i4pi) + gradgreen = -(op.γ + iR) * green * (iR * r) + cross.(Ref(gradgreen),op.op(x,y,g)) +end +identify(::VectorSurfaceSpace) = HHHvector() +identify(::ScalarSurfaceSpace) = HHHscalar() +kernel(op::HHHtestOperator) = kernel(op.op) +kernel(op::HHHkernelOperator) = op + +function defaultquadstrat(op::HHHOperator,testspace::Space,basisspace::Space) +@assert identify(basisspace) == inversemap(op,identify(testspace)) +defaultquadstrat(op,identify(testspace),identify(basisspace)) +end +defaultquadstrat(op::HHHOperator,::HHHdata,::HHHdata) = DoubleNumSauterQstrat(2,2,2,2,2,2) #TODO implement strategy that is stronger for nearby triangles \ No newline at end of file From a23cabb999805c9b8d0ea5d934583f2d75824574 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 19 Sep 2023 16:13:24 +0200 Subject: [PATCH 014/110] hhh debuged, TODO write compleet test, test defaultquadstrad --- src/BEAST.jl | 5 + src/Helmholtzhodge/helmholtzhodge.jl | 20 +--- src/Helmholtzhodge/hhhop.jl | 143 ++++++++---------------- src/Helmholtzhodge/test_HHHoperators.jl | 26 +++++ src/maxwell/mwops.jl | 4 +- 5 files changed, 82 insertions(+), 116 deletions(-) create mode 100644 src/Helmholtzhodge/test_HHHoperators.jl diff --git a/src/BEAST.jl b/src/BEAST.jl index 5aeb4b83..b2260912 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -257,6 +257,11 @@ include("solvers/itsolver.jl") include("utils/plotlyglue.jl") +#suport for helmholtzhodge equation +include("Helmholtzhodge/hhhop.jl") +include("Helmholtzhodge/helmholtzhodge.jl") + + diff --git a/src/Helmholtzhodge/helmholtzhodge.jl b/src/Helmholtzhodge/helmholtzhodge.jl index 0695d078..89a5f77c 100644 --- a/src/Helmholtzhodge/helmholtzhodge.jl +++ b/src/Helmholtzhodge/helmholtzhodge.jl @@ -1,21 +1,7 @@ -module Maxwell3D +module HHH using ..BEAST Mod = BEAST - - - """ - green(;gamma) - green(;wavenumber) - - Bilinear form given by: - - ```math - α ∬_{Γ^2} k(x) ⋅ G_γ(x-y) j(y) - ``` - - with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - """ function green(; alpha=nothing, gamma=nothing, @@ -30,7 +16,7 @@ module Maxwell3D alpha = 1.0 # Default to double precision end end - Mod.HHHgreen(gamma,alpha) + Mod.HHHgreen(alpha,gamma,Mod.hhhidentity()) end function gradgreen(; @@ -47,7 +33,7 @@ module Maxwell3D alpha = 1.0 # Default to double precision end end - Mod.HHHgradgreen(gamma,alpha) + Mod.HHHgradgreen(alpha,gamma,Mod.hhhidentity()) end end \ No newline at end of file diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index c7e8a463..bf4d3032 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -3,140 +3,83 @@ abstract type HHHOperator{T,K} <: IntegralOperator end abstract type HHHtestOperator{T,K} <: HHHOperator{T,K} end abstract type HHHbasisOperator{T,K} <: HHHOperator{T,K} end abstract type HHHkernelOperator{T,K} <: HHHOperator{T,K} end -scalartype(op::HHHOperator3D{T,K}) where {T, K <: Nothing} = T -scalartype(op::HHHOperator3D{T,K}) where {T, K} = promote_type(T, K) +# scalartype(op::HHHOperator{T,K}) where {T, K <: Nothing} = T +# scalartype(op::HHHOperator{T,K}) where {T, K} = promote_type(T, K) +scalartype(op::HHHOperator{T,K}) where {T, K <: Nothing} = Complex +scalartype(op::HHHOperator{T,K}) where {T, K} = Complex + const i4pi = 1 / (4pi) -struct HHHgreen{T,K} <: HHHkernelOperator{T,K} +mutable struct HHHgreen{T,K} <: HHHkernelOperator{T,K} α::K γ::T op::HHHOperator end -struct HHHgradgreen{T,K} <: HHHkernelOperator{T,K} +mutable struct HHHgradgreen{T,K} <: HHHkernelOperator{T,K} α::K γ::T op::HHHOperator end -struct HHHgradgreenCross{T,K} <: HHHkernelOperator{T,K} +mutable struct HHHgradgreenCross{T,K} <: HHHkernelOperator{T,K} α::K γ::T op::HHHOperator end -# struct HHHgreenNproj{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct HHHgradgreenCrossNproj{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct HHHgradgreenNproj{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct StraceHHHgreen{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct NtraceHHHgreen{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct StraceHHHgradgreen{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct NtraceHHHgradgreen{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct StraceHHHgradgreenCross{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct NtraceHHHgradgreenCross{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct StraceHHHgreenNproj{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct NtraceHHHgreenNproj{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct StraceHHHgradgreenCrossNproj{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end - -# struct NtraceHHHgradgreenCrossNproj{T,K} <: HHHOperator{T,K} -# α::K -# γ::T -# end abstract type HHHdata end struct HHHvector <:HHHdata end struct HHHscalar <:HHHdata end -VectorToVector = Union{HHHNtestCross,HHHNbasisCross,HHHgradgreenCross,HHHgreen} -ScalarToVector = Union{HHHNbasisnormal,HHHgradgreen} -VectorToScalar = Union{HHHNtestDot,HHHgradgreen} -ScalarToScalar = Union{HHHgreen} -struct HHHNtestCross{T,K} <: HHHtestOperator{T,K} + +mutable struct HHHNtestCross{T,K} <: HHHtestOperator{T,K} op::HHHOperator{T,K} end -inversemap(op::VectorToVector,::HHHVector) = inversemap(op.op,HHHvector()) -inversemap(op::ScalarToVector,::HHHvector) = inversemap(op.op,HHHscalar()) -inversemap(op::VectorToScalar,::HHHscalar) = inversemap(op.op,HHHvector()) -inversemap(op::ScalarToScalar,::HHHscalar) = HHHscalar() -inversemap(::HHHOperator,::HHHdata) = @error "trying to convert scalar to vector or vector to scalar" -inversemap(::HHHIdentity,data::HHHdata) = data -struct HHHNbasisCross <: HHHbasisOperator{T,K} + +mutable struct HHHNbasisCross{T,K} <: HHHbasisOperator{T,K} op::HHHOperator{T,K} end -struct HHHNtestDot{T,K} <: HHHtestOperator{T,K} +mutable struct HHHNtestDot{T,K} <: HHHtestOperator{T,K} op::HHHOperator{T,K} end -struct HHHNbasisnormal{T,K} <: HHHbasisOperator{T,K} +mutable struct HHHNbasisnormal{T,K} <: HHHbasisOperator{T,K} op::HHHOperator{T,K} end -struct HHHIdentity{T,K} <: HHHbasisOperator{T,K} +mutable struct HHHIdentity{T,K} <: HHHbasisOperator{T,K} end - +hhhidentity() = HHHIdentity{Complex,Complex}() +export HHH struct BasisFunction end basisfunction() = BasisFunction() export basisfunction - +VectorToVector = Union{HHHNtestCross,HHHNbasisCross,HHHgradgreenCross,HHHgreen} +ScalarToVector = Union{HHHNbasisnormal,HHHgradgreen} +VectorToScalar = Union{HHHNtestDot,HHHgradgreen} +ScalarToScalar = Union{HHHgreen} +inversemap(op::VectorToVector,::HHHvector) = inversemap(op.op,HHHvector()) +inversemap(op::ScalarToVector,::HHHvector) = inversemap(op.op,HHHscalar()) +inversemap(op::VectorToScalar,::HHHscalar) = inversemap(op.op,HHHvector()) +inversemap(op::ScalarToScalar,::HHHscalar) = HHHscalar() +inversemap(::HHHOperator,::HHHdata) = @error "trying to convert scalar to vector or vector to scalar" +inversemap(::HHHIdentity,data::HHHdata) = data ##### Operator building strace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestCross(op) ntrace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestDot(op) ×(op::HHHgradgreen,::Nothing) = HHHgradgreenCross(op.α,op.γ,op.op) -×(op::HHHgradgreen,::NormalVector) = HHHgradgreenCross(op.α,op.γ,op.op)(HHHNbasisnormal(HHHIdentity)) +×(op::HHHgradgreen,::NormalVector) = HHHgradgreenCross(op.α,op.γ,op.op)(HHHNbasisnormal(hhhidentity())) ×(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = strace(op) ⋅(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = ntrace(op) -*(::NormalVector,::BasisFunction) = HHHNbasisnormal(HHHIdentity()) -×(::NormalVector,::BasisFunction) = HHHNbasisCross(HHHIdentity()) -(op::HHHkernelOperator)(Basisop::HHHbasisOperator) = op.op=Basisop +*(::NormalVector,::BasisFunction) = HHHNbasisnormal(hhhidentity()) +×(::NormalVector,::BasisFunction) = HHHNbasisCross(hhhidentity()) +function (op::HHHkernelOperator)(Basisop::HHHbasisOperator) + return typeof(op)(op.α,op.γ,Basisop) +end @@ -176,25 +119,25 @@ function (op::HHHgreen)(x,y,g) r = cartesian(x) - cartesian(y) R = norm(r) iR = 1/R - green = exp(-op.γ*R)*(iR*i4pi) + green = op.α * exp(-op.γ*R)*(iR*i4pi) green*op.op(x,y,g) end -mydot.(a::Vector{Vector},b::Base.RefValue) = dot.(a,b) -mydot.(a::Vector,b::Base.RefValue) = a.*b +mydot(a::Vector{Vector},b::Base.RefValue) = dot.(a,b) +mydot(a::Vector,b::Base.RefValue) = a.*b function (op::HHHgradgreen)(x,y,g) r = cartesian(x) - cartesian(y) R = norm(r) iR = 1/R - green = exp(-op.γ*R)*(iR*i4pi) + green = op.α * exp(-op.γ*R)*(iR*i4pi) gradgreen = -(op.γ + iR) * green * (iR * r) - mydot.(op.op(x,y,g),Ref(gradgreen)) + mydot(op.op(x,y,g),Ref(gradgreen)) end function (op::HHHgradgreenCross)(x,y,g) r = cartesian(x) - cartesian(y) R = norm(r) iR = 1/R - green = exp(-op.γ*R)*(iR*i4pi) + green = op.α * exp(-op.γ*R)*(iR*i4pi) gradgreen = -(op.γ + iR) * green * (iR * r) cross.(Ref(gradgreen),op.op(x,y,g)) end @@ -207,4 +150,10 @@ function defaultquadstrat(op::HHHOperator,testspace::Space,basisspace::Space) @assert identify(basisspace) == inversemap(op,identify(testspace)) defaultquadstrat(op,identify(testspace),identify(basisspace)) end -defaultquadstrat(op::HHHOperator,::HHHdata,::HHHdata) = DoubleNumSauterQstrat(2,2,2,2,2,2) #TODO implement strategy that is stronger for nearby triangles \ No newline at end of file +defaultquadstrat(op::HHHOperator,::HHHdata,::HHHdata) = DoubleNumSauterQstrat(6,7,5,5,4,3) #TODO implement strategy that is stronger for nearby triangles + + +sign_upon_permutation(op::HHHIdentity,I,J) = 1 +sign_upon_permutation(op::HHHkernelOperator,I,J) = sign_upon_permutation(op.op,I,J) +sign_upon_permutation(op::Union{HHHNtestCross,HHHNtestDot},I,J) = Combinatorics.levicivita(I)*sign_upon_permutation(op.op,I,J) +sign_upon_permutation(op::Union{HHHNbasisnormal,HHHNbasisCross},I,J) = Combinatorics.levicivita(J)*sign_upon_permutation(op.op,I,J) \ No newline at end of file diff --git a/src/Helmholtzhodge/test_HHHoperators.jl b/src/Helmholtzhodge/test_HHHoperators.jl new file mode 100644 index 00000000..84126d60 --- /dev/null +++ b/src/Helmholtzhodge/test_HHHoperators.jl @@ -0,0 +1,26 @@ +using BEAST +using StaticArrays +using CompScienceMeshes +k = 1.0 + +green = HHH.green(wavenumber=k) +gradgreen = HHH.gradgreen(wavenumber=k) +b = basisfunction() +green +gradgreen +n×green +n×gradgreen +gradgreen×nothing +gradgreen×n +gradgreen(n×b) +gradgreen(n*b) +n×gradgreen(n×b) + +Γ1 = boundary(Mesh([SVector{3}([0.0,0.0,0.0]),SVector{3}([1.0,0.0,0.0]),SVector{3}([0.0,1.0,0.0]),SVector{3}([0.0,0.0,1.0])],[SVector{4}([1,2,3,4])])) +Γ2 = CompScienceMeshes.translate(Γ1,[0.0,0.0,0.0]) + +X1 = raviartthomas(Γ1) +X2 = raviartthomas(Γ2) + +display(assemble(gradgreen×nothing,X1,X2)) +display(assemble(Maxwell3D.doublelayer(wavenumber=k),X1,X2)) \ No newline at end of file diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index aa7163b1..2c39e4c6 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -227,8 +227,8 @@ function _legendre(n,a,b) collect(zip(x,w)) end -#defaultquadstrat(op::MaxwellOperator3D, tfs::Space, bfs::Space) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) -#defaultquadstrat(op::MaxwellOperator3D, tfs::RefSpace, bfs::RefSpace) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) +defaultquadstrat(op::MaxwellOperator3D, tfs::Space, bfs::Space) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) +defaultquadstrat(op::MaxwellOperator3D, tfs::RefSpace, bfs::RefSpace) = DoubleNumWiltonSauterQStrat(2,3,6,7,5,5,4,3) function quaddata(op::MaxwellOperator3D, From b2cf8a0beaecd4e6a8d7fce6d2f993716bb53d20 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 20 Sep 2023 09:44:07 +0200 Subject: [PATCH 015/110] debuged --- src/Helmholtzhodge/hhhop.jl | 27 +++++++++++++++++++------ src/Helmholtzhodge/test_HHHoperators.jl | 3 ++- src/bases/lagrange.jl | 2 +- src/quadrature/quadrule.jl | 2 +- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index bf4d3032..6e183a6d 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -49,7 +49,9 @@ end mutable struct HHHNbasisnormal{T,K} <: HHHbasisOperator{T,K} op::HHHOperator{T,K} end - +mutable struct HHHNbasisdot{T,K} <: HHHbasisOperator{T,K} + op::HHHOperator{T,K} +end mutable struct HHHIdentity{T,K} <: HHHbasisOperator{T,K} end hhhidentity() = HHHIdentity{Complex,Complex}() @@ -59,7 +61,7 @@ basisfunction() = BasisFunction() export basisfunction VectorToVector = Union{HHHNtestCross,HHHNbasisCross,HHHgradgreenCross,HHHgreen} ScalarToVector = Union{HHHNbasisnormal,HHHgradgreen} -VectorToScalar = Union{HHHNtestDot,HHHgradgreen} +VectorToScalar = Union{HHHNtestDot,HHHgradgreen,HHHNbasisdot} ScalarToScalar = Union{HHHgreen} inversemap(op::VectorToVector,::HHHvector) = inversemap(op.op,HHHvector()) inversemap(op::ScalarToVector,::HHHvector) = inversemap(op.op,HHHscalar()) @@ -76,7 +78,12 @@ ntrace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestDot(op) ×(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = strace(op) ⋅(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = ntrace(op) *(::NormalVector,::BasisFunction) = HHHNbasisnormal(hhhidentity()) +⋅(::NormalVector,::BasisFunction) = HHHNbasisdot(hhhidentity()) ×(::NormalVector,::BasisFunction) = HHHNbasisCross(hhhidentity()) +×(::NormalVector,op::HHHbasisOperator) = HHHNbasisCross(op) +⋅(::NormalVector,op::HHHbasisOperator) = HHHNbasisdot(op) + + function (op::HHHkernelOperator)(Basisop::HHHbasisOperator) return typeof(op)(op.α,op.γ,Basisop) end @@ -105,7 +112,11 @@ function (op::HHHNtestDot)(x,y,g) end function (op::HHHNbasisnormal)(x,y,g) ny = normal(y) - Ref(ny).*op.op(x.y.g) + Ref(ny).*op.op(x,y,g) +end +function (op::HHHNbasisdot)(x,y,g) + ny = normal(y) + dot.(Ref(ny),op.op(x,y,g)) end function (op::HHHNbasisCross)(x,y,g) ny = normal(y) @@ -122,8 +133,11 @@ function (op::HHHgreen)(x,y,g) green = op.α * exp(-op.γ*R)*(iR*i4pi) green*op.op(x,y,g) end -mydot(a::Vector{Vector},b::Base.RefValue) = dot.(a,b) -mydot(a::Vector,b::Base.RefValue) = a.*b +mydot(a::SVector{N,<:SVector},b::Base.RefValue) where {N} = dot.(a,b) +function mydot(a::SVector,b::Base.RefValue) + println("aaaa") + a.*b +end function (op::HHHgradgreen)(x,y,g) r = cartesian(x) - cartesian(y) R = norm(r) @@ -156,4 +170,5 @@ defaultquadstrat(op::HHHOperator,::HHHdata,::HHHdata) = DoubleNumSauterQstrat(6, sign_upon_permutation(op::HHHIdentity,I,J) = 1 sign_upon_permutation(op::HHHkernelOperator,I,J) = sign_upon_permutation(op.op,I,J) sign_upon_permutation(op::Union{HHHNtestCross,HHHNtestDot},I,J) = Combinatorics.levicivita(I)*sign_upon_permutation(op.op,I,J) -sign_upon_permutation(op::Union{HHHNbasisnormal,HHHNbasisCross},I,J) = Combinatorics.levicivita(J)*sign_upon_permutation(op.op,I,J) \ No newline at end of file +sign_upon_permutation(op::Union{HHHNbasisnormal,HHHNbasisCross,HHHNbasisdot},I,J) = Combinatorics.levicivita(J)*sign_upon_permutation(op.op,I,J) + diff --git a/src/Helmholtzhodge/test_HHHoperators.jl b/src/Helmholtzhodge/test_HHHoperators.jl index 84126d60..6682bda4 100644 --- a/src/Helmholtzhodge/test_HHHoperators.jl +++ b/src/Helmholtzhodge/test_HHHoperators.jl @@ -21,6 +21,7 @@ n×gradgreen(n×b) X1 = raviartthomas(Γ1) X2 = raviartthomas(Γ2) +X3 = lagrangec0d1(Γ1) -display(assemble(gradgreen×nothing,X1,X2)) +display(assemble((gradgreen)(n×b),X3,X2)) display(assemble(Maxwell3D.doublelayer(wavenumber=k),X1,X2)) \ No newline at end of file diff --git a/src/bases/lagrange.jl b/src/bases/lagrange.jl index 36403089..0b66e17f 100644 --- a/src/bases/lagrange.jl +++ b/src/bases/lagrange.jl @@ -11,7 +11,7 @@ function lagdimension end # M: mesh type # T: field type # NF: number of local shape functions -mutable struct LagrangeBasis{D,C,M,T,NF,P} <: ScalarSpace{T} +mutable struct LagrangeBasis{D,C,M,T,NF,P} <: ScalarSurfaceSpace{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/quadrature/quadrule.jl b/src/quadrature/quadrule.jl index 8307a966..a5eea12b 100644 --- a/src/quadrature/quadrule.jl +++ b/src/quadrature/quadrule.jl @@ -1,7 +1,7 @@ # This file contains kernel independent implementations of quadrule for # the various quadrature strategies defined in quadstrats.jl -function quadrule(op::IntegralOperator, g::RTRefSpace, f::RTRefSpace, i, τ, j, σ, qd, +function quadrule(op::IntegralOperator, g::RefSpace, f::RefSpace, i, τ, j, σ, qd, qs::DoubleNumSauterQstrat) T = eltype(eltype(τ.vertices)) From 85c41720d2320397ea9c7629180434bf4eecff48 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 20 Sep 2023 09:59:54 +0200 Subject: [PATCH 016/110] created test HHHOperators --- src/Helmholtzhodge/hhhop.jl | 1 - {src/Helmholtzhodge => test}/test_HHHoperators.jl | 11 +++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) rename {src/Helmholtzhodge => test}/test_HHHoperators.jl (63%) diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index 6e183a6d..8271118e 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -135,7 +135,6 @@ function (op::HHHgreen)(x,y,g) end mydot(a::SVector{N,<:SVector},b::Base.RefValue) where {N} = dot.(a,b) function mydot(a::SVector,b::Base.RefValue) - println("aaaa") a.*b end function (op::HHHgradgreen)(x,y,g) diff --git a/src/Helmholtzhodge/test_HHHoperators.jl b/test/test_HHHoperators.jl similarity index 63% rename from src/Helmholtzhodge/test_HHHoperators.jl rename to test/test_HHHoperators.jl index 6682bda4..19c8b41d 100644 --- a/src/Helmholtzhodge/test_HHHoperators.jl +++ b/test/test_HHHoperators.jl @@ -1,6 +1,7 @@ using BEAST using StaticArrays using CompScienceMeshes +using Test k = 1.0 green = HHH.green(wavenumber=k) @@ -16,6 +17,7 @@ gradgreen(n×b) gradgreen(n*b) n×gradgreen(n×b) + Γ1 = boundary(Mesh([SVector{3}([0.0,0.0,0.0]),SVector{3}([1.0,0.0,0.0]),SVector{3}([0.0,1.0,0.0]),SVector{3}([0.0,0.0,1.0])],[SVector{4}([1,2,3,4])])) Γ2 = CompScienceMeshes.translate(Γ1,[0.0,0.0,0.0]) @@ -23,5 +25,10 @@ X1 = raviartthomas(Γ1) X2 = raviartthomas(Γ2) X3 = lagrangec0d1(Γ1) -display(assemble((gradgreen)(n×b),X3,X2)) -display(assemble(Maxwell3D.doublelayer(wavenumber=k),X1,X2)) \ No newline at end of file +m1 = assemble(n×(n×(gradgreen×nothing)(n×(n×b))),X1,X2) +m2 = assemble((gradgreen)(n⋅(n×b)),X1,X2) +m3 = assemble(n⋅(gradgreen)(n⋅(n×b)),X3,X2) +m4 = assemble((green)(n×(n*b)),X1,X3) +dl = assemble(Maxwell3D.doublelayer(wavenumber=k),X1,X2) + +@test abs(sum(m1-dl)+sum(m2)+sum(m3)+sum(m4)) < 10^(-16) \ No newline at end of file From 03cfe782b220f4f6e42b4717f142571adc6012f7 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 20 Sep 2023 10:00:56 +0200 Subject: [PATCH 017/110] included test HHHoperators in BEAST --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index f635e5b9..6e0a3d95 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -70,7 +70,7 @@ include("test_tdrhs_scaling.jl") include("test_td_tensoroperator.jl") include("test_variational.jl") - +include("test_HHHoperators.jl") try Pkg.installed("BogaertInts10") From 2af25c7b7550d86ce5dc24f8cf05021116ce105d Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 20 Sep 2023 10:45:54 +0200 Subject: [PATCH 018/110] non used functions commented --- src/maxwell/maxwell.jl | 192 +------------ src/maxwell/mwops.jl | 639 ++++++++++++++++++++--------------------- 2 files changed, 315 insertions(+), 516 deletions(-) diff --git a/src/maxwell/maxwell.jl b/src/maxwell/maxwell.jl index e999c4bf..3000dd4a 100644 --- a/src/maxwell/maxwell.jl +++ b/src/maxwell/maxwell.jl @@ -63,35 +63,7 @@ module Maxwell3D Mod.MWDoubleLayer3D(gamma) end - # """ - # ndoublelayer(;gamma) - # ndoublelaher(;wavenumber) - # Bilinear form given by: - - # ```math - # α ∬_{Γ^2} k(x) ⋅ (∇G_γ(x-y) × n_y j(y)) - # ``` - - # with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - # """ - # function td∇GXn_ydb(; - # alpha=nothing, - # gamma=nothing, - # wavenumber=nothing) - - # gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - # if alpha === nothing - # if gamma !== nothing - # alpha = one(gamma) - # else - # alpha = 1.0 # Default to double precision - # end - # end - - # Mod.Td∇GXn_ydb(gamma) - # end planewave(; direction = error("missing arguement `direction`"), polarization = error("missing arguement `polarization`"), @@ -103,167 +75,5 @@ module Maxwell3D wavenumber = error("missing argument: `wavenumber`")) = Mod.MWFarField3D(wavenumber=wavenumber) - - # """ - # ngreenint(;gamma) - # ngreenint(;wavenumber) - - # Bilinear form given by: - - # ```math - # α ∬_{Γ^2} k(x) ⋅ n_y (G_γ(x-y)j(y)) - # ``` - - # with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - # """ - # function tdGdn_ydj(; - # alpha=nothing, - # gamma=nothing, - # wavenumber=nothing) - - # gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - # if alpha === nothing - # if gamma !== nothing - # alpha = one(gamma) - # else - # alpha = 1.0 # Default to double precision - # end - # end - # Mod.TdGdn_ydj(gamma,alpha) - # end - - # """ - # greenint(;gamma) - # greenint(;wavenumber) - - # Bilinear form given by: - - # ```math - # α ∬_{Γ^2} k(x) ⋅ G_γ(x-y) j(y) - # ``` - - # with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - # """ - # function greenint(; - # alpha=nothing, - # gamma=nothing, - # wavenumber=nothing) - - # gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - # if alpha === nothing - # if gamma !== nothing - # alpha = one(gamma) - # else - # alpha = 1.0 # Default to double precision - # end - # end - # Mod.MWgreenint(gamma,alpha) - # end - - """ - greenint(;gamma) - greenint(;wavenumber) - - Bilinear form given by: - - ```math - α ∬_{Γ^2} k(x) ⋅ G_γ(x-y) j(y) - ``` - - with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - """ - function greenint(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end - end - Mod.MWgreenint(gamma,alpha) - end - # """ - # gradgreenint(;gamma) - # gradgreenint(;wavenumber) - - # Bilinear form given by: - - # ```math - # α ∬_{Γ^2} k(x) ⋅∇G_γ(x-y) j(y) - # ``` - # or - # ```math - # α ∬_{Γ^2} k(x) ∇G_γ(x-y) ⋅ j(y) - # ``` - # with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - # """ - # function gradgreenint(; - # alpha=nothing, - # gamma=nothing, - # wavenumber=nothing) - - # gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - # if alpha === nothing - # if gamma !== nothing - # alpha = one(gamma) - # else - # alpha = 1.0 # Default to double precision - # end - # end - # Mod.MWgradgreenint(gamma,alpha) - # end - # """ - # ngradgreenint(;gamma) - # ngradgreenint(;wavenumber) - - # Bilinear form given by: - - # ```math - # α ∬_{Γ^2} k(x) ⋅∇G_γ(x-y)n_y j(y) - # ``` - # with ``G_γ = e^{-γ|x-y|} / 4π|x-y|`` - # """ - # function ngradgreenint(; - # alpha=nothing, - # gamma=nothing, - # wavenumber=nothing) - - # gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - # if alpha === nothing - # if gamma !== nothing - # alpha = one(gamma) - # else - # alpha = 1.0 # Default to double precision - # end - # end - # Mod.MWngradgreenint(gamma,alpha) - # end - - function gradgreendot(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end - end - Mod.MWgradgreendot(gamma,alpha) -end - + end diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index 2c39e4c6..f6fd05aa 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -39,160 +39,149 @@ struct MWDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} alpha::T gamma::K end -trace(op::MWDoubleLayer3D, or::Inside) = op+1/2*NCross() -trace(op::MWDoubleLayer3D, or::Outside) = op-1/2*(-1)*NCross() #extra -1 because of normal is chosen with respect to test function in localop.jl fix this. struct MWSingleLayer3D{T,U} <: MaxwellOperator3D{T,U} gamma::T α::U β::U end -trace(op::MWSingleLayer3D,or::Orientation) = op -# struct TdGdn_ydj{T,U} <: MaxwellOperator3D{T,U} +# struct MWgreenint{T,U} <: MaxwellOperator3D{T,U}#check # gamma::T # α::U # end -# TODO generalize traces for different normal combinations (see trace nXdoublelayer) -# TODO what if base and trial functions are not tangential +# trace(op::MWgreenint,or::Orientation) = op +# sign_upon_permutation(op::MWgreenint, I, J) = 1 -struct MWgreenint{T,U} <: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end - -trace(op::MWgreenint,or::Orientation) = op -sign_upon_permutation(op::MWgreenint, I, J) = 1 - -struct MWgradgreendot{T,U} <: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -trace(op::MWgradgreendot,or::Orientation) = op -sign_upon_permutation(op::MWgradgreendot, I, J) = 1 - - -struct nXMWgreenint{T,U} <: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -sign_upon_permutation(op::nXMWgreenint, I, J) = Combinatorics.levicivita(I) -trace(op::nXMWgreenint,or::Orientation) = op +# struct MWgradgreendot{T,U} <: MaxwellOperator3D{T,U}#check +# gamma::T +# α::U +# end +# trace(op::MWgradgreendot,or::Orientation) = op +# sign_upon_permutation(op::MWgradgreendot, I, J) = 1 -struct nXdoublelayer{T,U} <: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -sign_upon_permutation(op::nXdoublelayer, I, J) = Combinatorics.levicivita(I) -trace(op::nXdoublelayer,or::Orientation) = op-1/2*Identity() +# struct nXMWgreenint{T,U} <: MaxwellOperator3D{T,U}#check +# gamma::T +# α::U +# end +# sign_upon_permutation(op::nXMWgreenint, I, J) = Combinatorics.levicivita(I) +# trace(op::nXMWgreenint,or::Orientation) = op +# struct nXdoublelayer{T,U} <: MaxwellOperator3D{T,U}#check +# gamma::T +# α::U +# end +# sign_upon_permutation(op::nXdoublelayer, I, J) = Combinatorics.levicivita(I) +# trace(op::nXdoublelayer,or::Orientation) = op-1/2*Identity() -struct MWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -sign_upon_permutation(op::MWgreenintdotn, I, J) = Combinatorics.levicivita(J) -trace(op::MWgreenintdotn,or::Orientation) = op -struct nXMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -sign_upon_permutation(op::nXMWgreenintdotn, I, J) = Combinatorics.levicivita(J)*Combinatorics.levicivita(I) -trace(op::nXMWgreenintdotn,or::Orientation) = op +# struct MWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check +# gamma::T +# α::U +# end +# sign_upon_permutation(op::MWgreenintdotn, I, J) = Combinatorics.levicivita(J) +# trace(op::MWgreenintdotn,or::Orientation) = op -struct nXMWgradgreendot{T,U}<: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -sign_upon_permutation(op::nXMWgradgreendot, I, J) = Combinatorics.levicivita(I) -trace(op::nXMWgradgreendot,or::Orientation) = op +# struct nXMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check +# gamma::T +# α::U +# end +# sign_upon_permutation(op::nXMWgreenintdotn, I, J) = Combinatorics.levicivita(J)*Combinatorics.levicivita(I) +# trace(op::nXMWgreenintdotn,or::Orientation) = op -struct MWgradgreendotn{T,U}<: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -sign_upon_permutation(op::MWgradgreendotn, I, J) = Combinatorics.levicivita(J) -trace(op::MWgradgreendotn, or::Inside) = op+1/2*Identity() -trace(op::MWgradgreendotn, or::Outside) = op-1/2*Identity() +# struct nXMWgradgreendot{T,U}<: MaxwellOperator3D{T,U}#check +# gamma::T +# α::U +# end +# sign_upon_permutation(op::nXMWgradgreendot, I, J) = Combinatorics.levicivita(I) +# trace(op::nXMWgradgreendot,or::Orientation) = op -struct MWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -sign_upon_permutation(op::MWdoublelayerXn, I, J) = Combinatorics.levicivita(J) -trace(op::MWdoublelayerXn,or::Orientation) = op +# struct MWgradgreendotn{T,U}<: MaxwellOperator3D{T,U}#check +# gamma::T +# α::U +# end +# sign_upon_permutation(op::MWgradgreendotn, I, J) = Combinatorics.levicivita(J) +# trace(op::MWgradgreendotn, or::Inside) = op+1/2*Identity() +# trace(op::MWgradgreendotn, or::Outside) = op-1/2*Identity() -struct nXMWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check haakjes rechts - gamma::T - α::U -end -sign_upon_permutation(op::nXMWdoublelayerXn, I, J) = Combinatorics.levicivita(I)*Combinatorics.levicivita(J) -trace(op::nXMWdoublelayerXn,or::Orientation) = op +# struct MWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check +# gamma::T +# α::U +# end +# sign_upon_permutation(op::MWdoublelayerXn, I, J) = Combinatorics.levicivita(J) +# trace(op::MWdoublelayerXn,or::Orientation) = op -struct ndotMWdoublelayer{T,U}<: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -sign_upon_permutation(op::ndotMWdoublelayer, I, J) = Combinatorics.levicivita(I) -trace(op::ndotMWdoublelayer,or::Orientation) = op +# struct nXMWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check haakjes rechts +# gamma::T +# α::U +# end +# sign_upon_permutation(op::nXMWdoublelayerXn, I, J) = Combinatorics.levicivita(I)*Combinatorics.levicivita(J) +# trace(op::nXMWdoublelayerXn,or::Orientation) = op -struct ndotMWgreenint{T,U}<: MaxwellOperator3D{T,U}#cehck - gamma::T - α::U -end -sign_upon_permutation(op::ndotMWgreenint, I, J) = Combinatorics.levicivita(I) -trace(op::ndotMWgreenint,or::Orientation) = op +# struct ndotMWdoublelayer{T,U}<: MaxwellOperator3D{T,U}#check +# gamma::T +# α::U +# end +# sign_upon_permutation(op::ndotMWdoublelayer, I, J) = Combinatorics.levicivita(I) +# trace(op::ndotMWdoublelayer,or::Orientation) = op -struct ndotMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -sign_upon_permutation(op::ndotMWgreenintdotn, I, J) = Combinatorics.levicivita(J)*Combinatorics.levicivita(I) -trace(op::ndotMWgreenintdotn,or::Orientation) = op +# struct ndotMWgreenint{T,U}<: MaxwellOperator3D{T,U}#cehck +# gamma::T +# α::U +# end +# sign_upon_permutation(op::ndotMWgreenint, I, J) = Combinatorics.levicivita(I) +# trace(op::ndotMWgreenint,or::Orientation) = op -struct ndotMWgradgreen{T,U}<: MaxwellOperator3D{T,U}#check - gamma::T - α::U -end -sign_upon_permutation(op::ndotMWgradgreen, I, J) = Combinatorics.levicivita(I) -trace(op::ndotMWgradgreen,or::Orientation) = op+1/2*Identity() - -×(n::NormalVector,op::MWgreenint) = nXMWgreenint(op.gamma,op.α) -×(n::NormalVector,op::MWDoubleLayer3D) = nXdoublelayer(op.gamma,op.alpha) -⋅(op::MWgreenint,n::NormalVector) = MWgreenintdotn(op.gamma,op.α) -⋅(op::nXMWgreenint,n::NormalVector) = nXMWgreenintdotn(op.gamma,op.α) -×(n::NormalVector,op::MWgreenintdotn) = nXMWgreenintdotn(op.gamma,op.α) -×(n::NormalVector,op::MWgradgreendot) = nXMWgradgreendot(op.gamma,op.α) -⋅(op::MWgradgreendot,n::NormalVector) = MWgradgreendotn(op.gamma,op.α) -×(op::MWgradgreendot,n::NormalVector) = MWdoublelayerXn(op.gamma,op.α) -×(op::MWDoubleLayer3D,n::NormalVector) = MWdoublelayerXn(op.gamma,op.alpha) -×(n::NormalVector,op::MWdoublelayerXn) = nXMWdoublelayerXn(op.gamma,op.α) -⋅(n::NormalVector,op::MWDoubleLayer3D) = ndotMWdoublelayer(op.gamma,op.alpha) -⋅(n::NormalVector,op::MWgreenint) = ndotMWgreenint(op.gamma,op.α) -⋅(n::NormalVector,op::MWgreenintdotn) = ndotMWgreenintdotn(op.gamma,op.α) -⋅(op::ndotMWgreenint,n::NormalVector)= ndotMWgreenintdotn(op.gamma,op.α) -⋅(n::NormalVector,op::MWgradgreendot) = ndotMWgradgreen(op.gamma,op.α) - -# struct MWgradgreenint{T,U} <: MaxwellOperator3D{T,U} +# struct ndotMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check # gamma::T # α::U # end -# struct MWngradgreenint{T,U} <: MaxwellOperator3D{T,U} +# sign_upon_permutation(op::ndotMWgreenintdotn, I, J) = Combinatorics.levicivita(J)*Combinatorics.levicivita(I) +# trace(op::ndotMWgreenintdotn,or::Orientation) = op + + +# struct ndotMWgradgreen{T,U}<: MaxwellOperator3D{T,U}#check # gamma::T # α::U # end +# sign_upon_permutation(op::ndotMWgradgreen, I, J) = Combinatorics.levicivita(I) +# trace(op::ndotMWgradgreen,or::Orientation) = op+1/2*Identity() + +# ×(n::NormalVector,op::MWgreenint) = nXMWgreenint(op.gamma,op.α) +# ×(n::NormalVector,op::MWDoubleLayer3D) = nXdoublelayer(op.gamma,op.alpha) +# ⋅(op::MWgreenint,n::NormalVector) = MWgreenintdotn(op.gamma,op.α) +# ⋅(op::nXMWgreenint,n::NormalVector) = nXMWgreenintdotn(op.gamma,op.α) +# ×(n::NormalVector,op::MWgreenintdotn) = nXMWgreenintdotn(op.gamma,op.α) +# ×(n::NormalVector,op::MWgradgreendot) = nXMWgradgreendot(op.gamma,op.α) +# ⋅(op::MWgradgreendot,n::NormalVector) = MWgradgreendotn(op.gamma,op.α) +# ×(op::MWgradgreendot,n::NormalVector) = MWdoublelayerXn(op.gamma,op.α) +# ×(op::MWDoubleLayer3D,n::NormalVector) = MWdoublelayerXn(op.gamma,op.alpha) +# ×(n::NormalVector,op::MWdoublelayerXn) = nXMWdoublelayerXn(op.gamma,op.α) +# ⋅(n::NormalVector,op::MWDoubleLayer3D) = ndotMWdoublelayer(op.gamma,op.alpha) +# ⋅(n::NormalVector,op::MWgreenint) = ndotMWgreenint(op.gamma,op.α) +# ⋅(n::NormalVector,op::MWgreenintdotn) = ndotMWgreenintdotn(op.gamma,op.α) +# ⋅(op::ndotMWgreenint,n::NormalVector)= ndotMWgreenintdotn(op.gamma,op.α) +# ⋅(n::NormalVector,op::MWgradgreendot) = ndotMWgradgreen(op.gamma,op.α) + +# # struct MWgradgreenint{T,U} <: MaxwellOperator3D{T,U} +# # gamma::T +# # α::U +# # end +# # struct MWngradgreenint{T,U} <: MaxwellOperator3D{T,U} +# # gamma::T +# # α::U +# # end scalartype(op::MWSingleLayer3D{T,U}) where {T,U} = promote_type(T,U) sign_upon_permutation(op::MWSingleLayer3D, I, J) = 1 @@ -268,7 +257,7 @@ struct MWDoubleLayer3DReg{T,K} <: MaxwellOperator3DReg{T,K} end MWDoubleLayer3D(gamma) = MWDoubleLayer3D(1.0, gamma) # For legacy purposes -MWnDoubleLayer3D(gamma) = MWnDoubleLayer3D(1.0, gamma) # For legacy purposes +# MWnDoubleLayer3D(gamma) = MWnDoubleLayer3D(1.0, gamma) # For legacy purposes regularpart(op::MWDoubleLayer3D) = MWDoubleLayer3DReg(op.alpha, op.gamma) singularpart(op::MWDoubleLayer3D) = MWDoubleLayer3DSng(op.alpha, op.gamma) @@ -470,74 +459,53 @@ function (igd::Integrand{<:MWDoubleLayer3D})(x,y,f,g) G = cross.(Ref(gradgreen), gvalue) return _krondot(fvalue, G) end -function (igd::Integrand{<:ndotMWdoublelayer})(x,y,f,g) +# function (igd::Integrand{<:ndotMWdoublelayer})(x,y,f,g) - γ = igd.operator.gamma - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - nx = normal(x) - fvalue = getvalue(f) - gvalue = getvalue(g) - G = dot.(Ref(nx),cross.(Ref(gradgreen), gvalue)) - return _krondot(fvalue, G) -end -function (igd::Integrand{<:MWdoublelayerXn})(x,y,f,g) - - γ = igd.operator.gamma - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - ny = normal(y) - fvalue = getvalue(f) - gvalue = getvalue(g) - G = cross.(Ref(cross(gradgreen,n)), gvalue) - return _krondot(fvalue, G) -end +# γ = igd.operator.gamma -function (igd::Integrand{<:nXdoublelayer})(x,y,f,g) +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# nx = normal(x) +# fvalue = getvalue(f) +# gvalue = getvalue(g) +# G = dot.(Ref(nx),cross.(Ref(gradgreen), gvalue)) +# return _krondot(fvalue, G) +# end +# function (igd::Integrand{<:MWdoublelayerXn})(x,y,f,g) - γ = igd.operator.gamma - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - nx = normal(x) - fvalue = getvalue(f) - gvalue = getvalue(g) - G = cross.(Ref(cross(nx,gradgreen)), gvalue) - return _krondot(fvalue, G) -end -function (igd::Integrand{<:nXMWdoublelayerXn})(x,y,f,g) +# γ = igd.operator.gamma + +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# ny = normal(y) +# fvalue = getvalue(f) +# gvalue = getvalue(g) +# G = cross.(Ref(cross(gradgreen,n)), gvalue) +# return _krondot(fvalue, G) +# end + +# function (igd::Integrand{<:nXdoublelayer})(x,y,f,g) - γ = igd.operator.gamma - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - nx = normal(x) - ny = normal(y) - fvalue = getvalue(f) - gvalue = getvalue(g) - G = Ref(cross(nx,cross(gradgreen,ny))).* gvalue - return _krondot(fvalue, G) -end -# ttrace!(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), SameBase() -# strace!(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), mesh -# ttrace!(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), SameBase() -# strace!(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), mesh +# γ = igd.operator.gamma -# function (igd::Integrand{<:MWnDoubleLayer3D})(x,y,f,g) +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# nx = normal(x) +# fvalue = getvalue(f) +# gvalue = getvalue(g) +# G = cross.(Ref(cross(nx,gradgreen)), gvalue) +# return _krondot(fvalue, G) +# end +# function (igd::Integrand{<:nXMWdoublelayerXn})(x,y,f,g) # γ = igd.operator.gamma @@ -546,16 +514,37 @@ end # iR = 1/R # green = exp(-γ*R)*(iR*i4pi) # gradgreen = -(γ + iR) * green * (iR * r) -# normaly = normal(y) +# nx = normal(x) +# ny = normal(y) # fvalue = getvalue(f) # gvalue = getvalue(g) -# t1 = Ref(normaly).*gvalue -# G = cross.(Ref(gradgreen), t1) +# G = Ref(cross(nx,cross(gradgreen,ny))).* gvalue # return _krondot(fvalue, G) # end +# # ttrace!(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), SameBase() +# # strace!(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), mesh +# # ttrace!(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), SameBase() +# # strace!(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), mesh -# ttrace!(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), SameBase() -# strace!(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), mesh +# # function (igd::Integrand{<:MWnDoubleLayer3D})(x,y,f,g) + +# # γ = igd.operator.gamma + +# # r = cartesian(x) - cartesian(y) +# # R = norm(r) +# # iR = 1/R +# # green = exp(-γ*R)*(iR*i4pi) +# # gradgreen = -(γ + iR) * green * (iR * r) +# # normaly = normal(y) +# # fvalue = getvalue(f) +# # gvalue = getvalue(g) +# # t1 = Ref(normaly).*gvalue +# # G = cross.(Ref(gradgreen), t1) +# # return _krondot(fvalue, G) +# # end + +# # ttrace!(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), SameBase() +# # strace!(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), mesh function (igd::Integrand{<:MWDoubleLayer3DReg})(x,y,f,g) @@ -598,161 +587,161 @@ end -function (igd::Integrand{<:MWgreenint})(x,y,f,g) - γ = igd.operator.gamma +# function (igd::Integrand{<:MWgreenint})(x,y,f,g) +# γ = igd.operator.gamma - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) - fvalue = getvalue(f) - gvalue = getvalue(g) +# fvalue = getvalue(f) +# gvalue = getvalue(g) - t2 = green*gvalue - return _krondot(fvalue,t2) -end -function (igd::Integrand{<:ndotMWgreenint})(x,y,f,g) - γ = igd.operator.gamma - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - nx = normal(x) - fvalue = getvalue(f) - gvalue = getvalue(g) - - t2 = dot.(Ref(nx),green*gvalue) - return _krondot(fvalue,t2) -end -function (igd::Integrand{<:ndotMWgreenintdotn})(x,y,f,g) - γ = igd.operator.gamma - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - nx = normal(x) - ny = normal(y) - fvalue = getvalue(f) - gvalue = getvalue(g) - - t2 = dot.(Ref(nx),Ref(ny))*green*gvalue - return _krondot(fvalue,t2) -end -function (igd::Integrand{<:MWgreenintdotn})(x,y,f,g) - γ = igd.operator.gamma - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - ny = normal(y) - fvalue = getvalue(f) - gvalue = getvalue(g) - - t2 = green*gvalue.*Ref(ny) - return _krondot(fvalue,t2) -end -function (igd::Integrand{<:nXMWgreenintdotn})(x,y,f,g) - γ = igd.operator.gamma - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - ny = normal(y) - nx = normal(x) - fvalue = getvalue(f) - gvalue = getvalue(g) - t1 = green*gvalue.*Ref(ny) - t2 = cross.(Ref(nx),t1) - return _krondot(fvalue,t2) -end +# t2 = green*gvalue +# return _krondot(fvalue,t2) +# end +# function (igd::Integrand{<:ndotMWgreenint})(x,y,f,g) +# γ = igd.operator.gamma -function (igd::Integrand{<:nXMWgreenint})(x,y,f,g) - γ = igd.operator.gamma +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# nx = normal(x) +# fvalue = getvalue(f) +# gvalue = getvalue(g) - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - nx = normal(x) - fvalue = getvalue(f) - gvalue = getvalue(g) +# t2 = dot.(Ref(nx),green*gvalue) +# return _krondot(fvalue,t2) +# end +# function (igd::Integrand{<:ndotMWgreenintdotn})(x,y,f,g) +# γ = igd.operator.gamma - t2 = cross.(Ref(nx),green*gvalue) - return _krondot(fvalue,t2) -end +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# nx = normal(x) +# ny = normal(y) +# fvalue = getvalue(f) +# gvalue = getvalue(g) -function (igd::Integrand{<:MWgradgreendot})(x,y,f,g) - γ = igd.operator.gamma +# t2 = dot.(Ref(nx),Ref(ny))*green*gvalue +# return _krondot(fvalue,t2) +# end +# function (igd::Integrand{<:MWgreenintdotn})(x,y,f,g) +# γ = igd.operator.gamma - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# ny = normal(y) +# fvalue = getvalue(f) +# gvalue = getvalue(g) - fvalue = getvalue(f) - gvalue = getvalue(g) +# t2 = green*gvalue.*Ref(ny) +# return _krondot(fvalue,t2) +# end +# function (igd::Integrand{<:nXMWgreenintdotn})(x,y,f,g) +# γ = igd.operator.gamma - t2 = dot.(gvalue,Ref(gradgreen)) - return _krondot(fvalue,t2) -end -function (igd::Integrand{<:ndotMWgradgreen})(x,y,f,g) - γ = igd.operator.gamma - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - nx = normal(x) - fvalue = getvalue(f) - gvalue = getvalue(g) - - t2 = gvalue*dot(nx,gradgreen) - return _krondot(fvalue,t2) -end +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# ny = normal(y) +# nx = normal(x) +# fvalue = getvalue(f) +# gvalue = getvalue(g) +# t1 = green*gvalue.*Ref(ny) +# t2 = cross.(Ref(nx),t1) +# return _krondot(fvalue,t2) +# end -function (igd::Integrand{<:MWgradgreendotn})(x,y,f,g) - γ = igd.operator.gamma +# function (igd::Integrand{<:nXMWgreenint})(x,y,f,g) +# γ = igd.operator.gamma - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# nx = normal(x) +# fvalue = getvalue(f) +# gvalue = getvalue(g) - fvalue = getvalue(f) - gvalue = getvalue(g) - ny = normal(y) - t2 = gvalue * dot(ny,Ref(gradgreen)) - return _krondot(fvalue,t2) -end -function (igd::Integrand{<:nXMWgradgreendot})(x,y,f,g) - γ = igd.operator.gamma - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = exp(-γ*R)*(iR*i4pi) - gradgreen = -(γ + iR) * green * (iR * r) - nx = normal(x) - fvalue = getvalue(f) - gvalue = getvalue(g) - - t2 = gvalue.*Ref(cross(nx,gradgreen)) - return _krondot(fvalue,t2) -end +# t2 = cross.(Ref(nx),green*gvalue) +# return _krondot(fvalue,t2) +# end + +# function (igd::Integrand{<:MWgradgreendot})(x,y,f,g) +# γ = igd.operator.gamma + +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) + +# fvalue = getvalue(f) +# gvalue = getvalue(g) + +# t2 = dot.(gvalue,Ref(gradgreen)) +# return _krondot(fvalue,t2) +# end +# function (igd::Integrand{<:ndotMWgradgreen})(x,y,f,g) +# γ = igd.operator.gamma + +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# nx = normal(x) +# fvalue = getvalue(f) +# gvalue = getvalue(g) + +# t2 = gvalue*dot(nx,gradgreen) +# return _krondot(fvalue,t2) +# end + +# function (igd::Integrand{<:MWgradgreendotn})(x,y,f,g) +# γ = igd.operator.gamma + +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) + +# fvalue = getvalue(f) +# gvalue = getvalue(g) +# ny = normal(y) +# t2 = gvalue * dot(ny,Ref(gradgreen)) +# return _krondot(fvalue,t2) +# end +# function (igd::Integrand{<:nXMWgradgreendot})(x,y,f,g) +# γ = igd.operator.gamma + +# r = cartesian(x) - cartesian(y) +# R = norm(r) +# iR = 1/R +# green = exp(-γ*R)*(iR*i4pi) +# gradgreen = -(γ + iR) * green * (iR * r) +# nx = normal(x) +# fvalue = getvalue(f) +# gvalue = getvalue(g) + +# t2 = gvalue.*Ref(cross(nx,gradgreen)) +# return _krondot(fvalue,t2) +# end # ttrace!(op::MWgreenint, mesh, or) = ZeroOperator(), SameBase() # strace!(op::MWgreenint, mesh, or) = ZeroOperator(), mesh From d3e5502ae7fefe4da31f0fe55a7c93f4055c9b04 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 20 Sep 2023 16:32:04 +0200 Subject: [PATCH 019/110] design foundations of a general multi-trace approach --- src/BEAST.jl | 3 +- src/multi-trace/configuration.jl | 88 +++++++++++++++++++ .../design of the multi-trace approach.txt | 11 +++ src/multi-trace/traces.jl | 8 ++ 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 src/multi-trace/configuration.jl create mode 100644 src/multi-trace/design of the multi-trace approach.txt create mode 100644 src/multi-trace/traces.jl diff --git a/src/BEAST.jl b/src/BEAST.jl index b2260912..eed0d039 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -262,7 +262,8 @@ include("Helmholtzhodge/hhhop.jl") include("Helmholtzhodge/helmholtzhodge.jl") - +#suport for multi-trace +include("multi-trace/configuration.jl") const x̂ = point(1,0,0) diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl new file mode 100644 index 00000000..15e06cca --- /dev/null +++ b/src/multi-trace/configuration.jl @@ -0,0 +1,88 @@ +abstract type Domain end + +abstract type PhysicalInformation end #depends on the strategy +abstract type DomainData end + +struct HomogeneousDomain <: DomainData +ϵr +μr +testbasises +trialbasises +end + +struct BackgroundDomain <: DomainData + ϵ0 + μ0 +end + +struct SubDomain <: Domain + id::Int + children::Vector{Domain} + parent::Domain + data::DomainData +end +struct RootDomain <: Domain + id::Int + children::Vector{Domain} + data::DomainData +end + +struct Configuration #TODO add dict contining all subbasis info af touching objects + domains::Dict{Int,Domain} + root::RootDomain + touching::Dict{Tuple{Int,Int},<:Vector} +end + +function _adddomain(config::Configuration, newdom::Domain) + id = newdom.id + @assert !(id in keys(config.domains)) + dom = newdom.parent + config.domains[id] = newdom + push!(dom.children,newdom) +end + +function _createdomain(config::Configuration,id::Int,parentid::Int,values) + dom = SubDomain(id,Domain[],config.domains[parentid],values::DomainData) + + # push!(config.domains[parentid].children,dom) + return dom +end +function _createdomain(config::Configuration,id::Int,parentdom::Domain,values) + _createdomain(config,id,parentdom.id,values) +end + +function createdomain(config::Configuration,id::Int,parent::Union{Int,Domain},values::DomainData) + _adddomain(config,_createdomain(config,id,parent,values)) + +end + +function createconfiguration(data::BackgroundDomain) + r = RootDomain(0,Domain[],data) + Configuration(Dict{Int,Domain}(0=>r),r,Dict{Tuple{Int,Int},Any}()) # typle of the indices, returns the spaces: [test1,trial1,test2,trial2] +end + +function createdomains(config::Configuration,confdict::Dict) end#the confdict is the dictionary containing the information about the mesh, physical parameters,... + +""" +all objects in a domain touch each other, not with subdomains, well with the boundary + +""" +function alltouching(config::Configuration) + for i in keys(config) + #config.touching[(i,i)] = [config.domains[i].data.testbasises,config.domains[i].data.trialbasises,config.domains[i].data.testbasises,config.domains[i].data.trialbasises] + for child in config.domains[i].children + j = child.index + if typeof(config.domains[i]) <: Subdomain + config.touching[(i,j)] = [config.domains[i].data.testbasises,config.domains[i].data.trialbasises,child.data.testbasises,child.data.trialbasises] + config.touching[(j,i)] = [config.touching[(i,j)][3],config.touching[(i,j)][4],config.touching[(i,j)][1],config.touching[(i,j)][2]] + end + for child2 in config.domains[i].children + k = child2.index + config.touching[(j,k)] = [child.data.testbasises,child.data.trialbasises,child2.data.testbasises,child2.data.trialbasises] + config.touching[(k,j)] = [child2.data.testbasises,child2.data.trialbasises,child.data.testbasises,child.data.trialbasises] + end + end + end +end + + diff --git a/src/multi-trace/design of the multi-trace approach.txt b/src/multi-trace/design of the multi-trace approach.txt new file mode 100644 index 00000000..a65637f9 --- /dev/null +++ b/src/multi-trace/design of the multi-trace approach.txt @@ -0,0 +1,11 @@ +design of the multi-trace approach: + +structure is devided in a tree like domain of open domains, there is the free space, domain 1, and then all other domains are in this free space. (mesh object is a domain, thus when you ask in which domain it is it gives the upstream domain). The basis of a mesh object is in the domain of the mesh object. + +Object interacts with every object in the domain and with the boundary of the domain it is in. + +object domain:(Physical information, test and trial bases boundary, mesh, touching information: for each object it returns the subd test and trial basis, also for the object itself!!!!) + +intersect(\Omega1, \Omega2) = (subd test, trial 1), (subd test,trial 2) + +work with strategies, \ No newline at end of file diff --git a/src/multi-trace/traces.jl b/src/multi-trace/traces.jl new file mode 100644 index 00000000..0cf51328 --- /dev/null +++ b/src/multi-trace/traces.jl @@ -0,0 +1,8 @@ +#TODO define here the general background for the traces in function of the geometry. + +@hilbertspace a b c d +# zelfde voor test we werken met 1 volume, + +@discretise voor elke interactie gebruik makende van bovenstaande info, dit genereerd matrix dit dan op juiste plaats wordt gezet. + +#maak een object waarin je een matrix operator kunt maken die dan wordt meegegeven in de interactie zodat dit achter de schermen kan allemaal. \ No newline at end of file From 3f02d673cdc70dcfa04567b14b58917fdf62686d Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 21 Sep 2023 16:49:42 +0200 Subject: [PATCH 020/110] work in progress --- src/Helmholtzhodge/hhhop.jl | 10 ++++ src/bases/basis.jl | 2 + src/multi-trace/configuration.jl | 99 ++++++++++++++++++++++++++++++-- src/multi-trace/interactions.jl | 52 +++++++++++++++++ src/operator.jl | 14 +++-- 5 files changed, 165 insertions(+), 12 deletions(-) create mode 100644 src/multi-trace/interactions.jl diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index 8271118e..c48de0cd 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -171,3 +171,13 @@ sign_upon_permutation(op::HHHkernelOperator,I,J) = sign_upon_permutation(op.op,I sign_upon_permutation(op::Union{HHHNtestCross,HHHNtestDot},I,J) = Combinatorics.levicivita(I)*sign_upon_permutation(op.op,I,J) sign_upon_permutation(op::Union{HHHNbasisnormal,HHHNbasisCross,HHHNbasisdot},I,J) = Combinatorics.levicivita(J)*sign_upon_permutation(op.op,I,J) +""" +(number of test normals,number of trial normals) +""" +function number_of_normals(op::HHHOperator) end + + +number_of_normals(op::Union{HHHNtestCross,HHHNtestDot}) = [1,0]+number_of_normals(op.op) +number_of_normals(op::HHHkernelOperator) = number_of_normals(op.op) +number_of_normals(op::Union{HHHNbasisCross,HHHNbasisdot,HHHNbasisnormal}) = [0,1]+number_of_normals(op.op) +number_of_normals(op::HHHIdentity) = [0,0] \ No newline at end of file diff --git a/src/bases/basis.jl b/src/bases/basis.jl index c3d69ca5..13a600bb 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -95,7 +95,9 @@ function Base.:+(x::AbstractSpace...) end cross(a::Space{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}(Space{T}[a,b]) +cross(a::Space{T}, b::nothing) where {T} = a cross(a::DirectProductSpace{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b]) +cross(a::DirectProductSpace{T}, b::DirectProductSpace{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b.factors]) numfunctions(S::DirectProductSpace) = sum([numfunctions(s) for s in S.factors]) Base.length(S::DirectProductSpace) = numfunctions(S) scalartype(s::DirectProductSpace{T}) where {T} = T diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index 15e06cca..da70313c 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -3,11 +3,13 @@ abstract type Domain end abstract type PhysicalInformation end #depends on the strategy abstract type DomainData end -struct HomogeneousDomain <: DomainData +mutable struct HomogeneousDomain <: DomainData ϵr μr testbasises trialbasises +testindex = [] +trialindex = [] end struct BackgroundDomain <: DomainData @@ -15,22 +17,29 @@ struct BackgroundDomain <: DomainData μ0 end -struct SubDomain <: Domain +mutable struct SubDomain{T<:DomainData} <: Domain id::Int children::Vector{Domain} parent::Domain - data::DomainData + data::T end -struct RootDomain <: Domain +mutable struct RootDomain{T<:DomainData} <: Domain id::Int children::Vector{Domain} - data::DomainData + data::T end -struct Configuration #TODO add dict contining all subbasis info af touching objects +mutable struct Configuration #TODO add dict contining all subbasis info af touching objects domains::Dict{Int,Domain} root::RootDomain touching::Dict{Tuple{Int,Int},<:Vector} + testdirectproductspace + testcounter + trialcounter + trialdirectproductspace +end +function Configuration(dom,root,touching) +Configuration(dom,root,touching,nothing,0,0,nothing) end function _adddomain(config::Configuration, newdom::Domain) @@ -38,6 +47,16 @@ function _adddomain(config::Configuration, newdom::Domain) @assert !(id in keys(config.domains)) dom = newdom.parent config.domains[id] = newdom + for space in newdom.data.testbasises + config.testcounter += 1 + push!(newdom.data.testindex,config.testcounter) + config.testdirectproductspace = space × config.test_direct_productspace + end + for space in newdom.data.trialbasises + config.trialcounter += 1 + push!(newdom.data.trialindex,config.trialcounter) + config.trialdirectproductspace = space × config.trial_direct_productspace + end push!(dom.children,newdom) end @@ -55,7 +74,16 @@ function createdomain(config::Configuration,id::Int,parent::Union{Int,Domain},va _adddomain(config,_createdomain(config,id,parent,values)) end +""" +a child of b +""" +function is_child_of(a,b) + return a∈b +end +function brothers(a,b) +return is_child_of(a,b.parent) +end function createconfiguration(data::BackgroundDomain) r = RootDomain(0,Domain[],data) Configuration(Dict{Int,Domain}(0=>r),r,Dict{Tuple{Int,Int},Any}()) # typle of the indices, returns the spaces: [test1,trial1,test2,trial2] @@ -85,4 +113,63 @@ function alltouching(config::Configuration) end end +function (dom::Domain)(n::NormalVector,dom2::Domain) + if dom==dom2 + return 1.0 + elseif dom2 ∈ dom.children + return -1.0 + else + @error "domain is not in children of parent domain" + end + +end + +function generate_configuration(typelist,id_of_parentlist,background) + conf = createconfiguration(background) + l = length(typelist) + for (index,t,parent_id) in zip(index,typelist,id_of_parentlist) + createdomain(conf,index,parent_id,t) + end + return conf +end +function _create_bilform(operator_matrix,test_direct_productspace,trial_direct_productspace) +#TODO create the bilform + +end + +function generate_problem(config::Configuration) + @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) + N = length(config.testdirectproductspace.factors) + OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) + for (id,Ω) in config.domains + if id != 0 + inter = Interaction(config,Ω,Ω,Ω) + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter() + for child in Ω.children + inter = Interaction(config,Ω,child,Ω) + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += inter() + inter = Interaction(config,child,Ω,Ω) + OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter() + end + + end + for Ω1 in Ω.children + for Ω2 in Ω.children + if Ω1===Ω2 + inter = Interaction(config,Ω1,Ω2,Ω) + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter() + else + inter = Interaction(config,Ω1,Ω2,Ω) + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter() + inter = Interaction(config,Ω2,Ω1,Ω) + OperatorMatrix[Ω2.data.testindex[1]:last(Ω2.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += inter() + + end + + end + end + end + +#TODO the right hand side +end \ No newline at end of file diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl new file mode 100644 index 00000000..fd08756e --- /dev/null +++ b/src/multi-trace/interactions.jl @@ -0,0 +1,52 @@ + +""" +A is the type of the test structure, B is the type of the trial structure, C the type of ths structure embedding +""" +struct Interaction{A,B,C}# wordt gecrieerd bij de itteratie over alle volumes. + config + testvol::A + trialvol::B + embedvol::C +end +""" +Write for each type of interaction this type of function. +""" +function (int::Interaction)() + i = [] #interaction matrix + normalorient.(i,Ω1,Ω2,Ω3) # example + + return nothing +end + +function alpha(Ω1,Ω2) + + +end +""" +cauchylimit needs to be applied before the normalorient function +""" + +function cauchylimit(operator,Ω1,Ω2,Ω3) +#check first if touching is non empty + if Ω1===Ω2===Ω3 + sign = 1 + elseif !Ω1===Ω3 && !Ω2===Ω3 + sign = -1 + elseif Ω1===Ω3 + sing = -1 + elseif Ω2===Ω3 + sign = 1 + else + @error "cauchy called but possibly not neccesarry" + end + + + + + +end #TODO define these + +function normalorient(operator,Ω1,Ω2,Ω3) end + + +###### Interactions \ No newline at end of file diff --git a/src/operator.jl b/src/operator.jl index 41e3c82d..bcae4293 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -28,7 +28,7 @@ abstract type Operator <: AbstractOperator end # orientation # end -# struct ZeroOperator <: AbstractOperator end +struct ZeroOperator <: AbstractOperator end abstract type Orientation end struct Inside <: Orientation end struct Outside <: Orientation end @@ -82,6 +82,7 @@ end +(a::Number, b::AbstractOperator) = b + a *(a::Number, b::AbstractOperator) = LinearCombinationOfOperators([a], [b]) +*(a::AbstractOperator, b::Number) = b*a *(a::Number, b::LinearCombinationOfOperators) = LinearCombinationOfOperators(a * b.coeffs, b.ops) -(a::AbstractOperator, b::AbstractOperator) = a + (-1.0) * b -(a::AbstractOperator) = (-1.0) * a @@ -358,9 +359,10 @@ end -# Base.zero(op::AbstractOperator) = ZeroOperator() -# +(a::AbstractOperator,b::ZeroOperator) = a -# +(a::ZeroOperator,b::ZeroOperator) = a -# +(a::ZeroOperator,b::AbstractOperator) = b+a -# *(a::Number,b::ZeroOperator) = b +Base.zero(op::AbstractOperator) = ZeroOperator() ++(a::AbstractOperator,b::ZeroOperator) = a ++(a::ZeroOperator,b::ZeroOperator) = a ++(a::ZeroOperator,b::AbstractOperator) = b+a +-(a::ZeroOperator,b::AbstractOperator) = -b +*(a::Number,b::ZeroOperator) = b From e383457ac1e5666c6b9f4cc5a58e56d8cb568106 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 22 Sep 2023 09:20:59 +0200 Subject: [PATCH 021/110] update --- src/multi-trace/interactions.jl | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index fd08756e..f6425535 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -28,24 +28,19 @@ cauchylimit needs to be applied before the normalorient function function cauchylimit(operator,Ω1,Ω2,Ω3) #check first if touching is non empty - if Ω1===Ω2===Ω3 - sign = 1 - elseif !Ω1===Ω3 && !Ω2===Ω3 +@assert is_child_of(Ω1,Ω3)||Ω1===Ω3 +@assert is_child_of(Ω2,Ω3)||Ω2===Ω3 + if !Ω2===Ω3 sign = -1 - elseif Ω1===Ω3 - sing = -1 elseif Ω2===Ω3 sign = 1 - else - @error "cauchy called but possibly not neccesarry" end - - - + trace(operator,sign) end #TODO define these + function normalorient(operator,Ω1,Ω2,Ω3) end From 00cf973b51e42eaaaaf2b0b7b3ce2bb4197b477d Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 22 Sep 2023 10:26:02 +0200 Subject: [PATCH 022/110] overwritten meshpoint to add normals --- Project.toml | 4 ++-- src/identityop.jl | 6 +++--- src/localop.jl | 22 ++++++++++++++++++---- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Project.toml b/Project.toml index e765de34..fe9f241e 100644 --- a/Project.toml +++ b/Project.toml @@ -16,11 +16,13 @@ FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838" FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" +Lazy = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" LiftedMaps = "d22a30c1-52ac-4762-a8c9-5838452405e0" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" NestedUnitRanges = "032820ab-dc03-4b49-91f4-7d58d4da98b3" Requires = "ae029012-a4dd-5104-9daa-d747884805df" +ReusePatterns = "a39b5e78-89b5-562b-97d8-70689129df0c" SauterSchwab3D = "0a13313b-1c00-422e-8263-562364ed9544" SauterSchwabQuadrature = "535c7bfe-2023-5c1d-b712-654ef9d93a38" SharedArrays = "1a1011a3-84de-559e-8e89-a11a2f7dc383" @@ -53,5 +55,3 @@ SpecialFunctions = "0.7, 0.8, 0.9, 0.10, 1, 2" StaticArrays = "0.8.3, 0.9, 0.10, 0.11, 0.12, 1" WiltonInts84 = "0.2.3" julia = "1.6" - - diff --git a/src/identityop.jl b/src/identityop.jl index 703566af..7da97782 100644 --- a/src/identityop.jl +++ b/src/identityop.jl @@ -87,11 +87,11 @@ function quaddata(op::LocalOperator, g::LagrangeRefSpace{T,Deg,4} where {T,Deg}, end -function quadrule(op::LocalOperator, ψ::RefSpace, ϕ::RefSpace, τ, (qd,A), qs::SingleNumQStrat) +function quadrule(op::LocalOperator, ψ::RefSpace, ϕ::RefSpace, τ, (qd,A),nt,nb, qs::SingleNumQStrat) for i in eachindex(qd) q = qd[i] - w, p = q[1], neighborhood(τ,q[2]) + w, p = q[1], neighborhood(τ,q[2],nt,nb) A[i] = (w, p, ψ(p), ϕ(p)) end - return A + return (A,nt,nb) end diff --git a/src/localop.jl b/src/localop.jl index df9c337b..e39a9b3e 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -1,5 +1,16 @@ +####### designing neighborhood object which can save 2 normals +using ReusePatterns +struct MeshPointNormals + meshpoint::CompScienceMeshes.MeshPointNM + testnormal + trialnormal +end +ReusePatterns.@forward (MeshPointNormals, :meshpoint) CompScienceMeshes.MeshPointNM +function neighborhood(p::CompScienceMeshes.Simplex, bary,nt,nb) + MeshPointNormals(CompScienceMeshes.neighborhood(p,bary),nt,nb) +end - +normals(m::MeshPointNormals) = (m.testnormal,m.trialnormal) using CollisionDetection @@ -276,6 +287,8 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} bcell = bels[q] if overlap(tcell, bcell) + nt = normal(tcell) + nb = normal(bcell) isct = intersection(tcell, bcell) for cell in isct @@ -284,7 +297,7 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} P = restrict(brefs, bcell, cell) Q = restrict(trefs, tcell, cell) - qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) + qr = quadrule(biop, trefs, brefs, cell, qd,nt,nb, quadstrat) zlocal = cellinteractions(biop, trefs, brefs, cell, qr) zlocal = Q * zlocal * P' @@ -341,12 +354,13 @@ function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr) return zlocal end -function cellinteractions(biop, trefs::U, brefs::V, cell, qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} - +function cellinteractions(biop, trefs::U, brefs::V, cell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} + qr = qrtot num_tshs = length(qr[1][3]) num_bshs = length(qr[1][4]) zlocal = zeros(T, num_tshs, num_bshs) + for q in qr w, mp, tvals, bvals = q[1], q[2], q[3], q[4] From d6147b9ac83cb7da8cfba3f11508593de4465481 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 22 Sep 2023 11:46:22 +0200 Subject: [PATCH 023/110] trace operator in HHH created --- src/Helmholtzhodge/hhhop.jl | 102 ++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 5 deletions(-) diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index c48de0cd..79cd591f 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -1,4 +1,5 @@ import LinearAlgebra: ×, ⋅ +abstract type HHHLocalOperator <: LocalOperator end abstract type HHHOperator{T,K} <: IntegralOperator end abstract type HHHtestOperator{T,K} <: HHHOperator{T,K} end abstract type HHHbasisOperator{T,K} <: HHHOperator{T,K} end @@ -7,9 +8,9 @@ abstract type HHHkernelOperator{T,K} <: HHHOperator{T,K} end # scalartype(op::HHHOperator{T,K}) where {T, K} = promote_type(T, K) scalartype(op::HHHOperator{T,K}) where {T, K <: Nothing} = Complex scalartype(op::HHHOperator{T,K}) where {T, K} = Complex +scalartype(op::HHHLocalOperator) = Union{} - -const i4pi = 1 / (4pi) +#const i4pi = 1 / (4pi) mutable struct HHHgreen{T,K} <: HHHkernelOperator{T,K} α::K γ::T @@ -54,6 +55,30 @@ mutable struct HHHNbasisdot{T,K} <: HHHbasisOperator{T,K} end mutable struct HHHIdentity{T,K} <: HHHbasisOperator{T,K} end + +mutable struct HHHNtestCrossLocal{T,K} <: HHHtestOperator{T,K} + op::HHHOperator{T,K} +end + + +mutable struct HHHNbasisCrossLocal <: HHHLocalOperator + op::HHHLocalOperator +end + +mutable struct HHHNtestDotLocal <: HHHLocalOperator + op::HHHLocalOperator +end + +mutable struct HHHNbasisnormalLocal <: HHHLocalOperator + op::HHHLocalOperator +end +mutable struct HHHNbasisdotLocal <: HHHLocalOperator + op::HHHLocalOperator +end +mutable struct HHHIdentityLocal <: HHHLocalOperator +end + + hhhidentity() = HHHIdentity{Complex,Complex}() export HHH struct BasisFunction end @@ -177,7 +202,74 @@ sign_upon_permutation(op::Union{HHHNbasisnormal,HHHNbasisCross,HHHNbasisdot},I,J function number_of_normals(op::HHHOperator) end -number_of_normals(op::Union{HHHNtestCross,HHHNtestDot}) = [1,0]+number_of_normals(op.op) +number_of_normals(op::Union{HHHNtestCross,HHHNtestCrossLocal,HHHNtestDot,HHHNtestDotLocal}) = [1,0]+number_of_normals(op.op) number_of_normals(op::HHHkernelOperator) = number_of_normals(op.op) -number_of_normals(op::Union{HHHNbasisCross,HHHNbasisdot,HHHNbasisnormal}) = [0,1]+number_of_normals(op.op) -number_of_normals(op::HHHIdentity) = [0,0] \ No newline at end of file +number_of_normals(op::Union{HHHNbasisCross,HHHNbasisCrossLocal,HHHNbasisdot,HHHNbasisdotLocal,HHHNbasisnormal,HHHNbasisnormalLocal}) = [0,1]+number_of_normals(op.op) +number_of_normals(op::Union{HHHIdentity,HHHIdentityLocal}) = [0,0] + + + +#### trace definition + + + +alpha(op::HHHtestOperator) = alpha(op.op) +alpha(op::HHHkernelOperator) = op.α + +hhhntestcrosslocal(op::ZeroOperator) = op +hhhntestcrosslocal(op::HHHLocalOperator) = HHHNtestCrossLocal(op) +hhhntestdotlocal(op::ZeroOperator) = op +hhhntestdotlocal(op::HHHLocalOperator) = HHHNtestDotLocal(op) + +hhhnbasiscrosslocal(op::ZeroOperator) = op +hhhnbasiscrosslocal(op::HHHLocalOperator) = HHHNbasisCrossLocal(op) + +hhhnbasisdotlocal(op::ZeroOperator) = op +hhhnbasisdotlocal(op::HHHLocalOperator) = HHHNbasisdotLocal(op) + +hhhnbasisnormal(op::ZeroOperator) = op +hhhnbasisnormal(op::HHHLocalOperator) = HHHNbasisnormalLocal(op) + +localoperator(op::HHHNtestCross) = hhhntestcrosslocal(localoperator(op.op)) +localoperator(op::HHHNtestDot) = hhhntestdotlocal(localoperator(op.op)) +localoperator(op::HHHNbasisCross) = hhhnbasiscrosslocal(localoperator(op.op)) +localoperator(op::HHHNbasisdot) = hhhnbasisdotlocal(localoperator(op.op)) +localoperator(op::HHHNbasisnormal) = hhhnbasisnormal(localoperator(op.op)) +localoperator(op::HHHIdentity) = HHHIdentityLocal() + +localoperator(op::HHHgreen) = ZeroOperator() +localoperator(op::HHHgradgreen) = hhhnbasisdotlocal(op.op) +localoperator(op::HHHgradgreenCross) = hhhnbasiscrosslocal(op.op) + +function trace(op::HHHOperator,sign) + + localop = 1/2*sign*alpha(op)*localoperator(op) + + return op + localop +end + + +##### defining integrand of those local operators: + +function integrand(op::HHHLocalOperator,kernel,x,g,f) +dot(g[1],op(x,f[1])) +end + +function (op::HHHNtestCrossLocal)(x,f) + normals(x)[1]×op.op(x,f) +end +function (op::HHHNtestDotLocal)(x,f) + dot(normals(x)[1],op.op(x,f)) +end +function (op::HHHNbasisCross)(x,f) + normals(x)[2]×op.op(x,f) +end +function (op::HHHNbasisdotLocal)(x,f) + dot(normals(x)[2],op.op(x,f)) +end +function (op::HHHNbasisnormalLocal)(x,f) + normals(x)[2]*op.op(x,f) +end +function (op::HHHIdentityLocal)(x,f) + f +end \ No newline at end of file From b1378a3a5701000bdf7a5e70c7b9b25d5873ad84 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 22 Sep 2023 13:01:02 +0200 Subject: [PATCH 024/110] normalorient implemented --- src/Helmholtzhodge/hhhop.jl | 7 ++++-- src/multi-trace/interactions.jl | 43 ++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index 79cd591f..98d52b0e 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -247,7 +247,10 @@ function trace(op::HHHOperator,sign) return op + localop end - +function normalorient(op::Union{HHHOperator,HHHLocalOperator},signtest,signtrial) +test,trial = number_of_normals(op) +signtest^test*signtrial^trial*op +end ##### defining integrand of those local operators: @@ -271,5 +274,5 @@ function (op::HHHNbasisnormalLocal)(x,f) normals(x)[2]*op.op(x,f) end function (op::HHHIdentityLocal)(x,f) - f + return f end \ No newline at end of file diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index f6425535..36188112 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -26,7 +26,7 @@ end cauchylimit needs to be applied before the normalorient function """ -function cauchylimit(operator,Ω1,Ω2,Ω3) +function cauchylimit(operator::AbstractOperator,Ω1,Ω2,Ω3) #check first if touching is non empty @assert is_child_of(Ω1,Ω3)||Ω1===Ω3 @assert is_child_of(Ω2,Ω3)||Ω2===Ω3 @@ -38,10 +38,47 @@ function cauchylimit(operator,Ω1,Ω2,Ω3) trace(operator,sign) -end #TODO define these +end + +function trace(op::AbstractOperator,sign) + @warning "general abstract opterator trace function called returning pv of operator!: "*string(typeof(op)) + return op +end +function normalorient(op::AbstractOperator,signtest,signtrial) + @warning "normalorient not implemented for: "*string(typeof(op)) + return op +end + +function trace(op::LinearCombinationOfOperators,sign) + result = ZeroOperator() + for (c,o) in zip(op.coeffs,op.ops) + result += c*trace(o,sign) + end + return result +end -function normalorient(operator,Ω1,Ω2,Ω3) end +function normalorient(operator::LinearCombinationOfOperators,signtest,signtrial) + result = ZeroOperator() + for (c,o) in zip(op.coeffs,op.ops) + result += c*normalorient(o,signtest,signtrial) + end + return result +end + +function normalorient(operator::AbstractOperator,Ω1,Ω2,Ω3) + if Ω1===Ω3 + sign_test_normal = 1 + else + sign_test_normal = -1 + end + if Ω2===Ω3 + sign_trial_normal = 1 + else + sign_trial_normal = -1 + end + normalorient(operator,sign_test_normal,sign_trial_normal) +end ###### Interactions \ No newline at end of file From 7562f4d583a7b34852c9623db0d7ede05bb11999 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 22 Sep 2023 14:24:38 +0200 Subject: [PATCH 025/110] debuged, overloaded functions of compsciencemeshes are created in beast --- src/bases/basis.jl | 2 +- src/localop.jl | 10 +++++++++- src/multi-trace/configuration.jl | 5 +++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/bases/basis.jl b/src/bases/basis.jl index 13a600bb..8d390a1c 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -95,7 +95,7 @@ function Base.:+(x::AbstractSpace...) end cross(a::Space{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}(Space{T}[a,b]) -cross(a::Space{T}, b::nothing) where {T} = a +cross(a::Space{T}, b::Nothing) where {T} = a cross(a::DirectProductSpace{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b]) cross(a::DirectProductSpace{T}, b::DirectProductSpace{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b.factors]) numfunctions(S::DirectProductSpace) = sum([numfunctions(s) for s in S.factors]) diff --git a/src/localop.jl b/src/localop.jl index e39a9b3e..0cc02ccb 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -5,7 +5,15 @@ struct MeshPointNormals testnormal trialnormal end -ReusePatterns.@forward (MeshPointNormals, :meshpoint) CompScienceMeshes.MeshPointNM +#ReusePatterns.@forward (MeshPointNormals, :meshpoint) CompScienceMeshes.MeshPointNM + +code = forward((MeshPointNormals, :meshpoint),CompScienceMeshes.MeshPointNM) +uit = [code[1]] +for line in code[2:length(code)] + push!(uit,replace(line, " CompScienceMeshes " => " ")) +end +eval.(Meta.parse.(uit)) + function neighborhood(p::CompScienceMeshes.Simplex, bary,nt,nb) MeshPointNormals(CompScienceMeshes.neighborhood(p,bary),nt,nb) end diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index da70313c..2aa9effd 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -8,8 +8,9 @@ mutable struct HomogeneousDomain <: DomainData μr testbasises trialbasises -testindex = [] -trialindex = [] +testindex +trialindex +HomogeneousDomain(a,b,c,d) = new(a,b,c,d,[],[]) end struct BackgroundDomain <: DomainData From efc455fad741a915f15124b336584c87c017ffa4 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 26 Sep 2023 10:12:47 +0200 Subject: [PATCH 026/110] fixed passing nt and nb to hhhlocaloperator --- examples/junction_calderon.jl | 3 +- src/Helmholtzhodge/hhhop.jl | 83 +++++++++++++++++++++++++++----- src/identityop.jl | 15 ++++-- src/localop.jl | 27 ++++++----- src/maxwell/mwops.jl | 2 +- src/multi-trace/configuration.jl | 35 ++++++++++++-- src/multi-trace/interactions.jl | 2 +- src/utils/variational.jl | 8 +++ 8 files changed, 140 insertions(+), 35 deletions(-) diff --git a/examples/junction_calderon.jl b/examples/junction_calderon.jl index bc4db4a8..52429607 100644 --- a/examples/junction_calderon.jl +++ b/examples/junction_calderon.jl @@ -36,7 +36,8 @@ Nxy = assemble(@discretise(BEAST.diag(N)[p,q], p∈X, q∈Y)) Dyx = BEAST.GMRESSolver(Nxy, tol=2e-12, restart=250, verbose=false) Dxy = BEAST.GMRESSolver(transpose(Nxy), tol=2e-12, restart=250, verbose=false) Syy = BEAST.assemble(@discretise BEAST.diag(SL)[p,q] p∈Y q∈Y) -P = Dxy * Syy * Dyx +#P = Dxy * Syy * Dyx +P = Syy * Dyx # Solve system without and with preconditioner u1, ch1 = solve(BEAST.GMRESSolver(Sxx,tol=2e-5, restart=250), ex) diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index 98d52b0e..f6aa0dd8 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -254,25 +254,82 @@ end ##### defining integrand of those local operators: -function integrand(op::HHHLocalOperator,kernel,x,g,f) -dot(g[1],op(x,f[1])) +function integrand(op::HHHLocalOperator,kernel,x,g,f,nt,nb) +dot(g[1],op(x,f[1],nt,nb)) end -function (op::HHHNtestCrossLocal)(x,f) - normals(x)[1]×op.op(x,f) +function (op::HHHNtestCrossLocal)(x,f,nt,nb) + nt×op.op(x,f,nt,nb) end -function (op::HHHNtestDotLocal)(x,f) - dot(normals(x)[1],op.op(x,f)) +function (op::HHHNtestDotLocal)(x,f,nt,nb) + dot(nt,op.op(x,f,nt,nb)) end -function (op::HHHNbasisCross)(x,f) - normals(x)[2]×op.op(x,f) +function (op::HHHNbasisCross)(x,f,nt,nb) + nb×op.op(x,f,nt,nb) end -function (op::HHHNbasisdotLocal)(x,f) - dot(normals(x)[2],op.op(x,f)) +function (op::HHHNbasisdotLocal)(x,f,nt,nb) + dot(nb,op.op(x,f,nt,nb)) end -function (op::HHHNbasisnormalLocal)(x,f) - normals(x)[2]*op.op(x,f) +function (op::HHHNbasisnormalLocal)(x,f,nt,nb) + nb*op.op(x,f,nt,nb) end -function (op::HHHIdentityLocal)(x,f) +function (op::HHHIdentityLocal)(x,f,nt,nb) return f +end + +function cellinteractions(biop::HHHLocalOperator, trefs::U, brefs::V, cell,tcell,bcell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} + qr = qrtot + num_tshs = length(qr[1][3]) + num_bshs = length(qr[1][4]) + + zlocal = zeros(T, num_tshs, num_bshs) + nt = normal(tcell) + nb = normal(bcell) + for q in qr + + w, mp, tvals, bvals = q[1], q[2], q[3], q[4] + j = w * jacobian(mp) + kernel = kernelvals(biop, mp) + + for m in 1 : num_tshs + tval = tvals[m] + + for n in 1 : num_bshs + bval = bvals[n] + + igd = integrand(biop, kernel, mp, tval, bval,nt,nb) + zlocal[m,n] += j * igd + + end + end + end + + return zlocal +end +function cellinteractions_matched!(zlocal, biop::HHHLocalOperator, trefs, brefs, cell, qr,tcell=nothing,bcell=nothing) + + num_tshs = length(qr[1][3]) + num_bshs = length(qr[1][4]) + nt = normal(tcell) + nb = normal(bcell) + # zlocal = zeros(Float64, num_tshs, num_bshs) + for q in qr + + w, mp, tvals, bvals = q[1], q[2], q[3], q[4] + j = w * jacobian(mp) + kernel = kernelvals(biop, mp) + nt = normal(tcell) + nb = normal(bcell) + for n in 1 : num_bshs + bval = bvals[n] + for m in 1 : num_tshs + tval = tvals[m] + + igd = integrand(biop, kernel, mp, tval, bval,nt,nb) + zlocal[m,n] += j * igd + end + end + end + + return zlocal end \ No newline at end of file diff --git a/src/identityop.jl b/src/identityop.jl index 7da97782..f1b1f723 100644 --- a/src/identityop.jl +++ b/src/identityop.jl @@ -87,11 +87,20 @@ function quaddata(op::LocalOperator, g::LagrangeRefSpace{T,Deg,4} where {T,Deg}, end -function quadrule(op::LocalOperator, ψ::RefSpace, ϕ::RefSpace, τ, (qd,A),nt,nb, qs::SingleNumQStrat) +function quadrule(op::LocalOperator, ψ::RefSpace, ϕ::RefSpace, τ, (qd,A), qs::SingleNumQStrat) for i in eachindex(qd) q = qd[i] - w, p = q[1], neighborhood(τ,q[2],nt,nb) + w, p = q[1], neighborhood(τ,q[2]) A[i] = (w, p, ψ(p), ϕ(p)) end - return (A,nt,nb) + return A end + +# function quadrule(op::HHHLocalOperator, ψ::RefSpace, ϕ::RefSpace, τ, (qd,A),nt,nb, qs::SingleNumQStrat) +# for i in eachindex(qd) +# q = qd[i] +# w, p = q[1], extendedneighborhood(τ,q[2],nt,nb) +# A[i] = (w, p, ψ(p), ϕ(p)) +# end +# return A +# end diff --git a/src/localop.jl b/src/localop.jl index 0cc02ccb..a0b48160 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -1,5 +1,6 @@ ####### designing neighborhood object which can save 2 normals using ReusePatterns +using CompScienceMeshes struct MeshPointNormals meshpoint::CompScienceMeshes.MeshPointNM testnormal @@ -14,7 +15,7 @@ for line in code[2:length(code)] end eval.(Meta.parse.(uit)) -function neighborhood(p::CompScienceMeshes.Simplex, bary,nt,nb) +function extendedneighborhood(p::CompScienceMeshes.Simplex, bary,nt,nb) MeshPointNormals(CompScienceMeshes.neighborhood(p,bary),nt,nb) end @@ -81,6 +82,7 @@ function assemble!(biop::LocalOperator, tfs::Space, bfs::Space, store, quadstrat=defaultquadstrat(biop, tfs, bfs)) if geometry(tfs) == geometry(bfs) + @warn "Function cannot be used for infinitely thin surfaces!!!" return assemble_local_matched!(biop, tfs, bfs, store; quadstrat) end @@ -96,6 +98,7 @@ function assemble!(biop::LocalOperator, tfs::Space, bfs::Space, store, quadstrat=defaultquadstrat(biop, tfs, bfs)) if geometry(tfs) == geometry(bfs) + @warn "Function cannot be used for infinitely thin surfaces!!!" return assemble_local_matched!(biop, tfs, bfs, store; quadstrat) end @@ -131,7 +134,7 @@ function assemble_local_matched!(biop::LocalOperator, tfs::Space, bfs::Space, st qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) fill!(locmat, 0) - cellinteractions_matched!(locmat, biop, trefs, brefs, cell, qr) + cellinteractions_matched!(locmat, biop, trefs, brefs, cell, qr, cell,cell) for i in 1 : size(locmat, 1), j in 1 : size(locmat, 2) for (m,a) in tad[p,i], (n,b) in bad[q,j] @@ -183,7 +186,7 @@ function assemble_local_refines!(biop::LocalOperator, tfs::Space, bfs::Space, st Q = restrict(trefs, tcell, cell) qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) - zlocal = cellinteractions(biop, trefs, brefs, cell, qr) + zlocal = cellinteractions(biop, trefs, brefs, cell, qr,tcell,bcell) zlocal = Q * zlocal * P' for i in 1 : numfunctions(trefs) @@ -223,7 +226,7 @@ function assemble_local_matched!(biop::LocalOperator, tfs::subdBasis, bfs::subdB for (p,cell) in enumerate(tels) qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) - locmat = cellinteractions(biop, trefs, brefs, cell, qr) + locmat = cellinteractions(biop, trefs, brefs, cell, qr, tcell,bcell) for i in 1 : size(locmat, 1), j in 1 : size(locmat, 2) for (m,a) in tad[p][i], (n,b) in bad[p][j] @@ -295,8 +298,7 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} bcell = bels[q] if overlap(tcell, bcell) - nt = normal(tcell) - nb = normal(bcell) + isct = intersection(tcell, bcell) for cell in isct @@ -305,8 +307,8 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} P = restrict(brefs, bcell, cell) Q = restrict(trefs, tcell, cell) - qr = quadrule(biop, trefs, brefs, cell, qd,nt,nb, quadstrat) - zlocal = cellinteractions(biop, trefs, brefs, cell, qr) + qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) + zlocal = cellinteractions(biop, trefs, brefs, cell, qr,tcell,bcell) zlocal = Q * zlocal * P' for i in 1 : numfunctions(trefs) @@ -336,7 +338,7 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} end -function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr) +function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr,tcell=nothing,bcell=nothing) num_tshs = length(qr[1][3]) num_bshs = length(qr[1][4]) @@ -362,8 +364,8 @@ function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr) return zlocal end -function cellinteractions(biop, trefs::U, brefs::V, cell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} - qr = qrtot +function cellinteractions(biop, trefs::U, brefs::V, cell,qr,tcell=nothing,bcell=nothing) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} + num_tshs = length(qr[1][3]) num_bshs = length(qr[1][4]) @@ -390,3 +392,6 @@ function cellinteractions(biop, trefs::U, brefs::V, cell) where {U<:RefSpace{T}, return zlocal end + + + diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index f6fd05aa..bf2f575a 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -284,7 +284,7 @@ function quadrule(op::MaxwellOperator3D, g::RTRefSpace, f::RTRefSpace, i, τ, j h2 = volume(σ) xtol2 = 0.2 * 0.2 k2 = abs2(gamma(op)) - println(max(dmin2*k2, dmin2/16h2) < xtol2) + max(dmin2*k2, dmin2/16h2) < xtol2 && return WiltonSERule( qd.tpoints[2,i], DoubleQuadRule( diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index 2aa9effd..d1d69861 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -1,7 +1,7 @@ -abstract type Domain end +abstract type DomainData end +abstract type Domain{T<:DomainData} end abstract type PhysicalInformation end #depends on the strategy -abstract type DomainData end mutable struct HomogeneousDomain <: DomainData ϵr @@ -18,13 +18,13 @@ struct BackgroundDomain <: DomainData μ0 end -mutable struct SubDomain{T<:DomainData} <: Domain +mutable struct SubDomain{T} <: Domain{T} id::Int children::Vector{Domain} parent::Domain data::T end -mutable struct RootDomain{T<:DomainData} <: Domain +mutable struct RootDomain{T} <: Domain{T} id::Int children::Vector{Domain} data::T @@ -169,8 +169,33 @@ function generate_problem(config::Configuration) end end - end + end + # @hilbertspace test[1:N] + # @hilbertspace trial[1:N] + + # rhs = test'*OperatorMatrix*trial + # terms = [] + # for term in rhs.terms + # if typeof(term.kernel)!=ZeroOperator + # push!(terms,term) + # end + # end + # rhs.terms=terms + + lhs = + eq = rhs==lhs + # space_mappings = [test[i]=>config.testdirectproductspace.factors[i],trial[i]=>config.trialdirectproductspace.factors[i] for i in 1:N] + # discreteequation = discretise(eq,space_mappings) + # return discreteequation +#TODO assembly of the system #TODO the right hand side +#TODO solving system + +end + + +function map_solution_to_volumes(solution,config) + end \ No newline at end of file diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 36188112..03059ac8 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -11,7 +11,7 @@ end """ Write for each type of interaction this type of function. """ -function (int::Interaction)() +function (int::Interaction{<:Domain{BackgroundDomain},})() i = [] #interaction matrix normalorient.(i,Ω1,Ω2,Ω3) # example diff --git a/src/utils/variational.jl b/src/utils/variational.jl index d14396c2..3217ee5c 100644 --- a/src/utils/variational.jl +++ b/src/utils/variational.jl @@ -281,6 +281,14 @@ end Create a BilForm corresponding to A[v,u] """ +struct DualElement + operator + testhilbertspace +end + +*(h::HilbertVector, A::BEAST.AbstractOperator) = DualElement(A,h) +*(A::DualElement,h::HilbertVector) = A.operator[A.testhilbertspace,h] + function getindex(A, v::HilbertVector, u::HilbertVector) terms = [ BilTerm(v.idx, u.idx, v.opstack, u.opstack, 1, A) ] BilForm(v.space, u.space, terms) From bc96e12f5651014ab1d6851aa58c48a815676d3f Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 26 Sep 2023 13:40:23 +0200 Subject: [PATCH 027/110] generate rhs and lhs programmed, returns matrix --- src/localop.jl | 34 +++++++++++----------- src/multi-trace/configuration.jl | 50 +++++++++++++++++++++----------- src/operator.jl | 24 +++++++++++++++ src/solvers/solver.jl | 29 ++++++++++++++++++ 4 files changed, 103 insertions(+), 34 deletions(-) diff --git a/src/localop.jl b/src/localop.jl index a0b48160..42847fac 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -1,25 +1,25 @@ ####### designing neighborhood object which can save 2 normals -using ReusePatterns -using CompScienceMeshes -struct MeshPointNormals - meshpoint::CompScienceMeshes.MeshPointNM - testnormal - trialnormal -end +# using ReusePatterns +# using CompScienceMeshes +# struct MeshPointNormals +# meshpoint::CompScienceMeshes.MeshPointNM +# testnormal +# trialnormal +# end #ReusePatterns.@forward (MeshPointNormals, :meshpoint) CompScienceMeshes.MeshPointNM -code = forward((MeshPointNormals, :meshpoint),CompScienceMeshes.MeshPointNM) -uit = [code[1]] -for line in code[2:length(code)] - push!(uit,replace(line, " CompScienceMeshes " => " ")) -end -eval.(Meta.parse.(uit)) +# code = forward((MeshPointNormals, :meshpoint),CompScienceMeshes.MeshPointNM) +# uit = [code[1]] +# for line in code[2:length(code)] +# push!(uit,replace(line, " CompScienceMeshes " => " ")) +# end +# eval.(Meta.parse.(uit)) -function extendedneighborhood(p::CompScienceMeshes.Simplex, bary,nt,nb) - MeshPointNormals(CompScienceMeshes.neighborhood(p,bary),nt,nb) -end +# function extendedneighborhood(p::CompScienceMeshes.Simplex, bary,nt,nb) +# MeshPointNormals(CompScienceMeshes.neighborhood(p,bary),nt,nb) +# end -normals(m::MeshPointNormals) = (m.testnormal,m.trialnormal) +# normals(m::MeshPointNormals) = (m.testnormal,m.trialnormal) using CollisionDetection diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index d1d69861..f76e84b9 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -23,11 +23,13 @@ mutable struct SubDomain{T} <: Domain{T} children::Vector{Domain} parent::Domain data::T + excitation end mutable struct RootDomain{T} <: Domain{T} id::Int children::Vector{Domain} data::T + excitation end mutable struct Configuration #TODO add dict contining all subbasis info af touching objects @@ -37,7 +39,8 @@ mutable struct Configuration #TODO add dict contining all subbasis info af touch testdirectproductspace testcounter trialcounter - trialdirectproductspace + trialdirectproductspace + end function Configuration(dom,root,touching) Configuration(dom,root,touching,nothing,0,0,nothing) @@ -48,7 +51,7 @@ function _adddomain(config::Configuration, newdom::Domain) @assert !(id in keys(config.domains)) dom = newdom.parent config.domains[id] = newdom - for space in newdom.data.testbasises + for (i,space) in enumerate(newdom.data.testbasises) config.testcounter += 1 push!(newdom.data.testindex,config.testcounter) config.testdirectproductspace = space × config.test_direct_productspace @@ -61,18 +64,18 @@ function _adddomain(config::Configuration, newdom::Domain) push!(dom.children,newdom) end -function _createdomain(config::Configuration,id::Int,parentid::Int,values) - dom = SubDomain(id,Domain[],config.domains[parentid],values::DomainData) +function _createdomain(config::Configuration,id::Int,parentid::Int,values;excitation) + dom = SubDomain(id,Domain[],config.domains[parentid],values::DomainData,excitation) # push!(config.domains[parentid].children,dom) return dom end -function _createdomain(config::Configuration,id::Int,parentdom::Domain,values) - _createdomain(config,id,parentdom.id,values) +function _createdomain(config::Configuration,id::Int,parentdom::Domain,values;excitation) + _createdomain(config,id,parentdom.id,values;excitation) end -function createdomain(config::Configuration,id::Int,parent::Union{Int,Domain},values::DomainData) - _adddomain(config,_createdomain(config,id,parent,values)) +function createdomain(config::Configuration,id::Int,parent::Union{Int,Domain},values::DomainData;excitation=Dict()) + _adddomain(config,_createdomain(config,id,parent,values;excitation)) end """ @@ -85,8 +88,8 @@ end function brothers(a,b) return is_child_of(a,b.parent) end -function createconfiguration(data::BackgroundDomain) - r = RootDomain(0,Domain[],data) +function createconfiguration(data::BackgroundDomain,excitation=Dict()) + r = RootDomain(0,Domain[],data,excitation) Configuration(Dict{Int,Domain}(0=>r),r,Dict{Tuple{Int,Int},Any}()) # typle of the indices, returns the spaces: [test1,trial1,test2,trial2] end @@ -133,12 +136,12 @@ function generate_configuration(typelist,id_of_parentlist,background) end return conf end -function _create_bilform(operator_matrix,test_direct_productspace,trial_direct_productspace) -#TODO create the bilform +# function _create_bilform(operator_matrix,test_direct_productspace,trial_direct_productspace) +# #TODO create the bilform -end +# end -function generate_problem(config::Configuration) +function generate_problem_lhs(config::Configuration) @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) N = length(config.testdirectproductspace.factors) OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) @@ -182,9 +185,7 @@ function generate_problem(config::Configuration) # end # end # rhs.terms=terms - - lhs = - eq = rhs==lhs + return assemble(dot(config.testdirectproductspace,OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) # space_mappings = [test[i]=>config.testdirectproductspace.factors[i],trial[i]=>config.trialdirectproductspace.factors[i] for i in 1:N] # discreteequation = discretise(eq,space_mappings) # return discreteequation @@ -194,6 +195,21 @@ function generate_problem(config::Configuration) end +function generate_problem_rhs(config::Configuration) + linterms = Vector{LinTerm}() + @warn "only excitations in root domain implemented, check first if same aproach for others is appropriate" + for (id,Ω) in config.domains end + + for (key,func) in config.root.excitation + for child in config.root.children + + + push!(linterms,LinTerm(child.data.testindex[key],[],1,func)) + end + end + + return assemble(LinForm([],linterms),config.testdirectproductspace) +end function map_solution_to_volumes(solution,config) diff --git a/src/operator.jl b/src/operator.jl index bcae4293..5f133457 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -27,6 +27,17 @@ abstract type Operator <: AbstractOperator end # op # orientation # end +struct BasisOperatorLeft <: AbstractOperator +operator +left_function +end +struct BasisOperatorRight <: AbstractOperator + operator + right_function +end +*(f::Function,op::AbstractOperator) = BasisOperatorLeft(op,f) +*(op::AbstractOperator,f::Function) = BasisOperatorRight(op,f) + struct ZeroOperator <: AbstractOperator end abstract type Orientation end @@ -222,6 +233,8 @@ function assemble!(operator::Operator, test_functions::Space, trial_functions::S assemblechunk!(operator, test_functions, trial_functions, store; quadstrat) end +defaultquadstrat(op::BasisOperatorLeft,tfs,bfs) = defaultquadstrat(op.operator,op.left_function(tfs),bfs) +defaultquadstrat(op::BasisOperatorRight,tfs,bfs) = defaultquadstrat(op.operator,tfs,op.right_function(bfs)) @@ -232,6 +245,17 @@ function assemble!(op::TransposedOperator, tfs::Space, bfs::Space, store1(v,m,n) = store(v,n,m) assemble!(op.op, bfs, tfs, store1, threading; quadstrat) end +function assemble!(op::BasisOperatorLeft, tfs::Space, bfs::Space, store,threading = Threading{:multi}; + quadstrat=defaultquadstrat(op, tfs, bfs)) + #quadstrat = defaultquadstrat(op.operator,op.left_function(tfs),bfs) + assemble!(op.operator,op.left_function(tfs),bfs,store,threading;quadstrat) +end + +function assemble!(op::BasisOperatorRight, tfs::Space, bfs::Space, store,threading = Threading{:multi}; + quadstrat=defaultquadstrat(op, tfs, bfs)) + #quadstrat = defaultquadstrat(op.operator,tfs,op.right_function(bfs)) + assemble!(op.operator,tfs,op.right_function(bfs),store,threading;quadstrat) +end function assemble!(op::LinearCombinationOfOperators, tfs::AbstractSpace, bfs::AbstractSpace, diff --git a/src/solvers/solver.jl b/src/solvers/solver.jl index 0154434e..731e27a8 100644 --- a/src/solvers/solver.jl +++ b/src/solvers/solver.jl @@ -422,3 +422,32 @@ function td_assemble(bilform::BilForm, end return Z end + +# struct BilFormDirectProductSpace +# test_space +# trial_space +# terms +# end + +function LinearAlgebra.dot(test::DirectProductSpace,op::Matrix{AbstractOperator},trial::DirectProductSpace) +test_length = length(test) +trial_length = length(trial) +@assert size(op)==(test_length,trial_length) +terms = Vector{BilTerm}() +test_space_dict = Dict() +trial_space_dict = Dict() +for (i,space) in enumerate(test.factors) + test_space_dict[i]=space +end +for (i,space) in enumerate(trial.factors) + trial_space_dict[i]=space +end + +for i in 1:test_length + for j in 1:trial_length + push!(terms,BilTerm(i,j,[],[],1.0,op[i,j])) + end +end +BilForm([],[],terms) +end + From 3a265def27d367264ee01d97953b6dd4cbe75602 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 26 Sep 2023 14:49:13 +0200 Subject: [PATCH 028/110] debug --- src/bases/basis.jl | 2 +- src/multi-trace/configuration.jl | 44 +++++++++++++++++++++----------- src/multi-trace/interactions.jl | 10 +------- src/multi-trace/traces.jl | 8 ------ 4 files changed, 31 insertions(+), 33 deletions(-) delete mode 100644 src/multi-trace/traces.jl diff --git a/src/bases/basis.jl b/src/bases/basis.jl index 8d390a1c..bb1d3052 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -93,7 +93,7 @@ function Base.:+(x::AbstractSpace...) T = scalartype(x...) return DirectProductSpace{T, AbstractSpace}([x...]) end - +cross(a::Nothing,b::Space) = b cross(a::Space{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}(Space{T}[a,b]) cross(a::Space{T}, b::Nothing) where {T} = a cross(a::DirectProductSpace{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b]) diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index f76e84b9..1160e8ed 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -1,8 +1,22 @@ abstract type DomainData end abstract type Domain{T<:DomainData} end - +""" +A is the type of the test structure, B is the type of the trial structure, C the type of ths structure embedding +""" +struct Interaction{A,B,C}# wordt gecrieerd bij de itteratie over alle volumes. + config + testvol::A + trialvol::B + embedvol::C +end abstract type PhysicalInformation end #depends on the strategy +""" +subtypes of the NumericalStrategy type descirbe the followed strategy. for example a preconditioning strategy for a vector potential based problem, + a vector potential based problem, a fields based problem,... +""" +abstract type NumericalStrategy end +export NumericalStrategy mutable struct HomogeneousDomain <: DomainData ϵr μr @@ -35,7 +49,7 @@ end mutable struct Configuration #TODO add dict contining all subbasis info af touching objects domains::Dict{Int,Domain} root::RootDomain - touching::Dict{Tuple{Int,Int},<:Vector} + touching::Dict{Tuple{Int,Int},Vector} testdirectproductspace testcounter trialcounter @@ -54,12 +68,12 @@ function _adddomain(config::Configuration, newdom::Domain) for (i,space) in enumerate(newdom.data.testbasises) config.testcounter += 1 push!(newdom.data.testindex,config.testcounter) - config.testdirectproductspace = space × config.test_direct_productspace + config.testdirectproductspace = config.testdirectproductspace × space end for space in newdom.data.trialbasises config.trialcounter += 1 push!(newdom.data.trialindex,config.trialcounter) - config.trialdirectproductspace = space × config.trial_direct_productspace + config.trialdirectproductspace = config.trialdirectproductspace × space end push!(dom.children,newdom) end @@ -128,11 +142,11 @@ function (dom::Domain)(n::NormalVector,dom2::Domain) end -function generate_configuration(typelist,id_of_parentlist,background) - conf = createconfiguration(background) +function generate_configuration(typelist,id_of_parentlist,background,backgroundexcitation=Dict()) + conf = createconfiguration(background,backgroundexcitation) l = length(typelist) - for (index,t,parent_id) in zip(index,typelist,id_of_parentlist) - createdomain(conf,index,parent_id,t) + for (ind,t,parent_id) in zip(1:l,typelist,id_of_parentlist) + createdomain(conf,ind,parent_id,t) end return conf end @@ -141,19 +155,19 @@ end # end -function generate_problem_lhs(config::Configuration) +function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) N = length(config.testdirectproductspace.factors) OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) for (id,Ω) in config.domains if id != 0 inter = Interaction(config,Ω,Ω,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter() + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter(strat) for child in Ω.children inter = Interaction(config,Ω,child,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += inter() + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += inter(strat) inter = Interaction(config,child,Ω,Ω) - OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter() + OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter(strat) end end @@ -161,12 +175,12 @@ function generate_problem_lhs(config::Configuration) for Ω2 in Ω.children if Ω1===Ω2 inter = Interaction(config,Ω1,Ω2,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter() + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter(strat) else inter = Interaction(config,Ω1,Ω2,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter() + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter(strat) inter = Interaction(config,Ω2,Ω1,Ω) - OperatorMatrix[Ω2.data.testindex[1]:last(Ω2.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += inter() + OperatorMatrix[Ω2.data.testindex[1]:last(Ω2.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += inter(strat) end diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 03059ac8..6fe31a08 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -1,13 +1,5 @@ -""" -A is the type of the test structure, B is the type of the trial structure, C the type of ths structure embedding -""" -struct Interaction{A,B,C}# wordt gecrieerd bij de itteratie over alle volumes. - config - testvol::A - trialvol::B - embedvol::C -end + """ Write for each type of interaction this type of function. """ diff --git a/src/multi-trace/traces.jl b/src/multi-trace/traces.jl deleted file mode 100644 index 0cf51328..00000000 --- a/src/multi-trace/traces.jl +++ /dev/null @@ -1,8 +0,0 @@ -#TODO define here the general background for the traces in function of the geometry. - -@hilbertspace a b c d -# zelfde voor test we werken met 1 volume, - -@discretise voor elke interactie gebruik makende van bovenstaande info, dit genereerd matrix dit dan op juiste plaats wordt gezet. - -#maak een object waarin je een matrix operator kunt maken die dan wordt meegegeven in de interactie zodat dit achter de schermen kan allemaal. \ No newline at end of file From 519be03faadca75380efd919c1bdbecf920dd3f0 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 26 Sep 2023 16:23:54 +0200 Subject: [PATCH 029/110] adding divergence in HHH --- src/BEAST.jl | 4 ++++ src/Helmholtzhodge/hhhop.jl | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/BEAST.jl b/src/BEAST.jl index eed0d039..4295a304 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -126,6 +126,7 @@ export PlaneWaveDirichlet export PlaneWaveNeumann struct NormalVector end +struct Nabla end using CompScienceMeshes using Combinatorics @@ -274,4 +275,7 @@ export x̂, ŷ, ẑ const n = NormalVector() export n +const ∇ = Nabla() +export ∇ + end # module diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index f6aa0dd8..274f921d 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -55,6 +55,8 @@ mutable struct HHHNbasisdot{T,K} <: HHHbasisOperator{T,K} end mutable struct HHHIdentity{T,K} <: HHHbasisOperator{T,K} end +mutable struct HHHDivergence{T,K} <: HHHbasisOperator{T,K} +end mutable struct HHHNtestCrossLocal{T,K} <: HHHtestOperator{T,K} op::HHHOperator{T,K} @@ -77,11 +79,12 @@ mutable struct HHHNbasisdotLocal <: HHHLocalOperator end mutable struct HHHIdentityLocal <: HHHLocalOperator end - +mutable struct HHHDivergenceLocal <: HHHLocalOperator end hhhidentity() = HHHIdentity{Complex,Complex}() export HHH struct BasisFunction end +struct DivBasisFunction end basisfunction() = BasisFunction() export basisfunction VectorToVector = Union{HHHNtestCross,HHHNbasisCross,HHHgradgreenCross,HHHgreen} @@ -94,6 +97,7 @@ inversemap(op::VectorToScalar,::HHHscalar) = inversemap(op.op,HHHvector()) inversemap(op::ScalarToScalar,::HHHscalar) = HHHscalar() inversemap(::HHHOperator,::HHHdata) = @error "trying to convert scalar to vector or vector to scalar" inversemap(::HHHIdentity,data::HHHdata) = data +inversemap(::HHHDivergence,::HHHscalar) = HHHvector() ##### Operator building strace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestCross(op) @@ -103,6 +107,8 @@ ntrace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestDot(op) ×(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = strace(op) ⋅(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = ntrace(op) *(::NormalVector,::BasisFunction) = HHHNbasisnormal(hhhidentity()) +⋅(::Nabla,::BasisFunction) = HHHDivergence() +*(::NormalVector,::DivBasisFunction) = HHHNbasisnormal(HHHDivergence()) ⋅(::NormalVector,::BasisFunction) = HHHNbasisdot(hhhidentity()) ×(::NormalVector,::BasisFunction) = HHHNbasisCross(hhhidentity()) ×(::NormalVector,op::HHHbasisOperator) = HHHNbasisCross(op) @@ -150,6 +156,9 @@ end function (op::HHHIdentity)(x,y,g) getvalue(g) end +function (op::HHHDivergence)(x,y,g) + getdivergence(g) +end function (op::HHHgreen)(x,y,g) r = cartesian(x) - cartesian(y) @@ -191,7 +200,7 @@ end defaultquadstrat(op::HHHOperator,::HHHdata,::HHHdata) = DoubleNumSauterQstrat(6,7,5,5,4,3) #TODO implement strategy that is stronger for nearby triangles -sign_upon_permutation(op::HHHIdentity,I,J) = 1 +sign_upon_permutation(op::Union{HHHIdentity,HHHDivergence},I,J) = 1 sign_upon_permutation(op::HHHkernelOperator,I,J) = sign_upon_permutation(op.op,I,J) sign_upon_permutation(op::Union{HHHNtestCross,HHHNtestDot},I,J) = Combinatorics.levicivita(I)*sign_upon_permutation(op.op,I,J) sign_upon_permutation(op::Union{HHHNbasisnormal,HHHNbasisCross,HHHNbasisdot},I,J) = Combinatorics.levicivita(J)*sign_upon_permutation(op.op,I,J) @@ -205,7 +214,7 @@ function number_of_normals(op::HHHOperator) end number_of_normals(op::Union{HHHNtestCross,HHHNtestCrossLocal,HHHNtestDot,HHHNtestDotLocal}) = [1,0]+number_of_normals(op.op) number_of_normals(op::HHHkernelOperator) = number_of_normals(op.op) number_of_normals(op::Union{HHHNbasisCross,HHHNbasisCrossLocal,HHHNbasisdot,HHHNbasisdotLocal,HHHNbasisnormal,HHHNbasisnormalLocal}) = [0,1]+number_of_normals(op.op) -number_of_normals(op::Union{HHHIdentity,HHHIdentityLocal}) = [0,0] +number_of_normals(op::Union{HHHIdentity,HHHIdentityLocal,HHHDivergence,HHHDivergenceLocal}) = [0,0] @@ -236,6 +245,7 @@ localoperator(op::HHHNbasisCross) = hhhnbasiscrosslocal(localoperator(op.op)) localoperator(op::HHHNbasisdot) = hhhnbasisdotlocal(localoperator(op.op)) localoperator(op::HHHNbasisnormal) = hhhnbasisnormal(localoperator(op.op)) localoperator(op::HHHIdentity) = HHHIdentityLocal() +localoperator(op::HHHDivergence) = HHHDivergenceLocal() localoperator(op::HHHgreen) = ZeroOperator() localoperator(op::HHHgradgreen) = hhhnbasisdotlocal(op.op) @@ -276,6 +286,9 @@ end function (op::HHHIdentityLocal)(x,f,nt,nb) return f end +function (op::HHHDivergenceLocal)(x,f,nt,nb) + return f.divergence +end function cellinteractions(biop::HHHLocalOperator, trefs::U, brefs::V, cell,tcell,bcell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} qr = qrtot From a6e1a9fe5d7ca710a46dd44689a3775baa0fdac1 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 26 Sep 2023 16:34:52 +0200 Subject: [PATCH 030/110] update --- src/Helmholtzhodge/hhhop.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index 274f921d..7809a832 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -58,6 +58,7 @@ end mutable struct HHHDivergence{T,K} <: HHHbasisOperator{T,K} end + mutable struct HHHNtestCrossLocal{T,K} <: HHHtestOperator{T,K} op::HHHOperator{T,K} end @@ -82,6 +83,8 @@ end mutable struct HHHDivergenceLocal <: HHHLocalOperator end hhhidentity() = HHHIdentity{Complex,Complex}() +hhhdivergence() = HHHDivergence{Complex,Complex}() + export HHH struct BasisFunction end struct DivBasisFunction end @@ -107,8 +110,8 @@ ntrace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestDot(op) ×(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = strace(op) ⋅(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = ntrace(op) *(::NormalVector,::BasisFunction) = HHHNbasisnormal(hhhidentity()) -⋅(::Nabla,::BasisFunction) = HHHDivergence() -*(::NormalVector,::DivBasisFunction) = HHHNbasisnormal(HHHDivergence()) +⋅(::Nabla,::BasisFunction) = hhhdivergence() +*(::NormalVector,::DivBasisFunction) = HHHNbasisnormal(hhhdivergence()) ⋅(::NormalVector,::BasisFunction) = HHHNbasisdot(hhhidentity()) ×(::NormalVector,::BasisFunction) = HHHNbasisCross(hhhidentity()) ×(::NormalVector,op::HHHbasisOperator) = HHHNbasisCross(op) From f20941259c2c53575dd0846a17b09d6781d71847 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 28 Sep 2023 11:22:50 +0200 Subject: [PATCH 031/110] code runs succesfully --- src/BEAST.jl | 8 ++ src/Helmholtzhodge/hhhop.jl | 156 +++++++++++++++++++++---------- src/integralop.jl | 6 +- src/localop.jl | 6 +- src/multi-trace/configuration.jl | 10 +- src/multi-trace/interactions.jl | 14 +-- src/operator.jl | 12 ++- src/quadrature/quadstrats.jl | 2 +- src/solvers/solver.jl | 4 +- 9 files changed, 146 insertions(+), 72 deletions(-) diff --git a/src/BEAST.jl b/src/BEAST.jl index 4295a304..d26f2d49 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -265,6 +265,7 @@ include("Helmholtzhodge/helmholtzhodge.jl") #suport for multi-trace include("multi-trace/configuration.jl") +include("multi-trace/interactions.jl") const x̂ = point(1,0,0) @@ -278,4 +279,11 @@ export n const ∇ = Nabla() export ∇ + +export Interaction +export Domain +export HomogeneousDomain +export RootDomain +export SubDomain + end # module diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index 7809a832..8b5770ed 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -1,32 +1,38 @@ import LinearAlgebra: ×, ⋅ abstract type HHHLocalOperator <: LocalOperator end -abstract type HHHOperator{T,K} <: IntegralOperator end -abstract type HHHtestOperator{T,K} <: HHHOperator{T,K} end -abstract type HHHbasisOperator{T,K} <: HHHOperator{T,K} end -abstract type HHHkernelOperator{T,K} <: HHHOperator{T,K} end +abstract type HHHOperator <: IntegralOperator end +abstract type HHHtestOperator{U} <: HHHOperator end +abstract type HHHbasisOperator <: HHHOperator end +abstract type HHHkernelOperator{T,K,U} <: HHHOperator end # scalartype(op::HHHOperator{T,K}) where {T, K <: Nothing} = T # scalartype(op::HHHOperator{T,K}) where {T, K} = promote_type(T, K) -scalartype(op::HHHOperator{T,K}) where {T, K <: Nothing} = Complex -scalartype(op::HHHOperator{T,K}) where {T, K} = Complex +# scalartype(op::HHHOperator{T,K}) where {T, K <: Nothing} = T +# scalartype(op::HHHOperator) = ComplexF64 scalartype(op::HHHLocalOperator) = Union{} +scalartype(op::HHHkernelOperator{T,K,U}) where {T, K,U} = promote_type(T, K) +scalartype(op::HHHtestOperator{U}) where {U} = scalartype(U) + +scalartype(op::Type{<: HHHtestOperator{U}}) where {U} =scalartype(U) + +scalartype(op::Type{<: HHHkernelOperator{T,K,U}}) where {T,K,U} = promote_type(T, K) #const i4pi = 1 / (4pi) -mutable struct HHHgreen{T,K} <: HHHkernelOperator{T,K} +struct HHHgreen{T,K,U} <: HHHkernelOperator{T,K,U} α::K γ::T - op::HHHOperator + op::U end -mutable struct HHHgradgreen{T,K} <: HHHkernelOperator{T,K} +struct HHHgradgreen{T,K,U} <: HHHkernelOperator{T,K,U} α::K γ::T - op::HHHOperator + op::U end -mutable struct HHHgradgreenCross{T,K} <: HHHkernelOperator{T,K} +struct HHHgradgreenCross{T,K,U} <: HHHkernelOperator{T,K,U} α::K γ::T - op::HHHOperator + op::U end abstract type HHHdata end @@ -34,56 +40,56 @@ struct HHHvector <:HHHdata end struct HHHscalar <:HHHdata end -mutable struct HHHNtestCross{T,K} <: HHHtestOperator{T,K} - op::HHHOperator{T,K} +struct HHHNtestCross{U} <: HHHtestOperator{U} + op::U end -mutable struct HHHNbasisCross{T,K} <: HHHbasisOperator{T,K} - op::HHHOperator{T,K} +struct HHHNbasisCross{U} <: HHHbasisOperator + op::U end -mutable struct HHHNtestDot{T,K} <: HHHtestOperator{T,K} - op::HHHOperator{T,K} +struct HHHNtestDot{U} <: HHHtestOperator{U} + op::U end -mutable struct HHHNbasisnormal{T,K} <: HHHbasisOperator{T,K} - op::HHHOperator{T,K} +struct HHHNbasisnormal{U} <: HHHbasisOperator + op::U end -mutable struct HHHNbasisdot{T,K} <: HHHbasisOperator{T,K} - op::HHHOperator{T,K} +struct HHHNbasisdot{U} <: HHHbasisOperator + op::U end -mutable struct HHHIdentity{T,K} <: HHHbasisOperator{T,K} +struct HHHIdentity <: HHHbasisOperator end -mutable struct HHHDivergence{T,K} <: HHHbasisOperator{T,K} +struct HHHDivergence <: HHHbasisOperator end -mutable struct HHHNtestCrossLocal{T,K} <: HHHtestOperator{T,K} - op::HHHOperator{T,K} +mutable struct HHHNtestCrossLocal{U <: HHHLocalOperator} <: HHHLocalOperator + op::U end -mutable struct HHHNbasisCrossLocal <: HHHLocalOperator - op::HHHLocalOperator +mutable struct HHHNbasisCrossLocal{U <: HHHLocalOperator} <: HHHLocalOperator + op::U end -mutable struct HHHNtestDotLocal <: HHHLocalOperator - op::HHHLocalOperator +mutable struct HHHNtestDotLocal{U <: HHHLocalOperator} <: HHHLocalOperator + op::U end -mutable struct HHHNbasisnormalLocal <: HHHLocalOperator - op::HHHLocalOperator +mutable struct HHHNbasisnormalLocal{U <: HHHLocalOperator} <: HHHLocalOperator + op::U end -mutable struct HHHNbasisdotLocal <: HHHLocalOperator - op::HHHLocalOperator +mutable struct HHHNbasisdotLocal{U <: HHHLocalOperator} <: HHHLocalOperator + op::U end mutable struct HHHIdentityLocal <: HHHLocalOperator end mutable struct HHHDivergenceLocal <: HHHLocalOperator end -hhhidentity() = HHHIdentity{Complex,Complex}() -hhhdivergence() = HHHDivergence{Complex,Complex}() +hhhidentity() = HHHIdentity() +hhhdivergence() = HHHDivergence() export HHH struct BasisFunction end @@ -106,7 +112,7 @@ inversemap(::HHHDivergence,::HHHscalar) = HHHvector() strace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestCross(op) ntrace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestDot(op) ×(op::HHHgradgreen,::Nothing) = HHHgradgreenCross(op.α,op.γ,op.op) -×(op::HHHgradgreen,::NormalVector) = HHHgradgreenCross(op.α,op.γ,op.op)(HHHNbasisnormal(hhhidentity())) +#×(op::HHHgradgreen,::NormalVector) = HHHgradgreenCross(op.α,op.γ,op.op)(HHHNbasisnormal(hhhidentity())) ×(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = strace(op) ⋅(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = ntrace(op) *(::NormalVector,::BasisFunction) = HHHNbasisnormal(hhhidentity()) @@ -119,15 +125,37 @@ ntrace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestDot(op) function (op::HHHkernelOperator)(Basisop::HHHbasisOperator) - return typeof(op)(op.α,op.γ,Basisop) + return (Base.typename(typeof(op)).wrapper)(op.α,op.γ,Basisop) end - +### TODO make sure this function can be used, unpack everything and make new structure. function (op::HHHOperator)(BasisOperator::HHHbasisOperator) op.op = BasisOperator end +# ##### to generate integrand +# extract(a::Type{HHHNbasisCross{T}}) where {T} = [HHHNbasisCross;extract(T)] +# extract(a::Type{HHHNbasisdot{T}}) where {T} = [HHHNbasisdot;extract(T)] +# extract(a::Type{HHHNbasisnormal{T}}) where {T} = [HHHNbasisnormal;extract(T)] +# extract(a::Type{HHHNtestCross{T}}) where {T} = [HHHNtestCross;extract(T)] +# extract(a::Type{HHHNtestDot{T}}) where {T} = [HHHNtestDot;extract(T)] +# extract(a::Type{HHHgradgreen{T}}) where {T} = [HHHgradgreen;extract(T)] +# extract(a::Type{HHHgradgreenCross{T}}) where {T} = [HHHgradgreenCross;extract(T)] +# extract(a::Type{HHHgreen{T}}) where {T} = [HHHgreen;extract(T)] +# extract(a::Type{HHHIdentity}) = HHHIdentity +# extract(a::Type{HHHDivergence}) = HHHDivergence + + +# @generated function hhhintegrand(op,x,y,g) +# println("integrand generated") +# typelist = extract(typeof(op)) + + + +# end + + ##### Integrand definitions function (igd::Integrand{<:HHHOperator})(x,y,f,g) @@ -135,10 +163,12 @@ function (igd::Integrand{<:HHHOperator})(x,y,f,g) test = getvalue(f) _krondot(test,op(x,y,g)) + end function (op::HHHNtestCross)(x,y,g) nx = normal(x) - cross.(Ref(nx),op.op(x,y,g)) + cross.(Ref(nx),op.op(x,y,g)) + end function (op::HHHNtestDot)(x,y,g) nx = normal(x) @@ -175,21 +205,26 @@ function mydot(a::SVector,b::Base.RefValue) a.*b end function (op::HHHgradgreen)(x,y,g) + r = cartesian(x) - cartesian(y) R = norm(r) iR = 1/R green = op.α * exp(-op.γ*R)*(iR*i4pi) gradgreen = -(op.γ + iR) * green * (iR * r) + mydot(op.op(x,y,g),Ref(gradgreen)) end function (op::HHHgradgreenCross)(x,y,g) + r = cartesian(x) - cartesian(y) R = norm(r) iR = 1/R green = op.α * exp(-op.γ*R)*(iR*i4pi) gradgreen = -(op.γ + iR) * green * (iR * r) cross.(Ref(gradgreen),op.op(x,y,g)) + + end identify(::VectorSurfaceSpace) = HHHvector() identify(::ScalarSurfaceSpace) = HHHscalar() @@ -230,14 +265,27 @@ alpha(op::HHHkernelOperator) = op.α hhhntestcrosslocal(op::ZeroOperator) = op hhhntestcrosslocal(op::HHHLocalOperator) = HHHNtestCrossLocal(op) +hhhntestcrosslocal(op::Union{HHHNbasisnormalLocal}) = ZeroOperator() + hhhntestdotlocal(op::ZeroOperator) = op hhhntestdotlocal(op::HHHLocalOperator) = HHHNtestDotLocal(op) +hhhntestdotlocal(op::Union{HHHNtestCrossLocal,HHHNbasisCrossLocal}) = ZeroOperator() +hhhntestdotlocal(op::HHHNbasisnormalLocal) = localoperator(op.op) hhhnbasiscrosslocal(op::ZeroOperator) = op hhhnbasiscrosslocal(op::HHHLocalOperator) = HHHNbasisCrossLocal(op) +hhhnbasiscrosslocal(op::Union{HHHNbasisnormalLocal}) = ZeroOperator() hhhnbasisdotlocal(op::ZeroOperator) = op hhhnbasisdotlocal(op::HHHLocalOperator) = HHHNbasisdotLocal(op) +hhhnbasisdotlocal(op::HHHDivergenceLocal) = HHHNbasisnormalLocal(op) +hhhnbasisdotlocal(op::Union{HHHNtestCrossLocal,HHHNbasisCrossLocal}) = ZeroOperator() +function hhhnbasisdotlocal(op::HHHIdentityLocal) + @warn "assumed basisfunction is tangential to surface" +ZeroOperator() +end + +hhhnbasisdotlocal(op::HHHNbasisnormalLocal) = op.op hhhnbasisnormal(op::ZeroOperator) = op hhhnbasisnormal(op::HHHLocalOperator) = HHHNbasisnormalLocal(op) @@ -251,10 +299,15 @@ localoperator(op::HHHIdentity) = HHHIdentityLocal() localoperator(op::HHHDivergence) = HHHDivergenceLocal() localoperator(op::HHHgreen) = ZeroOperator() -localoperator(op::HHHgradgreen) = hhhnbasisdotlocal(op.op) -localoperator(op::HHHgradgreenCross) = hhhnbasiscrosslocal(op.op) +localoperator(op::HHHgradgreen) = hhhnbasisdotlocal(localoperator(op.op)) +localoperator(op::HHHgradgreenCross) = hhhnbasiscrosslocal(localoperator(op.op)) function trace(op::HHHOperator,sign) + l = localoperator(op) + if typeof(l) == HHHNbasisnormalLocal{HHHIdentityLocal} || typeof(l) == HHHNbasisnormalLocal{HHHDivergenceLocal} + @warn "assumed test function is tangential to surface" + l = ZeroOperator() + end localop = 1/2*sign*alpha(op)*localoperator(op) @@ -267,8 +320,10 @@ end ##### defining integrand of those local operators: + function integrand(op::HHHLocalOperator,kernel,x,g,f,nt,nb) -dot(g[1],op(x,f[1],nt,nb)) + +dot(g.value,op(x,f,nt,nb)) end function (op::HHHNtestCrossLocal)(x,f,nt,nb) @@ -277,7 +332,7 @@ end function (op::HHHNtestDotLocal)(x,f,nt,nb) dot(nt,op.op(x,f,nt,nb)) end -function (op::HHHNbasisCross)(x,f,nt,nb) +function (op::HHHNbasisCrossLocal)(x,f,nt,nb) nb×op.op(x,f,nt,nb) end function (op::HHHNbasisdotLocal)(x,f,nt,nb) @@ -287,7 +342,7 @@ function (op::HHHNbasisnormalLocal)(x,f,nt,nb) nb*op.op(x,f,nt,nb) end function (op::HHHIdentityLocal)(x,f,nt,nb) - return f + return f.value end function (op::HHHDivergenceLocal)(x,f,nt,nb) return f.divergence @@ -305,8 +360,8 @@ function cellinteractions(biop::HHHLocalOperator, trefs::U, brefs::V, cell,tcell w, mp, tvals, bvals = q[1], q[2], q[3], q[4] j = w * jacobian(mp) - kernel = kernelvals(biop, mp) - + # kernel = kernelvals(biop, mp) + kernel = nothing for m in 1 : num_tshs tval = tvals[m] @@ -333,9 +388,10 @@ function cellinteractions_matched!(zlocal, biop::HHHLocalOperator, trefs, brefs, w, mp, tvals, bvals = q[1], q[2], q[3], q[4] j = w * jacobian(mp) - kernel = kernelvals(biop, mp) - nt = normal(tcell) - nb = normal(bcell) + #kernel = kernelvals(biop, mp) + kernel = nothing + nt = normal(tcell) + nb = normal(bcell) for n in 1 : num_bshs bval = bvals[n] for m in 1 : num_tshs diff --git a/src/integralop.jl b/src/integralop.jl index 7aa2fa45..7d6a0269 100644 --- a/src/integralop.jl +++ b/src/integralop.jl @@ -111,7 +111,7 @@ function assemblechunk_body!(biop, qd, zlocal, store; quadstrat) myid = Threads.threadid() - myid == 1 && print("dots out of 10: ") + myid == 1 && print(string(typeof(biop))*" dots out of 10: ") todo, done, pctg = length(test_elements), 0, 0 for (p,tcell) in enumerate(test_elements) for (q,bcell) in enumerate(trial_elements) @@ -147,7 +147,7 @@ function assemblechunk_body_test_refines_trial!(biop, trial_shapes = refspace(trial_functions) myid = Threads.threadid() - myid == 1 && print("dots out of 10: ") + myid == 1 && print(string(typeof(biop))*" dots out of 10: ") todo, done, pctg = length(test_charts), 0, 0 for (p,(tcell,tchart)) in enumerate(zip(test_cells, test_charts)) for (q,(bcell,bchart)) in enumerate(zip(trial_cells, trial_charts)) @@ -188,7 +188,7 @@ function assemblechunk_body_trial_refines_test!(biop, trial_shapes = refspace(trial_functions) myid = Threads.threadid() - myid == 1 && print("dots out of 10: ") + myid == 1 && print(string(typeof(biop))*" dots out of 10: ") todo, done, pctg = length(test_charts), 0, 0 for (p,(tcell,tchart)) in enumerate(zip(test_cells, test_charts)) for (q,(bcell,bchart)) in enumerate(zip(trial_cells, trial_charts)) diff --git a/src/localop.jl b/src/localop.jl index 42847fac..79132393 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -124,7 +124,7 @@ function assemble_local_matched!(biop::LocalOperator, tfs::Space, bfs::Space, st qd = quaddata(biop, trefs, brefs, tels, bels, quadstrat) verbose = length(tels) > 10_000 - verbose && print("dots out of 20: ") + verbose && print(string(typeof(biop))*" dots out of 20: ") todo, done, pctg = length(tels), 0, 0 locmat = zeros(scalartype(biop, trefs, brefs), numfunctions(trefs), numfunctions(brefs)) for (p,cell) in enumerate(tels) @@ -168,7 +168,7 @@ function assemble_local_refines!(biop::LocalOperator, tfs::Space, bfs::Space, st qd = quaddata(biop, trefs, brefs, tels, bels, quadstrat) - print("dots out of 10: ") + print(string(typeof(biop))*" dots out of 10: ") todo, done, pctg = length(tels), 0, 0 for (p,tcell) in enumerate(tels) @@ -286,7 +286,7 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} # store the bcells in an octree tree = elementstree(bels) - print("dots out of 10: ") + print(string(typeof(biop))*" dots out of 10: ") todo, done, pctg = length(tels), 0, 0 for (p,tcell) in enumerate(tels) diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index 1160e8ed..8c5dfc13 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -96,7 +96,7 @@ end a child of b """ function is_child_of(a,b) - return a∈b + return a∈b.children end function brothers(a,b) @@ -114,16 +114,16 @@ all objects in a domain touch each other, not with subdomains, well with the bou """ function alltouching(config::Configuration) - for i in keys(config) + for i in keys(config.domains) #config.touching[(i,i)] = [config.domains[i].data.testbasises,config.domains[i].data.trialbasises,config.domains[i].data.testbasises,config.domains[i].data.trialbasises] for child in config.domains[i].children - j = child.index - if typeof(config.domains[i]) <: Subdomain + j = child.id + if typeof(config.domains[i]) <: SubDomain config.touching[(i,j)] = [config.domains[i].data.testbasises,config.domains[i].data.trialbasises,child.data.testbasises,child.data.trialbasises] config.touching[(j,i)] = [config.touching[(i,j)][3],config.touching[(i,j)][4],config.touching[(i,j)][1],config.touching[(i,j)][2]] end for child2 in config.domains[i].children - k = child2.index + k = child2.id config.touching[(j,k)] = [child.data.testbasises,child.data.trialbasises,child2.data.testbasises,child2.data.trialbasises] config.touching[(k,j)] = [child2.data.testbasises,child2.data.trialbasises,child.data.testbasises,child.data.trialbasises] end diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 6fe31a08..fe49eccc 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -18,11 +18,11 @@ end cauchylimit needs to be applied before the normalorient function """ -function cauchylimit(operator::AbstractOperator,Ω1,Ω2,Ω3) +function cauchylimit(operator::AbstractOperator;Ω1,Ω2,Ω3) #check first if touching is non empty @assert is_child_of(Ω1,Ω3)||Ω1===Ω3 @assert is_child_of(Ω2,Ω3)||Ω2===Ω3 - if !Ω2===Ω3 + if Ω2!==Ω3 sign = -1 elseif Ω2===Ω3 sign = 1 @@ -33,13 +33,14 @@ function cauchylimit(operator::AbstractOperator,Ω1,Ω2,Ω3) end function trace(op::AbstractOperator,sign) - @warning "general abstract opterator trace function called returning pv of operator!: "*string(typeof(op)) + @warn "general abstract opterator trace function called returning pv of operator!: "*string(typeof(op)) return op end function normalorient(op::AbstractOperator,signtest,signtrial) - @warning "normalorient not implemented for: "*string(typeof(op)) + @warn "normalorient not implemented for: "*string(typeof(op)) return op end +trace(op::ZeroOperator,s) = op function trace(op::LinearCombinationOfOperators,sign) result = ZeroOperator() @@ -50,7 +51,7 @@ function trace(op::LinearCombinationOfOperators,sign) end -function normalorient(operator::LinearCombinationOfOperators,signtest,signtrial) +function normalorient(op::LinearCombinationOfOperators,signtest,signtrial) result = ZeroOperator() for (c,o) in zip(op.coeffs,op.ops) result += c*normalorient(o,signtest,signtrial) @@ -58,7 +59,7 @@ function normalorient(operator::LinearCombinationOfOperators,signtest,signtrial) return result end -function normalorient(operator::AbstractOperator,Ω1,Ω2,Ω3) +function normalorient(operator::AbstractOperator;Ω1,Ω2,Ω3) if Ω1===Ω3 sign_test_normal = 1 else @@ -72,5 +73,6 @@ function normalorient(operator::AbstractOperator,Ω1,Ω2,Ω3) normalorient(operator,sign_test_normal,sign_trial_normal) end +normalorient(op::ZeroOperator,a,b) = op ###### Interactions \ No newline at end of file diff --git a/src/operator.jl b/src/operator.jl index 5f133457..955110c6 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -108,7 +108,8 @@ end transpose(op::TransposedOperator) = op.op transpose(op::Operator) = TransposedOperator(op) - +defaultquadstrat(op::ZeroOperator,tfs,bfs) = nothing +scalartype(op::ZeroOperator) = Union{} defaultquadstrat(lc::LinearCombinationOfOperators, tfs, bfs) = [defaultquadstrat(op,tfs,bfs) for op in lc.ops] @@ -245,6 +246,11 @@ function assemble!(op::TransposedOperator, tfs::Space, bfs::Space, store1(v,m,n) = store(v,n,m) assemble!(op.op, bfs, tfs, store1, threading; quadstrat) end +function assemble!(op::ZeroOperator, tfs::Space, bfs::Space, + store, threading = Threading{:multi}; + quadstrat=nothing) +end + function assemble!(op::BasisOperatorLeft, tfs::Space, bfs::Space, store,threading = Threading{:multi}; quadstrat=defaultquadstrat(op, tfs, bfs)) #quadstrat = defaultquadstrat(op.operator,op.left_function(tfs),bfs) @@ -386,7 +392,9 @@ end Base.zero(op::AbstractOperator) = ZeroOperator() +(a::AbstractOperator,b::ZeroOperator) = a +(a::ZeroOperator,b::ZeroOperator) = a -+(a::ZeroOperator,b::AbstractOperator) = b+a ++(a::ZeroOperator,b::AbstractOperator) = b ++(a::ZeroOperator,b::LinearCombinationOfOperators) = b ++(b::LinearCombinationOfOperators,a::ZeroOperator) = b -(a::ZeroOperator,b::AbstractOperator) = -b *(a::Number,b::ZeroOperator) = b diff --git a/src/quadrature/quadstrats.jl b/src/quadrature/quadstrats.jl index 40c9a994..3c131fb5 100644 --- a/src/quadrature/quadstrats.jl +++ b/src/quadrature/quadstrats.jl @@ -40,7 +40,7 @@ end function defaultquadstrat(op, tfs, bfs) - @warn "made use of general defaultquadstrat routine which cals defaultquadstrat on refspaces" + @warn "made use of general defaultquadstrat routine which cals defaultquadstrat on refspaces "*string(typeof(op)) defaultquadstrat(op, refspace(tfs), refspace(bfs)) end macro defaultquadstrat(dop, body) diff --git a/src/solvers/solver.jl b/src/solvers/solver.jl index 731e27a8..5bcabb5d 100644 --- a/src/solvers/solver.jl +++ b/src/solvers/solver.jl @@ -430,8 +430,8 @@ end # end function LinearAlgebra.dot(test::DirectProductSpace,op::Matrix{AbstractOperator},trial::DirectProductSpace) -test_length = length(test) -trial_length = length(trial) +test_length = length(test.factors) +trial_length = length(trial.factors) @assert size(op)==(test_length,trial_length) terms = Vector{BilTerm}() test_space_dict = Dict() From e7d28a3c47e95928b1b1f1659554d2a6df0677d4 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 28 Sep 2023 14:54:10 +0200 Subject: [PATCH 032/110] display operators possible --- Project.toml | 2 + src/BEAST.jl | 2 + src/display.jl | 98 ++++++++++++++++++++++++++++++++ src/multi-trace/configuration.jl | 2 + src/operator.jl | 10 ++-- 5 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 src/display.jl diff --git a/Project.toml b/Project.toml index fe9f241e..15b78c24 100644 --- a/Project.toml +++ b/Project.toml @@ -21,6 +21,7 @@ LiftedMaps = "d22a30c1-52ac-4762-a8c9-5838452405e0" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" NestedUnitRanges = "032820ab-dc03-4b49-91f4-7d58d4da98b3" +PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" Requires = "ae029012-a4dd-5104-9daa-d747884805df" ReusePatterns = "a39b5e78-89b5-562b-97d8-70689129df0c" SauterSchwab3D = "0a13313b-1c00-422e-8263-562364ed9544" @@ -30,6 +31,7 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" SparseMatrixDicts = "5cb6c4b0-9b79-11e8-24c9-f9621d252589" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +TableView = "40c74d1a-b44c-5b06-a7c1-6cbea58ea978" WiltonInts84 = "a3e2863e-c0ee-5ff6-a523-307a4cdc8724" [compat] diff --git a/src/BEAST.jl b/src/BEAST.jl index d26f2d49..3deb4bc4 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -267,6 +267,8 @@ include("Helmholtzhodge/helmholtzhodge.jl") include("multi-trace/configuration.jl") include("multi-trace/interactions.jl") +#suport for displaying operators +include("display.jl") const x̂ = point(1,0,0) const ŷ = point(0,1,0) diff --git a/src/display.jl b/src/display.jl new file mode 100644 index 00000000..53c51b45 --- /dev/null +++ b/src/display.jl @@ -0,0 +1,98 @@ +import Base: show, print + +Base.show(io::IO,::MIME"text/plain",op::AbstractOperator) = print(io,op) + +function Base.print(io::IO,op::LinearCombinationOfOperators) + l = length(op.coeffs) + for (ind,coef,operator) in zip(1:l,op.coeffs,op.ops) + if typeof(coef) <: Complex + imag(coef) ≈ 0.0 && (coef=real(coef)) + end + if typeof(coef) <: Real + if ind == 1 && coef < 0 + print(io," -") + end + if ind > 1 && coef >0 + print(io, " + ") + end + if ind > 1 && coef < 0 + print(io, " - ") + end + + if !(abs(coef) ≈ 1.0) + print(io,abs(coef)) + end + + print(io,operator) + + else + if ind > 1 + print(io," + ") + end + print(io,coef) + print(io,operator) + + + end + + end +end + +Base.print(io::IO, op::Identity) = print(io,"I") +Base.print(io::IO, op::ZeroOperator) = print(io,"Zero") +function Base.print(io::IO, op::BasisOperatorLeft) + print(io,"f*") + print(io,op.operator) +end +function Base.print(io::IO, op::BasisOperatorRight) + print(io,op.operator) + print(io,"*f") +end + +function Base.print(io::IO, op::HHHgreen) +if !(op.α ≈ 1.0) + @warn "alpha is not 1 and not printed" +end +print(io,"S[$(abs(op.γ))]") +print(io,op.op) +end +function Base.print(io::IO, op::HHHgradgreen) + if !(op.α ≈ 1.0) + @warn "alpha is not 1 and not printed" + end + print(io,"∇S[$(abs(op.γ))]") + print(io,op.op) +end +function Base.print(io::IO, op::HHHgradgreenCross) + if !(op.α ≈ 1.0) + @warn "alpha is not 1 and not printed" + end + print(io,"S[$(abs(op.γ))]×") + print(io,op.op) +end +function Base.print(io::IO, op::Union{HHHNtestCross,HHHNtestCrossLocal}) + print(io,"nₜₑ×") + print(io,op.op) +end +function Base.print(io::IO, op::Union{HHHNbasisCross,HHHNbasisCrossLocal}) + print(io,"nₜᵣ×") + print(io,op.op) +end +function Base.print(io::IO, op::Union{HHHNtestDot,HHHNtestDotLocal}) + print(io,"nₜₑ⋅") + print(io,op.op) +end +function Base.print(io::IO, op::Union{HHHNbasisnormal,HHHNbasisnormalLocal}) + print(io,"nₜᵣ") + print(io,op.op) +end +function Base.print(io::IO, op::Union{HHHNbasisdot,HHHNbasisdotLocal}) + print(io,"nₜᵣ⋅") + print(io,op.op) +end +function Base.print(io::IO, op::Union{HHHIdentity,HHHIdentityLocal}) + print(io,"B") +end +function Base.print(io::IO, op::Union{HHHDivergence,HHHDivergenceLocal}) + print(io,"∇⋅B") +end \ No newline at end of file diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index 8c5dfc13..4ff60adf 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -1,5 +1,6 @@ abstract type DomainData end abstract type Domain{T<:DomainData} end +using PrettyTables """ A is the type of the test structure, B is the type of the trial structure, C the type of ths structure embedding """ @@ -199,6 +200,7 @@ function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) # end # end # rhs.terms=terms + pretty_table(OperatorMatrix, noheader=true) return assemble(dot(config.testdirectproductspace,OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) # space_mappings = [test[i]=>config.testdirectproductspace.factors[i],trial[i]=>config.trialdirectproductspace.factors[i] for i in 1:N] # discreteequation = discretise(eq,space_mappings) diff --git a/src/operator.jl b/src/operator.jl index 955110c6..bc131c57 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -40,11 +40,11 @@ end struct ZeroOperator <: AbstractOperator end -abstract type Orientation end -struct Inside <: Orientation end -struct Outside <: Orientation end -inside() = Inside() -outside() = Outside() +# abstract type Orientation end +# struct Inside <: Orientation end +# struct Outside <: Orientation end +# inside() = Inside() +# outside() = Outside() mutable struct TransposedOperator <: AbstractOperator From d09028cbdff1fff9ae35da795deee53fa1684d94 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 28 Sep 2023 16:12:25 +0200 Subject: [PATCH 033/110] possibility to transform basis --- src/display.jl | 2 +- src/multi-trace/configuration.jl | 32 +++++++++---------- src/multi-trace/interactions.jl | 53 +++++++++++++++++++++++++++++++- src/operator.jl | 14 +++++++-- 4 files changed, 81 insertions(+), 20 deletions(-) diff --git a/src/display.jl b/src/display.jl index 53c51b45..793324dc 100644 --- a/src/display.jl +++ b/src/display.jl @@ -12,7 +12,7 @@ function Base.print(io::IO,op::LinearCombinationOfOperators) if ind == 1 && coef < 0 print(io," -") end - if ind > 1 && coef >0 + if ind > 1 && coef >=0 print(io, " + ") end if ind > 1 && coef < 0 diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index 4ff60adf..8b935dc8 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -19,18 +19,20 @@ abstract type NumericalStrategy end export NumericalStrategy mutable struct HomogeneousDomain <: DomainData -ϵr -μr +ϵ +μ +ω testbasises trialbasises testindex trialindex -HomogeneousDomain(a,b,c,d) = new(a,b,c,d,[],[]) +HomogeneousDomain(a,b,c,d,e) = new(a,b,c,d,e,[],[]) end struct BackgroundDomain <: DomainData - ϵ0 - μ0 + ϵ + μ + ω end mutable struct SubDomain{T} <: Domain{T} @@ -155,6 +157,7 @@ end # #TODO create the bilform # end +#function convert_inside_to_outside_basis(Ωchild,Ωparent,strat) end function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) @@ -166,25 +169,22 @@ function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter(strat) for child in Ω.children inter = Interaction(config,Ω,child,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += inter(strat) + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += inter(strat)*convert_inside_to_outside_basis(child,Ω,strat) inter = Interaction(config,child,Ω,Ω) - OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter(strat) + OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += convert_inside_to_outside_basis(child,Ω,strat)*inter(strat) end end for Ω1 in Ω.children + + inter = Interaction(config,Ω1,Ω1,Ω) + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += convert_inside_to_outside_basis(Ω1,Ω,strat)*inter(strat)*convert_inside_to_outside_basis(Ω1,Ω,strat) + for Ω2 in Ω.children - if Ω1===Ω2 - inter = Interaction(config,Ω1,Ω2,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter(strat) - else + if Ω1!==Ω2 inter = Interaction(config,Ω1,Ω2,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter(strat) - inter = Interaction(config,Ω2,Ω1,Ω) - OperatorMatrix[Ω2.data.testindex[1]:last(Ω2.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += inter(strat) - + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += convert_inside_to_outside_basis(Ω1,Ω,strat)*inter(strat)*convert_inside_to_outside_basis(Ω2,Ω,strat) end - end end diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index fe49eccc..3b1bb81b 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -75,4 +75,55 @@ end normalorient(op::ZeroOperator,a,b) = op -###### Interactions \ No newline at end of file +###### Interactions +struct VectorStrat <: BEAST.NumericalStrategy end + +function convert_inside_to_outside_basis(child,parent,::VectorStrat) + a = [-1 0 0 0 + 0 1 0 0 + 0 0 -parent.data.μ/child.data.μ 0 + 0 0 0 -child.data.ϵ/parent.data.ϵ] + + return a +end + + + + +function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: RootDomain})(::VectorStrat) + k = sqrt(int.embedvol.data.ϵ*int.embedvol.data.μ)*int.embedvol.data.ω + green = HHH.green(wavenumber=k) + gradgreen = HHH.gradgreen(wavenumber=k) + b = basisfunction() + + a = [n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen + BEAST.ZeroOperator() -gradgreen(n*b) gradgreen -(-k^2*green) + -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() + -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] + if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) + println("cauchy limit taken") + a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + end + a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + + return a + +end +function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: SubDomain})(::VectorStrat) + k = sqrt(int.embedvol.data.ϵ*int.embedvol.data.μ)*int.embedvol.data.ω #foute lijn, puur voor test!!! + green = HHH.green(wavenumber=k) + gradgreen = HHH.gradgreen(wavenumber=k) + b = basisfunction() + + a = [n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen + BEAST.ZeroOperator() -gradgreen(n*b) gradgreen -(-k^2*green) + -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() + -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] + if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) + println("cauchy limit taken") + a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + end + a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + return a + +end \ No newline at end of file diff --git a/src/operator.jl b/src/operator.jl index bc131c57..8fc9ec09 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -92,9 +92,19 @@ end +(a::AbstractOperator, b::Number) = a + (b * Identity()) +(a::Number, b::AbstractOperator) = b + a -*(a::Number, b::AbstractOperator) = LinearCombinationOfOperators([a], [b]) +function *(a::Number, b::AbstractOperator) + if abs(a) ≈ 0 + return ZeroOperator() + end + LinearCombinationOfOperators([a], [b]) +end *(a::AbstractOperator, b::Number) = b*a -*(a::Number, b::LinearCombinationOfOperators) = LinearCombinationOfOperators(a * b.coeffs, b.ops) +function *(a::Number, b::LinearCombinationOfOperators) + if abs(a) ≈ 0 + return ZeroOperator() + end + LinearCombinationOfOperators(a * b.coeffs, b.ops) +end -(a::AbstractOperator, b::AbstractOperator) = a + (-1.0) * b -(a::AbstractOperator) = (-1.0) * a From c0fbf8ba7ece96fa107c86bb56590606d4b60c6e Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 29 Sep 2023 10:35:18 +0200 Subject: [PATCH 034/110] functional based on function implemented --- src/BEAST.jl | 1 + src/Helmholtzhodge/hhhexc.jl | 13 +++++++++++++ src/multi-trace/configuration.jl | 15 +++++++++------ 3 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 src/Helmholtzhodge/hhhexc.jl diff --git a/src/BEAST.jl b/src/BEAST.jl index 3deb4bc4..b13c4548 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -261,6 +261,7 @@ include("utils/plotlyglue.jl") #suport for helmholtzhodge equation include("Helmholtzhodge/hhhop.jl") include("Helmholtzhodge/helmholtzhodge.jl") +include("Helmholtzhodge/hhhexc.jl") #suport for multi-trace diff --git a/src/Helmholtzhodge/hhhexc.jl b/src/Helmholtzhodge/hhhexc.jl new file mode 100644 index 00000000..307afb65 --- /dev/null +++ b/src/Helmholtzhodge/hhhexc.jl @@ -0,0 +1,13 @@ +mutable struct FunctionExcitation{T} <: Functional + f::Function + coeff::T +end +FunctionExcitation(f) = FunctionExcitation(f,f([0.0,0.0,0.0])) + +function (e::FunctionExcitation)(p) + x = cartesian(p) + e.f(x) +end +integrand(::FunctionExcitation,test_vals, field_val) = dot(test_vals.value,field_val) +scalartype(e::FunctionExcitation{T}) where {T<:Number} = T +scalartype(e::FunctionExcitation{Vector{T}}) where {T<:Number} = T \ No newline at end of file diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index 8b935dc8..225bdf44 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -24,15 +24,17 @@ mutable struct HomogeneousDomain <: DomainData ω testbasises trialbasises +coeff testindex trialindex -HomogeneousDomain(a,b,c,d,e) = new(a,b,c,d,e,[],[]) +HomogeneousDomain(a,b,c,d,e,f) = new(a,b,c,d,e,f,[],[]) end struct BackgroundDomain <: DomainData ϵ μ ω + coeff end mutable struct SubDomain{T} <: Domain{T} @@ -164,26 +166,27 @@ function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) N = length(config.testdirectproductspace.factors) OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) for (id,Ω) in config.domains + c = Ω.data.coeff if id != 0 inter = Interaction(config,Ω,Ω,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter(strat) + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*inter(strat) for child in Ω.children inter = Interaction(config,Ω,child,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += inter(strat)*convert_inside_to_outside_basis(child,Ω,strat) + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += c*inter(strat)*convert_inside_to_outside_basis(child,Ω,strat) inter = Interaction(config,child,Ω,Ω) - OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += convert_inside_to_outside_basis(child,Ω,strat)*inter(strat) + OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*convert_inside_to_outside_basis(child,Ω,strat)*inter(strat) end end for Ω1 in Ω.children inter = Interaction(config,Ω1,Ω1,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += convert_inside_to_outside_basis(Ω1,Ω,strat)*inter(strat)*convert_inside_to_outside_basis(Ω1,Ω,strat) + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += c*convert_inside_to_outside_basis(Ω1,Ω,strat)*inter(strat)*convert_inside_to_outside_basis(Ω1,Ω,strat) for Ω2 in Ω.children if Ω1!==Ω2 inter = Interaction(config,Ω1,Ω2,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += convert_inside_to_outside_basis(Ω1,Ω,strat)*inter(strat)*convert_inside_to_outside_basis(Ω2,Ω,strat) + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += c*convert_inside_to_outside_basis(Ω1,Ω,strat)*inter(strat)*convert_inside_to_outside_basis(Ω2,Ω,strat) end end end From 289c7d037e0c32cc979a8f761b27d40ab3d174b6 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 29 Sep 2023 17:13:18 +0200 Subject: [PATCH 035/110] update --- .gitignore | 1 + src/BEAST.jl | 6 +- src/Helmholtzhodge/hhhexc.jl | 30 ++++++- src/Helmholtzhodge/hhhnearfield.jl | 132 +++++++++++++++++++++++++++++ src/Helmholtzhodge/hhhop.jl | 38 +++++++-- src/display.jl | 9 +- src/identityop.jl | 2 + src/multi-trace/configuration.jl | 32 +++---- src/multi-trace/interactions.jl | 38 ++++++--- src/solvers/itsolver.jl | 12 +++ 10 files changed, 253 insertions(+), 47 deletions(-) create mode 100644 src/Helmholtzhodge/hhhnearfield.jl diff --git a/.gitignore b/.gitignore index 715a5a38..7c4505e4 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ profile/ /envs/ programs/ results/ +src/todo.txt diff --git a/src/BEAST.jl b/src/BEAST.jl index b13c4548..686795c6 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -262,7 +262,7 @@ include("utils/plotlyglue.jl") include("Helmholtzhodge/hhhop.jl") include("Helmholtzhodge/helmholtzhodge.jl") include("Helmholtzhodge/hhhexc.jl") - +include("Helmholtzhodge/hhhnearfield.jl") #suport for multi-trace include("multi-trace/configuration.jl") @@ -289,4 +289,8 @@ export HomogeneousDomain export RootDomain export SubDomain +export FunctionExcitation +export NdotExcitation +export NcrossExcitation + end # module diff --git a/src/Helmholtzhodge/hhhexc.jl b/src/Helmholtzhodge/hhhexc.jl index 307afb65..da89f1fc 100644 --- a/src/Helmholtzhodge/hhhexc.jl +++ b/src/Helmholtzhodge/hhhexc.jl @@ -1,13 +1,35 @@ -mutable struct FunctionExcitation{T} <: Functional +abstract type HHHFunctional{T} <: Functional end + +mutable struct FunctionExcitation{T} <: HHHFunctional{T} f::Function coeff::T end +mutable struct NdotExcitation{T} <: HHHFunctional{T} + e::HHHFunctional{T} +end +mutable struct NcrossExcitation{T} <: HHHFunctional{T} + e::HHHFunctional{T} +end + FunctionExcitation(f) = FunctionExcitation(f,f([0.0,0.0,0.0])) function (e::FunctionExcitation)(p) x = cartesian(p) e.f(x) end -integrand(::FunctionExcitation,test_vals, field_val) = dot(test_vals.value,field_val) -scalartype(e::FunctionExcitation{T}) where {T<:Number} = T -scalartype(e::FunctionExcitation{Vector{T}}) where {T<:Number} = T \ No newline at end of file +function (e::NdotExcitation)(p) + n = normal(p) + dot(n,e.e(p)) +end +function (e::NcrossExcitation)(p) + n = normal(p) + cross(n,e.e(p)) +end + + + +integrand(::HHHFunctional,test_vals, field_val) = dot(test_vals.value,field_val) + + +scalartype(e::HHHFunctional{T}) where {T<:Number} = T +scalartype(e::HHHFunctional{Vector{T}}) where {T<:Number} = T \ No newline at end of file diff --git a/src/Helmholtzhodge/hhhnearfield.jl b/src/Helmholtzhodge/hhhnearfield.jl new file mode 100644 index 00000000..2be12ad9 --- /dev/null +++ b/src/Helmholtzhodge/hhhnearfield.jl @@ -0,0 +1,132 @@ +mutable struct HHHGreenField{T,U} + gamma::T + op::U +end +mutable struct HHHGradGreenField{T,U} + gamma::T + op::U +end +mutable struct HHHGradGreenCrossField{T,U} + gamma::T + op::U +end + +mutable struct HHHBasisNtimesField{U} + op::U +end +mutable struct HHHIdentityField end +mutable struct HHHDivergenceField end + +function HHHGreenField(; + gamma=nothing, + wavenumber=nothing +) + + if (gamma === nothing) && (wavenumber === nothing) + error("Supply one of (not both) gamma or wavenumber") + end + + if (gamma !== nothing) && (wavenumber !== nothing) + error("Supply one of (not both) gamma or wavenumber") + end + + if gamma === nothing + if iszero(real(wavenumber)) + gamma = -imag(wavenumber) + else + gamma = im*wavenumber + end + end + + @assert gamma !== nothing + + HHHGreenField(gamma,HHHIdentityField()) +end +function HHHGradGreenField(; + gamma=nothing, + wavenumber=nothing +) + + if (gamma === nothing) && (wavenumber === nothing) + error("Supply one of (not both) gamma or wavenumber") + end + + if (gamma !== nothing) && (wavenumber !== nothing) + error("Supply one of (not both) gamma or wavenumber") + end + + if gamma === nothing + if iszero(real(wavenumber)) + gamma = -imag(wavenumber) + else + gamma = im*wavenumber + end + end + + @assert gamma !== nothing + + HHHGradGreenField(gamma,HHHIdentityField()) +end +function HHHGradGreenCrossField(; + gamma=nothing, + wavenumber=nothing +) + + if (gamma === nothing) && (wavenumber === nothing) + error("Supply one of (not both) gamma or wavenumber") + end + + if (gamma !== nothing) && (wavenumber !== nothing) + error("Supply one of (not both) gamma or wavenumber") + end + + if gamma === nothing + if iszero(real(wavenumber)) + gamma = -imag(wavenumber) + else + gamma = im*wavenumber + end + end + + @assert gamma !== nothing + + HHHGradGreenCrossField(gamma,HHHIdentityField()) +end + +const HHHField = Union{HHHGreenField,HHHGradGreenField,HHHGradGreenCrossField} +defaultquadstrat(op::HHHField, basis) = SingleNumQStrat(2) +quaddata(op::HHHField,rs,els,qs::SingleNumQStrat) = quadpoints(rs,els,(qs.quad_rule,)) +quadrule(op::HHHField,refspace,p,y,q,el,qdata,qs::SingleNumQStrat) = qdata[1,q] + +function kernelvals(op::HHHField,y,p) + + γ = op.gamma + r = y - cartesian(p) + R = norm(r) + + γR = γ*R + expn = exp(-γR) + green = expn / (4pi*R) + gradgreen = -(γ + 1/R) * green / R * r + + krn = (trans=r, dist=R, green=green, gradgreen=gradgreen) +end + +function integrand(op::HHHGreenField, krn, y, fp, p) +G = krn.green +G*integrand(op.op, krn, y, fp, p) +end + +function integrand(op::HHHBasisNtimesField, krn, y, fp, p) + n = normal(p) + n*integrand(op.op, krn, y, fp, p) +end +integrand(op::HHHIdentityField, krn,y,fp,p) = fp.value +integrand(op::HHHDivergenceField,krn,y,fp,p) = fp.divergence + +function integrand(op::HHHGradGreenField, krn, y, fp, p) + dot(integrand(op.op, krn,y,fp,p),krn.gradgreen) +end +function integrand(op::HHHGradGreenCrossField, krn, y, fp, p) + cross(krn.gradgreen,integrand(op.op, krn,y,fp,p)) +end diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index 8b5770ed..bfcc95cc 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -29,12 +29,21 @@ struct HHHgradgreen{T,K,U} <: HHHkernelOperator{T,K,U} op::U end +struct HHHgradgreenDot{T,K,U} <: HHHkernelOperator{T,K,U} + α::K + γ::T + op::U +end + + struct HHHgradgreenCross{T,K,U} <: HHHkernelOperator{T,K,U} α::K γ::T op::U end + + abstract type HHHdata end struct HHHvector <:HHHdata end struct HHHscalar <:HHHdata end @@ -98,7 +107,7 @@ basisfunction() = BasisFunction() export basisfunction VectorToVector = Union{HHHNtestCross,HHHNbasisCross,HHHgradgreenCross,HHHgreen} ScalarToVector = Union{HHHNbasisnormal,HHHgradgreen} -VectorToScalar = Union{HHHNtestDot,HHHgradgreen,HHHNbasisdot} +VectorToScalar = Union{HHHNtestDot,HHHgradgreenDot,HHHNbasisdot} ScalarToScalar = Union{HHHgreen} inversemap(op::VectorToVector,::HHHvector) = inversemap(op.op,HHHvector()) inversemap(op::ScalarToVector,::HHHvector) = inversemap(op.op,HHHscalar()) @@ -112,6 +121,7 @@ inversemap(::HHHDivergence,::HHHscalar) = HHHvector() strace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestCross(op) ntrace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestDot(op) ×(op::HHHgradgreen,::Nothing) = HHHgradgreenCross(op.α,op.γ,op.op) +⋅(op::HHHgradgreen,::Nothing) = HHHgradgreenDot(op.α,op.γ,op.op) #×(op::HHHgradgreen,::NormalVector) = HHHgradgreenCross(op.α,op.γ,op.op)(HHHNbasisnormal(hhhidentity())) ×(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = strace(op) ⋅(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = ntrace(op) @@ -200,10 +210,10 @@ function (op::HHHgreen)(x,y,g) green = op.α * exp(-op.γ*R)*(iR*i4pi) green*op.op(x,y,g) end -mydot(a::SVector{N,<:SVector},b::Base.RefValue) where {N} = dot.(a,b) -function mydot(a::SVector,b::Base.RefValue) - a.*b -end +# mydot(a::SVector{N,<:SVector},b::Base.RefValue) where {N} = dot.(a,b) +# function mydot(a::SVector,b::Base.RefValue) +# a.*b +# end function (op::HHHgradgreen)(x,y,g) r = cartesian(x) - cartesian(y) @@ -212,9 +222,18 @@ function (op::HHHgradgreen)(x,y,g) green = op.α * exp(-op.γ*R)*(iR*i4pi) gradgreen = -(op.γ + iR) * green * (iR * r) - mydot(op.op(x,y,g),Ref(gradgreen)) + op.op(x,y,g).*Ref(gradgreen) +end +function (op::HHHgradgreenDot)(x,y,g) + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = op.α * exp(-op.γ*R)*(iR*i4pi) + gradgreen = -(op.γ + iR) * green * (iR * r) + + dot(op.op(x,y,g),Ref(gradgreen)) end - function (op::HHHgradgreenCross)(x,y,g) r = cartesian(x) - cartesian(y) @@ -270,7 +289,7 @@ hhhntestcrosslocal(op::Union{HHHNbasisnormalLocal}) = ZeroOperator() hhhntestdotlocal(op::ZeroOperator) = op hhhntestdotlocal(op::HHHLocalOperator) = HHHNtestDotLocal(op) hhhntestdotlocal(op::Union{HHHNtestCrossLocal,HHHNbasisCrossLocal}) = ZeroOperator() -hhhntestdotlocal(op::HHHNbasisnormalLocal) = localoperator(op.op) +#hhhntestdotlocal(op::HHHNbasisnormalLocal) = localoperator(op.op) hhhnbasiscrosslocal(op::ZeroOperator) = op hhhnbasiscrosslocal(op::HHHLocalOperator) = HHHNbasisCrossLocal(op) @@ -299,7 +318,8 @@ localoperator(op::HHHIdentity) = HHHIdentityLocal() localoperator(op::HHHDivergence) = HHHDivergenceLocal() localoperator(op::HHHgreen) = ZeroOperator() -localoperator(op::HHHgradgreen) = hhhnbasisdotlocal(localoperator(op.op)) +localoperator(op::HHHgradgreen) = hhhnbasisnormal(localoperator(op.op)) +localoperator(op::HHHgradgreenDot) = hhhnbasisdotlocal(localoperator(op.op)) localoperator(op::HHHgradgreenCross) = hhhnbasiscrosslocal(localoperator(op.op)) function trace(op::HHHOperator,sign) diff --git a/src/display.jl b/src/display.jl index 793324dc..4fc69bec 100644 --- a/src/display.jl +++ b/src/display.jl @@ -63,11 +63,18 @@ function Base.print(io::IO, op::HHHgradgreen) print(io,"∇S[$(abs(op.γ))]") print(io,op.op) end +function Base.print(io::IO, op::HHHgradgreenDot) + if !(op.α ≈ 1.0) + @warn "alpha is not 1 and not printed" + end + print(io,"∇S⋅[$(abs(op.γ))]") + print(io,op.op) +end function Base.print(io::IO, op::HHHgradgreenCross) if !(op.α ≈ 1.0) @warn "alpha is not 1 and not printed" end - print(io,"S[$(abs(op.γ))]×") + print(io,"∇S×[$(abs(op.γ))]×") print(io,op.op) end function Base.print(io::IO, op::Union{HHHNtestCross,HHHNtestCrossLocal}) diff --git a/src/identityop.jl b/src/identityop.jl index f1b1f723..8a48c6c1 100644 --- a/src/identityop.jl +++ b/src/identityop.jl @@ -104,3 +104,5 @@ end # end # return A # end + + diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index 225bdf44..ca8918c6 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -43,6 +43,7 @@ mutable struct SubDomain{T} <: Domain{T} parent::Domain data::T excitation + results end mutable struct RootDomain{T} <: Domain{T} id::Int @@ -84,7 +85,7 @@ function _adddomain(config::Configuration, newdom::Domain) end function _createdomain(config::Configuration,id::Int,parentid::Int,values;excitation) - dom = SubDomain(id,Domain[],config.domains[parentid],values::DomainData,excitation) + dom = SubDomain(id,Domain[],config.domains[parentid],values::DomainData,excitation,[]) # push!(config.domains[parentid].children,dom) return dom @@ -192,25 +193,9 @@ function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) end end - # @hilbertspace test[1:N] - # @hilbertspace trial[1:N] - - # rhs = test'*OperatorMatrix*trial - # terms = [] - # for term in rhs.terms - # if typeof(term.kernel)!=ZeroOperator - # push!(terms,term) - # end - # end - # rhs.terms=terms - pretty_table(OperatorMatrix, noheader=true) + + pretty_table(OperatorMatrix, noheader=true, backend=Val(:latex)) return assemble(dot(config.testdirectproductspace,OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) - # space_mappings = [test[i]=>config.testdirectproductspace.factors[i],trial[i]=>config.trialdirectproductspace.factors[i] for i in 1:N] - # discreteequation = discretise(eq,space_mappings) - # return discreteequation -#TODO assembly of the system -#TODO the right hand side -#TODO solving system end @@ -231,6 +216,13 @@ function generate_problem_rhs(config::Configuration) end function map_solution_to_volumes(solution,config) +for (id,dom) in config.domains + id == 0 && continue + for i in dom.data.trialindex + config.trial_direct_productspace.factors[i] + end +end + +end -end \ No newline at end of file diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 3b1bb81b..1fd5d635 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -22,11 +22,13 @@ function cauchylimit(operator::AbstractOperator;Ω1,Ω2,Ω3) #check first if touching is non empty @assert is_child_of(Ω1,Ω3)||Ω1===Ω3 @assert is_child_of(Ω2,Ω3)||Ω2===Ω3 - if Ω2!==Ω3 - sign = -1 - elseif Ω2===Ω3 - sign = 1 - end + # if Ω2!==Ω3 + # sign = -1 + # elseif Ω2===Ω3 + # sign = 1 + # end + @warn "correct sign for inside is 1?" + sign = 1 trace(operator,sign) @@ -95,11 +97,17 @@ function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDom green = HHH.green(wavenumber=k) gradgreen = HHH.gradgreen(wavenumber=k) b = basisfunction() - - a = [n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen - BEAST.ZeroOperator() -gradgreen(n*b) gradgreen -(-k^2*green) + @warn "check if extra - in front of a is correct, describtion of As from paper asumes n outward so inward in outer domain?" + a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen + BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] + id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() + ZeroOperator() Identity() ZeroOperator() ZeroOperator() + ZeroOperator() ZeroOperator() Identity() ZeroOperator() + ZeroOperator() ZeroOperator() ZeroOperator() Identity()] + a = id - a + if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) println("cauchy limit taken") a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) @@ -115,15 +123,21 @@ function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDom gradgreen = HHH.gradgreen(wavenumber=k) b = basisfunction() - a = [n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen - BEAST.ZeroOperator() -gradgreen(n*b) gradgreen -(-k^2*green) + a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen + BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() - -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] + -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] + id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() + ZeroOperator() Identity() ZeroOperator() ZeroOperator() + ZeroOperator() ZeroOperator() Identity() ZeroOperator() + ZeroOperator() ZeroOperator() ZeroOperator() Identity()] + a = id - a + if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) println("cauchy limit taken") a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) end - a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) return a end \ No newline at end of file diff --git a/src/solvers/itsolver.jl b/src/solvers/itsolver.jl index bc6a9fcf..58915414 100644 --- a/src/solvers/itsolver.jl +++ b/src/solvers/itsolver.jl @@ -90,7 +90,19 @@ function gmres_ch(eq::DiscreteEquation; maxiter=0, restart=0, tol=0) ax = nestedrange(Y, 1, numfunctions) return PseudoBlockVector(x, (ax,)), ch end +function gmres_ch(b,Z,trial_direct_product_space; maxiter=0, restart=0, tol=0) + if tol == 0 + invZ = GMRESSolver(Z, maxiter=maxiter, restart=restart) + else + invZ = GMRESSolver(Z, maxiter=maxiter, restart=restart, tol=tol) + end + x, ch = solve(invZ, b) + # x = invZ * b + + ax = nestedrange(trial_direct_product_space, 1, numfunctions) + return PseudoBlockVector(x, (ax,)), ch +end gmres(eq::DiscreteEquation; maxiter=0, restart=0, tol=0) = gmres_ch(eq; maxiter, restart, tol)[1] From 0df9324e15ec48a4a2b90023b6c03ff245a51256 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 19 Oct 2023 13:37:21 +0200 Subject: [PATCH 036/110] update, multi-trace werkt --- Project.toml | 1 + examples/ex_globalmultitrace.jl | 25 ++++- examples/pmchwt.jl | 14 +-- src/BEAST.jl | 1 + src/Helmholtzhodge/hhhnearfield.jl | 35 ++++++- src/Helmholtzhodge/hhhop.jl | 8 +- src/bases/basis.jl | 2 +- src/localop.jl | 29 +++++- src/multi-trace/configuration.jl | 152 +++++++++++++++++++---------- src/multi-trace/interactions.jl | 18 ++-- src/multi-trace/postprocessing.jl | 118 ++++++++++++++++++++++ 11 files changed, 323 insertions(+), 80 deletions(-) create mode 100644 src/multi-trace/postprocessing.jl diff --git a/Project.toml b/Project.toml index 15b78c24..c4edadeb 100644 --- a/Project.toml +++ b/Project.toml @@ -21,6 +21,7 @@ LiftedMaps = "d22a30c1-52ac-4762-a8c9-5838452405e0" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" NestedUnitRanges = "032820ab-dc03-4b49-91f4-7d58d4da98b3" +Plotly = "58dd65bb-95f3-509e-9936-c39a10fdeae7" PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" Requires = "ae029012-a4dd-5104-9daa-d747884805df" ReusePatterns = "a39b5e78-89b5-562b-97d8-70689129df0c" diff --git a/examples/ex_globalmultitrace.jl b/examples/ex_globalmultitrace.jl index 8b9a5efc..a16f2bc2 100644 --- a/examples/ex_globalmultitrace.jl +++ b/examples/ex_globalmultitrace.jl @@ -3,15 +3,28 @@ using BEAST using LinearAlgebra import Plotly + +# ϵ0 = 8.854e-12 +# μ0 = 4π*1e-7 +ϵr1 = 2.0 +μr1 = 2.0 +ϵr2 = 3.0 +μr2 = 3.0 +# c = 1/√(ϵ0*μ0) +# λ = 2.9979563769321627 +# ω = 2π*c/λ +# k0 = ω*sqrt(ϵ0*μ0) +k0 = 3.0 + # Exterior wavenumber -κ₀ = 3.0 +κ₀ = k0 # This is where the number of domains enters the problem description -κ = [1.5κ₀, 2.5κ₀] +κ = [sqrt(ϵr1*μr1)*κ₀, sqrt(ϵr2*μr2)*κ₀] # Description of the domain boundaries h = 0.125 -Γ1 = meshcuboid(0.5, 1.0, 1.0, h) +Γ1 = meshcuboid(1.0, 1.0, 1.0, h) Γ2 = -Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))) Γ = [Γ1, Γ2] @@ -19,7 +32,7 @@ h = 0.125 # of the number of domains and their relative positioning # Incident field -Einc = Maxwell3D.planewave(direction=(x̂+ẑ)/√2, polarization=ŷ, wavenumber=κ₀) +Einc = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=im*κ₀) Hinc = -1/(im*κ₀)*curl(Einc) # Definition of the boundary integral operators @@ -97,4 +110,6 @@ Etot = Eo + sum(Ei) Htot = Ho + sum(Hi) import Plots -Plots.heatmap(Xs, Zs, clamp.(real.(getindex.(Etot,2)),-2.0,2.0); colormap=:viridis) \ No newline at end of file +Plots.heatmap(Xs, Zs, clamp.(real.(getindex.(Htot,2)),-1,1); colormap=:viridis) + +Plots.heatmap(Xs, Zs, real.(getindex.(Htot,2))) \ No newline at end of file diff --git a/examples/pmchwt.jl b/examples/pmchwt.jl index 4500ab56..7e170fa5 100644 --- a/examples/pmchwt.jl +++ b/examples/pmchwt.jl @@ -23,17 +23,17 @@ end ϵ0 = 8.854e-12 μ0 = 4π*1e-7 c = 1/√(ϵ0*μ0) - +radius = 1.0 λ = 2.9979563769321627 ω = 2π*c/λ -Ω = CompScienceMeshes.tetmeshsphere(λ,0.1*λ) +Ω = CompScienceMeshes.tetmeshsphere(radius,0.4*radius) Γ = boundary(Ω) X = raviartthomas(Γ) @show numfunctions(X) -ϵr = 2.0 -μr = 1.0 +ϵr = 2.0*0+5.0 +μr = 10.0 κ, η = ω/c, √(μ0/ϵ0) κ′, η′ = κ*√(ϵr*μr), η*√(μr/ϵr) @@ -46,7 +46,7 @@ T′ = Maxwell3D.singlelayer(wavenumber=κ′) K = Maxwell3D.doublelayer(wavenumber=κ) K′ = Maxwell3D.doublelayer(wavenumber=κ′) -E = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=κ) +E = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=im*κ) H = -1/(im*κ*η)*curl(E) e = (n × E) × n @@ -116,8 +116,8 @@ Plots.contour(real.(getindex.(H_tot,2))) Plots.heatmap(Z, Y, clamp.(real.(getindex.(E_tot,1)),-1.5,1.5)) Plots.heatmap(Z, Y, clamp.(imag.(getindex.(E_tot,1)),-1.5,1.5)) -Plots.heatmap(Z, Y, real.(getindex.(H_tot,2))) -Plots.heatmap(Z, Y, imag.(getindex.(H_tot,2))) +display(Plots.heatmap(Z, Y, real.(getindex.(H_tot,2)))) +display(Plots.heatmap(Z, Y, imag.(getindex.(H_tot,2)))) Plots.plot(real.(getindex.(E_tot[:,51],1))) Plots.plot(real.(getindex.(H_tot[:,51],2))) diff --git a/src/BEAST.jl b/src/BEAST.jl index 686795c6..44b6b899 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -267,6 +267,7 @@ include("Helmholtzhodge/hhhnearfield.jl") #suport for multi-trace include("multi-trace/configuration.jl") include("multi-trace/interactions.jl") +include("multi-trace/postprocessing.jl") #suport for displaying operators include("display.jl") diff --git a/src/Helmholtzhodge/hhhnearfield.jl b/src/Helmholtzhodge/hhhnearfield.jl index 2be12ad9..f31c0d92 100644 --- a/src/Helmholtzhodge/hhhnearfield.jl +++ b/src/Helmholtzhodge/hhhnearfield.jl @@ -10,6 +10,10 @@ mutable struct HHHGradGreenCrossField{T,U} gamma::T op::U end +mutable struct HHHGradGreenDotField{T,U} + gamma::T + op::U +end mutable struct HHHBasisNtimesField{U} op::U @@ -92,6 +96,31 @@ function HHHGradGreenCrossField(; HHHGradGreenCrossField(gamma,HHHIdentityField()) end +function HHHGradGreenDotField(; + gamma=nothing, + wavenumber=nothing +) + + if (gamma === nothing) && (wavenumber === nothing) + error("Supply one of (not both) gamma or wavenumber") + end + + if (gamma !== nothing) && (wavenumber !== nothing) + error("Supply one of (not both) gamma or wavenumber") + end + + if gamma === nothing + if iszero(real(wavenumber)) + gamma = -imag(wavenumber) + else + gamma = im*wavenumber + end + end + + @assert gamma !== nothing + + HHHGradGreenDotField(gamma,HHHIdentityField()) +end const HHHField = Union{HHHGreenField,HHHGradGreenField,HHHGradGreenCrossField} defaultquadstrat(op::HHHField, basis) = SingleNumQStrat(2) @@ -125,8 +154,12 @@ integrand(op::HHHIdentityField, krn,y,fp,p) = fp.value integrand(op::HHHDivergenceField,krn,y,fp,p) = fp.divergence function integrand(op::HHHGradGreenField, krn, y, fp, p) - dot(integrand(op.op, krn,y,fp,p),krn.gradgreen) + integrand(op.op, krn,y,fp,p)*krn.gradgreen end + function integrand(op::HHHGradGreenCrossField, krn, y, fp, p) cross(krn.gradgreen,integrand(op.op, krn,y,fp,p)) end +function integrand(op::HHHGradGreenDotField, krn, y, fp, p) + dot(integrand(op.op, krn,y,fp,p),krn.gradgreen) +end \ No newline at end of file diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl index bfcc95cc..050d76c7 100644 --- a/src/Helmholtzhodge/hhhop.jl +++ b/src/Helmholtzhodge/hhhop.jl @@ -231,8 +231,8 @@ function (op::HHHgradgreenDot)(x,y,g) iR = 1/R green = op.α * exp(-op.γ*R)*(iR*i4pi) gradgreen = -(op.γ + iR) * green * (iR * r) - - dot(op.op(x,y,g),Ref(gradgreen)) + + dot.(op.op(x,y,g),Ref(gradgreen)) end function (op::HHHgradgreenCross)(x,y,g) @@ -368,8 +368,8 @@ function (op::HHHDivergenceLocal)(x,f,nt,nb) return f.divergence end -function cellinteractions(biop::HHHLocalOperator, trefs::U, brefs::V, cell,tcell,bcell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} - qr = qrtot +function cellinteractions(biop::HHHLocalOperator, trefs::U, brefs::V, cell,qr,tcell,bcell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} + num_tshs = length(qr[1][3]) num_bshs = length(qr[1][4]) diff --git a/src/bases/basis.jl b/src/bases/basis.jl index bb1d3052..fe715775 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -93,7 +93,7 @@ function Base.:+(x::AbstractSpace...) T = scalartype(x...) return DirectProductSpace{T, AbstractSpace}([x...]) end -cross(a::Nothing,b::Space) = b +cross(a::Nothing,b::Space{T}) where {T}= DirectProductSpace{T,Space{T}}(Space{T}[b]) cross(a::Space{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}(Space{T}[a,b]) cross(a::Space{T}, b::Nothing) where {T} = a cross(a::DirectProductSpace{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b]) diff --git a/src/localop.jl b/src/localop.jl index 79132393..4df37e2b 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -364,7 +364,7 @@ function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr,tcell=no return zlocal end -function cellinteractions(biop, trefs::U, brefs::V, cell,qr,tcell=nothing,bcell=nothing) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} +function cellinteractions(biop, trefs::U, brefs::V, cell,qr,tcell,bcell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} num_tshs = length(qr[1][3]) num_bshs = length(qr[1][4]) @@ -393,5 +393,32 @@ function cellinteractions(biop, trefs::U, brefs::V, cell,qr,tcell=nothing,bcell= return zlocal end +function cellinteractions(biop, trefs::U, brefs::V, cell,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} + + num_tshs = length(qr[1][3]) + num_bshs = length(qr[1][4]) + + zlocal = zeros(T, num_tshs, num_bshs) + + for q in qr + + w, mp, tvals, bvals = q[1], q[2], q[3], q[4] + j = w * jacobian(mp) + kernel = kernelvals(biop, mp) + + for m in 1 : num_tshs + tval = tvals[m] + + for n in 1 : num_bshs + bval = bvals[n] + + igd = integrand(biop, kernel, mp, tval, bval) + zlocal[m,n] += j * igd + end + end + end + + return zlocal +end diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index ca8918c6..29f13261 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -10,7 +10,7 @@ struct Interaction{A,B,C}# wordt gecrieerd bij de itteratie over alle volumes. trialvol::B embedvol::C end -abstract type PhysicalInformation end #depends on the strategy +# abstract type PhysicalInformation end #depends on the strategy """ subtypes of the NumericalStrategy type descirbe the followed strategy. for example a preconditioning strategy for a vector potential based problem, a vector potential based problem, a fields based problem,... @@ -19,23 +19,23 @@ abstract type NumericalStrategy end export NumericalStrategy mutable struct HomogeneousDomain <: DomainData -ϵ -μ -ω +physicalinformation testbasises trialbasises coeff testindex trialindex -HomogeneousDomain(a,b,c,d,e,f) = new(a,b,c,d,e,f,[],[]) +HomogeneousDomain(a,b,c,d) = new(a,b,c,d,[],[]) end struct BackgroundDomain <: DomainData - ϵ - μ - ω + physicalinformation coeff end +physicalconstants(d::DomainData) = d.physicalinformation +physicalconstants(d::Domain) = physicalconstants(d.data) +testspace(d::DomainData) = d.testbasises +trialspace(d::DomainData) = d.trialbasises mutable struct SubDomain{T} <: Domain{T} id::Int @@ -57,37 +57,29 @@ mutable struct Configuration #TODO add dict contining all subbasis info af touch root::RootDomain touching::Dict{Tuple{Int,Int},Vector} testdirectproductspace - testcounter - trialcounter - trialdirectproductspace - -end -function Configuration(dom,root,touching) -Configuration(dom,root,touching,nothing,0,0,nothing) + trialdirectproductspace end +Configuration(dom,root,touching) = Configuration(dom,root,touching,nothing,nothing) + function _adddomain(config::Configuration, newdom::Domain) id = newdom.id @assert !(id in keys(config.domains)) dom = newdom.parent config.domains[id] = newdom - for (i,space) in enumerate(newdom.data.testbasises) - config.testcounter += 1 - push!(newdom.data.testindex,config.testcounter) + for space in newdom.data.testbasises config.testdirectproductspace = config.testdirectproductspace × space + push!(newdom.data.testindex,length(config.testdirectproductspace.factors)) end for space in newdom.data.trialbasises - config.trialcounter += 1 - push!(newdom.data.trialindex,config.trialcounter) config.trialdirectproductspace = config.trialdirectproductspace × space + push!(newdom.data.trialindex,length(config.trialdirectproductspace.factors)) end push!(dom.children,newdom) end function _createdomain(config::Configuration,id::Int,parentid::Int,values;excitation) dom = SubDomain(id,Domain[],config.domains[parentid],values::DomainData,excitation,[]) - - # push!(config.domains[parentid].children,dom) return dom end function _createdomain(config::Configuration,id::Int,parentdom::Domain,values;excitation) @@ -96,7 +88,6 @@ end function createdomain(config::Configuration,id::Int,parent::Union{Int,Domain},values::DomainData;excitation=Dict()) _adddomain(config,_createdomain(config,id,parent,values;excitation)) - end """ a child of b @@ -161,42 +152,92 @@ end # end #function convert_inside_to_outside_basis(Ωchild,Ωparent,strat) end - -function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) +function interaction_matrix(config::Configuration,id,strat::NumericalStrategy) @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) N = length(config.testdirectproductspace.factors) OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) - for (id,Ω) in config.domains - c = Ω.data.coeff - if id != 0 - inter = Interaction(config,Ω,Ω,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*inter(strat) - for child in Ω.children - inter = Interaction(config,Ω,child,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += c*inter(strat)*convert_inside_to_outside_basis(child,Ω,strat) - inter = Interaction(config,child,Ω,Ω) - OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*convert_inside_to_outside_basis(child,Ω,strat)*inter(strat) - end - + indexen = [] + Ω = config.domains[id] + if id != 0 + indexen = [indexen; Ω.data.testindex] + inter = Interaction(config,Ω,Ω,Ω) + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) + for child in Ω.children + inter = Interaction(config,Ω,child,Ω) + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat) + inter = Interaction(config,child,Ω,Ω) + OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) end - for Ω1 in Ω.children - - inter = Interaction(config,Ω1,Ω1,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += c*convert_inside_to_outside_basis(Ω1,Ω,strat)*inter(strat)*convert_inside_to_outside_basis(Ω1,Ω,strat) - for Ω2 in Ω.children - if Ω1!==Ω2 - inter = Interaction(config,Ω1,Ω2,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += c*convert_inside_to_outside_basis(Ω1,Ω,strat)*inter(strat)*convert_inside_to_outside_basis(Ω2,Ω,strat) - end + end + for Ω1 in Ω.children + indexen = [indexen; Ω1.data.testindex] + inter = Interaction(config,Ω1,Ω1,Ω) + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += inter(strat) + + for Ω2 in Ω.children + if Ω1!==Ω2 + inter = Interaction(config,Ω1,Ω2,Ω) + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter(strat) end end + end + + id = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) + for i in 1:N + i∈indexen && (id[i,i] = Identity()) end + pretty_table(id-OperatorMatrix, noheader=true, backend=Val(:latex)) + return assemble(dot(config.testdirectproductspace,id-OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) +end - pretty_table(OperatorMatrix, noheader=true, backend=Val(:latex)) - return assemble(dot(config.testdirectproductspace,OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) +# function generate_problem_lhs(config::Configuration,strat::NumericalStrategy)#Make more correct by assambling for eacht domain an add with coeffeicient, add idetity at that place +# @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) +# N = length(config.testdirectproductspace.factors) +# OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) +# for (id,Ω) in config.domains +# c = Ω.data.coeff +# if id != 0 +# inter = Interaction(config,Ω,Ω,Ω) +# OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) +# for child in Ω.children +# inter = Interaction(config,Ω,child,Ω) +# OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += c*inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat) +# inter = Interaction(config,child,Ω,Ω) +# OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) +# end + +# end +# for Ω1 in Ω.children + +# inter = Interaction(config,Ω1,Ω1,Ω) +# OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += c*inter(strat) + +# for Ω2 in Ω.children +# if Ω1!==Ω2 +# inter = Interaction(config,Ω1,Ω2,Ω) +# OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += c*inter(strat) +# end +# end +# end + +# end +# id = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) +# for i in 1:N +# id[i,i] = 2*Identity() +# end +# pretty_table(id-OperatorMatrix, noheader=true, backend=Val(:latex)) +# return assemble(dot(config.testdirectproductspace,id-OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) +# end +function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) + out = interaction_matrix(config,0,strat) + for (id,Ω) in config.domains + id==0 && continue + out += interaction_matrix(config,id,strat) + end + return out end function generate_problem_rhs(config::Configuration) @@ -215,14 +256,17 @@ function generate_problem_rhs(config::Configuration) return assemble(LinForm([],linterms),config.testdirectproductspace) end -function map_solution_to_volumes(solution,config) -for (id,dom) in config.domains - id == 0 && continue - for i in dom.data.trialindex - config.trial_direct_productspace.factors[i] +function map_solution_to_volumes!(config,solution) + for (id,dom) in config.domains + id==0 && continue + out = [] + for i in dom.data.trialindex + push!(out,solution[Block(i)]) + end + dom.results = out end end -end + diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 1fd5d635..50a2c936 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -80,11 +80,13 @@ normalorient(op::ZeroOperator,a,b) = op ###### Interactions struct VectorStrat <: BEAST.NumericalStrategy end -function convert_inside_to_outside_basis(child,parent,::VectorStrat) +function convert_outside_to_inside_basis(child,parent,::VectorStrat) + p = physicalconstants(parent.data) + c = physicalconstants(child.data) a = [-1 0 0 0 0 1 0 0 - 0 0 -parent.data.μ/child.data.μ 0 - 0 0 0 -child.data.ϵ/parent.data.ϵ] + 0 0 -c.μ/p.μ 0 + 0 0 0 -p.ϵ/c.ϵ] return a end @@ -93,7 +95,8 @@ end function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: RootDomain})(::VectorStrat) - k = sqrt(int.embedvol.data.ϵ*int.embedvol.data.μ)*int.embedvol.data.ω + p = physicalconstants(int.embedvol.data) + k = sqrt(p.ϵ*p.μ)*p.ω green = HHH.green(wavenumber=k) gradgreen = HHH.gradgreen(wavenumber=k) b = basisfunction() @@ -106,7 +109,7 @@ function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDom ZeroOperator() Identity() ZeroOperator() ZeroOperator() ZeroOperator() ZeroOperator() Identity() ZeroOperator() ZeroOperator() ZeroOperator() ZeroOperator() Identity()] - a = id - a + #a = id - a if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) println("cauchy limit taken") @@ -118,7 +121,8 @@ function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDom end function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: SubDomain})(::VectorStrat) - k = sqrt(int.embedvol.data.ϵ*int.embedvol.data.μ)*int.embedvol.data.ω #foute lijn, puur voor test!!! + p = physicalconstants(int.embedvol.data) + k = sqrt(p.ϵ*p.μ)*p.ω green = HHH.green(wavenumber=k) gradgreen = HHH.gradgreen(wavenumber=k) b = basisfunction() @@ -131,7 +135,7 @@ function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDom ZeroOperator() Identity() ZeroOperator() ZeroOperator() ZeroOperator() ZeroOperator() Identity() ZeroOperator() ZeroOperator() ZeroOperator() ZeroOperator() Identity()] - a = id - a + #a = id - a if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) println("cauchy limit taken") diff --git a/src/multi-trace/postprocessing.jl b/src/multi-trace/postprocessing.jl new file mode 100644 index 00000000..317734ab --- /dev/null +++ b/src/multi-trace/postprocessing.jl @@ -0,0 +1,118 @@ +import Base.Threads: @spawn +function nearfield_A(dom::Domain{HomogeneousDomain},pts,strat::VectorStrat) + p = physicalconstants(dom) + parent_const = physicalconstants(dom.parent) + k = sqrt(p.ϵ*p.μ)*p.ω + + nxb_out1,σ_out1,a_out1,γ_out1 = dom.results + nxb1,σ1,a1,γ1 = dom.data.trialbasises + + vector_potential = p.μ/parent_const.μ* potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out1,a1) .- + potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out1,nxb1) .- + parent_const.ϵ/p.ϵ*potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out1,γ1) .-#compensatie omdat normal naar buiten wijst + potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out1,σ1); + + for Ω in dom.children + nxb_out,σ_out,a_out,γ_out = Ω.results + nxb,σ,a,γ = Ω.data.trialbasises + vector_potential = vector_potential .+ -1*potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out,a) .+ + potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out,nxb) .+ + potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out,γ) .+#compensatie omdat normal naar buiten wijst + potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); + end + return vector_potential +end +function nearfield_A(dom::Domain{BackgroundDomain},pts,strat::VectorStrat) + p = physicalconstants(dom) + k = sqrt(p.ϵ*p.μ)*p.ω + vector_potential = zeros(SVector{3,Complex},size(pts)) + for Ω in dom.children + nxb_out,σ_out,a_out,γ_out = Ω.results + nxb,σ,a,γ = Ω.data.trialbasises + vector_potential = vector_potential + -1*potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out,a) + + potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out,nxb) + + potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out,γ) +#compensatie omdat normal naar buiten wijst + potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); + end + return vector_potential +end +function nearfield_A(config::Configuration,points,strat::VectorStrat) + tasks = [] + for (id,dom) in config.domains + push!(tasks,@spawn nearfield_A(dom,points,strat)) + end + fields = fetch.(tasks) + out = zeros(SVector{3,Complex},size(points)) + for field in fields + out = out .+ field + end + return out +end +function nearfield_B(dom::Domain{HomogeneousDomain},pts,strat::VectorStrat) + p = physicalconstants(dom) + parent_const = physicalconstants(dom.parent) + k = sqrt(p.ϵ*p.μ)*p.ω + + nxb_out1,σ_out1,a_out1,γ_out1 = dom.results + nxb1,σ1,a1,γ1 = dom.data.trialbasises + + BField = p.μ/parent_const.μ* potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out1,a1) .- + (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out1,nxb1)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out1,nxb1)) .- + potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out1,σ1); + + for Ω in dom.children + nxb_out,σ_out,a_out,γ_out = Ω.results + nxb,σ,a,γ = Ω.data.trialbasises + BField = BField .+ -1*potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out,a) .+ + (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out,nxb)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out,nxb)) .+ + potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); + end + return BField +end + +function nearfield_H(dom::Domain{HomogeneousDomain},points,strat::VectorStrat) + nearfield_B(dom,points,strat)./physicalconstants(dom).μ +end + + +function nearfield_B(dom::Domain{BackgroundDomain},pts,strat::VectorStrat) + p = physicalconstants(dom) + k = sqrt(p.ϵ*p.μ)*p.ω + BField = zeros(SVector{3,Complex},size(pts)) + for Ω in dom.children + nxb_out,σ_out,a_out,γ_out = Ω.results + nxb,σ,a,γ = Ω.data.trialbasises + BField = BField + -1*potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out,a) + + (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out,nxb)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out,nxb)) + + potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ) + end + return BField +end +function nearfield_B(config::Configuration,points,strat::VectorStrat) + tasks = [] + for (id,dom) in config.domains + push!(tasks,@spawn nearfield_B(dom,points,strat)) + end + fields = fetch.(tasks) + out = zeros(SVector{3,Complex},size(points)) + for field in fields + out = out .+ field + end + return out +end +function nearfield_H(dom::Domain{BackgroundDomain},points,strat::VectorStrat) + nearfield_B(dom,points,strat)./physicalconstants(dom).μ +end + +function nearfield_H(config::Configuration,points,strat::VectorStrat) + tasks = [] + for (id,dom) in config.domains + push!(tasks,nearfield_H(dom,points,strat)) + end + #fields = fetch.(tasks) + out = zeros(SVector{3,Complex},size(points)) + for field in tasks + out = out .+ field + end + return out +end \ No newline at end of file From 6634a50f929171375d04645e748e6c2d55ead511 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 20 Oct 2023 11:35:38 +0200 Subject: [PATCH 037/110] introducing new type of notation for composed operator --- src/composedoperator/composeoperator.jl | 67 +++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/composedoperator/composeoperator.jl diff --git a/src/composedoperator/composeoperator.jl b/src/composedoperator/composeoperator.jl new file mode 100644 index 00000000..a58f5d12 --- /dev/null +++ b/src/composedoperator/composeoperator.jl @@ -0,0 +1,67 @@ +import Base: * +import BEAST +abstract type ComposedOperatorLocal <: BEAST.LocalOperator end +abstract type ComposedOperatorIntegral <: BEAST.IntegralOperator end + + +struct TestNormalLocal{T,O} <: ComposedOperatorLocal +inner::T +operation::O +end + + +struct TrialNormalLocal{T,O} <: ComposedOperatorLocal +inner::T +operation::O +end + +struct TestNormalIntegral{T,O} <: ComposedOperatorIntegral + inner::T + operation::O +end +TestNormalLocal(inner::ComposedOperatorIntegral,op) = TestNormalIntegral(inner,op) + +struct TrialNormalIntegral{T,O} <: ComposedOperatorIntegral + inner::T + operation::O +end +TrialNormalLocal(inner::ComposedOperatorIntegral,op) = TrialNormalIntegral(inner,op) + +const nt = TestNormalLocal +const nb = TrialNormalLocal + +abstract type Kern end + + +struct Kernel{T,O,P <: Kern} <: ComposedOperatorInegral + inner::T + operation::O + Kern::P +end + +function (k::Kern)(operation) +return x -> Kernel(x,operation,k) +end + + +function (a::Type{<: ComposedOperatorLocal})(operation) +return x->a(x,operation) +end + + + +struct HH3DGreen{T} <: Kern + gamma::T +end +struct HH3DGradGreen{T} <: Kern + gamma::T +end +∇(G::HH3DGreen) = HH3DGradGreen(G.wavenumber) +function (G::Kernel{T,O,HH3DGreen{Q}})(testnb,trialnb) where {T,O,Q} + green = + return G.operation.(G.inner(testnb,trialnb),Ref(green)) +end +function (G::Kernel{T,O,HH3DGradGreen{Q}})(testnb,trialnb) where {T,O,Q} + gradgreen = + return G.operation.(G.inner(testnb,trialnb),Ref(gradgreen)) +end \ No newline at end of file From e7bdce6e1d253a3061fc066c97701427c3690d28 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 20 Oct 2023 11:44:34 +0200 Subject: [PATCH 038/110] changed cellinteractions --- src/localop.jl | 101 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 69 insertions(+), 32 deletions(-) diff --git a/src/localop.jl b/src/localop.jl index 4df37e2b..6ce60e66 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -364,34 +364,52 @@ function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr,tcell=no return zlocal end -function cellinteractions(biop, trefs::U, brefs::V, cell,qr,tcell,bcell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} - +function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr) + num_tshs = length(qr[1][3]) num_bshs = length(qr[1][4]) - zlocal = zeros(T, num_tshs, num_bshs) - + # zlocal = zeros(Float64, num_tshs, num_bshs) for q in qr - w, mp, tvals, bvals = q[1], q[2], q[3], q[4] - j = w * jacobian(mp) - kernel = kernelvals(biop, mp) + w, (tp,bp), tvals, bvals = q[1], q[2], q[3], q[4] + j = w * jacobian(tp) + kernel = kernelvals(biop, tp, bp) + + zlocal += j * integrand(biop, kernel, tp, bp, tvals, bvals) + end + + return zlocal +end - for m in 1 : num_tshs - tval = tvals[m] +# function cellinteractions(biop, trefs::U, brefs::V, cell,qr,tcell,bcell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} + +# num_tshs = length(qr[1][3]) +# num_bshs = length(qr[1][4]) - for n in 1 : num_bshs - bval = bvals[n] +# zlocal = zeros(T, num_tshs, num_bshs) + +# for q in qr - igd = integrand(biop, kernel, mp, tval, bval) - zlocal[m,n] += j * igd +# w, mp, tvals, bvals = q[1], q[2], q[3], q[4] +# j = w * jacobian(mp) +# kernel = kernelvals(biop, mp) - end - end - end +# for m in 1 : num_tshs +# tval = tvals[m] - return zlocal -end +# for n in 1 : num_bshs +# bval = bvals[n] + +# igd = integrand(biop, kernel, mp, tval, bval) +# zlocal[m,n] += j * igd + +# end +# end +# end + +# return zlocal +# end function cellinteractions(biop, trefs::U, brefs::V, cell,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} @@ -402,23 +420,42 @@ function cellinteractions(biop, trefs::U, brefs::V, cell,qr) where {U<:RefSpace{ for q in qr - w, mp, tvals, bvals = q[1], q[2], q[3], q[4] - j = w * jacobian(mp) - kernel = kernelvals(biop, mp) - - for m in 1 : num_tshs - tval = tvals[m] + w, (tp,bp), tvals, bvals = q[1], q[2], q[3], q[4] + j = w * jacobian(tp) + kernel = kernelvals(biop, tp,bp) - for n in 1 : num_bshs - bval = bvals[n] - - igd = integrand(biop, kernel, mp, tval, bval) - zlocal[m,n] += j * igd - - end - end + zlocal += j * integrand(biop, kernel, tp, bp, tvals, bvals) end return zlocal end +# function cellinteractions(biop, trefs::U, brefs::V, cell,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} + +# num_tshs = length(qr[1][3]) +# num_bshs = length(qr[1][4]) + +# zlocal = zeros(T, num_tshs, num_bshs) + +# for q in qr + +# w, mp, tvals, bvals = q[1], q[2], q[3], q[4] +# j = w * jacobian(mp) +# kernel = kernelvals(biop, mp) + +# for m in 1 : num_tshs +# tval = tvals[m] + +# for n in 1 : num_bshs +# bval = bvals[n] + +# igd = integrand(biop, kernel, mp, tval, bval) +# zlocal[m,n] += j * igd + +# end +# end +# end + +# return zlocal +# end + From 58a5e765f8ce2a6bd219d466719af17e2c1cfb95 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 20 Oct 2023 15:14:21 +0200 Subject: [PATCH 039/110] posible to build operator changed localoperator routines to be comparable to integral operator routines --- src/BEAST.jl | 2 + src/composedoperator/composeoperator.jl | 83 ++++++++++++++++++++++--- src/identityop.jl | 4 +- src/localop.jl | 66 ++++++++++---------- src/utils/geometrie.jl | 30 +++++++++ 5 files changed, 144 insertions(+), 41 deletions(-) create mode 100644 src/utils/geometrie.jl diff --git a/src/BEAST.jl b/src/BEAST.jl index 44b6b899..a2468326 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -141,6 +141,7 @@ include("utils/combinatorics.jl") include("utils/linearspace.jl") include("utils/zeromap.jl") include("utils/rank1map.jl") +include("utils/geometrie.jl") include("bases/basis.jl") include("bases/lincomb.jl") @@ -270,6 +271,7 @@ include("multi-trace/interactions.jl") include("multi-trace/postprocessing.jl") #suport for displaying operators +include("composedoperator/composeoperator.jl") include("display.jl") const x̂ = point(1,0,0) diff --git a/src/composedoperator/composeoperator.jl b/src/composedoperator/composeoperator.jl index a58f5d12..2afb2106 100644 --- a/src/composedoperator/composeoperator.jl +++ b/src/composedoperator/composeoperator.jl @@ -1,9 +1,41 @@ import Base: * +import LinearAlgebra: ×, ⋅ import BEAST -abstract type ComposedOperatorLocal <: BEAST.LocalOperator end -abstract type ComposedOperatorIntegral <: BEAST.IntegralOperator end +abstract type ComposedOperatorLocal <: LocalOperator end +abstract type ComposedOperatorIntegral <: IntegralOperator end + +struct BasisFunction end +struct DivBasisFunction end + +struct TestFunctionLocal{T} <: ComposedOperatorLocal + inner::T +end +struct TestFunctionIntegral{T} <: ComposedOperatorIntegral + inner::T +end +TestFunctionLocal(inner::ComposedOperatorIntegral) = TestFunctionIntegral(inner) + +struct DivTestFunctionLocal{T} <: ComposedOperatorLocal + inner::T +end +struct DivTestFunctionIntegral{T} <: ComposedOperatorIntegral + inner::T +end + +struct CurlBasisFunction end + +const b = BasisFunction() +const t = TestFunctionLocal +export t +export b + +×(::Nabla,::BasisFunction) = CurlBasisFunction() +⋅(::Nabla,::BasisFunction) = DivBasisFunction() +⋅(::Nabla,::Type{TestFunctionLocal}) = DivTestFunctionLocal +⋅(::Nabla,::Type{TestFunctionIntegral}) = DivTestFunctionIntegral + struct TestNormalLocal{T,O} <: ComposedOperatorLocal inner::T operation::O @@ -33,7 +65,7 @@ const nb = TrialNormalLocal abstract type Kern end -struct Kernel{T,O,P <: Kern} <: ComposedOperatorInegral +struct Kernel{T,O,P <: Kern} <: ComposedOperatorIntegral inner::T operation::O Kern::P @@ -56,12 +88,49 @@ end struct HH3DGradGreen{T} <: Kern gamma::T end -∇(G::HH3DGreen) = HH3DGradGreen(G.wavenumber) +function (::Nabla)(G::HH3DGreen) + HH3DGradGreen(G.wavenumber) +end function (G::Kernel{T,O,HH3DGreen{Q}})(testnb,trialnb) where {T,O,Q} green = - return G.operation.(G.inner(testnb,trialnb),Ref(green)) + return G.operation.(Ref(green),G.inner(testnb,trialnb)) end function (G::Kernel{T,O,HH3DGradGreen{Q}})(testnb,trialnb) where {T,O,Q} gradgreen = - return G.operation.(G.inner(testnb,trialnb),Ref(gradgreen)) -end \ No newline at end of file + return G.operation.(Ref(gradgreen),G.inner(testnb,trialnb)) +end + +function (igd::Integrand{<:ComposedOperatorIntegral})(x,y,f,g) +op = igd.operator +op(x,y,f,g) +end + +function (op::Union{TestFunctionIntegral,TestFunctionLocal})(x,y,f,g) + _krondot(getvalue(f),op(x,y,g)) +end +function (op::Union{DivTestFunctionIntegral,DivTestFunctionLocal})(x,y,f,g) + _krondot(getdivergence(f),op(x,y,g)) +end + +function integrand(op::ComposedOperatorLocal,kernel,x,y,f,g) + op(x,y,f,g) +end + +function (op::Union{TestNormalIntegral,TestNormalLocal})(x,y,g) + op.operation(normal(x),op.inner(x,y,g)) +end + +function (op::Union{TrialNormalIntegral,TrialNormalLocal})(x,y,g) + op.operation(normal(y),op.inner(x,y,g)) +end + +function (op::BasisFunction)(x,y,g) + getvalue(g) +end +function (op::DivBasisFunction)(x,y,g) + getdivergence(g) +end +function (op::CurlBasisFunction)(x,y,g) + getcurl(g) +end + diff --git a/src/identityop.jl b/src/identityop.jl index 8a48c6c1..be72b2c7 100644 --- a/src/identityop.jl +++ b/src/identityop.jl @@ -2,14 +2,14 @@ struct Identity <: LocalOperator end kernelvals(biop::Identity, x) = nothing -integrand(op::Identity, kernel, x, g, f) = dot(f[1], g[1]) +integrand(op::Identity, kernel, x,y, g, f) = dot.(getvalue(f), getvalue(g)) scalartype(op::Identity) = Union{} struct NCross <: LocalOperator end kernelvals(op::NCross, mp) = nothing -integrand(op::NCross, kernel, x, g, f) = dot(g[1], normal(x) × f[1]) +integrand(op::NCross, kernel, x,y, g, f) = dot.(getvalue(g), Ref(normal(x)) .× getvalue(f)) scalartype(op::NCross) = Union{} function _alloc_workspace(qd, g, f, tels, bels) diff --git a/src/localop.jl b/src/localop.jl index 6ce60e66..7f14abf7 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -134,7 +134,7 @@ function assemble_local_matched!(biop::LocalOperator, tfs::Space, bfs::Space, st qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) fill!(locmat, 0) - cellinteractions_matched!(locmat, biop, trefs, brefs, cell, qr, cell,cell) + cellinteractions_matched!(locmat, biop, trefs, brefs, cell, 1, qr) for i in 1 : size(locmat, 1), j in 1 : size(locmat, 2) for (m,a) in tad[p,i], (n,b) in bad[q,j] @@ -178,7 +178,7 @@ function assemble_local_refines!(biop::LocalOperator, tfs::Space, bfs::Space, st bcell = bels[q] @assert overlap(tcell, bcell) - + s = sign(dot(normal(tcell),normal(bcell))) isct = intersection(tcell, bcell) for cell in isct @@ -186,7 +186,7 @@ function assemble_local_refines!(biop::LocalOperator, tfs::Space, bfs::Space, st Q = restrict(trefs, tcell, cell) qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) - zlocal = cellinteractions(biop, trefs, brefs, cell, qr,tcell,bcell) + zlocal = cellinteractions(biop, trefs, brefs, cell, s, qr) zlocal = Q * zlocal * P' for i in 1 : numfunctions(trefs) @@ -226,7 +226,7 @@ function assemble_local_matched!(biop::LocalOperator, tfs::subdBasis, bfs::subdB for (p,cell) in enumerate(tels) qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) - locmat = cellinteractions(biop, trefs, brefs, cell, qr, tcell,bcell) + locmat = cellinteractions(biop, trefs, brefs, cell,1, qr) for i in 1 : size(locmat, 1), j in 1 : size(locmat, 2) for (m,a) in tad[p][i], (n,b) in bad[p][j] @@ -298,7 +298,7 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} bcell = bels[q] if overlap(tcell, bcell) - + s = sign(dot(normal(tcell),normal(bcell))) isct = intersection(tcell, bcell) for cell in isct @@ -308,7 +308,7 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} Q = restrict(trefs, tcell, cell) qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) - zlocal = cellinteractions(biop, trefs, brefs, cell, qr,tcell,bcell) + zlocal = cellinteractions(biop, trefs, brefs, cell, s, qr) zlocal = Q * zlocal * P' for i in 1 : numfunctions(trefs) @@ -338,33 +338,33 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} end -function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr,tcell=nothing,bcell=nothing) +# function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr,tcell=nothing,bcell=nothing) - num_tshs = length(qr[1][3]) - num_bshs = length(qr[1][4]) +# num_tshs = length(qr[1][3]) +# num_bshs = length(qr[1][4]) - # zlocal = zeros(Float64, num_tshs, num_bshs) - for q in qr +# # zlocal = zeros(Float64, num_tshs, num_bshs) +# for q in qr - w, mp, tvals, bvals = q[1], q[2], q[3], q[4] - j = w * jacobian(mp) - kernel = kernelvals(biop, mp) +# w, mp, tvals, bvals = q[1], q[2], q[3], q[4] +# j = w * jacobian(mp) +# kernel = kernelvals(biop, mp) - for n in 1 : num_bshs - bval = bvals[n] - for m in 1 : num_tshs - tval = tvals[m] - - igd = integrand(biop, kernel, mp, tval, bval) - zlocal[m,n] += j * igd - end - end - end +# for n in 1 : num_bshs +# bval = bvals[n] +# for m in 1 : num_tshs +# tval = tvals[m] - return zlocal -end +# igd = integrand(biop, kernel, mp, tval, bval) +# zlocal[m,n] += j * igd +# end +# end +# end + +# return zlocal +# end -function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr) +function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell,sign, qr) num_tshs = length(qr[1][3]) num_bshs = length(qr[1][4]) @@ -372,9 +372,10 @@ function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr) # zlocal = zeros(Float64, num_tshs, num_bshs) for q in qr - w, (tp,bp), tvals, bvals = q[1], q[2], q[3], q[4] + w, tp, tvals, bvals = q[1], q[2], q[3], q[4] + bp = map(tp,sign) j = w * jacobian(tp) - kernel = kernelvals(biop, tp, bp) + kernel = kernelvals(biop, tp) zlocal += j * integrand(biop, kernel, tp, bp, tvals, bvals) end @@ -411,7 +412,7 @@ end # return zlocal # end -function cellinteractions(biop, trefs::U, brefs::V, cell,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} +function cellinteractions(biop, trefs::U, brefs::V, cell, sign,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} num_tshs = length(qr[1][3]) num_bshs = length(qr[1][4]) @@ -420,9 +421,10 @@ function cellinteractions(biop, trefs::U, brefs::V, cell,qr) where {U<:RefSpace{ for q in qr - w, (tp,bp), tvals, bvals = q[1], q[2], q[3], q[4] + w, tp, tvals, bvals = q[1], q[2], q[3], q[4] + bp = map(tp,sign) j = w * jacobian(tp) - kernel = kernelvals(biop, tp,bp) + kernel = kernelvals(biop, tp) zlocal += j * integrand(biop, kernel, tp, bp, tvals, bvals) end diff --git a/src/utils/geometrie.jl b/src/utils/geometrie.jl new file mode 100644 index 00000000..cdce09f5 --- /dev/null +++ b/src/utils/geometrie.jl @@ -0,0 +1,30 @@ +import Base.- +struct MinusMeshPointNM{T} + meshpoint::T +end +# struct MinusSimplex{T} +# simplex::T +# end + +normal(a::MinusMeshPointNM) = -normal(a.meshpoint) +# normal(a::MinusSimplex) = -normal(a.MinusSimplex) + +function map(b::Union{CompScienceMeshes.MeshPointNM,MinusMeshPointNM},sign::Int) + sign==-1 && (return -b) + sign == 1 && (return b) + @error "sign was not 1 or -1" +end + +-(b::CompScienceMeshes.MeshPointNM) = MinusMeshPointNM(b) +-(b::MinusMeshPointNM) = b.meshpoint +# -(b::Simplex) = MinusSimple(b) +# -(b::MinusSimplex) = b.simplex + +Base.length(m::MinusMeshPointNM) = length(m.meshpoint) +Base.getindex(p::MinusMeshPointNM, i::Int) = p.meshpoint[i] +cartesian(m::MinusMeshPointNM) = cartesian(m.meshpoint) +parametric(m::MinusMeshPointNM) = parametric(m.meshpoint) +chart(m::MinusMeshPointNM) = chart(m.meshpoint) +barycentric(mp::MinusMeshPointNM) = barycentric(mp.meshpoint) +jacobian(mp::MinusMeshPointNM) = jacobian(mp.meshpoint) +tangents(mp::MinusMeshPointNM,i) = tangents(mp.meshpoint,i) From 5aeaeff59ec74a9ed08c414c3c30a491e925d372 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 24 Oct 2023 11:34:09 +0200 Subject: [PATCH 040/110] update composed operator starts to be mathematical correct --- src/BEAST.jl | 4 +- src/composedoperator/composed2.jl | 300 ++++++++++++++++++++++++ src/composedoperator/composeoperator.jl | 110 +++++++-- src/multi-trace/interactions.jl | 121 ++++++---- 4 files changed, 478 insertions(+), 57 deletions(-) create mode 100644 src/composedoperator/composed2.jl diff --git a/src/BEAST.jl b/src/BEAST.jl index a2468326..a7df8176 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -260,7 +260,7 @@ include("solvers/itsolver.jl") include("utils/plotlyglue.jl") #suport for helmholtzhodge equation -include("Helmholtzhodge/hhhop.jl") +#include("Helmholtzhodge/hhhop.jl") include("Helmholtzhodge/helmholtzhodge.jl") include("Helmholtzhodge/hhhexc.jl") include("Helmholtzhodge/hhhnearfield.jl") @@ -271,7 +271,7 @@ include("multi-trace/interactions.jl") include("multi-trace/postprocessing.jl") #suport for displaying operators -include("composedoperator/composeoperator.jl") +include("composedoperator/composed2.jl") include("display.jl") const x̂ = point(1,0,0) diff --git a/src/composedoperator/composed2.jl b/src/composedoperator/composed2.jl new file mode 100644 index 00000000..27a13044 --- /dev/null +++ b/src/composedoperator/composed2.jl @@ -0,0 +1,300 @@ +import Base: * +import LinearAlgebra: ×, ⋅ + + + + +#const i4pi = 1 / (4pi) +abstract type ComposedOperatorLocal <: LocalOperator end +abstract type ComposedOperatorIntegral <: IntegralOperator end +abstract type Kernel <: ComposedOperatorIntegral end +ComposedOperator = Union{ComposedOperatorIntegral,ComposedOperatorLocal} + +struct BasisFunction <: ComposedOperatorLocal end +struct DivBasisFunction <: ComposedOperatorLocal end +const B = BasisFunction +export B + +struct TimesLocal{U,V} <: ComposedOperatorLocal + lhs::U + rhs::V +end + +struct DotLocal{U,V} <: ComposedOperatorLocal + lhs::U + rhs::V +end + +struct CrossLocal{U,V} <: ComposedOperatorLocal + lhs::U + rhs::V +end + +struct TimesIntegral{U,V} <: ComposedOperatorIntegral + lhs::U + rhs::V +end + +struct DotIntegral{U,V} <: ComposedOperatorIntegral + lhs::U + rhs::V +end + +struct CrossIntegral{U,V} <: ComposedOperatorIntegral + lhs::U + rhs::V +end + +function TimesLocal(lhs::LinearCombinationOfOperators,rhs::Union{ComposedOperator,LinearCombinationOfOperators}) + out = ZeroOperator() + for (op,coeff) in zip(lhs.ops,lhs.coeffs) + out += coeff*TimesLocal(op,rhs) + end + return out +end + +function TimesLocal(lhs::ComposedOperator,rhs::LinearCombinationOfOperators) + out = ZeroOperator() + for (op,coeff) in zip(rhs.ops,rhs.coeffs) + out += coeff*TimesLocal(lhs,op) + end + return out +end + +function DotLocal(lhs::LinearCombinationOfOperators,rhs::Union{ComposedOperator,LinearCombinationOfOperators}) + out = ZeroOperator() + for (op,coeff) in zip(lhs.ops,lhs.coeffs) + out += coeff*DotLocal(op,rhs) + end + return out +end + +function DotLocal(lhs::ComposedOperator,rhs::LinearCombinationOfOperators) + out = ZeroOperator() + for (op,coeff) in zip(rhs.ops,rhs.coeffs) + out += coeff*DotLocal(lhs,op) + end + return out +end + +function CrossLocal(lhs::LinearCombinationOfOperators,rhs::Union{ComposedOperator,LinearCombinationOfOperators}) + out = ZeroOperator() + for (op,coeff) in zip(lhs.ops,lhs.coeffs) + out += coeff*CrossLocal(op,rhs) + end + return out +end + +function CrossLocal(lhs::ComposedOperator,rhs::LinearCombinationOfOperators) + out = ZeroOperator() + for (op,coeff) in zip(rhs.ops,rhs.coeffs) + out += coeff*CrossLocal(lhs,op) + end + return out +end +get_constructor(::TimesLocal) = TimesLocal +get_constructor(::TimesIntegral) = TimesLocal +get_constructor(::DotLocal) = DotLocal +get_constructor(::DotIntegral) = DotLocal +get_constructor(::CrossLocal) = CrossLocal +get_constructor(::CrossIntegral) = CrossLocal + +OperationsLocal = Union{TimesLocal,DotLocal,CrossLocal} +OperationsIntegral = Union{TimesIntegral,DotIntegral,CrossIntegral} +Operations = Union{OperationsIntegral,OperationsLocal} + +TimesLocal(a::ComposedOperatorIntegral,b::ComposedOperatorLocal) = TimesIntegral(a,b) +TimesLocal(a::ComposedOperatorLocal,b::ComposedOperatorIntegral) = TimesIntegral(a,b) +TimesLocal(a::ComposedOperatorIntegral,b::ComposedOperatorIntegral) = TimesIntegral(a,b) + +DotLocal(a::ComposedOperatorIntegral,b::ComposedOperatorLocal) = DotIntegral(a,b) +DotLocal(a::ComposedOperatorLocal,b::ComposedOperatorIntegral) = DotIntegral(a,b) +DotLocal(a::ComposedOperatorIntegral,b::ComposedOperatorIntegral) = DotIntegral(a,b) + +CrossLocal(a::ComposedOperatorIntegral,b::ComposedOperatorLocal) = CrossIntegral(a,b) +CrossLocal(a::ComposedOperatorLocal,b::ComposedOperatorIntegral) = CrossIntegral(a,b) +CrossLocal(a::ComposedOperatorIntegral,b::ComposedOperatorIntegral) = CrossIntegral(a,b) + +×(a::ComposedOperator,b::ComposedOperator) = CrossLocal(a,b) +⋅(a::ComposedOperator,b::ComposedOperator) = DotLocal(a,b) +*(a::ComposedOperator,b::ComposedOperator) = TimesLocal(a,b) + +div(::BasisFunction) = DivBasisFunction() + +scalartype(op::Operations) = promote_type(scalartype(op.lhs),scalartype(op.rhs)) + +struct TestNormal <: ComposedOperatorLocal end +struct TrialNormal <: ComposedOperatorLocal end +scalartype(op::Union{TestNormal,TrialNormal,BasisFunction}) = Float64 + + +const nt = TestNormal() + +struct Potential{T} <: Operator + operator::T + surface +end + +function count_test_normals(op::Operations) + count_test_normals(op.lhs) + count_test_normals(op.rhs) +end +count_test_normals(op::Kern) = 0 +count_test_normals(op::TestNormal) = 1 +count_test_normals(op::TrialNormal) = 0 + +function count_trial_normals(op::Operations) + count_trial_normals(op.lhs) + count_trial_normals(op.rhs) +end +count_trial_normals(op::Kern) = 0 +count_trial_normals(op::TestNormal) = 0 +count_trial_normals(op::TrialNormal) = 1 + +function replace_normal_by_testnormal(op::Operations) + get_constructor(op)(replace_normal_by_testnormal(op.lhs),replace_normal_by_testnormal(op.rhs)) +end +replace_normal_by_testnormal(op::Kern) = op +replace_normal_by_testnormal(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction}) = op +replace_normal_by_testnormal(op::NormalVector) = TestNormal() + +function replace_normal_by_trialnormal(op::Operations) + get_constructor(op)(replace_normal_by_trialnormal(op.lhs),replace_normal_by_trialnormal(op.rhs)) +end +replace_normal_by_trialnormal(op::Kern) = op +replace_normal_by_trialnormal(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction}) = op +replace_normal_by_trialnormal(op::NormalVector) = TrialNormal() + + + +function build_potential(op::ComposedOperator,surface::CompScienceMeshes.Mesh) + newop = replace_normal_by_trialnormal(op) + Potential(newop,surface) +end + +function γ(op::Operations,sign) + + return get_constructor(op)(γ(op.lhs,sign),γ(op.rhs,sign)) +end +γ(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction},sign) = op +function check_if_coincide(a,b) + @warn "all meshes coincide" + return true +end + +function γ(op::Potential,surface,sign)# sign + if according to normal on surface, - otherwise + check_if_coincide(op.surface,surface) || return op.operator + newop = γ(op.operator,sign) + return newop +end + + + +γₜᶜ(op::Potential,surface) = nt×(γ(op,surface,-1)×nt) +γₜ(op::Potential,surface) = nt×(γ(op,surface,1)×nt) + +γₛ(op::Potential,surface) = nt×γ(op,surface,1) +γₛᶜ(op::Potential,surface) = nt×γ(op,surface,-1) +γₙ(op::Potential,surface) = nt⋅γ(op,surface,1) +γₙᶜ(op::Potential,surface) = nt⋅γ(op,surface,-1) +τ(op::Potential,surface) = γ(op,surface,1) +τᶜ(op::Potential,surface) = γ(op,surface,-1) + +function greenhh3d(; + gamma=nothing, + wavenumber=nothing) + +gamma, wavenumber = gamma_wavenumber_handler(gamma, wavenumber) +@assert gamma !== nothing +GreenHH3D(gamma) +end +function gradgreenhh3d(; + gamma=nothing, + wavenumber=nothing) + +gamma, wavenumber = gamma_wavenumber_handler(gamma, wavenumber) +@assert gamma !== nothing +GradGreenHH3D(gamma) +end + +struct GreenHH3D{T} <: Kernel + gamma{T} +end + +struct GradGreenHH3D{T} <: Kernel + gamma{T} +end + + +function (op::GreenHH3D)(x,y,g) + gamma = op.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-gamma*R)*(i4pi*iR) + Ref(green) +end + +function (op::GradGreenHH3D)(x,y,g) + gamma = op.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-gamma*R)*(iR*i4pi) + gradgreen = -(gamma + iR) * green * (iR * r) + Ref(gradgreen) +end + +γ(op::GreenHH3D,sign) = op +γ(op::GradGreenHH3D,sign) = op + sign*1/2*nt + +grad(G::GreenHH3D) = GradGreenHH3D(G.gamma) +∇(G) = grad(G) +scalartype(G::GreenHH3D{T}) where {T} = T +scalartype(G::GradGreenHH3D{T}) where {T} = T + + + +div(B::BasisFunction) = DivBasisFunction() + + +function (op::Union{TimesIntegral,TimesLocal})(x,y,g) + op.lhs(x,y,g).*op.rhs(x,y,g) +end +function (op::Union{DotIntegral,DotLocal})(x,y,g) + dot.(op.lhs(x,y,g),op.rhs(x,y,g)) +end +function (op::Union{CrossIntegral,CrossLocal})(x,y,g) + cross.(op.lhs(x,y,g),op.rhs(x,y,g)) +end + +function (op::TrialNormal)(x,y,g) + Ref(normal(y)) +end +function (op::TestNormal)(x,y,g) + Ref(normal(x)) +end +function (op::BasisFunction)(x,y,g) + getvalue(g) +end +function (op::DivBasisFunction)(x,y,g) + getdivergence(g) +end + + + +function (igd::Integrand{<:ComposedOperatorIntegral})(x,y,f,g) + op = igd.operator + dot.(f,op(x,y,g)) +end + +function integrand(op::ComposedOperatorLocal,kernel,x,y,g) + dot.(f,op(x,y,g)) +end + + +defaultquadstrat(op::ComposedOperator,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(6,7,5,5,4,3) +sign_upon_permutation(op::ComposedOperator,I,J) = Combinatorics.levicivita(I)^count_test_normals(op)*Combinatorics.levicivita(J)^count_trial_normals(op) + + +normalorient(op::ComposedOperator,sign_test_normal,sign_trial_normal) = sign_test_normal^count_test_normals*sign_trial_normal^count_trial_normals \ No newline at end of file diff --git a/src/composedoperator/composeoperator.jl b/src/composedoperator/composeoperator.jl index 2afb2106..1c54313c 100644 --- a/src/composedoperator/composeoperator.jl +++ b/src/composedoperator/composeoperator.jl @@ -9,21 +9,38 @@ abstract type ComposedOperatorIntegral <: IntegralOperator end struct BasisFunction end struct DivBasisFunction end -struct TestFunctionLocal{T} <: ComposedOperatorLocal +struct TestFunctionLocal{T <: ComposedOperatorLocal} <: ComposedOperatorLocal inner::T end -struct TestFunctionIntegral{T} <: ComposedOperatorIntegral +struct TestFunctionIntegral{T <: ComposedOperatorIntegral} <: ComposedOperatorIntegral inner::T end TestFunctionLocal(inner::ComposedOperatorIntegral) = TestFunctionIntegral(inner) -struct DivTestFunctionLocal{T} <: ComposedOperatorLocal +struct DivTestFunctionLocal{T <: ComposedOperatorLocal} <: ComposedOperatorLocal inner::T end -struct DivTestFunctionIntegral{T} <: ComposedOperatorIntegral +struct DivTestFunctionIntegral{T <: ComposedOperatorIntegral} <: ComposedOperatorIntegral inner::T end +function TestFunctionLocal(inner::LinearCombinationOfOperators) + out = ZeroOperator() + for op in inner.ops + out += TestFunctionLocal(op) + end + return out +end + +function DivTestFunctionLocal(inner::LinearCombinationOfOperators) + out = ZeroOperator() + for op in inner.ops + out += DivTestFunctionLocal(op) + end + return out +end + + struct CurlBasisFunction end const b = BasisFunction() @@ -36,29 +53,44 @@ export b ⋅(::Nabla,::Type{TestFunctionLocal}) = DivTestFunctionLocal ⋅(::Nabla,::Type{TestFunctionIntegral}) = DivTestFunctionIntegral -struct TestNormalLocal{T,O} <: ComposedOperatorLocal +struct TestNormalLocal{T,O,P} <: ComposedOperatorLocal inner::T operation::O +factor::P end -struct TrialNormalLocal{T,O} <: ComposedOperatorLocal +struct TrialNormalLocal{T,O,P} <: ComposedOperatorLocal inner::T operation::O +factor::P end -struct TestNormalIntegral{T,O} <: ComposedOperatorIntegral + +*(a::Number,b::TrialNormalLocal) = TrialNormalLocal(b.inner,b.operation,a*b.factor) +*(a::Number,b::TestNormalLocal) = TestNormalLocal(b.inner,b.operation,a*b.factor) +struct TestNormalIntegral{T,O,P} <: ComposedOperatorIntegral inner::T operation::O + factor::P + end + TestNormalLocal(inner::ComposedOperatorIntegral,op) = TestNormalIntegral(inner,op) -struct TrialNormalIntegral{T,O} <: ComposedOperatorIntegral +struct TrialNormalIntegral{T,O,P} <: ComposedOperatorIntegral inner::T operation::O + factor::P end +TrialNormalIntegral(a,b) = TrialNormalIntegral(a,b,1.0) +TestNormalIntegral(a,b) = TestNormalIntegral(a,b,1.0) +TestNormalLocal(a,b) = TestNormalLocal(a,b,1.0) +TestNormalIntegral(a,b) = TestNormalIntegral(a,b,1.0) TrialNormalLocal(inner::ComposedOperatorIntegral,op) = TrialNormalIntegral(inner,op) +*(a::Number,b::TrialNormalIntegral) = TrialNormalIntegral(b.inner,b.operation,a*b.factor) +*(a::Number,b::TestNormalIntegral) = TestNormalIntegral(b.inner,b.operation,a*b.factor) const nt = TestNormalLocal const nb = TrialNormalLocal @@ -77,10 +109,19 @@ end function (a::Type{<: ComposedOperatorLocal})(operation) -return x->a(x,operation) +return x->dist(a,x,operation) end - +function dist(a::Type{<: ComposedOperatorLocal},x::Union{ComposedOperatorIntegral,ComposedOperatorLocal},operation) + return a(x,operation) +end +function dist(a::Type{<: ComposedOperatorLocal},x::LinearCombinationOfOperators,operation) + out = ZeroOperator() + for op in x.ops + out += a(op,operation) + end + return out +end struct HH3DGreen{T} <: Kern gamma::T @@ -91,15 +132,27 @@ end function (::Nabla)(G::HH3DGreen) HH3DGradGreen(G.wavenumber) end -function (G::Kernel{T,O,HH3DGreen{Q}})(testnb,trialnb) where {T,O,Q} +function (G::Kernel{T,O,HH3DGreen{Q}})(testnb,trialnb,f,g) where {T,O,Q} green = - return G.operation.(Ref(green),G.inner(testnb,trialnb)) + return G.operation.(Ref(green),G.inner(testnb,trialnb,f,g)) end -function (G::Kernel{T,O,HH3DGradGreen{Q}})(testnb,trialnb) where {T,O,Q} +function (G::Kernel{T,O,HH3DGradGreen{Q}})(testnb,trialnb,f,g) where {T,O,Q} gradgreen = return G.operation.(Ref(gradgreen),G.inner(testnb,trialnb)) end +#define with respect to from inside omega. +function traceterm(G::HH3DGreen) +ZeroOperator() +end + +function traceterm(G::HH3DGradGreen) +1/2*nt(G.inner,G.operation) +end + + + + function (igd::Integrand{<:ComposedOperatorIntegral})(x,y,f,g) op = igd.operator op(x,y,f,g) @@ -121,7 +174,7 @@ function (op::Union{TestNormalIntegral,TestNormalLocal})(x,y,g) end function (op::Union{TrialNormalIntegral,TrialNormalLocal})(x,y,g) - op.operation(normal(y),op.inner(x,y,g)) + op.factor*op.operation(normal(y),op.inner(x,y,g)) end function (op::BasisFunction)(x,y,g) @@ -134,3 +187,32 @@ function (op::CurlBasisFunction)(x,y,g) getcurl(g) end + +#### support for traces to find equivalent operator. +""" +inside positive, outside negative +""" +struct Trace +direction +end + +function (t::Trace)(operator) +operator+t.direction*traceterm(operator) +end + + + + + +const γₜᶜ = nt((x -> -x ∘ ×))∘ nt(×)∘Trace(-1) +const γₜ = nt((x -> -x ∘ ×))∘ nt(×)∘Trace(1) + +const γₛ = nt(×)∘Trace(1) +const γₛᶜ = nt(×)∘Trace(-1) +const γₙ = nt(⋅)∘Trace(1) +const γₙᶜ = nt(⋅)∘Trace(-1) + +export γₙ +export γₙᶜ +export γₜ +export γₜᶜ \ No newline at end of file diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 50a2c936..a099e513 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -94,54 +94,93 @@ end -function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: RootDomain})(::VectorStrat) - p = physicalconstants(int.embedvol.data) - k = sqrt(p.ϵ*p.μ)*p.ω - green = HHH.green(wavenumber=k) - gradgreen = HHH.gradgreen(wavenumber=k) - b = basisfunction() - @warn "check if extra - in front of a is correct, describtion of As from paper asumes n outward so inward in outer domain?" - a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen - BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) - -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() - -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] - id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() - ZeroOperator() Identity() ZeroOperator() ZeroOperator() - ZeroOperator() ZeroOperator() Identity() ZeroOperator() - ZeroOperator() ZeroOperator() ZeroOperator() Identity()] - #a = id - a +# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: RootDomain})(::VectorStrat) +# p = physicalconstants(int.embedvol.data) +# k = sqrt(p.ϵ*p.μ)*p.ω +# green = HHH.green(wavenumber=k) +# gradgreen = HHH.gradgreen(wavenumber=k) +# b = basisfunction() +# @warn "check if extra - in front of a is correct, describtion of As from paper asumes n outward so inward in outer domain?" +# a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen +# BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) +# -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() +# -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] +# id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() +# ZeroOperator() Identity() ZeroOperator() ZeroOperator() +# ZeroOperator() ZeroOperator() Identity() ZeroOperator() +# ZeroOperator() ZeroOperator() ZeroOperator() Identity()] +# #a = id - a - if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) - println("cauchy limit taken") - a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) - end - a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) +# if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) +# println("cauchy limit taken") +# a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) +# end +# a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) - return a +# return a + +# end +# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: SubDomain})(::VectorStrat) +# p = physicalconstants(int.embedvol.data) +# k = sqrt(p.ϵ*p.μ)*p.ω +# green = HHH.green(wavenumber=k) +# gradgreen = HHH.gradgreen(wavenumber=k) +# b = basisfunction() + +# a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen +# BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) +# -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() +# -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] +# id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() +# ZeroOperator() Identity() ZeroOperator() ZeroOperator() +# ZeroOperator() ZeroOperator() Identity() ZeroOperator() +# ZeroOperator() ZeroOperator() ZeroOperator() Identity()] +# #a = id - a + +# if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) +# println("cauchy limit taken") +# a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) +# end +# a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) +# return a -end -function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: SubDomain})(::VectorStrat) +# end + + +function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<:Union{RootDomain,SubDomain}})(::VectorStrat) p = physicalconstants(int.embedvol.data) k = sqrt(p.ϵ*p.μ)*p.ω - green = HHH.green(wavenumber=k) - gradgreen = HHH.gradgreen(wavenumber=k) - b = basisfunction() - - a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen - BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) - -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() - -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] - id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() - ZeroOperator() Identity() ZeroOperator() ZeroOperator() - ZeroOperator() ZeroOperator() Identity() ZeroOperator() - ZeroOperator() ZeroOperator() ZeroOperator() Identity()] - #a = id - a + G = BEAST.greenhh3d(wavenumber=k) + ∇G = BEAST.∇(G) + Ω1=int.testvol + Ω2=int.trialvol + Ω3=int.embedvol + ∇Gx = BEAST.build_potential(∇G×B,Ω2.data.trialbasises[1].geo) + Gn = BEAST.build_potential(G*n*B,Ω2.data.trialbasises[1].geo) + Gnx = BEAST.build_potential(G*n × B,Ω2.data.trialbasises[1].geo) + ∇G = BEAST.build_potential(∇G*B,Ω2.data.trialbasises[1].geo) + ∇Gdotn = BEAST.build_potential(∇G⋅n*B,Ω2.data.trialbasises[1].geo) + ∇Gdot = BEAST.build_potential(∇G⋅B,Ω2.data.trialbasises[1].geo) - if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) - println("cauchy limit taken") - a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + Gr = BEAST.build_potential(G*B,Ω2.data.trialbasises[1].geo) + ∇G∇B = BEAST.build_potential(∇G*∇(B),Ω2.data.trialbasises[1].geo) + ∇Gxn = BEAST.build_potential(∇G×n*B,Ω2.data.trialbasises[1].geo) + testsurf = Ω1.data.testbasises[1].geo + if Ω1==Ω2 + a = -[γₛ(∇Gx,testsurf) γₛ(Gn,testsurf) -γₛ(Gnx,testsurf) γₛ(∇G,testsurf) + BEAST.ZeroOperator() -τ(∇Gdotn,testsurf) τ(∇Gdot,testsurf) k^2*τ(Gr,testsurf) + -γₛ(∇G∇B,testsurf)-k^2*γₛ(Gr,testsurf) -γₛ(∇Gxn,testsurf) γₛ(∇Gx,testsurf) BEAST.ZeroOperator() + -γₙ(∇Gx,testsurf) -γₙ(Gn,testsurf) γₙ(Gr,testsurf) -γₙ(∇G,testsurf)] + else + a = -[γₛᶜ(∇Gx,testsurf) γₛᶜ(Gn,testsurf) -γₛᶜ(Gnx,testsurf) γₛᶜ(∇G,testsurf) + BEAST.ZeroOperator() -τᶜ(∇Gdotn,testsurf) τᶜ(∇Gdot,testsurf) k^2*τᶜ(Gr,testsurf) + -γₛᶜ(∇G∇B,testsurf)-k^2*γₛᶜ(Gr,testsurf) -γₛᶜ(∇Gxn,testsurf) γₛᶜ(∇Gx,testsurf) BEAST.ZeroOperator() + -γₙᶜ(∇Gx,testsurf) -γₙᶜ(Gn,testsurf) γₙᶜ(Gr,testsurf) -γₙᶜ(∇G,testsurf)] end - a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + + + a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + return a end \ No newline at end of file From 5fd4ff3faa032f4c6657d49900c4b32117384ba9 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 24 Oct 2023 13:38:17 +0200 Subject: [PATCH 041/110] added chart which explicitly saves normal --- src/utils/extendedcharts.jl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/utils/extendedcharts.jl diff --git a/src/utils/extendedcharts.jl b/src/utils/extendedcharts.jl new file mode 100644 index 00000000..1c65c040 --- /dev/null +++ b/src/utils/extendedcharts.jl @@ -0,0 +1,24 @@ +import Base.length + +struct NormalChart{U,D,C,N,T} + chart::CompScienceMeshes.Simplex{U,D,C,N,T} + normals::SVector{C,SVector{U,T}} +end + +normals(chart::NormalChart) = chart.normals +chart(chart::NormalChart) = chart.chart +dimtype(chart::NormalChart) = dimtype(chart(chart)) +coordtype(chart::NormalChart) = coordtype(chart(chart)) +volume(chart::NormalChart) = volume(chart(chart)) +dimension(chart::NormalChart) = dimension(chart(chart)) +Base.length(chart::NormalChart) = length(chart(chart)) +universedimension(chart::NormalChart) = universedimension(chart(chart)) +getindex(p::NormalChart,I::Union{Number,SVector,Array}) = chart(p)[I] + + +function normalchart(chart::Simplex) + normals = normals(chart) + NormalChart(chart,normals) +end + +normalchart(chart::Simplex,normals) = NormalChart(chart,normals) \ No newline at end of file From 678cbfeb793c74277b396eee625ba4b0a4e26ea3 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 24 Oct 2023 13:38:34 +0200 Subject: [PATCH 042/110] added normalchart --- .gitignore | 8 ++++++++ src/BEAST.jl | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b879feb5..bfa3e6f8 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,11 @@ dev/ profile/ /Manifest.toml /envs/ +programs/vector_potential_globalmultitrace.jl +programs/draft/create neighobrhood.jl +programs/draft/test_strace_doublelayer.jl +programs/draft/test_trace_operators_visual.jl +programs/draft/test_ttrace_doublelayer.jl +programs/draft/vector_potential_sphere.jl +src/todo.txt + diff --git a/src/BEAST.jl b/src/BEAST.jl index d79f78d3..5f3d5807 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -254,7 +254,7 @@ include("solvers/lusolver.jl") include("solvers/itsolver.jl") include("utils/plotlyglue.jl") - +include("utils/extendedcharts.jl") From 3c0c60d8d903f4454250e9d5187095730f0433b7 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 25 Oct 2023 11:49:21 +0200 Subject: [PATCH 043/110] local bases definition independent of normal --- src/bases/local/laglocal.jl | 3 ++- src/bases/local/ncrossbdmlocal.jl | 4 ++-- src/bases/local/ndlocal.jl | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/bases/local/laglocal.jl b/src/bases/local/laglocal.jl index 29bad742..f663ca1a 100644 --- a/src/bases/local/laglocal.jl +++ b/src/bases/local/laglocal.jl @@ -78,7 +78,8 @@ function gradient(ref::LagrangeRefSpace{T,1,4}, sh, tet) where {T} # opp_face = simplex(other_verts...) opp_face = faces(tet)[sh.refid] ctr_opp_face = center(opp_face) - n = normal(ctr_opp_face) + # n = normal(ctr_opp_face) + n = normalize(tangents(ctr_opp_face,1)×tangents(ctr_opp_face,2)) h = -dot(this_vert - cartesian(ctr_opp_face), n) @assert h > 0 gradval = -(1/h)*n diff --git a/src/bases/local/ncrossbdmlocal.jl b/src/bases/local/ncrossbdmlocal.jl index b7dc7504..275b433f 100644 --- a/src/bases/local/ncrossbdmlocal.jl +++ b/src/bases/local/ncrossbdmlocal.jl @@ -3,10 +3,10 @@ struct NCrossBDMRefSpace{T} <: RefSpace{T,6} end function (f::NCrossBDMRefSpace{T})(p) where T u,v = parametric(p) - n = normal(p) + # n = normal(p) tu = tangents(p,1) tv = tangents(p,2) - + n = normalize(tu×tv) j = jacobian(p) d = 1/j diff --git a/src/bases/local/ndlocal.jl b/src/bases/local/ndlocal.jl index 9f0c196f..45e6b3df 100644 --- a/src/bases/local/ndlocal.jl +++ b/src/bases/local/ndlocal.jl @@ -11,12 +11,12 @@ mutable struct NDRefSpace{T} <: RefSpace{T,3} end function (ϕ::NDRefSpace)(nbd) u, v = parametric(nbd) - n = normal(nbd) + #n = normal(nbd) j = jacobian(nbd) tu = tangents(nbd,1) tv = tangents(nbd,2) - + n = normalize(tu×tv) d = 2/j return SVector(( From ddc9a3d572b9821c1bf765f4668e537ea08fa510 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 25 Oct 2023 13:29:17 +0200 Subject: [PATCH 044/110] add revise --- Project.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 387e9053..834c3d31 100644 --- a/Project.toml +++ b/Project.toml @@ -21,6 +21,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" NestedUnitRanges = "032820ab-dc03-4b49-91f4-7d58d4da98b3" Requires = "ae029012-a4dd-5104-9daa-d747884805df" +Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" SauterSchwab3D = "0a13313b-1c00-422e-8263-562364ed9544" SauterSchwabQuadrature = "535c7bfe-2023-5c1d-b712-654ef9d93a38" SharedArrays = "1a1011a3-84de-559e-8e89-a11a2f7dc383" @@ -53,5 +54,3 @@ SpecialFunctions = "0.7, 0.8, 0.9, 0.10, 1, 2" StaticArrays = "0.8.3, 0.9, 0.10, 0.11, 0.12, 1" WiltonInts84 = "0.2.5" julia = "1.6" - - From d0f1f2f1b8071ee72aac09cc37e9c64be4a16ec8 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 25 Oct 2023 16:34:59 +0200 Subject: [PATCH 045/110] change of permutation to redefinition on barycentric coordinates, compared to old matrix for Float64 -> exactly the same, for Float32 small error because integration routines are written in Float 64 --- src/BEAST.jl | 7 +- src/decoupled/dpops.jl | 65 +++++++- src/helmholtz3d/hh3d_sauterschwabqr.jl | 215 +++++++++++++++++++++++-- src/quadrature/sauterschwabints.jl | 55 ++++++- src/utils/extendedcharts.jl | 53 +++--- 5 files changed, 350 insertions(+), 45 deletions(-) diff --git a/src/BEAST.jl b/src/BEAST.jl index 5f3d5807..e47cef53 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -18,6 +18,9 @@ using LiftedMaps using AbstractTrees using NestedUnitRanges +using StaticArrays +using CompScienceMeshes + import LinearAlgebra: cross, dot import LinearAlgebra: ×, ⋅ @@ -129,7 +132,7 @@ using FFTW using SparseArrays function convolve end - +include("utils/extendedcharts.jl") include("utils/polynomial.jl") include("utils/specialfns.jl") include("utils/combinatorics.jl") @@ -254,7 +257,7 @@ include("solvers/lusolver.jl") include("solvers/itsolver.jl") include("utils/plotlyglue.jl") -include("utils/extendedcharts.jl") + diff --git a/src/decoupled/dpops.jl b/src/decoupled/dpops.jl index cfae115d..ec321394 100644 --- a/src/decoupled/dpops.jl +++ b/src/decoupled/dpops.jl @@ -21,12 +21,15 @@ function momintegrals!(op::CurlSingleLayerDP3D, test_local_space::RTRefSpace, trial_local_space::LagrangeRefSpace, test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) + out_old = copy(out) + momintegrals!_old(op,test_local_space,trial_local_space,test_triangular_element,trial_triangular_element,out_old,strat) + I, J, K, L = SauterSchwabQuadrature.reorder( test_triangular_element.vertices, trial_triangular_element.vertices, strat) - test_triangular_element = simplex(test_triangular_element.vertices[I]...) - trial_triangular_element = simplex(trial_triangular_element.vertices[J]...) + # test_triangular_element = simplex(test_triangular_element.vertices[I]...) + # trial_triangular_element = simplex(trial_triangular_element.vertices[J]...) function igd(u,v) α = op.alpha @@ -54,14 +57,15 @@ function momintegrals!(op::CurlSingleLayerDP3D, R = @SVector[αjGG*g[i].value for i in 1:3] return @SMatrix[dot(f[i].value × nx, R[j]) for i in 1:3, j in 1:3] end - - Q = sauterschwab_parameterized(igd, strat) + f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) + Q = sauterschwab_parameterized(f, strat) for j ∈ 1:3 for i ∈ 1:3 - out[i,j] += Q[K[i],L[j]] + # out[i,j] += Q[K[i],L[j]] + out[i,j] += Q[i,j] end end - + @assert out_old ≈ out rtol = eps() nothing end @@ -71,3 +75,52 @@ function quadrule(op::BEAST.CurlSingleLayerDP3D, qrdf(op, test_local_space, trial_local_space, test_index, test_chart, trial_index, trial_chart, quadrature_data) end + + +function momintegrals!_old(op::CurlSingleLayerDP3D, + test_local_space::RTRefSpace, trial_local_space::LagrangeRefSpace, + test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) + + I, J, K, L = SauterSchwabQuadrature.reorder( + test_triangular_element.vertices, + trial_triangular_element.vertices, strat) + + test_triangular_element = simplex(test_triangular_element.vertices[I]...) + trial_triangular_element = simplex(trial_triangular_element.vertices[J]...) + + function igd(u,v) + α = op.alpha + γ = op.gamma + + x = neighborhood(test_triangular_element,u) + y = neighborhood(trial_triangular_element,v) + + nx = normal(x) + + r = cartesian(x) - cartesian(y) + R = norm(r) + G = exp(-γ*R)/(4π*R) + GG = -(γ + 1/R) * G / R * r + + f = test_local_space(x) + g = trial_local_space(y) + + jx = jacobian(x) + jy = jacobian(y) + j = jx*jy + + αjGG = α*j*GG + + R = @SVector[αjGG*g[i].value for i in 1:3] + return @SMatrix[dot(f[i].value × nx, R[j]) for i in 1:3, j in 1:3] + end + + Q = sauterschwab_parameterized(igd, strat) + for j ∈ 1:3 + for i ∈ 1:3 + out[i,j] += Q[K[i],L[j]] + end + end + + nothing +end \ No newline at end of file diff --git a/src/helmholtz3d/hh3d_sauterschwabqr.jl b/src/helmholtz3d/hh3d_sauterschwabqr.jl index 1b59a052..6359f39a 100644 --- a/src/helmholtz3d/hh3d_sauterschwabqr.jl +++ b/src/helmholtz3d/hh3d_sauterschwabqr.jl @@ -123,6 +123,200 @@ function momintegrals!(op::Helmholtz3DOp, test_local_space::LagrangeRefSpace{<:Any,0}, trial_local_space::LagrangeRefSpace{<:Any,0}, test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) + out_old = copy(out) + momintegrals!_old(op,test_local_space,trial_local_space,test_triangular_element,trial_triangular_element,out_old,strat) + I, J, K, L = SauterSchwabQuadrature.reorder( + test_triangular_element.vertices, + trial_triangular_element.vertices, strat) + + # test_triangular_elementex = simplex( + # test_triangular_element.vertices[I[1]], + # test_triangular_element.vertices[I[2]], + # test_triangular_element.vertices[I[3]]) + + # trial_triangular_elementex = simplex( + # trial_triangular_element.vertices[J[1]], + # trial_triangular_element.vertices[J[2]], + # trial_triangular_element.vertices[J[3]]) + + # test_sign = Combinatorics.levicivita(I) + # trial_sign = Combinatorics.levicivita(J) + # σ = momintegrals_sign(op, test_sign, trial_sign) + # @assert sign(dot(normal(test_triangular_element),normal(test_triangular_elementex))) == test_sign + # test_triangular_element = CompScienceMeshes.Simplex(test_triangular_elementex.vertices, + # test_triangular_elementex.tangents, + # test_triangular_element.normals, + # test_triangular_elementex.volume) + # trial_triangular_element = CompScienceMeshes.Simplex(trial_triangular_elementex.vertices, + # trial_triangular_elementex.tangents, + # trial_triangular_element.normals, + # trial_triangular_elementex.volume) + + + igd = pulled_back_integrand(op, test_local_space, trial_local_space, + test_triangular_element, trial_triangular_element) + + f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) + G = SauterSchwabQuadrature.sauterschwab_parameterized(f, strat) + out[1,1] += G[1,1]# * σ + + @assert out_old ≈ out rtol = eps() + nothing +end + + +function momintegrals!(op::Helmholtz3DOp, + test_local_space::LagrangeRefSpace, trial_local_space::LagrangeRefSpace, + test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) + out_old = copy(out) + momintegrals!_old(op,test_local_space,trial_local_space,test_triangular_element,trial_triangular_element,out_old,strat) + I, J, K, L = SauterSchwabQuadrature.reorder( + test_triangular_element.vertices, + trial_triangular_element.vertices, strat) + + # test_triangular_elementex = simplex( + # test_triangular_element.vertices[I[1]], + # test_triangular_element.vertices[I[2]], + # test_triangular_element.vertices[I[3]]) + + # trial_triangular_elementex = simplex( + # trial_triangular_element.vertices[J[1]], + # trial_triangular_element.vertices[J[2]], + # trial_triangular_element.vertices[J[3]]) + + # test_sign = Combinatorics.levicivita(I) + # trial_sign = Combinatorics.levicivita(J) + # σ = momintegrals_sign(op, test_sign, trial_sign) + # @assert sign(dot(normal(test_triangular_element),normal(test_triangular_elementex))) == test_sign + # test_triangular_element = CompScienceMeshes.Simplex(test_triangular_elementex.vertices, + # test_triangular_elementex.tangents, + # test_triangular_element.normals, + # test_triangular_elementex.volume) + # trial_triangular_element = CompScienceMeshes.Simplex(trial_triangular_elementex.vertices, + # trial_triangular_elementex.tangents, + # trial_triangular_element.normals, + # trial_triangular_elementex.volume) + + igd = pulled_back_integrand(op, test_local_space, trial_local_space, + test_triangular_element, trial_triangular_element) + f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) + G = SauterSchwabQuadrature.sauterschwab_parameterized(f, strat) + for j ∈ 1:3, i ∈ 1:3 + # out[i,j] += G[K[i],L[j]]# * σ + out[i,j] += G[i,j]# * σ + end + @assert out_old ≈ out rtol = eps() + nothing +end + +function momintegrals!(op::Helmholtz3DOp, + test_local_space::LagrangeRefSpace{<:Any,0}, trial_local_space::LagrangeRefSpace{<:Any,1}, + test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) + out_old = copy(out) + momintegrals!_old(op,test_local_space,trial_local_space,test_triangular_element,trial_triangular_element,out_old,strat) + I, J, K, L = SauterSchwabQuadrature.reorder( + test_triangular_element.vertices, + trial_triangular_element.vertices, strat) + + # test_triangular_elementex = simplex( + # test_triangular_element.vertices[I[1]], + # test_triangular_element.vertices[I[2]], + # test_triangular_element.vertices[I[3]]) + + # trial_triangular_elementex = simplex( + # trial_triangular_element.vertices[J[1]], + # trial_triangular_element.vertices[J[2]], + # trial_triangular_element.vertices[J[3]]) + + # test_sign = Combinatorics.levicivita(I) + # trial_sign = Combinatorics.levicivita(J) + # σ = momintegrals_sign(op, test_sign, trial_sign) + # @assert sign(dot(normal(test_triangular_element),normal(test_triangular_elementex))) == test_sign + # test_triangular_element = CompScienceMeshes.Simplex(test_triangular_elementex.vertices, + # test_triangular_elementex.tangents, + # test_triangular_element.normals, + # test_triangular_elementex.volume) + # trial_triangular_element = CompScienceMeshes.Simplex(trial_triangular_elementex.vertices, + # trial_triangular_elementex.tangents, + # trial_triangular_element.normals, + # trial_triangular_elementex.volume) + + igd = pulled_back_integrand(op, test_local_space, trial_local_space, + test_triangular_element, trial_triangular_element) + f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) + G = SauterSchwabQuadrature.sauterschwab_parameterized(f, strat) + + for i ∈ 1:3 + #out[1,i] += G[L[i]]# * σ + out[1,i] += G[i]# * σ + end + @assert out_old ≈ out rtol = eps() + nothing +end + +function momintegrals!(op::Helmholtz3DOp, + test_local_space::LagrangeRefSpace{<:Any,1}, trial_local_space::LagrangeRefSpace{<:Any,0}, + test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) + out_old = copy(out) + momintegrals!_old(op,test_local_space,trial_local_space,test_triangular_element,trial_triangular_element,out_old,strat) + I, J, K, L = SauterSchwabQuadrature.reorder( + test_triangular_element.vertices, + trial_triangular_element.vertices, strat) + + # test_triangular_element = simplex( + # test_triangular_element.vertices[I[1]], + # test_triangular_element.vertices[I[2]], + # test_triangular_element.vertices[I[3]]) + + # trial_triangular_element = simplex( + # trial_triangular_element.vertices[J[1]], + # trial_triangular_element.vertices[J[2]], + # trial_triangular_element.vertices[J[3]]) + # # test_triangular_element = CompScienceMeshes.Simplex(test_triangular_element1.vertices, + # # test_triangular_element1.tangents, + # # test_triangular_element.normals, + # # test_triangular_element1.volume) + # # trial_triangular_element = CompScienceMeshes.Simplex(trial_triangular_element1.vertices, + # # trial_triangular_element1.tangents, + # # trial_triangular_element.normals, + # # trial_triangular_element1.volume) + # test_sign = Combinatorics.levicivita(I) + # trial_sign = Combinatorics.levicivita(J) + + # σ = momintegrals_sign(op, test_sign, trial_sign) + + igd = pulled_back_integrand(op, test_local_space, trial_local_space, + test_triangular_element, trial_triangular_element) + f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) + G = SauterSchwabQuadrature.sauterschwab_parameterized(f, strat) + + for i ∈ 1:3 + #out[i,1] += G[K[i]] * σ + out[i,1] += G[i] + end + @assert out_old ≈ out rtol = eps() + nothing +end + +function momintegrals_sign(op::HH3DSingleLayerFDBIO, test_sign, trial_sign) + return 1 +end +function momintegrals_sign(op::HH3DDoubleLayerFDBIO, test_sign, trial_sign) + return trial_sign +end +function momintegrals_sign(op::HH3DDoubleLayerTransposedFDBIO, test_sign, trial_sign) + return test_sign +end +function momintegrals_sign(op::HH3DHyperSingularFDBIO, test_sign, trial_sign) + return test_sign * trial_sign +end + + + +function momintegrals!_old(op::Helmholtz3DOp, + test_local_space::LagrangeRefSpace{<:Any,0}, trial_local_space::LagrangeRefSpace{<:Any,0}, + test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) + I, J, K, L = SauterSchwabQuadrature.reorder( test_triangular_element.vertices, trial_triangular_element.vertices, strat) @@ -150,7 +344,7 @@ function momintegrals!(op::Helmholtz3DOp, end -function momintegrals!(op::Helmholtz3DOp, +function momintegrals!_old(op::Helmholtz3DOp, test_local_space::LagrangeRefSpace, trial_local_space::LagrangeRefSpace, test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) @@ -183,7 +377,7 @@ function momintegrals!(op::Helmholtz3DOp, nothing end -function momintegrals!(op::Helmholtz3DOp, +function momintegrals!_old(op::Helmholtz3DOp, test_local_space::LagrangeRefSpace{<:Any,0}, trial_local_space::LagrangeRefSpace{<:Any,1}, test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) @@ -217,7 +411,7 @@ function momintegrals!(op::Helmholtz3DOp, nothing end -function momintegrals!(op::Helmholtz3DOp, +function momintegrals!_old(op::Helmholtz3DOp, test_local_space::LagrangeRefSpace{<:Any,1}, trial_local_space::LagrangeRefSpace{<:Any,0}, test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) @@ -249,17 +443,4 @@ function momintegrals!(op::Helmholtz3DOp, end nothing -end - -function momintegrals_sign(op::HH3DSingleLayerFDBIO, test_sign, trial_sign) - return 1 -end -function momintegrals_sign(op::HH3DDoubleLayerFDBIO, test_sign, trial_sign) - return trial_sign -end -function momintegrals_sign(op::HH3DDoubleLayerTransposedFDBIO, test_sign, trial_sign) - return test_sign -end -function momintegrals_sign(op::HH3DHyperSingularFDBIO, test_sign, trial_sign) - return test_sign * trial_sign -end +end \ No newline at end of file diff --git a/src/quadrature/sauterschwabints.jl b/src/quadrature/sauterschwabints.jl index 459a36ca..5bf60b5d 100644 --- a/src/quadrature/sauterschwabints.jl +++ b/src/quadrature/sauterschwabints.jl @@ -91,6 +91,60 @@ function momintegrals!(op::Operator, test_local_space::RefSpace, trial_local_space::RefSpace, test_chart, trial_chart, out, rule::SauterSchwabStrategy) + out_old = copy(out) + momintegrals!_old(op,test_local_space,trial_local_space,test_chart,trial_chart,out_old,rule) + I, J, K, L = SauterSchwabQuadrature.reorder( + test_chart.vertices, + trial_chart.vertices, rule) + + # test_chart1 = simplex( + # test_chart.vertices[I[1]], + # test_chart.vertices[I[2]], + # test_chart.vertices[I[3]]) + + # trial_chart1 = simplex( + # trial_chart.vertices[J[1]], + # trial_chart.vertices[J[2]], + # trial_chart.vertices[J[3]]) + # test_chart = CompScienceMeshes.Simplex(test_chart1.vertices, + # test_chart1.tangents, + # test_chart.normals, + # test_chart1.volume) + # trial_chart = CompScienceMeshes.Simplex(trial_chart1.vertices, + # trial_chart1.tangents, + # trial_chart.normals, + # trial_chart1.volume) + igd = Integrand(op, test_local_space, trial_local_space, test_chart, trial_chart) + K1 = dof_permutation(test_local_space, I) + L1 = dof_permutation(trial_local_space, J) + K1 = [i for i in K1] + L1 = [i for i in L1] + @assert K1 == K + @assert L1 == L + f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) + G = SauterSchwabQuadrature.sauterschwab_parameterized(f, rule) + # σ = sign_upon_permutation(op, I, J) + + for i in 1:numfunctions(test_local_space) + for j in 1:numfunctions(trial_local_space) + #out[i,j] = σ * G[K[i],L[j]] + out[i,j] =G[i,j] + end end + if typeof(abs(out[1,1])) <: Float64 + + @assert isapprox(out,out_old,rtol=eps(Float64)) + + end + + + nothing +end + +nextcomplex(a) = nextfloat(real(a))+im*nextfloat(imag(a)) +function momintegrals!_old(op::Operator, + test_local_space::RefSpace, trial_local_space::RefSpace, + test_chart, trial_chart, out, rule::SauterSchwabStrategy) + I, J, _, _ = SauterSchwabQuadrature.reorder( test_chart.vertices, trial_chart.vertices, rule) @@ -119,7 +173,6 @@ function momintegrals!(op::Operator, nothing end - function momintegrals_test_refines_trial!(out, op, test_functions, test_cell, test_chart, trial_functions, trial_cell, trial_chart, diff --git a/src/utils/extendedcharts.jl b/src/utils/extendedcharts.jl index 1c65c040..e62660f2 100644 --- a/src/utils/extendedcharts.jl +++ b/src/utils/extendedcharts.jl @@ -1,24 +1,39 @@ -import Base.length +# import Base.length +# import CompScienceMeshes: chart,dimtype,coordtype,volume,dimension,universedimension +# struct NormalChart{U,V} +# chart::U +# normals::V +# end -struct NormalChart{U,D,C,N,T} - chart::CompScienceMeshes.Simplex{U,D,C,N,T} - normals::SVector{C,SVector{U,T}} -end +# normals(chart::NormalChart) = chart.normals +# chart(c::NormalChart) = c.chart +# dimtype(c::NormalChart) = dimtype(chart(c)) +# coordtype(c::NormalChart) = coordtype(chart(chart)) -normals(chart::NormalChart) = chart.normals -chart(chart::NormalChart) = chart.chart -dimtype(chart::NormalChart) = dimtype(chart(chart)) -coordtype(chart::NormalChart) = coordtype(chart(chart)) -volume(chart::NormalChart) = volume(chart(chart)) -dimension(chart::NormalChart) = dimension(chart(chart)) -Base.length(chart::NormalChart) = length(chart(chart)) -universedimension(chart::NormalChart) = universedimension(chart(chart)) -getindex(p::NormalChart,I::Union{Number,SVector,Array}) = chart(p)[I] +# volume(c::NormalChart) = volume(chart(chart)) +# dimension(chart::NormalChart) = dimension(chart(chart)) +# Base.length(chart::NormalChart) = length(chart(chart)) +# universedimension(chart::NormalChart) = universedimension(chart(chart)) +# getindex(p::NormalChart,I::Union{Number,SVector,Array}) = chart(p)[I] -function normalchart(chart::Simplex) - normals = normals(chart) - NormalChart(chart,normals) -end +# function normalchart(chart::CompScienceMeshes.Simplex) +# normals = chart.normals +# NormalChart(chart,normals) +# end + +# normalchart(chart::CompScienceMeshes.Simplex,normals) = NormalChart(chart,normals) -normalchart(chart::Simplex,normals) = NormalChart(chart,normals) \ No newline at end of file +CompScienceMeshes.normal(t::CompScienceMeshes.Simplex{3,2,1,3,<:Number}) = t.normals[1] + + +function permute_barycentric(perm,bary::Tuple{T,T}) where {T} + last_coef = 1-sum(bary) + total_bary = SVector{3,T}([bary[1],bary[2],last_coef]) + return Tuple{T,T}(total_bary[perm][1:end-1]) +end +function permute_barycentric(perm,bary::Tuple{T,T,T}) where {T} + last_coef = 1-sum(bary) + total_bary = SVector{4,T}([bary[1],bary[2],bary[3],last_coef]) + return Tuple{T,T,T}(total_bary[perm][1:end-1]) +end \ No newline at end of file From cc68dc155b07d170639d0079722590a27b5fd82c Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 25 Oct 2023 16:35:39 +0200 Subject: [PATCH 046/110] make alpha if one, of correct type --- src/maxwell/maxwell.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/maxwell/maxwell.jl b/src/maxwell/maxwell.jl index a155ab8b..6a26e6b4 100644 --- a/src/maxwell/maxwell.jl +++ b/src/maxwell/maxwell.jl @@ -53,16 +53,16 @@ module Maxwell3D wavenumber=nothing) gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - + println(typeof(wavenumber)) if alpha === nothing if gamma !== nothing alpha = one(gamma) else - alpha = 1.0 # Default to double precision + alpha = one(typeof(wavenumber)) # Default to double precision end end - - Mod.MWDoubleLayer3D(gamma) + println(alpha) + Mod.MWDoubleLayer3D(alpha,gamma) end planewave(; From b22f6bdd91d627526787e8ed7e3345ed62bbf56b Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 25 Oct 2023 16:45:55 +0200 Subject: [PATCH 047/110] cleanup --- src/quadrature/sauterschwabints.jl | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/quadrature/sauterschwabints.jl b/src/quadrature/sauterschwabints.jl index 5bf60b5d..08b35ef7 100644 --- a/src/quadrature/sauterschwabints.jl +++ b/src/quadrature/sauterschwabints.jl @@ -96,24 +96,7 @@ function momintegrals!(op::Operator, I, J, K, L = SauterSchwabQuadrature.reorder( test_chart.vertices, trial_chart.vertices, rule) - - # test_chart1 = simplex( - # test_chart.vertices[I[1]], - # test_chart.vertices[I[2]], - # test_chart.vertices[I[3]]) - - # trial_chart1 = simplex( - # trial_chart.vertices[J[1]], - # trial_chart.vertices[J[2]], - # trial_chart.vertices[J[3]]) - # test_chart = CompScienceMeshes.Simplex(test_chart1.vertices, - # test_chart1.tangents, - # test_chart.normals, - # test_chart1.volume) - # trial_chart = CompScienceMeshes.Simplex(trial_chart1.vertices, - # trial_chart1.tangents, - # trial_chart.normals, - # trial_chart1.volume) + igd = Integrand(op, test_local_space, trial_local_space, test_chart, trial_chart) K1 = dof_permutation(test_local_space, I) L1 = dof_permutation(trial_local_space, J) @@ -140,7 +123,6 @@ function momintegrals!(op::Operator, nothing end -nextcomplex(a) = nextfloat(real(a))+im*nextfloat(imag(a)) function momintegrals!_old(op::Operator, test_local_space::RefSpace, trial_local_space::RefSpace, test_chart, trial_chart, out, rule::SauterSchwabStrategy) From 8b534484c871203d3f507ee1ad054dbd288c1fed Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 25 Oct 2023 17:15:37 +0200 Subject: [PATCH 048/110] moved to compsciencemeshes package --- src/utils/extendedcharts.jl | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/utils/extendedcharts.jl b/src/utils/extendedcharts.jl index e62660f2..8fece9ce 100644 --- a/src/utils/extendedcharts.jl +++ b/src/utils/extendedcharts.jl @@ -24,16 +24,16 @@ # normalchart(chart::CompScienceMeshes.Simplex,normals) = NormalChart(chart,normals) -CompScienceMeshes.normal(t::CompScienceMeshes.Simplex{3,2,1,3,<:Number}) = t.normals[1] - - -function permute_barycentric(perm,bary::Tuple{T,T}) where {T} - last_coef = 1-sum(bary) - total_bary = SVector{3,T}([bary[1],bary[2],last_coef]) - return Tuple{T,T}(total_bary[perm][1:end-1]) -end -function permute_barycentric(perm,bary::Tuple{T,T,T}) where {T} - last_coef = 1-sum(bary) - total_bary = SVector{4,T}([bary[1],bary[2],bary[3],last_coef]) - return Tuple{T,T,T}(total_bary[perm][1:end-1]) -end \ No newline at end of file +#CompScienceMeshes.normal(t::CompScienceMeshes.Simplex{3,2,1,3,<:Number}) = t.normals[1] + + +# function permute_barycentric(perm,bary::Tuple{T,T}) where {T} +# last_coef = 1-sum(bary) +# total_bary = SVector{3,T}([bary[1],bary[2],last_coef]) +# return Tuple{T,T}(total_bary[perm][1:end-1]) +# end +# function permute_barycentric(perm,bary::Tuple{T,T,T}) where {T} +# last_coef = 1-sum(bary) +# total_bary = SVector{4,T}([bary[1],bary[2],bary[3],last_coef]) +# return Tuple{T,T,T}(total_bary[perm][1:end-1]) +# end \ No newline at end of file From c2da4df420cb6dc3a36d377f04f50f6dd0fb837f Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 26 Oct 2023 13:59:14 +0200 Subject: [PATCH 049/110] in curl definition taken acount for normal made use of the permute_vertices function in sauterschwab rule -> no sign_uppon_permutation needed --- src/bases/local/laglocal.jl | 18 +- src/decoupled/dpops.jl | 66 +----- src/helmholtz3d/hh3d_sauterschwabqr.jl | 279 +++---------------------- src/quadrature/sauterschwabints.jl | 54 +---- 4 files changed, 55 insertions(+), 362 deletions(-) diff --git a/src/bases/local/laglocal.jl b/src/bases/local/laglocal.jl index f663ca1a..db176107 100644 --- a/src/bases/local/laglocal.jl +++ b/src/bases/local/laglocal.jl @@ -30,8 +30,9 @@ function (f::LagrangeRefSpace{T,1,3})(t) where T # (value=u,), # (value=v,), # (value=w,)) - - j = jacobian(t) + tu = tangents(t,1) + tv = tangents(t,2) + j = jacobian(t)*sign(dot(normal(t),tu×tv)) p = t.patch SVector( (value=u, curl=(p[3]-p[2])/j), @@ -47,7 +48,9 @@ Compute the values of the shape functions together with their curl. """ function (f::LagrangeRefSpace{T,1,3})(t, ::Type{Val{:withcurl}}) where T # Evaluete linear Lagrange elements on a triange, together with their curl - j = jacobian(t) + tu = tangents(t,1) + tv = tangents(t,2) + j = jacobian(t)*sign(dot(normal(t),tu×tv)) u,v,w, = barycentric(t) p = t.patch SVector( @@ -171,8 +174,9 @@ end ## Quadratic Lagrange element on a triangle function (f::LagrangeRefSpace{T,2,3})(t) where T u,v,w, = barycentric(t) - - j = jacobian(t) + tu = tangents(t,1) + tv = tangents(t,2) + j = jacobian(t)*sign(dot(normal(t),tu×tv)) p = t.patch #curl=(p[3]-p[2])/j), @@ -191,7 +195,9 @@ end function (f::LagrangeRefSpace{T,2,3})(t, ::Type{Val{:withcurl}}) where T # Evaluete quadratic Lagrange elements on a triange, together with their curl - j = jacobian(t) + tu = tangents(t,1) + tv = tangents(t,2) + j = jacobian(t)*sign(dot(normal(t),tu×tv)) u,v,w, = barycentric(t) p = t.patch SVector( diff --git a/src/decoupled/dpops.jl b/src/decoupled/dpops.jl index ec321394..1d4c2a96 100644 --- a/src/decoupled/dpops.jl +++ b/src/decoupled/dpops.jl @@ -17,20 +17,17 @@ function integrand(op::CurlSingleLayerDP3D, kernel_vals, return -α * dot(nx × gx, ∇G * fy) end + function momintegrals!(op::CurlSingleLayerDP3D, test_local_space::RTRefSpace, trial_local_space::LagrangeRefSpace, test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) - out_old = copy(out) - momintegrals!_old(op,test_local_space,trial_local_space,test_triangular_element,trial_triangular_element,out_old,strat) - I, J, K, L = SauterSchwabQuadrature.reorder( test_triangular_element.vertices, trial_triangular_element.vertices, strat) - # test_triangular_element = simplex(test_triangular_element.vertices[I]...) - # trial_triangular_element = simplex(trial_triangular_element.vertices[J]...) - + test_triangular_element = CompScienceMeshes.permute_vertices(test_triangular_element,I) + trial_triangular_element = CompScienceMeshes.permute_vertices(trial_triangular_element,J) function igd(u,v) α = op.alpha γ = op.gamma @@ -57,15 +54,14 @@ function momintegrals!(op::CurlSingleLayerDP3D, R = @SVector[αjGG*g[i].value for i in 1:3] return @SMatrix[dot(f[i].value × nx, R[j]) for i in 1:3, j in 1:3] end - f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) - Q = sauterschwab_parameterized(f, strat) + + Q = sauterschwab_parameterized(igd, strat) for j ∈ 1:3 for i ∈ 1:3 - # out[i,j] += Q[K[i],L[j]] - out[i,j] += Q[i,j] + out[i,j] += Q[K[i],L[j]] end end - @assert out_old ≈ out rtol = eps() + nothing end @@ -76,51 +72,3 @@ function quadrule(op::BEAST.CurlSingleLayerDP3D, qrdf(op, test_local_space, trial_local_space, test_index, test_chart, trial_index, trial_chart, quadrature_data) end - -function momintegrals!_old(op::CurlSingleLayerDP3D, - test_local_space::RTRefSpace, trial_local_space::LagrangeRefSpace, - test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) - - I, J, K, L = SauterSchwabQuadrature.reorder( - test_triangular_element.vertices, - trial_triangular_element.vertices, strat) - - test_triangular_element = simplex(test_triangular_element.vertices[I]...) - trial_triangular_element = simplex(trial_triangular_element.vertices[J]...) - - function igd(u,v) - α = op.alpha - γ = op.gamma - - x = neighborhood(test_triangular_element,u) - y = neighborhood(trial_triangular_element,v) - - nx = normal(x) - - r = cartesian(x) - cartesian(y) - R = norm(r) - G = exp(-γ*R)/(4π*R) - GG = -(γ + 1/R) * G / R * r - - f = test_local_space(x) - g = trial_local_space(y) - - jx = jacobian(x) - jy = jacobian(y) - j = jx*jy - - αjGG = α*j*GG - - R = @SVector[αjGG*g[i].value for i in 1:3] - return @SMatrix[dot(f[i].value × nx, R[j]) for i in 1:3, j in 1:3] - end - - Q = sauterschwab_parameterized(igd, strat) - for j ∈ 1:3 - for i ∈ 1:3 - out[i,j] += Q[K[i],L[j]] - end - end - - nothing -end \ No newline at end of file diff --git a/src/helmholtz3d/hh3d_sauterschwabqr.jl b/src/helmholtz3d/hh3d_sauterschwabqr.jl index 6359f39a..ed658088 100644 --- a/src/helmholtz3d/hh3d_sauterschwabqr.jl +++ b/src/helmholtz3d/hh3d_sauterschwabqr.jl @@ -119,48 +119,24 @@ function pulled_back_integrand(op::HH3DDoubleLayerTransposedFDBIO, end end + function momintegrals!(op::Helmholtz3DOp, test_local_space::LagrangeRefSpace{<:Any,0}, trial_local_space::LagrangeRefSpace{<:Any,0}, test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) - out_old = copy(out) - momintegrals!_old(op,test_local_space,trial_local_space,test_triangular_element,trial_triangular_element,out_old,strat) I, J, K, L = SauterSchwabQuadrature.reorder( test_triangular_element.vertices, trial_triangular_element.vertices, strat) - # test_triangular_elementex = simplex( - # test_triangular_element.vertices[I[1]], - # test_triangular_element.vertices[I[2]], - # test_triangular_element.vertices[I[3]]) - - # trial_triangular_elementex = simplex( - # trial_triangular_element.vertices[J[1]], - # trial_triangular_element.vertices[J[2]], - # trial_triangular_element.vertices[J[3]]) - - # test_sign = Combinatorics.levicivita(I) - # trial_sign = Combinatorics.levicivita(J) - # σ = momintegrals_sign(op, test_sign, trial_sign) - # @assert sign(dot(normal(test_triangular_element),normal(test_triangular_elementex))) == test_sign - # test_triangular_element = CompScienceMeshes.Simplex(test_triangular_elementex.vertices, - # test_triangular_elementex.tangents, - # test_triangular_element.normals, - # test_triangular_elementex.volume) - # trial_triangular_element = CompScienceMeshes.Simplex(trial_triangular_elementex.vertices, - # trial_triangular_elementex.tangents, - # trial_triangular_element.normals, - # trial_triangular_elementex.volume) + test_triangular_element = CompScienceMeshes.permute_vertices(test_triangular_element,I) + trial_triangular_element = CompScienceMeshes.permute_vertices(trial_triangular_element,J) igd = pulled_back_integrand(op, test_local_space, trial_local_space, test_triangular_element, trial_triangular_element) + G = SauterSchwabQuadrature.sauterschwab_parameterized(igd, strat) + out[1,1] += G[1,1] #* σ - f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) - G = SauterSchwabQuadrature.sauterschwab_parameterized(f, strat) - out[1,1] += G[1,1]# * σ - - @assert out_old ≈ out rtol = eps() nothing end @@ -168,136 +144,75 @@ end function momintegrals!(op::Helmholtz3DOp, test_local_space::LagrangeRefSpace, trial_local_space::LagrangeRefSpace, test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) - out_old = copy(out) - momintegrals!_old(op,test_local_space,trial_local_space,test_triangular_element,trial_triangular_element,out_old,strat) + I, J, K, L = SauterSchwabQuadrature.reorder( test_triangular_element.vertices, trial_triangular_element.vertices, strat) - # test_triangular_elementex = simplex( - # test_triangular_element.vertices[I[1]], - # test_triangular_element.vertices[I[2]], - # test_triangular_element.vertices[I[3]]) - - # trial_triangular_elementex = simplex( - # trial_triangular_element.vertices[J[1]], - # trial_triangular_element.vertices[J[2]], - # trial_triangular_element.vertices[J[3]]) - - # test_sign = Combinatorics.levicivita(I) - # trial_sign = Combinatorics.levicivita(J) - # σ = momintegrals_sign(op, test_sign, trial_sign) - # @assert sign(dot(normal(test_triangular_element),normal(test_triangular_elementex))) == test_sign - # test_triangular_element = CompScienceMeshes.Simplex(test_triangular_elementex.vertices, - # test_triangular_elementex.tangents, - # test_triangular_element.normals, - # test_triangular_elementex.volume) - # trial_triangular_element = CompScienceMeshes.Simplex(trial_triangular_elementex.vertices, - # trial_triangular_elementex.tangents, - # trial_triangular_element.normals, - # trial_triangular_elementex.volume) + test_triangular_element = CompScienceMeshes.permute_vertices(test_triangular_element,I) + + trial_triangular_element = CompScienceMeshes.permute_vertices(trial_triangular_element,J) + igd = pulled_back_integrand(op, test_local_space, trial_local_space, test_triangular_element, trial_triangular_element) - f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) - G = SauterSchwabQuadrature.sauterschwab_parameterized(f, strat) + G = SauterSchwabQuadrature.sauterschwab_parameterized(igd, strat) for j ∈ 1:3, i ∈ 1:3 - # out[i,j] += G[K[i],L[j]]# * σ - out[i,j] += G[i,j]# * σ + out[i,j] += G[K[i],L[j]]# * σ end - @assert out_old ≈ out rtol = eps() + nothing end function momintegrals!(op::Helmholtz3DOp, test_local_space::LagrangeRefSpace{<:Any,0}, trial_local_space::LagrangeRefSpace{<:Any,1}, test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) - out_old = copy(out) - momintegrals!_old(op,test_local_space,trial_local_space,test_triangular_element,trial_triangular_element,out_old,strat) + I, J, K, L = SauterSchwabQuadrature.reorder( test_triangular_element.vertices, trial_triangular_element.vertices, strat) - - # test_triangular_elementex = simplex( - # test_triangular_element.vertices[I[1]], - # test_triangular_element.vertices[I[2]], - # test_triangular_element.vertices[I[3]]) - - # trial_triangular_elementex = simplex( - # trial_triangular_element.vertices[J[1]], - # trial_triangular_element.vertices[J[2]], - # trial_triangular_element.vertices[J[3]]) - - # test_sign = Combinatorics.levicivita(I) - # trial_sign = Combinatorics.levicivita(J) - # σ = momintegrals_sign(op, test_sign, trial_sign) - # @assert sign(dot(normal(test_triangular_element),normal(test_triangular_elementex))) == test_sign - # test_triangular_element = CompScienceMeshes.Simplex(test_triangular_elementex.vertices, - # test_triangular_elementex.tangents, - # test_triangular_element.normals, - # test_triangular_elementex.volume) - # trial_triangular_element = CompScienceMeshes.Simplex(trial_triangular_elementex.vertices, - # trial_triangular_elementex.tangents, - # trial_triangular_element.normals, - # trial_triangular_elementex.volume) + + test_triangular_element = CompScienceMeshes.permute_vertices(test_triangular_element,I) + + trial_triangular_element = CompScienceMeshes.permute_vertices(trial_triangular_element,J) + igd = pulled_back_integrand(op, test_local_space, trial_local_space, test_triangular_element, trial_triangular_element) - f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) - G = SauterSchwabQuadrature.sauterschwab_parameterized(f, strat) + G = SauterSchwabQuadrature.sauterschwab_parameterized(igd, strat) for i ∈ 1:3 - #out[1,i] += G[L[i]]# * σ - out[1,i] += G[i]# * σ + out[1,i] += G[L[i]]# * σ end - @assert out_old ≈ out rtol = eps() + nothing end function momintegrals!(op::Helmholtz3DOp, test_local_space::LagrangeRefSpace{<:Any,1}, trial_local_space::LagrangeRefSpace{<:Any,0}, test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) - out_old = copy(out) - momintegrals!_old(op,test_local_space,trial_local_space,test_triangular_element,trial_triangular_element,out_old,strat) + I, J, K, L = SauterSchwabQuadrature.reorder( test_triangular_element.vertices, trial_triangular_element.vertices, strat) - # test_triangular_element = simplex( - # test_triangular_element.vertices[I[1]], - # test_triangular_element.vertices[I[2]], - # test_triangular_element.vertices[I[3]]) - - # trial_triangular_element = simplex( - # trial_triangular_element.vertices[J[1]], - # trial_triangular_element.vertices[J[2]], - # trial_triangular_element.vertices[J[3]]) - # # test_triangular_element = CompScienceMeshes.Simplex(test_triangular_element1.vertices, - # # test_triangular_element1.tangents, - # # test_triangular_element.normals, - # # test_triangular_element1.volume) - # # trial_triangular_element = CompScienceMeshes.Simplex(trial_triangular_element1.vertices, - # # trial_triangular_element1.tangents, - # # trial_triangular_element.normals, - # # trial_triangular_element1.volume) - # test_sign = Combinatorics.levicivita(I) - # trial_sign = Combinatorics.levicivita(J) - - # σ = momintegrals_sign(op, test_sign, trial_sign) + test_triangular_element = CompScienceMeshes.permute_vertices(test_triangular_element,I) + + trial_triangular_element = CompScienceMeshes.permute_vertices(trial_triangular_element,J) + igd = pulled_back_integrand(op, test_local_space, trial_local_space, test_triangular_element, trial_triangular_element) - f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) - G = SauterSchwabQuadrature.sauterschwab_parameterized(f, strat) + G = SauterSchwabQuadrature.sauterschwab_parameterized(igd, strat) for i ∈ 1:3 - #out[i,1] += G[K[i]] * σ - out[i,1] += G[i] + out[i,1] += G[K[i]]# * σ end - @assert out_old ≈ out rtol = eps() + nothing end + function momintegrals_sign(op::HH3DSingleLayerFDBIO, test_sign, trial_sign) return 1 end @@ -312,135 +227,3 @@ function momintegrals_sign(op::HH3DHyperSingularFDBIO, test_sign, trial_sign) end - -function momintegrals!_old(op::Helmholtz3DOp, - test_local_space::LagrangeRefSpace{<:Any,0}, trial_local_space::LagrangeRefSpace{<:Any,0}, - test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) - - I, J, K, L = SauterSchwabQuadrature.reorder( - test_triangular_element.vertices, - trial_triangular_element.vertices, strat) - - test_triangular_element = simplex( - test_triangular_element.vertices[I[1]], - test_triangular_element.vertices[I[2]], - test_triangular_element.vertices[I[3]]) - - trial_triangular_element = simplex( - trial_triangular_element.vertices[J[1]], - trial_triangular_element.vertices[J[2]], - trial_triangular_element.vertices[J[3]]) - - test_sign = Combinatorics.levicivita(I) - trial_sign = Combinatorics.levicivita(J) - σ = momintegrals_sign(op, test_sign, trial_sign) - - igd = pulled_back_integrand(op, test_local_space, trial_local_space, - test_triangular_element, trial_triangular_element) - G = SauterSchwabQuadrature.sauterschwab_parameterized(igd, strat) - out[1,1] += G[1,1] * σ - - nothing -end - - -function momintegrals!_old(op::Helmholtz3DOp, - test_local_space::LagrangeRefSpace, trial_local_space::LagrangeRefSpace, - test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) - - I, J, K, L = SauterSchwabQuadrature.reorder( - test_triangular_element.vertices, - trial_triangular_element.vertices, strat) - - test_triangular_element = simplex( - test_triangular_element.vertices[I[1]], - test_triangular_element.vertices[I[2]], - test_triangular_element.vertices[I[3]]) - - trial_triangular_element = simplex( - trial_triangular_element.vertices[J[1]], - trial_triangular_element.vertices[J[2]], - trial_triangular_element.vertices[J[3]]) - - test_sign = Combinatorics.levicivita(I) - trial_sign = Combinatorics.levicivita(J) - - σ = momintegrals_sign(op, test_sign, trial_sign) - - igd = pulled_back_integrand(op, test_local_space, trial_local_space, - test_triangular_element, trial_triangular_element) - G = SauterSchwabQuadrature.sauterschwab_parameterized(igd, strat) - for j ∈ 1:3, i ∈ 1:3 - out[i,j] += G[K[i],L[j]] * σ - end - - nothing -end - -function momintegrals!_old(op::Helmholtz3DOp, - test_local_space::LagrangeRefSpace{<:Any,0}, trial_local_space::LagrangeRefSpace{<:Any,1}, - test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) - - I, J, K, L = SauterSchwabQuadrature.reorder( - test_triangular_element.vertices, - trial_triangular_element.vertices, strat) - - test_triangular_element = simplex( - test_triangular_element.vertices[I[1]], - test_triangular_element.vertices[I[2]], - test_triangular_element.vertices[I[3]]) - - trial_triangular_element = simplex( - trial_triangular_element.vertices[J[1]], - trial_triangular_element.vertices[J[2]], - trial_triangular_element.vertices[J[3]]) - - test_sign = Combinatorics.levicivita(I) - trial_sign = Combinatorics.levicivita(J) - - σ = momintegrals_sign(op, test_sign, trial_sign) - - igd = pulled_back_integrand(op, test_local_space, trial_local_space, - test_triangular_element, trial_triangular_element) - G = SauterSchwabQuadrature.sauterschwab_parameterized(igd, strat) - - for i ∈ 1:3 - out[1,i] += G[L[i]] * σ - end - - nothing -end - -function momintegrals!_old(op::Helmholtz3DOp, - test_local_space::LagrangeRefSpace{<:Any,1}, trial_local_space::LagrangeRefSpace{<:Any,0}, - test_triangular_element, trial_triangular_element, out, strat::SauterSchwabStrategy) - - I, J, K, L = SauterSchwabQuadrature.reorder( - test_triangular_element.vertices, - trial_triangular_element.vertices, strat) - - test_triangular_element = simplex( - test_triangular_element.vertices[I[1]], - test_triangular_element.vertices[I[2]], - test_triangular_element.vertices[I[3]]) - - trial_triangular_element = simplex( - trial_triangular_element.vertices[J[1]], - trial_triangular_element.vertices[J[2]], - trial_triangular_element.vertices[J[3]]) - - test_sign = Combinatorics.levicivita(I) - trial_sign = Combinatorics.levicivita(J) - - σ = momintegrals_sign(op, test_sign, trial_sign) - - igd = pulled_back_integrand(op, test_local_space, trial_local_space, - test_triangular_element, trial_triangular_element) - G = SauterSchwabQuadrature.sauterschwab_parameterized(igd, strat) - - for i ∈ 1:3 - out[i,1] += G[K[i]] * σ - end - - nothing -end \ No newline at end of file diff --git a/src/quadrature/sauterschwabints.jl b/src/quadrature/sauterschwabints.jl index 08b35ef7..25b3a583 100644 --- a/src/quadrature/sauterschwabints.jl +++ b/src/quadrature/sauterschwabints.jl @@ -83,47 +83,9 @@ function (igd::Integrand)(x,y,f,g) end -# function sign_upon_permutation(op, I, J) -# return 1 -# end -function momintegrals!(op::Operator, - test_local_space::RefSpace, trial_local_space::RefSpace, - test_chart, trial_chart, out, rule::SauterSchwabStrategy) - - out_old = copy(out) - momintegrals!_old(op,test_local_space,trial_local_space,test_chart,trial_chart,out_old,rule) - I, J, K, L = SauterSchwabQuadrature.reorder( - test_chart.vertices, - trial_chart.vertices, rule) - - igd = Integrand(op, test_local_space, trial_local_space, test_chart, trial_chart) - K1 = dof_permutation(test_local_space, I) - L1 = dof_permutation(trial_local_space, J) - K1 = [i for i in K1] - L1 = [i for i in L1] - @assert K1 == K - @assert L1 == L - f = (u,v) -> igd(permute_barycentric(K,u),permute_barycentric(L,v)) - G = SauterSchwabQuadrature.sauterschwab_parameterized(f, rule) - # σ = sign_upon_permutation(op, I, J) - for i in 1:numfunctions(test_local_space) - for j in 1:numfunctions(trial_local_space) - #out[i,j] = σ * G[K[i],L[j]] - out[i,j] =G[i,j] - end end - if typeof(abs(out[1,1])) <: Float64 - - @assert isapprox(out,out_old,rtol=eps(Float64)) - - end - - - nothing -end - -function momintegrals!_old(op::Operator, +function momintegrals!(op::Operator, test_local_space::RefSpace, trial_local_space::RefSpace, test_chart, trial_chart, out, rule::SauterSchwabStrategy) @@ -131,25 +93,19 @@ function momintegrals!_old(op::Operator, test_chart.vertices, trial_chart.vertices, rule) - test_chart = simplex( - test_chart.vertices[I[1]], - test_chart.vertices[I[2]], - test_chart.vertices[I[3]]) + test_chart = CompScienceMeshes.permute_vertices(test_chart,I) - trial_chart = simplex( - trial_chart.vertices[J[1]], - trial_chart.vertices[J[2]], - trial_chart.vertices[J[3]]) + trial_chart = CompScienceMeshes.permute_vertices(trial_chart,J) igd = Integrand(op, test_local_space, trial_local_space, test_chart, trial_chart) G = SauterSchwabQuadrature.sauterschwab_parameterized(igd, rule) - σ = sign_upon_permutation(op, I, J) + #σ = sign_upon_permutation(op, I, J) K = dof_permutation(test_local_space, I) L = dof_permutation(trial_local_space, J) for i in 1:numfunctions(test_local_space) for j in 1:numfunctions(trial_local_space) - out[i,j] = σ * G[K[i],L[j]] + out[i,j] = G[K[i],L[j]] # * σ end end nothing From 397f843132c3f66167157f53be9aa4f8c30ee4ea Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 26 Oct 2023 14:09:03 +0200 Subject: [PATCH 050/110] Revert "Merge branch 'master' into decouple-normal" This reverts commit 1c1d9fe0479477c252fec58a9d2e9a712538c65b, reversing changes made to c2da4df420cb6dc3a36d377f04f50f6dd0fb837f. wrong commit --- .gitignore | 2 - src/BEAST.jl | 9 - src/Helmholtzhodge/helmholtzhodge.jl | 39 --- src/Helmholtzhodge/hhhop.jl | 173 ---------- src/bases/basis.jl | 9 - src/bases/bdm3dspace.jl | 2 +- src/bases/bdmdiv.jl | 2 +- src/bases/lagrange.jl | 2 +- src/bases/ncrossbdmspace.jl | 2 +- src/bases/ndlccspace.jl | 2 +- src/bases/ndlcdspace.jl | 2 +- src/bases/ndspace.jl | 2 +- src/bases/rtspace.jl | 2 +- src/bases/trace.jl | 3 +- src/integralop.jl | 1 + src/maxwell/maxwell.jl | 3 +- src/maxwell/mwops.jl | 474 +-------------------------- src/maxwell/nxdbllayer.jl | 3 +- src/operator.jl | 45 +-- src/quadrature/quadrule.jl | 2 +- src/quadrature/quadstrats.jl | 5 +- test/runtests.jl | 2 +- test/test_HHHoperators.jl | 34 -- 23 files changed, 24 insertions(+), 796 deletions(-) delete mode 100644 src/Helmholtzhodge/helmholtzhodge.jl delete mode 100644 src/Helmholtzhodge/hhhop.jl delete mode 100644 test/test_HHHoperators.jl diff --git a/.gitignore b/.gitignore index 997e7ab0..bfa3e6f8 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,3 @@ programs/draft/test_ttrace_doublelayer.jl programs/draft/vector_potential_sphere.jl src/todo.txt -programs/ -results/ diff --git a/src/BEAST.jl b/src/BEAST.jl index b6a6e1d3..e47cef53 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -28,11 +28,7 @@ import SharedArrays: sdata export dot -export ⋅ -export trace -export MWgradgreendot, MWgreenint export planewave -export inside, outside export RefSpace, numfunctions, coordtype, scalartype, assemblydata, geometry, refspace, valuetype export lagrangecxd0, lagrangec0d1, duallagrangec0d1 export duallagrangecxd0 @@ -262,11 +258,6 @@ include("solvers/itsolver.jl") include("utils/plotlyglue.jl") -#suport for helmholtzhodge equation -include("Helmholtzhodge/hhhop.jl") -include("Helmholtzhodge/helmholtzhodge.jl") - - diff --git a/src/Helmholtzhodge/helmholtzhodge.jl b/src/Helmholtzhodge/helmholtzhodge.jl deleted file mode 100644 index 89a5f77c..00000000 --- a/src/Helmholtzhodge/helmholtzhodge.jl +++ /dev/null @@ -1,39 +0,0 @@ -module HHH - using ..BEAST - Mod = BEAST - - function green(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end - end - Mod.HHHgreen(alpha,gamma,Mod.hhhidentity()) - end - - function gradgreen(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end - end - Mod.HHHgradgreen(alpha,gamma,Mod.hhhidentity()) -end - -end \ No newline at end of file diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl deleted file mode 100644 index 8271118e..00000000 --- a/src/Helmholtzhodge/hhhop.jl +++ /dev/null @@ -1,173 +0,0 @@ -import LinearAlgebra: ×, ⋅ -abstract type HHHOperator{T,K} <: IntegralOperator end -abstract type HHHtestOperator{T,K} <: HHHOperator{T,K} end -abstract type HHHbasisOperator{T,K} <: HHHOperator{T,K} end -abstract type HHHkernelOperator{T,K} <: HHHOperator{T,K} end -# scalartype(op::HHHOperator{T,K}) where {T, K <: Nothing} = T -# scalartype(op::HHHOperator{T,K}) where {T, K} = promote_type(T, K) -scalartype(op::HHHOperator{T,K}) where {T, K <: Nothing} = Complex -scalartype(op::HHHOperator{T,K}) where {T, K} = Complex - - -const i4pi = 1 / (4pi) -mutable struct HHHgreen{T,K} <: HHHkernelOperator{T,K} - α::K - γ::T - op::HHHOperator -end - -mutable struct HHHgradgreen{T,K} <: HHHkernelOperator{T,K} - α::K - γ::T - op::HHHOperator -end - -mutable struct HHHgradgreenCross{T,K} <: HHHkernelOperator{T,K} - α::K - γ::T - op::HHHOperator -end - -abstract type HHHdata end -struct HHHvector <:HHHdata end -struct HHHscalar <:HHHdata end - - -mutable struct HHHNtestCross{T,K} <: HHHtestOperator{T,K} - op::HHHOperator{T,K} -end - - -mutable struct HHHNbasisCross{T,K} <: HHHbasisOperator{T,K} - op::HHHOperator{T,K} -end - -mutable struct HHHNtestDot{T,K} <: HHHtestOperator{T,K} - op::HHHOperator{T,K} -end - -mutable struct HHHNbasisnormal{T,K} <: HHHbasisOperator{T,K} - op::HHHOperator{T,K} -end -mutable struct HHHNbasisdot{T,K} <: HHHbasisOperator{T,K} - op::HHHOperator{T,K} -end -mutable struct HHHIdentity{T,K} <: HHHbasisOperator{T,K} -end -hhhidentity() = HHHIdentity{Complex,Complex}() -export HHH -struct BasisFunction end -basisfunction() = BasisFunction() -export basisfunction -VectorToVector = Union{HHHNtestCross,HHHNbasisCross,HHHgradgreenCross,HHHgreen} -ScalarToVector = Union{HHHNbasisnormal,HHHgradgreen} -VectorToScalar = Union{HHHNtestDot,HHHgradgreen,HHHNbasisdot} -ScalarToScalar = Union{HHHgreen} -inversemap(op::VectorToVector,::HHHvector) = inversemap(op.op,HHHvector()) -inversemap(op::ScalarToVector,::HHHvector) = inversemap(op.op,HHHscalar()) -inversemap(op::VectorToScalar,::HHHscalar) = inversemap(op.op,HHHvector()) -inversemap(op::ScalarToScalar,::HHHscalar) = HHHscalar() -inversemap(::HHHOperator,::HHHdata) = @error "trying to convert scalar to vector or vector to scalar" -inversemap(::HHHIdentity,data::HHHdata) = data -##### Operator building - -strace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestCross(op) -ntrace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestDot(op) -×(op::HHHgradgreen,::Nothing) = HHHgradgreenCross(op.α,op.γ,op.op) -×(op::HHHgradgreen,::NormalVector) = HHHgradgreenCross(op.α,op.γ,op.op)(HHHNbasisnormal(hhhidentity())) -×(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = strace(op) -⋅(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = ntrace(op) -*(::NormalVector,::BasisFunction) = HHHNbasisnormal(hhhidentity()) -⋅(::NormalVector,::BasisFunction) = HHHNbasisdot(hhhidentity()) -×(::NormalVector,::BasisFunction) = HHHNbasisCross(hhhidentity()) -×(::NormalVector,op::HHHbasisOperator) = HHHNbasisCross(op) -⋅(::NormalVector,op::HHHbasisOperator) = HHHNbasisdot(op) - - -function (op::HHHkernelOperator)(Basisop::HHHbasisOperator) - return typeof(op)(op.α,op.γ,Basisop) -end - - - -function (op::HHHOperator)(BasisOperator::HHHbasisOperator) - op.op = BasisOperator -end - - -##### Integrand definitions -function (igd::Integrand{<:HHHOperator})(x,y,f,g) - op = igd.operator - -test = getvalue(f) -_krondot(test,op(x,y,g)) -end -function (op::HHHNtestCross)(x,y,g) - nx = normal(x) - cross.(Ref(nx),op.op(x,y,g)) -end -function (op::HHHNtestDot)(x,y,g) - nx = normal(x) - dot.(Ref(nx),op.op(x,y,g)) -end -function (op::HHHNbasisnormal)(x,y,g) - ny = normal(y) - Ref(ny).*op.op(x,y,g) -end -function (op::HHHNbasisdot)(x,y,g) - ny = normal(y) - dot.(Ref(ny),op.op(x,y,g)) -end -function (op::HHHNbasisCross)(x,y,g) - ny = normal(y) - cross.(Ref(ny),op.op(x,y,g)) -end -function (op::HHHIdentity)(x,y,g) - getvalue(g) -end -function (op::HHHgreen)(x,y,g) - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = op.α * exp(-op.γ*R)*(iR*i4pi) - green*op.op(x,y,g) -end -mydot(a::SVector{N,<:SVector},b::Base.RefValue) where {N} = dot.(a,b) -function mydot(a::SVector,b::Base.RefValue) - a.*b -end -function (op::HHHgradgreen)(x,y,g) - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = op.α * exp(-op.γ*R)*(iR*i4pi) - gradgreen = -(op.γ + iR) * green * (iR * r) - mydot(op.op(x,y,g),Ref(gradgreen)) -end - -function (op::HHHgradgreenCross)(x,y,g) - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = op.α * exp(-op.γ*R)*(iR*i4pi) - gradgreen = -(op.γ + iR) * green * (iR * r) - cross.(Ref(gradgreen),op.op(x,y,g)) -end -identify(::VectorSurfaceSpace) = HHHvector() -identify(::ScalarSurfaceSpace) = HHHscalar() -kernel(op::HHHtestOperator) = kernel(op.op) -kernel(op::HHHkernelOperator) = op - -function defaultquadstrat(op::HHHOperator,testspace::Space,basisspace::Space) -@assert identify(basisspace) == inversemap(op,identify(testspace)) -defaultquadstrat(op,identify(testspace),identify(basisspace)) -end -defaultquadstrat(op::HHHOperator,::HHHdata,::HHHdata) = DoubleNumSauterQstrat(6,7,5,5,4,3) #TODO implement strategy that is stronger for nearby triangles - - -sign_upon_permutation(op::HHHIdentity,I,J) = 1 -sign_upon_permutation(op::HHHkernelOperator,I,J) = sign_upon_permutation(op.op,I,J) -sign_upon_permutation(op::Union{HHHNtestCross,HHHNtestDot},I,J) = Combinatorics.levicivita(I)*sign_upon_permutation(op.op,I,J) -sign_upon_permutation(op::Union{HHHNbasisnormal,HHHNbasisCross,HHHNbasisdot},I,J) = Combinatorics.levicivita(J)*sign_upon_permutation(op.op,I,J) - diff --git a/src/bases/basis.jl b/src/bases/basis.jl index c3d69ca5..40ddedf0 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -1,15 +1,6 @@ abstract type RefSpace{T,D} end abstract type AbstractSpace end abstract type Space{T} <: AbstractSpace end -abstract type ScalarSpace{T} <: Space{T} end -abstract type VectorSpace{T} <: Space{T} end -abstract type ScalarSurfaceSpace{T} <: ScalarSpace{T} end -abstract type ScalarVolumeSpace{T} <: ScalarSpace{T} end -abstract type VectorSurfaceSpace{T} <: VectorSpace{T} end -abstract type VectorVolumeSpace{T} <: VectorSpace{T} end - -VolumeSpace = Union{ScalarVolumeSpace,VectorVolumeSpace} -SurfaceSpace = Union{ScalarSurfaceSpace,VectorSurfaceSpace} Base.length(s::AbstractSpace) = numfunctions(s) Base.in(x, s::AbstractSpace) = (x => s) diff --git a/src/bases/bdm3dspace.jl b/src/bases/bdm3dspace.jl index 8cdc2414..cabb8774 100644 --- a/src/bases/bdm3dspace.jl +++ b/src/bases/bdm3dspace.jl @@ -1,4 +1,4 @@ -mutable struct BDM3DBasis{T,M,P} <: VectorVolumeSpace{T} +mutable struct BDM3DBasis{T,M,P} <: Space{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/bdmdiv.jl b/src/bases/bdmdiv.jl index 72cc11c7..7865825d 100644 --- a/src/bases/bdmdiv.jl +++ b/src/bases/bdmdiv.jl @@ -1,4 +1,4 @@ -struct BDMBasis{T,M,P} <: VectorSurfaceSpace{T} +struct BDMBasis{T,M,P} <: Space{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/lagrange.jl b/src/bases/lagrange.jl index 0b66e17f..790492e3 100644 --- a/src/bases/lagrange.jl +++ b/src/bases/lagrange.jl @@ -11,7 +11,7 @@ function lagdimension end # M: mesh type # T: field type # NF: number of local shape functions -mutable struct LagrangeBasis{D,C,M,T,NF,P} <: ScalarSurfaceSpace{T} +mutable struct LagrangeBasis{D,C,M,T,NF,P} <: Space{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/ncrossbdmspace.jl b/src/bases/ncrossbdmspace.jl index efda3646..c5ed0364 100644 --- a/src/bases/ncrossbdmspace.jl +++ b/src/bases/ncrossbdmspace.jl @@ -1,4 +1,4 @@ -struct NCrossBDMBasis{T,M,P} <: VectorSurfaceSpace{T} +struct NCrossBDMBasis{T,M,P} <: Space{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/ndlccspace.jl b/src/bases/ndlccspace.jl index 5fce51a9..aabea3e6 100644 --- a/src/bases/ndlccspace.jl +++ b/src/bases/ndlccspace.jl @@ -1,4 +1,4 @@ -mutable struct NDLCCBasis{T,M,P} <: VectorVolumeSpace{T} +mutable struct NDLCCBasis{T,M,P} <: Space{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/ndlcdspace.jl b/src/bases/ndlcdspace.jl index d9ea5828..11d43b81 100644 --- a/src/bases/ndlcdspace.jl +++ b/src/bases/ndlcdspace.jl @@ -1,4 +1,4 @@ -mutable struct NDLCDBasis{T,M,P} <: VectorVolumeSpace{T} +mutable struct NDLCDBasis{T,M,P} <: Space{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/ndspace.jl b/src/bases/ndspace.jl index 6bcc1815..0393e5bb 100644 --- a/src/bases/ndspace.jl +++ b/src/bases/ndspace.jl @@ -1,4 +1,4 @@ -struct NDBasis{T,M,P} <: VectorSurfaceSpace{T} +struct NDBasis{T,M,P} <: Space{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/rtspace.jl b/src/bases/rtspace.jl index 933e48cd..b6a280a6 100644 --- a/src/bases/rtspace.jl +++ b/src/bases/rtspace.jl @@ -1,6 +1,6 @@ -mutable struct RTBasis{T,M,P} <: VectorSurfaceSpace{T} +mutable struct RTBasis{T,M,P} <: Space{T} geo::M fns::Vector{Vector{Shape{T}}} pos::Vector{P} diff --git a/src/bases/trace.jl b/src/bases/trace.jl index f0ef8ce4..ea52a307 100644 --- a/src/bases/trace.jl +++ b/src/bases/trace.jl @@ -17,7 +17,7 @@ function strace(X::DirectProductSpace{T}, γ) where T return DirectProductSpace(x) end -struct SameBase end + function ntrace(X::Space, γ) @@ -193,7 +193,6 @@ currently not working! # # ttrace(X, Σ, fns) # end -ttrace(X::Space, y::SameBase)=X function ttrace(X::Space, γ) diff --git a/src/integralop.jl b/src/integralop.jl index 7aa2fa45..f4a61320 100644 --- a/src/integralop.jl +++ b/src/integralop.jl @@ -115,6 +115,7 @@ function assemblechunk_body!(biop, todo, done, pctg = length(test_elements), 0, 0 for (p,tcell) in enumerate(test_elements) for (q,bcell) in enumerate(trial_elements) + fill!(zlocal, 0) qrule = quadrule(biop, test_shapes, trial_shapes, p, tcell, q, bcell, qd, quadstrat) momintegrals!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, qrule) diff --git a/src/maxwell/maxwell.jl b/src/maxwell/maxwell.jl index b9c36725..6a26e6b4 100644 --- a/src/maxwell/maxwell.jl +++ b/src/maxwell/maxwell.jl @@ -1,4 +1,5 @@ module Maxwell3D + using ..BEAST Mod = BEAST @@ -74,6 +75,4 @@ module Maxwell3D farfield(; wavenumber = error("missing argument: `wavenumber`")) = Mod.MWFarField3D(wavenumber=wavenumber) - - end diff --git a/src/maxwell/mwops.jl b/src/maxwell/mwops.jl index f6fd05aa..5f034de6 100644 --- a/src/maxwell/mwops.jl +++ b/src/maxwell/mwops.jl @@ -1,8 +1,6 @@ abstract type MaxwellOperator3D{T,K} <: IntegralOperator end abstract type MaxwellOperator3DReg{T,K} <: MaxwellOperator3D{T,K} end - - scalartype(op::MaxwellOperator3D{T,K}) where {T, K <: Nothing} = T scalartype(op::MaxwellOperator3D{T,K}) where {T, K} = promote_type(T, K) @@ -35,10 +33,7 @@ function kernelvals(biop::MaxwellOperator3D, p, q) KernelValsMaxwell3D(γ, r, R, green, gradgreen) end -struct MWDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} - alpha::T - gamma::K -end + struct MWSingleLayer3D{T,U} <: MaxwellOperator3D{T,U} gamma::T @@ -46,142 +41,6 @@ struct MWSingleLayer3D{T,U} <: MaxwellOperator3D{T,U} β::U end -# struct MWgreenint{T,U} <: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end - -# trace(op::MWgreenint,or::Orientation) = op -# sign_upon_permutation(op::MWgreenint, I, J) = 1 - -# struct MWgradgreendot{T,U} <: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# trace(op::MWgradgreendot,or::Orientation) = op -# sign_upon_permutation(op::MWgradgreendot, I, J) = 1 - - -# struct nXMWgreenint{T,U} <: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# sign_upon_permutation(op::nXMWgreenint, I, J) = Combinatorics.levicivita(I) -# trace(op::nXMWgreenint,or::Orientation) = op - - -# struct nXdoublelayer{T,U} <: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# sign_upon_permutation(op::nXdoublelayer, I, J) = Combinatorics.levicivita(I) -# trace(op::nXdoublelayer,or::Orientation) = op-1/2*Identity() - - - -# struct MWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# sign_upon_permutation(op::MWgreenintdotn, I, J) = Combinatorics.levicivita(J) -# trace(op::MWgreenintdotn,or::Orientation) = op - - -# struct nXMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# sign_upon_permutation(op::nXMWgreenintdotn, I, J) = Combinatorics.levicivita(J)*Combinatorics.levicivita(I) -# trace(op::nXMWgreenintdotn,or::Orientation) = op - - -# struct nXMWgradgreendot{T,U}<: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# sign_upon_permutation(op::nXMWgradgreendot, I, J) = Combinatorics.levicivita(I) -# trace(op::nXMWgradgreendot,or::Orientation) = op - - -# struct MWgradgreendotn{T,U}<: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# sign_upon_permutation(op::MWgradgreendotn, I, J) = Combinatorics.levicivita(J) -# trace(op::MWgradgreendotn, or::Inside) = op+1/2*Identity() -# trace(op::MWgradgreendotn, or::Outside) = op-1/2*Identity() - - -# struct MWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# sign_upon_permutation(op::MWdoublelayerXn, I, J) = Combinatorics.levicivita(J) -# trace(op::MWdoublelayerXn,or::Orientation) = op - - -# struct nXMWdoublelayerXn{T,U}<: MaxwellOperator3D{T,U}#check haakjes rechts -# gamma::T -# α::U -# end -# sign_upon_permutation(op::nXMWdoublelayerXn, I, J) = Combinatorics.levicivita(I)*Combinatorics.levicivita(J) -# trace(op::nXMWdoublelayerXn,or::Orientation) = op - - -# struct ndotMWdoublelayer{T,U}<: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# sign_upon_permutation(op::ndotMWdoublelayer, I, J) = Combinatorics.levicivita(I) -# trace(op::ndotMWdoublelayer,or::Orientation) = op - - -# struct ndotMWgreenint{T,U}<: MaxwellOperator3D{T,U}#cehck -# gamma::T -# α::U -# end -# sign_upon_permutation(op::ndotMWgreenint, I, J) = Combinatorics.levicivita(I) -# trace(op::ndotMWgreenint,or::Orientation) = op - -# struct ndotMWgreenintdotn{T,U}<: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# sign_upon_permutation(op::ndotMWgreenintdotn, I, J) = Combinatorics.levicivita(J)*Combinatorics.levicivita(I) -# trace(op::ndotMWgreenintdotn,or::Orientation) = op - - -# struct ndotMWgradgreen{T,U}<: MaxwellOperator3D{T,U}#check -# gamma::T -# α::U -# end -# sign_upon_permutation(op::ndotMWgradgreen, I, J) = Combinatorics.levicivita(I) -# trace(op::ndotMWgradgreen,or::Orientation) = op+1/2*Identity() - -# ×(n::NormalVector,op::MWgreenint) = nXMWgreenint(op.gamma,op.α) -# ×(n::NormalVector,op::MWDoubleLayer3D) = nXdoublelayer(op.gamma,op.alpha) -# ⋅(op::MWgreenint,n::NormalVector) = MWgreenintdotn(op.gamma,op.α) -# ⋅(op::nXMWgreenint,n::NormalVector) = nXMWgreenintdotn(op.gamma,op.α) -# ×(n::NormalVector,op::MWgreenintdotn) = nXMWgreenintdotn(op.gamma,op.α) -# ×(n::NormalVector,op::MWgradgreendot) = nXMWgradgreendot(op.gamma,op.α) -# ⋅(op::MWgradgreendot,n::NormalVector) = MWgradgreendotn(op.gamma,op.α) -# ×(op::MWgradgreendot,n::NormalVector) = MWdoublelayerXn(op.gamma,op.α) -# ×(op::MWDoubleLayer3D,n::NormalVector) = MWdoublelayerXn(op.gamma,op.alpha) -# ×(n::NormalVector,op::MWdoublelayerXn) = nXMWdoublelayerXn(op.gamma,op.α) -# ⋅(n::NormalVector,op::MWDoubleLayer3D) = ndotMWdoublelayer(op.gamma,op.alpha) -# ⋅(n::NormalVector,op::MWgreenint) = ndotMWgreenint(op.gamma,op.α) -# ⋅(n::NormalVector,op::MWgreenintdotn) = ndotMWgreenintdotn(op.gamma,op.α) -# ⋅(op::ndotMWgreenint,n::NormalVector)= ndotMWgreenintdotn(op.gamma,op.α) -# ⋅(n::NormalVector,op::MWgradgreendot) = ndotMWgradgreen(op.gamma,op.α) - -# # struct MWgradgreenint{T,U} <: MaxwellOperator3D{T,U} -# # gamma::T -# # α::U -# # end -# # struct MWngradgreenint{T,U} <: MaxwellOperator3D{T,U} -# # gamma::T -# # α::U -# # end scalartype(op::MWSingleLayer3D{T,U}) where {T,U} = promote_type(T,U) sign_upon_permutation(op::MWSingleLayer3D, I, J) = 1 @@ -237,12 +96,10 @@ function quaddata(op::MaxwellOperator3D, return (tpoints=tqd, bpoints=bqd, gausslegendre=leg) end - - -# struct MWnDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} -# alpha::T -# gamma::K -# end +struct MWDoubleLayer3D{T,K} <: MaxwellOperator3D{T,K} + alpha::T + gamma::K +end sign_upon_permutation(op::MWDoubleLayer3D, I, J) = 1 @@ -257,7 +114,6 @@ struct MWDoubleLayer3DReg{T,K} <: MaxwellOperator3DReg{T,K} end MWDoubleLayer3D(gamma) = MWDoubleLayer3D(1.0, gamma) # For legacy purposes -# MWnDoubleLayer3D(gamma) = MWnDoubleLayer3D(1.0, gamma) # For legacy purposes regularpart(op::MWDoubleLayer3D) = MWDoubleLayer3DReg(op.alpha, op.gamma) singularpart(op::MWDoubleLayer3D) = MWDoubleLayer3DSng(op.alpha, op.gamma) @@ -276,15 +132,14 @@ function quadrule(op::MaxwellOperator3D, g::RTRefSpace, f::RTRefSpace, i, τ, j hits += (d2 < dtol) end end - + hits == 3 && return SauterSchwabQuadrature.CommonFace(qd.gausslegendre[3]) hits == 2 && return SauterSchwabQuadrature.CommonEdge(qd.gausslegendre[2]) hits == 1 && return SauterSchwabQuadrature.CommonVertex(qd.gausslegendre[1]) h2 = volume(σ) - xtol2 = 0.2 * 0.2 + xtol2 = 0.2 * 0.2 k2 = abs2(gamma(op)) - println(max(dmin2*k2, dmin2/16h2) < xtol2) max(dmin2*k2, dmin2/16h2) < xtol2 && return WiltonSERule( qd.tpoints[2,i], DoubleQuadRule( @@ -421,8 +276,6 @@ function (igd::Integrand{<:MWSingleLayer3D})(x,y,f,g) αG * dot(fi.value, gj.value) + βG * dot(fi.divergence, gj.divergence) end end -# ttrace!(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), SameBase() -# strace!(op::MWSingleLayer3D, mesh, or) = ZeroOperator(), mesh function (igd::Integrand{<:MWSingleLayer3DReg})(x,y,f,g) α = igd.operator.α @@ -459,92 +312,7 @@ function (igd::Integrand{<:MWDoubleLayer3D})(x,y,f,g) G = cross.(Ref(gradgreen), gvalue) return _krondot(fvalue, G) end -# function (igd::Integrand{<:ndotMWdoublelayer})(x,y,f,g) - -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# nx = normal(x) -# fvalue = getvalue(f) -# gvalue = getvalue(g) -# G = dot.(Ref(nx),cross.(Ref(gradgreen), gvalue)) -# return _krondot(fvalue, G) -# end -# function (igd::Integrand{<:MWdoublelayerXn})(x,y,f,g) - -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# ny = normal(y) -# fvalue = getvalue(f) -# gvalue = getvalue(g) -# G = cross.(Ref(cross(gradgreen,n)), gvalue) -# return _krondot(fvalue, G) -# end - -# function (igd::Integrand{<:nXdoublelayer})(x,y,f,g) - -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# nx = normal(x) -# fvalue = getvalue(f) -# gvalue = getvalue(g) -# G = cross.(Ref(cross(nx,gradgreen)), gvalue) -# return _krondot(fvalue, G) -# end -# function (igd::Integrand{<:nXMWdoublelayerXn})(x,y,f,g) - -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# nx = normal(x) -# ny = normal(y) -# fvalue = getvalue(f) -# gvalue = getvalue(g) -# G = Ref(cross(nx,cross(gradgreen,ny))).* gvalue -# return _krondot(fvalue, G) -# end -# # ttrace!(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), SameBase() -# # strace!(op::MWDoubleLayer3D, mesh, orientation::Inside) = 1/2*NCross(), mesh -# # ttrace!(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), SameBase() -# # strace!(op::MWDoubleLayer3D, mesh, orientation::Outside) = -1/2*NCross(), mesh - -# # function (igd::Integrand{<:MWnDoubleLayer3D})(x,y,f,g) - -# # γ = igd.operator.gamma - -# # r = cartesian(x) - cartesian(y) -# # R = norm(r) -# # iR = 1/R -# # green = exp(-γ*R)*(iR*i4pi) -# # gradgreen = -(γ + iR) * green * (iR * r) -# # normaly = normal(y) -# # fvalue = getvalue(f) -# # gvalue = getvalue(g) -# # t1 = Ref(normaly).*gvalue -# # G = cross.(Ref(gradgreen), t1) -# # return _krondot(fvalue, G) -# # end - -# # ttrace!(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), SameBase() -# # strace!(op::MWnDoubleLayer3D, mesh, or) = ZeroOperator(), mesh + function (igd::Integrand{<:MWDoubleLayer3DReg})(x,y,f,g) @@ -564,232 +332,6 @@ function (igd::Integrand{<:MWDoubleLayer3DReg})(x,y,f,g) return _krondot(fvalue, G) end -# function (igd::Integrand{<:MWngreenint})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# γR = γ*R -# iR = 1/R -# expo = exp(-γR) -# green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) - -# normaly = normal(y) -# fvalue = getvalue(f) -# gvalue = getvalue(g) -# t = normaly*green -# t2 = Ref(t).*gvalue -# return _krondot(fvalue,t2) -# end - -# ttrace!(op::MWngreenint, mesh, or) = ZeroOperator(), SameBase() -# strace!(op::MWngreenint, mesh, or) = ZeroOperator(), mesh - - - -# function (igd::Integrand{<:MWgreenint})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) - -# fvalue = getvalue(f) -# gvalue = getvalue(g) - -# t2 = green*gvalue -# return _krondot(fvalue,t2) -# end -# function (igd::Integrand{<:ndotMWgreenint})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# nx = normal(x) -# fvalue = getvalue(f) -# gvalue = getvalue(g) - -# t2 = dot.(Ref(nx),green*gvalue) -# return _krondot(fvalue,t2) -# end -# function (igd::Integrand{<:ndotMWgreenintdotn})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# nx = normal(x) -# ny = normal(y) -# fvalue = getvalue(f) -# gvalue = getvalue(g) - -# t2 = dot.(Ref(nx),Ref(ny))*green*gvalue -# return _krondot(fvalue,t2) -# end -# function (igd::Integrand{<:MWgreenintdotn})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# ny = normal(y) -# fvalue = getvalue(f) -# gvalue = getvalue(g) - -# t2 = green*gvalue.*Ref(ny) -# return _krondot(fvalue,t2) -# end -# function (igd::Integrand{<:nXMWgreenintdotn})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# ny = normal(y) -# nx = normal(x) -# fvalue = getvalue(f) -# gvalue = getvalue(g) -# t1 = green*gvalue.*Ref(ny) -# t2 = cross.(Ref(nx),t1) -# return _krondot(fvalue,t2) -# end - -# function (igd::Integrand{<:nXMWgreenint})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# nx = normal(x) -# fvalue = getvalue(f) -# gvalue = getvalue(g) - -# t2 = cross.(Ref(nx),green*gvalue) -# return _krondot(fvalue,t2) -# end - -# function (igd::Integrand{<:MWgradgreendot})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) - -# fvalue = getvalue(f) -# gvalue = getvalue(g) - -# t2 = dot.(gvalue,Ref(gradgreen)) -# return _krondot(fvalue,t2) -# end -# function (igd::Integrand{<:ndotMWgradgreen})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# nx = normal(x) -# fvalue = getvalue(f) -# gvalue = getvalue(g) - -# t2 = gvalue*dot(nx,gradgreen) -# return _krondot(fvalue,t2) -# end - -# function (igd::Integrand{<:MWgradgreendotn})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) - -# fvalue = getvalue(f) -# gvalue = getvalue(g) -# ny = normal(y) -# t2 = gvalue * dot(ny,Ref(gradgreen)) -# return _krondot(fvalue,t2) -# end -# function (igd::Integrand{<:nXMWgradgreendot})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# iR = 1/R -# green = exp(-γ*R)*(iR*i4pi) -# gradgreen = -(γ + iR) * green * (iR * r) -# nx = normal(x) -# fvalue = getvalue(f) -# gvalue = getvalue(g) - -# t2 = gvalue.*Ref(cross(nx,gradgreen)) -# return _krondot(fvalue,t2) -# end - -# ttrace!(op::MWgreenint, mesh, or) = ZeroOperator(), SameBase() -# strace!(op::MWgreenint, mesh, or) = ZeroOperator(), mesh -# ntrace!(op::MWgreenint, mesh, or) = ZeroOperator(), mesh - -# function (igd::Integrand{<:MWgradgreenint})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# γR = γ*R -# iR = 1/R -# expo = exp(-γR) -# green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) -# gradgreen = ( -(γR + 1)*expo + (1 - 0.5*γR^2) ) * (i4pi*iR^3) * r - -# fvalue = getvalue(f) -# gvalue = getvalue(g) - -# t2 = dot.(gvalue,Ref(gradgreen)) - -# return _krondot(fvalue,t2) -# end -# ttrace!(op::MWgradgreenint, mesh, or) = ZeroOperator(), SameBase() -# strace!(op::MWgradgreenint, mesh, or) = ZeroOperator(), mesh -# ntrace!(op::MWgradgreenint, mesh, or) = 1/2*Identity(), mesh - -# function (igd::Integrand{<:MWngradgreenint})(x,y,f,g) -# γ = igd.operator.gamma - -# r = cartesian(x) - cartesian(y) -# R = norm(r) -# γR = γ*R -# iR = 1/R -# expo = exp(-γR) -# green = (expo - 1 + γR - 0.5*γR^2) * (i4pi*iR) -# gradgreen = ( -(γR + 1)*expo + (1 - 0.5*γR^2) ) * (i4pi*iR^3) * r - -# fvalue = getvalue(f) -# gvalue = getvalue(g) -# normaly = normal(y) -# t1 = Ref(normaly).*gvalue -# t2 = dot.(t1,Ref(gradgreen)) - -# return _krondot(fvalue,t2) -# end - -# scallartrace!(op::MWngradgreenint, mesh, or) = 1/2*Identity(), SameBase() ################################################################################ # # Handling of operator parameters (Helmholtz and Maxwell) diff --git a/src/maxwell/nxdbllayer.jl b/src/maxwell/nxdbllayer.jl index 5ad1719c..5343d986 100644 --- a/src/maxwell/nxdbllayer.jl +++ b/src/maxwell/nxdbllayer.jl @@ -6,7 +6,7 @@ mutable struct DoubleLayerRotatedMW3D{T,K} <: MaxwellOperator3D{T,K} gamma::K end -#LinearAlgebra.cross(::NormalVector, a::MWDoubleLayer3D) = DoubleLayerRotatedMW3D(a.alpha, a.gamma) +LinearAlgebra.cross(::NormalVector, a::MWDoubleLayer3D) = DoubleLayerRotatedMW3D(a.alpha, a.gamma) # defaultquadstrat(::DoubleLayerRotatedMW3D, tfs, bfs) = DoubleNumQStrat(2,3) @@ -41,7 +41,6 @@ function quadrule(op::DoubleLayerRotatedMW3D, g::RTRefSpace, f::RTRefSpace, i, hits = 0 dtol = 1.0e3 * eps(eltype(eltype(τ.vertices))) - dmin2 = floatmax(eltype(eltype(τ.vertices))) for t in τ.vertices for s in σ.vertices diff --git a/src/operator.jl b/src/operator.jl index 41e3c82d..71c815e2 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -3,9 +3,7 @@ using .LinearSpace struct LongDelays{T} end struct Threading{T} end - - -import Base: transpose, +, -, *, zero +import Base: transpose, +, -, * abstract type AbstractOperator end @@ -16,26 +14,6 @@ abstract type AbstractOperator end """ abstract type Operator <: AbstractOperator end -# abstract type TraceOperator <: Operator end - -# struct Strace <: TraceOperator -# op -# orientation -# end - -# struct Ttrace <: TraceOperator -# op -# orientation -# end - -# struct ZeroOperator <: AbstractOperator end -abstract type Orientation end -struct Inside <: Orientation end -struct Outside <: Orientation end -inside() = Inside() -outside() = Outside() - - mutable struct TransposedOperator <: AbstractOperator op::AbstractOperator end @@ -242,15 +220,7 @@ function assemble!(op::LinearCombinationOfOperators, tfs::AbstractSpace, bfs::Ab assemble!(A, tfs, bfs, store1, threading; quadstrat=qs) end end -# function assemble(op::Ttrace, tfs::AbstractSpace, bfs::AbstractSpace) -# pvterm, mesh = ttrace!(op.op,tfs.geo,op.orientation) -# assemble(pvterm+op.op,ttrace(tfs,mesh),bfs) -# end -# function assemble(op::Strace, tfs::AbstractSpace, bfs::AbstractSpace) -# pvterm, mesh = strace!(op.op,tfs.geo,op.orientation) -# assemble(-pvterm-op.op,strace(tfs,mesh),bfs) -# end # Support for direct product spaces function assemble!(op::AbstractOperator, tfs::DirectProductSpace, bfs::Space, @@ -351,16 +321,3 @@ function assemble!(op::BlockFullOperators, U::DirectProductSpace, V::DirectProdu end end end - - -# strace(op::Operator,orientation::Orientation) = Strace(op,orientation) -# ttrace(op::Operator,orientation::Orientation) = Ttrace(op,orientation) - - - -# Base.zero(op::AbstractOperator) = ZeroOperator() -# +(a::AbstractOperator,b::ZeroOperator) = a -# +(a::ZeroOperator,b::ZeroOperator) = a -# +(a::ZeroOperator,b::AbstractOperator) = b+a -# *(a::Number,b::ZeroOperator) = b - diff --git a/src/quadrature/quadrule.jl b/src/quadrature/quadrule.jl index a5eea12b..8307a966 100644 --- a/src/quadrature/quadrule.jl +++ b/src/quadrature/quadrule.jl @@ -1,7 +1,7 @@ # This file contains kernel independent implementations of quadrule for # the various quadrature strategies defined in quadstrats.jl -function quadrule(op::IntegralOperator, g::RefSpace, f::RefSpace, i, τ, j, σ, qd, +function quadrule(op::IntegralOperator, g::RTRefSpace, f::RTRefSpace, i, τ, j, σ, qd, qs::DoubleNumSauterQstrat) T = eltype(eltype(τ.vertices)) diff --git a/src/quadrature/quadstrats.jl b/src/quadrature/quadstrats.jl index 40c9a994..40d4bddb 100644 --- a/src/quadrature/quadstrats.jl +++ b/src/quadrature/quadstrats.jl @@ -39,10 +39,7 @@ struct OuterNumInnerAnalyticQStrat{R} end -function defaultquadstrat(op, tfs, bfs) - @warn "made use of general defaultquadstrat routine which cals defaultquadstrat on refspaces" - defaultquadstrat(op, refspace(tfs), refspace(bfs)) -end +defaultquadstrat(op, tfs, bfs) = defaultquadstrat(op, refspace(tfs), refspace(bfs)) macro defaultquadstrat(dop, body) @assert dop.head == :tuple @assert length(dop.args) == 3 diff --git a/test/runtests.jl b/test/runtests.jl index bb33121c..cf2ca17a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -71,7 +71,7 @@ include("test_tdrhs_scaling.jl") include("test_td_tensoroperator.jl") include("test_variational.jl") -include("test_HHHoperators.jl") + try Pkg.installed("BogaertInts10") diff --git a/test/test_HHHoperators.jl b/test/test_HHHoperators.jl deleted file mode 100644 index 19c8b41d..00000000 --- a/test/test_HHHoperators.jl +++ /dev/null @@ -1,34 +0,0 @@ -using BEAST -using StaticArrays -using CompScienceMeshes -using Test -k = 1.0 - -green = HHH.green(wavenumber=k) -gradgreen = HHH.gradgreen(wavenumber=k) -b = basisfunction() -green -gradgreen -n×green -n×gradgreen -gradgreen×nothing -gradgreen×n -gradgreen(n×b) -gradgreen(n*b) -n×gradgreen(n×b) - - -Γ1 = boundary(Mesh([SVector{3}([0.0,0.0,0.0]),SVector{3}([1.0,0.0,0.0]),SVector{3}([0.0,1.0,0.0]),SVector{3}([0.0,0.0,1.0])],[SVector{4}([1,2,3,4])])) -Γ2 = CompScienceMeshes.translate(Γ1,[0.0,0.0,0.0]) - -X1 = raviartthomas(Γ1) -X2 = raviartthomas(Γ2) -X3 = lagrangec0d1(Γ1) - -m1 = assemble(n×(n×(gradgreen×nothing)(n×(n×b))),X1,X2) -m2 = assemble((gradgreen)(n⋅(n×b)),X1,X2) -m3 = assemble(n⋅(gradgreen)(n⋅(n×b)),X3,X2) -m4 = assemble((green)(n×(n*b)),X1,X3) -dl = assemble(Maxwell3D.doublelayer(wavenumber=k),X1,X2) - -@test abs(sum(m1-dl)+sum(m2)+sum(m3)+sum(m4)) < 10^(-16) \ No newline at end of file From ac602e1f4f00d38a46b1602395449a9ff04009f8 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 26 Oct 2023 14:10:52 +0200 Subject: [PATCH 051/110] update gitignore --- .gitignore | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index bfa3e6f8..1c03d978 100644 --- a/.gitignore +++ b/.gitignore @@ -11,11 +11,6 @@ dev/ profile/ /Manifest.toml /envs/ -programs/vector_potential_globalmultitrace.jl -programs/draft/create neighobrhood.jl -programs/draft/test_strace_doublelayer.jl -programs/draft/test_trace_operators_visual.jl -programs/draft/test_ttrace_doublelayer.jl -programs/draft/vector_potential_sphere.jl +programs/ src/todo.txt From c9b8eadd843a8f516953bcd8fb94bd12266ac70d Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 26 Oct 2023 14:14:35 +0200 Subject: [PATCH 052/110] remove extendedcharts --- src/utils/extendedcharts.jl | 39 ------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 src/utils/extendedcharts.jl diff --git a/src/utils/extendedcharts.jl b/src/utils/extendedcharts.jl deleted file mode 100644 index 8fece9ce..00000000 --- a/src/utils/extendedcharts.jl +++ /dev/null @@ -1,39 +0,0 @@ -# import Base.length -# import CompScienceMeshes: chart,dimtype,coordtype,volume,dimension,universedimension -# struct NormalChart{U,V} -# chart::U -# normals::V -# end - -# normals(chart::NormalChart) = chart.normals -# chart(c::NormalChart) = c.chart -# dimtype(c::NormalChart) = dimtype(chart(c)) -# coordtype(c::NormalChart) = coordtype(chart(chart)) - -# volume(c::NormalChart) = volume(chart(chart)) -# dimension(chart::NormalChart) = dimension(chart(chart)) -# Base.length(chart::NormalChart) = length(chart(chart)) -# universedimension(chart::NormalChart) = universedimension(chart(chart)) -# getindex(p::NormalChart,I::Union{Number,SVector,Array}) = chart(p)[I] - - -# function normalchart(chart::CompScienceMeshes.Simplex) -# normals = chart.normals -# NormalChart(chart,normals) -# end - -# normalchart(chart::CompScienceMeshes.Simplex,normals) = NormalChart(chart,normals) - -#CompScienceMeshes.normal(t::CompScienceMeshes.Simplex{3,2,1,3,<:Number}) = t.normals[1] - - -# function permute_barycentric(perm,bary::Tuple{T,T}) where {T} -# last_coef = 1-sum(bary) -# total_bary = SVector{3,T}([bary[1],bary[2],last_coef]) -# return Tuple{T,T}(total_bary[perm][1:end-1]) -# end -# function permute_barycentric(perm,bary::Tuple{T,T,T}) where {T} -# last_coef = 1-sum(bary) -# total_bary = SVector{4,T}([bary[1],bary[2],bary[3],last_coef]) -# return Tuple{T,T,T}(total_bary[perm][1:end-1]) -# end \ No newline at end of file From dd8ca41cde081d7fff37bf05a74e68acefb6197b Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 26 Oct 2023 14:16:10 +0200 Subject: [PATCH 053/110] cleanup --- src/maxwell/maxwell.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/maxwell/maxwell.jl b/src/maxwell/maxwell.jl index 6a26e6b4..b4783ece 100644 --- a/src/maxwell/maxwell.jl +++ b/src/maxwell/maxwell.jl @@ -53,7 +53,6 @@ module Maxwell3D wavenumber=nothing) gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - println(typeof(wavenumber)) if alpha === nothing if gamma !== nothing alpha = one(gamma) @@ -61,7 +60,6 @@ module Maxwell3D alpha = one(typeof(wavenumber)) # Default to double precision end end - println(alpha) Mod.MWDoubleLayer3D(alpha,gamma) end From fa273f7875fe1dcf16449ba8195f03e0e57845ee Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 26 Oct 2023 14:33:35 +0200 Subject: [PATCH 054/110] updat gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 715a5a38..7c4505e4 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ profile/ /envs/ programs/ results/ +src/todo.txt From cc3aa34da6b4dd4ae5b1e534a7cc399e36fa3b1a Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 30 Oct 2023 15:25:24 +0100 Subject: [PATCH 055/110] added Trace Operator, made it possible to symbalically construct operator, decoupled normal from chart in local operator, made integrand of local operator and integral operator similar, wrote small test for composed operator and trace --- src/BEAST.jl | 6 +- src/bases/local/rtlocal.jl | 7 +- src/composedoperator/composed2.jl | 157 +++++++++++++++++++-------- src/composedoperator/tracesimplex.jl | 106 ++++++++++++++++++ src/display.jl | 124 ++++++++++----------- src/identityop.jl | 16 +-- src/localop.jl | 84 +++++++------- src/operator.jl | 27 +++-- src/quadrature/quadrule.jl | 12 +- src/quadrature/sauterschwabints.jl | 4 +- src/utils/geometrie.jl | 50 ++++----- test/runtests.jl | 2 +- test/test_basis.jl | 1 + test/test_composed_operator.jl | 84 ++++++++++++++ test/test_local_storage.jl | 6 +- 15 files changed, 482 insertions(+), 204 deletions(-) create mode 100644 src/composedoperator/tracesimplex.jl create mode 100644 test/test_composed_operator.jl diff --git a/src/BEAST.jl b/src/BEAST.jl index 690c8ebc..f6f6bd9b 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -25,6 +25,7 @@ import LinearAlgebra: cross, dot import LinearAlgebra: ×, ⋅ import SharedArrays: sdata +import CompScienceMeshes: normal, chart, mesh, coordtype, simplex, domain export dot @@ -133,7 +134,8 @@ using FFTW using SparseArrays function convolve end -include("utils/extendedcharts.jl") + + include("utils/polynomial.jl") include("utils/specialfns.jl") include("utils/combinatorics.jl") @@ -268,6 +270,8 @@ include("multi-trace/postprocessing.jl") #suport for displaying operators include("composedoperator/composed2.jl") +include("composedoperator/tracesimplex.jl") + include("display.jl") const x̂ = point(1,0,0) diff --git a/src/bases/local/rtlocal.jl b/src/bases/local/rtlocal.jl index f883a3bf..6d56e679 100644 --- a/src/bases/local/rtlocal.jl +++ b/src/bases/local/rtlocal.jl @@ -57,14 +57,15 @@ function restrict(ϕ::RTRefSpace{T}, dom1, dom2) where T for i in 1:K # find the center of edge i of dom2 - a = dom2.vertices[mod1(i+1,D+1)] - b = dom2.vertices[mod1(i+2,D+1)] + a = verticeslist(dom2)[mod1(i+1,D+1)] + b = verticeslist(dom2)[mod1(i+2,D+1)] c = (a + b) / 2 # find the outer binormal there t = b - a l = norm(t) - n = dom2.normals[1] + # n = dom2.normals[1] + n = normalize(tangents(dom2,1)×tangents(dom2,2)) m = cross(t, n) / l u = carttobary(dom1, c) diff --git a/src/composedoperator/composed2.jl b/src/composedoperator/composed2.jl index 27a13044..621255c5 100644 --- a/src/composedoperator/composed2.jl +++ b/src/composedoperator/composed2.jl @@ -1,4 +1,4 @@ -import Base: * +import Base: *, div import LinearAlgebra: ×, ⋅ @@ -15,6 +15,41 @@ struct DivBasisFunction <: ComposedOperatorLocal end const B = BasisFunction export B + +struct TestNormal <: ComposedOperatorLocal end +struct TrialNormal <: ComposedOperatorLocal end +struct TraceDirection <: ComposedOperatorLocal end +scalartype(op::Union{TestNormal,TrialNormal,BasisFunction,TraceDirection}) = Float16 + + +const nt = TestNormal() + +struct Potential{T} <: AbstractOperator + operator::T + surface +end +normal_surface(p::Potential) = p.surface +function Potential(linop::LinearCombinationOfOperators,surface) + out = ZeroOperator() + for (op,coeff) in zip(linop.ops,linop.coeffs) + out += coeff*Potential(op,surface) + end + return out +end +struct TraceOperator{T} <: AbstractOperator + operator::T + directionsurface + normalsurface +end +function TraceOperator(linop::LinearCombinationOfOperators,dsurf,nsurf) + out = ZeroOperator() + for (op,coeff) in zip(linop.ops,linop.coeffs) + out += coeff*TraceOperator(op,dsurf,nsurf) + end +return out +end +normal_surface(p::TraceOperator) = p.normalsurface +direction_surface(p::TraceOperator) = p.directionsurface struct TimesLocal{U,V} <: ComposedOperatorLocal lhs::U rhs::V @@ -119,47 +154,37 @@ CrossLocal(a::ComposedOperatorIntegral,b::ComposedOperatorIntegral) = CrossInteg ⋅(a::ComposedOperator,b::ComposedOperator) = DotLocal(a,b) *(a::ComposedOperator,b::ComposedOperator) = TimesLocal(a,b) -div(::BasisFunction) = DivBasisFunction() +Base.div(::BasisFunction) = DivBasisFunction() scalartype(op::Operations) = promote_type(scalartype(op.lhs),scalartype(op.rhs)) - -struct TestNormal <: ComposedOperatorLocal end -struct TrialNormal <: ComposedOperatorLocal end -scalartype(op::Union{TestNormal,TrialNormal,BasisFunction}) = Float64 - - -const nt = TestNormal() - -struct Potential{T} <: Operator - operator::T - surface -end +scalartype(op::Potential) = scalartype(op.operator) +scalartype(op::TraceOperator) = scalartype(op.operator) function count_test_normals(op::Operations) count_test_normals(op.lhs) + count_test_normals(op.rhs) end -count_test_normals(op::Kern) = 0 +count_test_normals(op::Kernel) = 0 count_test_normals(op::TestNormal) = 1 count_test_normals(op::TrialNormal) = 0 function count_trial_normals(op::Operations) count_trial_normals(op.lhs) + count_trial_normals(op.rhs) end -count_trial_normals(op::Kern) = 0 +count_trial_normals(op::Kernel) = 0 count_trial_normals(op::TestNormal) = 0 count_trial_normals(op::TrialNormal) = 1 function replace_normal_by_testnormal(op::Operations) get_constructor(op)(replace_normal_by_testnormal(op.lhs),replace_normal_by_testnormal(op.rhs)) end -replace_normal_by_testnormal(op::Kern) = op +replace_normal_by_testnormal(op::Kernel) = op replace_normal_by_testnormal(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction}) = op replace_normal_by_testnormal(op::NormalVector) = TestNormal() function replace_normal_by_trialnormal(op::Operations) get_constructor(op)(replace_normal_by_trialnormal(op.lhs),replace_normal_by_trialnormal(op.rhs)) end -replace_normal_by_trialnormal(op::Kern) = op +replace_normal_by_trialnormal(op::Kernel) = op replace_normal_by_trialnormal(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction}) = op replace_normal_by_trialnormal(op::NormalVector) = TrialNormal() @@ -180,23 +205,25 @@ function check_if_coincide(a,b) return true end -function γ(op::Potential,surface,sign)# sign + if according to normal on surface, - otherwise +function γ(op::Potential,direction::CompScienceMeshes.AbstractMesh,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise check_if_coincide(op.surface,surface) || return op.operator newop = γ(op.operator,sign) - return newop + return TraceOperator(Potential(newop,op.surface),direction,surface) +end +function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise + γ(op,surface,surface,sign) end +# γₜᶜ(op::Potential,surface) = nt×(γ(op,surface,-1)×nt) +# γₜ(op::Potential,surface) = nt×(γ(op,surface,1)×nt) -γₜᶜ(op::Potential,surface) = nt×(γ(op,surface,-1)×nt) -γₜ(op::Potential,surface) = nt×(γ(op,surface,1)×nt) - -γₛ(op::Potential,surface) = nt×γ(op,surface,1) -γₛᶜ(op::Potential,surface) = nt×γ(op,surface,-1) -γₙ(op::Potential,surface) = nt⋅γ(op,surface,1) -γₙᶜ(op::Potential,surface) = nt⋅γ(op,surface,-1) -τ(op::Potential,surface) = γ(op,surface,1) -τᶜ(op::Potential,surface) = γ(op,surface,-1) +# γₛ(op::Potential,surface) = nt×γ(op,surface,1) +# γₛᶜ(op::Potential,surface) = nt×γ(op,surface,-1) +# γₙ(op::Potential,surface) = nt⋅γ(op,surface,1) +# γₙᶜ(op::Potential,surface) = nt⋅γ(op,surface,-1) +# τ(op::Potential,surface) = γ(op,surface,1) +# τᶜ(op::Potential,surface) = γ(op,surface,-1) function greenhh3d(; gamma=nothing, @@ -216,11 +243,11 @@ GradGreenHH3D(gamma) end struct GreenHH3D{T} <: Kernel - gamma{T} + gamma::T end struct GradGreenHH3D{T} <: Kernel - gamma{T} + gamma::T end @@ -245,17 +272,18 @@ function (op::GradGreenHH3D)(x,y,g) Ref(gradgreen) end -γ(op::GreenHH3D,sign) = op -γ(op::GradGreenHH3D,sign) = op + sign*1/2*nt +γ(op::GreenHH3D,sign::Int) = op +γ(op::GradGreenHH3D,sign::Int) = op + sign*1/2*TraceDirection() grad(G::GreenHH3D) = GradGreenHH3D(G.gamma) -∇(G) = grad(G) -scalartype(G::GreenHH3D{T}) where {T} = T -scalartype(G::GradGreenHH3D{T}) where {T} = T +function (::Nabla)(G::Kernel) + grad(G) +end -div(B::BasisFunction) = DivBasisFunction() +scalartype(G::GreenHH3D{T}) where {T} = T +scalartype(G::GradGreenHH3D{T}) where {T} = T function (op::Union{TimesIntegral,TimesLocal})(x,y,g) @@ -274,6 +302,9 @@ end function (op::TestNormal)(x,y,g) Ref(normal(x)) end +function (op::TraceDirection)(x,y,g) + Ref(tracedirection(x)) +end function (op::BasisFunction)(x,y,g) getvalue(g) end @@ -284,17 +315,57 @@ end function (igd::Integrand{<:ComposedOperatorIntegral})(x,y,f,g) - op = igd.operator - dot.(f,op(x,y,g)) + _krondot(getvalue(f),igd.operator(x,y,g)) end -function integrand(op::ComposedOperatorLocal,kernel,x,y,g) - dot.(f,op(x,y,g)) +function integrand(op::ComposedOperatorLocal,kernel,x,y,f,g) + _krondot(getvalue(f),op(x,y,g)) end -defaultquadstrat(op::ComposedOperator,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(6,7,5,5,4,3) +defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(6,7,5,5,4,3) +defaultquadstrat(op::ComposedOperatorLocal,testspace::Space,trialpsace::Space) = SingleNumQStrat(6) sign_upon_permutation(op::ComposedOperator,I,J) = Combinatorics.levicivita(I)^count_test_normals(op)*Combinatorics.levicivita(J)^count_trial_normals(op) -normalorient(op::ComposedOperator,sign_test_normal,sign_trial_normal) = sign_test_normal^count_test_normals*sign_trial_normal^count_trial_normals \ No newline at end of file +normalorient(op::ComposedOperator,sign_test_normal,sign_trial_normal) = sign_test_normal^count_test_normals*sign_trial_normal^count_trial_normals + + +defaultquadstrat(op::TraceOperator,test,trial) = defaultquadstrat(op.operator,test,trial) +defaultquadstrat(op::Potential,test,trial) = defaultquadstrat(op.operator,test,trial) + + + +function assemble!(op::Potential, test_functions::Space, trial_functions::Space, + store, threading = Threading{:multi}; + quadstrat = defaultquadstrat(op, test_functions, trial_functions)) + + nsurf = normal_surface(op) + surf = geometry(trial_functions) + @assert same_geometry(nsurf,surf) + trial = typeof(trial_functions).name.wrapper + trial_functions = trial(OrientedMesh(surf,nsurf),trial_functions.fns,trial_functions.pos) + + assemble!(op.operator, test_functions, trial_functions, store, threading; + quadstrat = quadstrat) +end + +function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, + store, threading = Threading{:multi}; + quadstrat = defaultquadstrat(op, test_functions, trial_functions)) + + nsurf = normal_surface(op) + dsurf = direction_surface(op) + surf = geometry(test_functions) + @assert same_geometry(nsurf,dsurf) + @assert same_geometry(nsurf,surf) + + test = typeof(test_functions).name.wrapper + + test_functions = test(TraceMesh(OrientedMesh(surf,nsurf),dsurf),test_functions.fns,test_functions.pos) + + assemble!(op.operator, test_functions, trial_functions, store, threading; + quadstrat = quadstrat) +end + +kernelvals(op::ComposedOperator,a) = nothing \ No newline at end of file diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl new file mode 100644 index 00000000..40496270 --- /dev/null +++ b/src/composedoperator/tracesimplex.jl @@ -0,0 +1,106 @@ +import Base.sign +struct TraceSimplex{T} + simp::T + sign::Int +end +simplex(t::TraceSimplex) = t.simp +sign(t::TraceSimplex) = t.sign +struct TraceMeshPointNM{T} + neighborhood::T + sign::Int +end + +function CompScienceMeshes.neighborhood(p::TraceSimplex, bary) + TraceMeshPointNM(neighborhood(p.simp,bary),p.sign) +end +CompScienceMeshes.cartesian(p::TraceMeshPointNM) = cartesian(p.neighborhood) +CompScienceMeshes.parametric(p::TraceMeshPointNM) = parametric(p.neighborhood) +chart(p::TraceMeshPointNM) = chart(p.neighborhood) +CompScienceMeshes.normal(p::TraceMeshPointNM) = normal(p.neighborhood) +tracedirection(p::TraceMeshPointNM) = p.sign*normal(p) +CompScienceMeshes.jacobian(p::TraceMeshPointNM) = jacobian(p.neighborhood) +CompScienceMeshes.tangents(p::TraceMeshPointNM,i) = tangents(p.neighborhood,i) + +coordtype(p::TraceSimplex) = coordtype(p.simp) + + + +struct OrientedMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} + mesh::CompScienceMeshes.AbstractMesh{U,D1,T} + normalmesh::CompScienceMeshes.AbstractMesh{U,D1,T} +end +struct TraceMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} + mesh::CompScienceMeshes.AbstractMesh{U,D1,T} + direction::CompScienceMeshes.AbstractMesh{U,D1,T} +end +mesh(p::OrientedMesh) = p.mesh +mesh(p::TraceMesh) = p.mesh +CompScienceMeshes.normal(p::OrientedMesh) = p.normalmesh +direction(p::TraceMesh) = p.direction + +function CompScienceMeshes.chart(p::OrientedMesh,i) + c = chart(mesh(p),i) + n1 = normal(c) + n2 = normal(chart(normal(p),i)) + d = dot(n1,n2) + @assert abs(d) ≈ 1.0 + sign(d) == 1 && return c + return flip_normal(c) +end +function CompScienceMeshes.chart(p::TraceMesh,i) + c = chart(mesh(p),i) + d = chart(direction(p),i) + p = dot(normal(c),normal(d)) + @assert abs(p) ≈ 1.0 + TraceSimplex(c,Int(sign(p))) +end + +function same_geometry(m1,m2) + return (vertices(m1) == vertices(m2))*prod(_ispermutation.(cells(m1),cells(m2))) +end + +_ispermutation(a,b) = sort(a)==sort(b) +CompScienceMeshes.cells(p::OrientedMesh) = cells(mesh(p)) +CompScienceMeshes.cells(p::TraceMesh) = cells(mesh(p)) + + +CompScienceMeshes.domain(ch::TraceSimplex) = CompScienceMeshes.domain(simplex(ch)) + + +function CompScienceMeshes.quadpoints(chart::TraceSimplex, rule) + PV = quadpoints(CompScienceMeshes.domain(chart), rule) + map(PV) do pv + q = neighborhood(chart, pv[1]) + w = jacobian(q)*pv[2] + (q,w) + end +end +CompScienceMeshes.verticeslist(p::TraceSimplex) = verticeslist(simplex(p)) +CompScienceMeshes.permute_vertices(simp::TraceSimplex,I) = TraceSimplex(CompScienceMeshes.permute_vertices(simplex(simp),I),sign(simp)) +CompScienceMeshes.overlap(a::TraceSimplex,b::TraceSimplex) = overlap(simplex(a),simplex(b)) +CompScienceMeshes.overlap(a::CompScienceMeshes.Simplex,b::TraceSimplex) = overlap(a,simplex(b)) +CompScienceMeshes.overlap(a::TraceSimplex,b::CompScienceMeshes.Simplex) = overlap(simplex(a),b) + +CompScienceMeshes.intersection(a::CompScienceMeshes.Simplex,b::TraceSimplex) = intersection(a,simplex(b)) + +function CompScienceMeshes.intersection(a::TraceSimplex,b::Union{TraceSimplex,CompScienceMeshes.Simplex}) + int = intersection(simplex(a),b) + TraceSimplex.(int,sign(a)) +end + +function CompScienceMeshes.intersection2(a::TraceSimplex,b::TraceSimplex) + int = intersection2(simplex(a),simplex(b)) + return [(TraceSimplex(i[1],sign(a)),TraceSimplex(i[2],sign(b))) for i in int] +end +function CompScienceMeshes.intersection2(a::CompScienceMeshes.Simplex,b::TraceSimplex) + int = intersection2(a,simplex(b)) + return [(i[1],TraceSimplex(i[2],sign(b))) for i in int] +end +function CompScienceMeshes.intersection2(a::TraceSimplex,b::CompScienceMeshes.Simplex) + int = intersection2(simplex(a),b) + return [(TraceSimplex(i[1],sign(a)),i[2]) for i in int] +end +CompScienceMeshes.volume(a::TraceSimplex) = volume(simplex(a)) +CompScienceMeshes.dimension(a::TraceSimplex) = dimension(simplex(a)) +CompScienceMeshes.tangents(a::TraceSimplex,i::Int) = tangents(simplex(a),i) +CompScienceMeshes.carttobary(a::TraceSimplex,b::SVector{T}) where {T} = carttobary(simplex(a),b) diff --git a/src/display.jl b/src/display.jl index 4fc69bec..fd6a7b4c 100644 --- a/src/display.jl +++ b/src/display.jl @@ -40,66 +40,66 @@ end Base.print(io::IO, op::Identity) = print(io,"I") Base.print(io::IO, op::ZeroOperator) = print(io,"Zero") -function Base.print(io::IO, op::BasisOperatorLeft) - print(io,"f*") - print(io,op.operator) -end -function Base.print(io::IO, op::BasisOperatorRight) - print(io,op.operator) - print(io,"*f") -end +# function Base.print(io::IO, op::BasisOperatorLeft) +# print(io,"f*") +# print(io,op.operator) +# end +# function Base.print(io::IO, op::BasisOperatorRight) +# print(io,op.operator) +# print(io,"*f") +# end -function Base.print(io::IO, op::HHHgreen) -if !(op.α ≈ 1.0) - @warn "alpha is not 1 and not printed" -end -print(io,"S[$(abs(op.γ))]") -print(io,op.op) -end -function Base.print(io::IO, op::HHHgradgreen) - if !(op.α ≈ 1.0) - @warn "alpha is not 1 and not printed" - end - print(io,"∇S[$(abs(op.γ))]") - print(io,op.op) -end -function Base.print(io::IO, op::HHHgradgreenDot) - if !(op.α ≈ 1.0) - @warn "alpha is not 1 and not printed" - end - print(io,"∇S⋅[$(abs(op.γ))]") - print(io,op.op) -end -function Base.print(io::IO, op::HHHgradgreenCross) - if !(op.α ≈ 1.0) - @warn "alpha is not 1 and not printed" - end - print(io,"∇S×[$(abs(op.γ))]×") - print(io,op.op) -end -function Base.print(io::IO, op::Union{HHHNtestCross,HHHNtestCrossLocal}) - print(io,"nₜₑ×") - print(io,op.op) -end -function Base.print(io::IO, op::Union{HHHNbasisCross,HHHNbasisCrossLocal}) - print(io,"nₜᵣ×") - print(io,op.op) -end -function Base.print(io::IO, op::Union{HHHNtestDot,HHHNtestDotLocal}) - print(io,"nₜₑ⋅") - print(io,op.op) -end -function Base.print(io::IO, op::Union{HHHNbasisnormal,HHHNbasisnormalLocal}) - print(io,"nₜᵣ") - print(io,op.op) -end -function Base.print(io::IO, op::Union{HHHNbasisdot,HHHNbasisdotLocal}) - print(io,"nₜᵣ⋅") - print(io,op.op) -end -function Base.print(io::IO, op::Union{HHHIdentity,HHHIdentityLocal}) - print(io,"B") -end -function Base.print(io::IO, op::Union{HHHDivergence,HHHDivergenceLocal}) - print(io,"∇⋅B") -end \ No newline at end of file +# function Base.print(io::IO, op::HHHgreen) +# if !(op.α ≈ 1.0) +# @warn "alpha is not 1 and not printed" +# end +# print(io,"S[$(abs(op.γ))]") +# print(io,op.op) +# end +# function Base.print(io::IO, op::HHHgradgreen) +# if !(op.α ≈ 1.0) +# @warn "alpha is not 1 and not printed" +# end +# print(io,"∇S[$(abs(op.γ))]") +# print(io,op.op) +# end +# function Base.print(io::IO, op::HHHgradgreenDot) +# if !(op.α ≈ 1.0) +# @warn "alpha is not 1 and not printed" +# end +# print(io,"∇S⋅[$(abs(op.γ))]") +# print(io,op.op) +# end +# function Base.print(io::IO, op::HHHgradgreenCross) +# if !(op.α ≈ 1.0) +# @warn "alpha is not 1 and not printed" +# end +# print(io,"∇S×[$(abs(op.γ))]×") +# print(io,op.op) +# end +# function Base.print(io::IO, op::Union{HHHNtestCross,HHHNtestCrossLocal}) +# print(io,"nₜₑ×") +# print(io,op.op) +# end +# function Base.print(io::IO, op::Union{HHHNbasisCross,HHHNbasisCrossLocal}) +# print(io,"nₜᵣ×") +# print(io,op.op) +# end +# function Base.print(io::IO, op::Union{HHHNtestDot,HHHNtestDotLocal}) +# print(io,"nₜₑ⋅") +# print(io,op.op) +# end +# function Base.print(io::IO, op::Union{HHHNbasisnormal,HHHNbasisnormalLocal}) +# print(io,"nₜᵣ") +# print(io,op.op) +# end +# function Base.print(io::IO, op::Union{HHHNbasisdot,HHHNbasisdotLocal}) +# print(io,"nₜᵣ⋅") +# print(io,op.op) +# end +# function Base.print(io::IO, op::Union{HHHIdentity,HHHIdentityLocal}) +# print(io,"B") +# end +# function Base.print(io::IO, op::Union{HHHDivergence,HHHDivergenceLocal}) +# print(io,"∇⋅B") +# end \ No newline at end of file diff --git a/src/identityop.jl b/src/identityop.jl index be72b2c7..4eb878ab 100644 --- a/src/identityop.jl +++ b/src/identityop.jl @@ -2,21 +2,22 @@ struct Identity <: LocalOperator end kernelvals(biop::Identity, x) = nothing -integrand(op::Identity, kernel, x,y, g, f) = dot.(getvalue(f), getvalue(g)) +integrand(op::Identity, kernel, x,y, g, f) = _krondot(getvalue(g), getvalue(f)) scalartype(op::Identity) = Union{} struct NCross <: LocalOperator end kernelvals(op::NCross, mp) = nothing -integrand(op::NCross, kernel, x,y, g, f) = dot.(getvalue(g), Ref(normal(x)) .× getvalue(f)) +integrand(op::NCross, kernel, x,y, g, f) = _krondot(getvalue(g), Ref(normal(x)) .× getvalue(f)) scalartype(op::NCross) = Union{} function _alloc_workspace(qd, g, f, tels, bels) q = qd[1] τ = tels[1] - w, p = q[1], neighborhood(τ,q[2]) - a = (w, p, g(p), f(p)) + σ = bels[1] + w, p1, p2 = q[1], neighborhood(τ,q[2]), neighborhood(σ,q[2]) + a = (w, (p1,p2), g(p1), f(p2)) A = Vector{typeof(a)}(undef,length(qd)) end @@ -87,11 +88,12 @@ function quaddata(op::LocalOperator, g::LagrangeRefSpace{T,Deg,4} where {T,Deg}, end -function quadrule(op::LocalOperator, ψ::RefSpace, ϕ::RefSpace, τ, (qd,A), qs::SingleNumQStrat) +function quadrule(op::LocalOperator, ψ::RefSpace, ϕ::RefSpace, τ,σ, (qd,A), qs::SingleNumQStrat) for i in eachindex(qd) q = qd[i] - w, p = q[1], neighborhood(τ,q[2]) - A[i] = (w, p, ψ(p), ϕ(p)) + w, p1, p2 = q[1], neighborhood(τ,q[2]), neighborhood(σ,q[2]) + A[i] = (w, (p1,p2), ψ(p1), ϕ(p2)) + end return A end diff --git a/src/localop.jl b/src/localop.jl index 7f14abf7..f54ad860 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -59,7 +59,7 @@ function allocatestorage(op::LocalOperator, testfunctions, trialfunctions, n = numfunctions(trialfunctions) Z = SparseMatrixDict{T,Int}(m,n) - store(v,m,n) = (Z[m,n] += v) + store(v,m,n) = (Z[m,n] += T(v)) freeze() = SparseArrays.SparseMatrixCSC(Z) return freeze, store @@ -71,7 +71,7 @@ function allocatestorage(op::LocalOperator, test_functions, trial_functions, T = scalartype(op, test_functions, trial_functions) Z = zeros(T, numfunctions(test_functions), numfunctions(trial_functions)) - store(v,m,n) = (Z[m,n] += v) + store(v,m,n) = (Z[m,n] += T(v)) freeze() = Z return freeze, store @@ -126,18 +126,23 @@ function assemble_local_matched!(biop::LocalOperator, tfs::Space, bfs::Space, st verbose = length(tels) > 10_000 verbose && print(string(typeof(biop))*" dots out of 20: ") todo, done, pctg = length(tels), 0, 0 - locmat = zeros(scalartype(biop, trefs, brefs), numfunctions(trefs), numfunctions(brefs)) - for (p,cell) in enumerate(tels) + # locmat = zeros(scalartype(biop, trefs, brefs), numfunctions(trefs), numfunctions(brefs)) + for (p,tcell) in enumerate(tels) + P = ta2g[p] + bcell = bels[P] + + @assert same_cell(bcell,tcell) q = bg2a[P] q == 0 && continue - qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) - fill!(locmat, 0) - cellinteractions_matched!(locmat, biop, trefs, brefs, cell, 1, qr) + qr = quadrule(biop, trefs, brefs, tcell, bcell,qd, quadstrat) + # fill!(locmat, 0) + locmat = cellinteractions(biop, trefs, brefs, tcell, bcell, qr) for i in 1 : size(locmat, 1), j in 1 : size(locmat, 2) for (m,a) in tad[p,i], (n,b) in bad[q,j] + store(a * locmat[i,j] * b, m, n) end end @@ -178,15 +183,15 @@ function assemble_local_refines!(biop::LocalOperator, tfs::Space, bfs::Space, st bcell = bels[q] @assert overlap(tcell, bcell) - s = sign(dot(normal(tcell),normal(bcell))) - isct = intersection(tcell, bcell) - for cell in isct + #s = sign(dot(normal(tcell),normal(bcell))) + isct = intersection2(tcell, bcell) + for (tcell2,bcell2) in isct - P = restrict(brefs, bcell, cell) - Q = restrict(trefs, tcell, cell) + P = restrict(brefs, bcell, bcell2) + Q = restrict(trefs, tcell, tcell2) - qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) - zlocal = cellinteractions(biop, trefs, brefs, cell, s, qr) + qr = quadrule(biop, trefs, brefs, tcell2,bcell2, qd, quadstrat) + zlocal = cellinteractions(biop, trefs, brefs, tcell2, bcell2, qr) zlocal = Q * zlocal * P' for i in 1 : numfunctions(trefs) @@ -223,16 +228,19 @@ function assemble_local_matched!(biop::LocalOperator, tfs::subdBasis, bfs::subdB brefs = refspace(bfs) qd = quaddata(biop, trefs, brefs, tels, bels, quadstrat) - for (p,cell) in enumerate(tels) - - qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) - locmat = cellinteractions(biop, trefs, brefs, cell,1, qr) + for (p,tcell) in enumerate(tels) + bcell = bels[p] + @assert same_cell(bcell,tcell) + qr = quadrule(biop, trefs, brefs, tcell,bcell, qd, quadstrat) + locmat = cellinteractions(biop, trefs, brefs, tcell,bcell, qr) for i in 1 : size(locmat, 1), j in 1 : size(locmat, 2) for (m,a) in tad[p][i], (n,b) in bad[p][j] store(a * locmat[i,j] * b, m, n) end end end end - +function same_cell(a,b) +sort(verticeslist(a)) ≈ sort(verticeslist(b)) +end function elementstree(elements) @@ -290,7 +298,7 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} todo, done, pctg = length(tels), 0, 0 for (p,tcell) in enumerate(tels) - tc, ts = boundingbox(tcell.vertices) + tc, ts = boundingbox(verticeslist(tcell)) pred = (c,s) -> boxesoverlap(c,s,tc,ts) for box in boxes(tree, pred) @@ -298,17 +306,16 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} bcell = bels[q] if overlap(tcell, bcell) - s = sign(dot(normal(tcell),normal(bcell))) - isct = intersection(tcell, bcell) - for cell in isct - volume(cell) < tol && continue + isct = intersection2(tcell, bcell) + for (cellt,cellb) in isct + volume(cellt) < tol && continue - P = restrict(brefs, bcell, cell) - Q = restrict(trefs, tcell, cell) + P = restrict(brefs, bcell, cellb) + Q = restrict(trefs, tcell, cellt) - qr = quadrule(biop, trefs, brefs, cell, qd, quadstrat) - zlocal = cellinteractions(biop, trefs, brefs, cell, s, qr) + qr = quadrule(biop, trefs, brefs, cellt,cellb, qd, quadstrat) + zlocal = cellinteractions(biop, trefs, brefs, cellt, cellb, qr) zlocal = Q * zlocal * P' for i in 1 : numfunctions(trefs) @@ -364,7 +371,7 @@ end # return zlocal # end -function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell,sign, qr) +function cellinteractions_matched!(zlocal, biop, trefs, brefs, cellt,cellb, qr) num_tshs = length(qr[1][3]) num_bshs = length(qr[1][4]) @@ -372,14 +379,12 @@ function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell,sign, qr) # zlocal = zeros(Float64, num_tshs, num_bshs) for q in qr - w, tp, tvals, bvals = q[1], q[2], q[3], q[4] - bp = map(tp,sign) + w, (tp,bp), tvals, bvals = q[1], q[2], q[3], q[4] j = w * jacobian(tp) kernel = kernelvals(biop, tp) zlocal += j * integrand(biop, kernel, tp, bp, tvals, bvals) end - return zlocal end @@ -412,26 +417,31 @@ end # return zlocal # end -function cellinteractions(biop, trefs::U, brefs::V, cell, sign,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} +function cellinteractions(biop, trefs::U, brefs::V, cellt,cellb,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} num_tshs = length(qr[1][3]) num_bshs = length(qr[1][4]) zlocal = zeros(T, num_tshs, num_bshs) - + for q in qr - w, tp, tvals, bvals = q[1], q[2], q[3], q[4] - bp = map(tp,sign) + + w, (tp,bp), tvals, bvals = q[1], q[2], q[3], q[4] + j = w * jacobian(tp) kernel = kernelvals(biop, tp) zlocal += j * integrand(biop, kernel, tp, bp, tvals, bvals) + end return zlocal end - +function getvalue(list::Matrix{T}) where {T} + + return SVector{length(list),T}([i for i in list]) +end # function cellinteractions(biop, trefs::U, brefs::V, cell,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} # num_tshs = length(qr[1][3]) diff --git a/src/operator.jl b/src/operator.jl index 60b4027f..e1a094dd 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -216,9 +216,8 @@ function assemble!(operator::Operator, test_functions::Space, trial_functions::S assemblechunk!(operator, test_functions, trial_functions, store; quadstrat) end -defaultquadstrat(op::BasisOperatorLeft,tfs,bfs) = defaultquadstrat(op.operator,op.left_function(tfs),bfs) -defaultquadstrat(op::BasisOperatorRight,tfs,bfs) = defaultquadstrat(op.operator,tfs,op.right_function(bfs)) - +# defaultquadstrat(op::BasisOperatorLeft,tfs,bfs) = defaultquadstrat(op.operator,op.left_function(tfs),bfs) +# defaultquadstrat(op::BasisOperatorRight,tfs,bfs) = defaultquadstrat(op.operator,tfs,op.right_function(bfs)) function assemble!(op::TransposedOperator, tfs::Space, bfs::Space, @@ -233,17 +232,17 @@ function assemble!(op::ZeroOperator, tfs::Space, bfs::Space, quadstrat=nothing) end -function assemble!(op::BasisOperatorLeft, tfs::Space, bfs::Space, store,threading = Threading{:multi}; - quadstrat=defaultquadstrat(op, tfs, bfs)) - #quadstrat = defaultquadstrat(op.operator,op.left_function(tfs),bfs) - assemble!(op.operator,op.left_function(tfs),bfs,store,threading;quadstrat) -end - -function assemble!(op::BasisOperatorRight, tfs::Space, bfs::Space, store,threading = Threading{:multi}; - quadstrat=defaultquadstrat(op, tfs, bfs)) - #quadstrat = defaultquadstrat(op.operator,tfs,op.right_function(bfs)) - assemble!(op.operator,tfs,op.right_function(bfs),store,threading;quadstrat) -end +# function assemble!(op::BasisOperatorLeft, tfs::Space, bfs::Space, store,threading = Threading{:multi}; +# quadstrat=defaultquadstrat(op, tfs, bfs)) +# #quadstrat = defaultquadstrat(op.operator,op.left_function(tfs),bfs) +# assemble!(op.operator,op.left_function(tfs),bfs,store,threading;quadstrat) +# end + +# function assemble!(op::BasisOperatorRight, tfs::Space, bfs::Space, store,threading = Threading{:multi}; +# quadstrat=defaultquadstrat(op, tfs, bfs)) +# #quadstrat = defaultquadstrat(op.operator,tfs,op.right_function(bfs)) +# assemble!(op.operator,tfs,op.right_function(bfs),store,threading;quadstrat) +# end function assemble!(op::LinearCombinationOfOperators, tfs::AbstractSpace, bfs::AbstractSpace, diff --git a/src/quadrature/quadrule.jl b/src/quadrature/quadrule.jl index 8307a966..a7ad862c 100644 --- a/src/quadrature/quadrule.jl +++ b/src/quadrature/quadrule.jl @@ -4,12 +4,12 @@ function quadrule(op::IntegralOperator, g::RTRefSpace, f::RTRefSpace, i, τ, j, σ, qd, qs::DoubleNumSauterQstrat) - T = eltype(eltype(τ.vertices)) + T = eltype(eltype(verticeslist(τ))) hits = 0 dtol = 1.0e3 * eps(T) dmin2 = floatmax(T) - for t in τ.vertices - for s in σ.vertices + for t in verticeslist(τ) + for s in verticeslist(σ) d2 = LinearAlgebra.norm_sqr(t-s) dmin2 = min(dmin2, d2) hits += (d2 < dtol) @@ -29,12 +29,12 @@ end function quadrule(op::IntegralOperator, g::LagrangeRefSpace, f::LagrangeRefSpace, i, τ, j, σ, qd, qs::DoubleNumSauterQstrat) - T = eltype(eltype(τ.vertices)) + T = eltype(eltype(verticeslist(τ))) hits = 0 dtol = 1.0e3 * eps(T) dmin2 = floatmax(T) - for t in τ.vertices - for s in σ.vertices + for t in verticeslist(τ) + for s in verticeslist(σ) d2 = LinearAlgebra.norm_sqr(t-s) dmin2 = min(dmin2, d2) hits += (d2 < dtol) diff --git a/src/quadrature/sauterschwabints.jl b/src/quadrature/sauterschwabints.jl index 25b3a583..6321cbc2 100644 --- a/src/quadrature/sauterschwabints.jl +++ b/src/quadrature/sauterschwabints.jl @@ -90,8 +90,8 @@ function momintegrals!(op::Operator, test_chart, trial_chart, out, rule::SauterSchwabStrategy) I, J, _, _ = SauterSchwabQuadrature.reorder( - test_chart.vertices, - trial_chart.vertices, rule) + verticeslist(test_chart), + verticeslist(trial_chart), rule) test_chart = CompScienceMeshes.permute_vertices(test_chart,I) diff --git a/src/utils/geometrie.jl b/src/utils/geometrie.jl index cdce09f5..47c4e891 100644 --- a/src/utils/geometrie.jl +++ b/src/utils/geometrie.jl @@ -1,30 +1,30 @@ -import Base.- -struct MinusMeshPointNM{T} - meshpoint::T -end -# struct MinusSimplex{T} -# simplex::T +# import Base.- +# struct MinusMeshPointNM{T} +# meshpoint::T # end +# # struct MinusSimplex{T} +# # simplex::T +# # end -normal(a::MinusMeshPointNM) = -normal(a.meshpoint) -# normal(a::MinusSimplex) = -normal(a.MinusSimplex) +# normal(a::MinusMeshPointNM) = -normal(a.meshpoint) +# # normal(a::MinusSimplex) = -normal(a.MinusSimplex) -function map(b::Union{CompScienceMeshes.MeshPointNM,MinusMeshPointNM},sign::Int) - sign==-1 && (return -b) - sign == 1 && (return b) - @error "sign was not 1 or -1" -end +# function map(b::Union{CompScienceMeshes.MeshPointNM,MinusMeshPointNM},sign::Int) +# sign==-1 && (return -b) +# sign == 1 && (return b) +# @error "sign was not 1 or -1" +# end --(b::CompScienceMeshes.MeshPointNM) = MinusMeshPointNM(b) --(b::MinusMeshPointNM) = b.meshpoint -# -(b::Simplex) = MinusSimple(b) -# -(b::MinusSimplex) = b.simplex +# -(b::CompScienceMeshes.MeshPointNM) = MinusMeshPointNM(b) +# -(b::MinusMeshPointNM) = b.meshpoint +# # -(b::Simplex) = MinusSimple(b) +# # -(b::MinusSimplex) = b.simplex -Base.length(m::MinusMeshPointNM) = length(m.meshpoint) -Base.getindex(p::MinusMeshPointNM, i::Int) = p.meshpoint[i] -cartesian(m::MinusMeshPointNM) = cartesian(m.meshpoint) -parametric(m::MinusMeshPointNM) = parametric(m.meshpoint) -chart(m::MinusMeshPointNM) = chart(m.meshpoint) -barycentric(mp::MinusMeshPointNM) = barycentric(mp.meshpoint) -jacobian(mp::MinusMeshPointNM) = jacobian(mp.meshpoint) -tangents(mp::MinusMeshPointNM,i) = tangents(mp.meshpoint,i) +# Base.length(m::MinusMeshPointNM) = length(m.meshpoint) +# Base.getindex(p::MinusMeshPointNM, i::Int) = p.meshpoint[i] +# CompScienceMeshes.cartesian(m::MinusMeshPointNM) = cartesian(m.meshpoint) +# CompScienceMeshes.parametric(m::MinusMeshPointNM) = parametric(m.meshpoint) +# CompScienceMeshes.chart(m::MinusMeshPointNM) = chart(m.meshpoint) +# CompScienceMeshes.barycentric(mp::MinusMeshPointNM) = barycentric(mp.meshpoint) +# CompScienceMeshes.jacobian(mp::MinusMeshPointNM) = jacobian(mp.meshpoint) +# CompScienceMeshes.tangents(mp::MinusMeshPointNM,i) = tangents(mp.meshpoint,i) diff --git a/test/runtests.jl b/test/runtests.jl index cf2ca17a..1d4e0b76 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -71,7 +71,7 @@ include("test_tdrhs_scaling.jl") include("test_td_tensoroperator.jl") include("test_variational.jl") - +include("test_composed_operator.jl") try Pkg.installed("BogaertInts10") diff --git a/test/test_basis.jl b/test/test_basis.jl index 672ed1ed..dbb4655f 100644 --- a/test/test_basis.jl +++ b/test/test_basis.jl @@ -22,6 +22,7 @@ for T in [Float32, Float64] @test size(N) == (numfunctions(X), numfunctions(X)) @test size(I) == (numfunctions(X), numfunctions(X)) + @test rank(I) == numfunctions(X) @time e = assemble(PlaneWaveNeumann(κ, point(0.0, 1.0)), X) diff --git a/test/test_composed_operator.jl b/test/test_composed_operator.jl new file mode 100644 index 00000000..cd83bd81 --- /dev/null +++ b/test/test_composed_operator.jl @@ -0,0 +1,84 @@ +using CompScienceMeshes +using BEAST +using Test + +m = meshrectangle(1.0, 1.0, 0.5, 3) +k = 1.2 + +K = Maxwell3D.doublelayer(wavenumber = k) +I = Identity() +r = raviartthomas(m) + +KM = assemble(K,r,r) +IM = assemble(I,r,r) +CM = assemble(NCross(),r,r) # normal on test function +#limit from inside +TM = KM +1/2*CM + + +G = BEAST.greenhh3d(wavenumber=k) +KC = BEAST.build_potential(∇(G)×B(),m) +KCT1 = BEAST.γ(KC,m,m,1) +TCM1 = assemble(KCT1,r,r) +KCT2 = BEAST.γ(KC,-m,m,-1) +TCM2 = assemble(KCT2,r,r) + +@test TM ≈ TCM1 atol=eps() +@test TM ≈ TCM2 atol=eps() + +#limit from outside +TM = KM -1/2*CM + + +G = BEAST.greenhh3d(wavenumber=k) +KC = BEAST.build_potential(∇(G)×B(),m) +KCT1 = BEAST.γ(KC,m,m,-1) +TCM1 = assemble(KCT1,r,r) +KCT2 = BEAST.γ(KC,-m,m,1) +TCM2 = assemble(KCT2,r,r) + +@test TM ≈ TCM1 atol=eps() +@test TM ≈ TCM2 atol=eps() + +## same for non matching meshes + +m1 = meshrectangle(1.0, 1.0, 0.5, 3) +m2 = translate(m1,[0.2,0.2,0.0]) +k = 1.2 + +K = Maxwell3D.doublelayer(wavenumber = k) +I = Identity() +r1 = raviartthomas(m1) +r2 = raviartthomas(m2) + +KM = assemble(K,r1,r2) +IM = assemble(I,r1,r2) +CM = assemble(NCross(),r1,r2) # normal on test function +#limit from inside +TM = KM +1/2*CM + + +G = BEAST.greenhh3d(wavenumber=k) +KC = BEAST.build_potential(∇(G)×B(),m2) +KCT1 = BEAST.γ(KC,m1,m1,1) +TCM1 = assemble(KCT1,r1,r2) +KCT2 = BEAST.γ(KC,-m1,m1,-1) +TCM2 = assemble(KCT2,r1,r2) + +@test TM ≈ TCM1 atol=eps() +@test TM ≈ TCM2 atol=eps() + +#limit from outside +TM = KM -1/2*CM + + +G = BEAST.greenhh3d(wavenumber=k) +KC = BEAST.build_potential(∇(G)×B(),m2) +KCT1 = BEAST.γ(KC,m1,m1,-1) +TCM1 = assemble(KCT1,r1,r2) +KCT2 = BEAST.γ(KC,-m1,m1,1) +TCM2 = assemble(KCT2,r1,r2) + +@test TM ≈ TCM1 atol=eps() +@test TM ≈ TCM2 atol=eps() + diff --git a/test/test_local_storage.jl b/test/test_local_storage.jl index 7e186ae1..61fc6d71 100644 --- a/test/test_local_storage.jl +++ b/test/test_local_storage.jl @@ -3,11 +3,11 @@ using BEAST using CompScienceMeshes using SparseArrays for T in [Float32, Float64] - local fn = joinpath(@__DIR__, "assets/sphere5.in") - local m = readmesh(fn, T=T) + fn = joinpath(@__DIR__, "assets/sphere5.in") + m = readmesh(fn, T=T) Id = BEAST.Identity() - local X = BEAST.raviartthomas(m) + X = BEAST.raviartthomas(m) Z1 = assemble(Id, X, X, storage_policy=Val{:densestorage}) Z2 = assemble(Id, X, X, storage_policy=Val{:bandedstorage}) From 5cc1522bb2b74034ec0561949d4dc21db56538ac Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 30 Oct 2023 18:24:10 +0100 Subject: [PATCH 056/110] debuged --- examples/ex_globalmultitrace.jl | 6 +- src/BEAST.jl | 2 + src/bases/bdm3dspace.jl | 1 + src/bases/bdmdiv.jl | 1 + src/bases/lagrange.jl | 2 +- src/bases/local/laglocal.jl | 4 +- src/bases/ncrossbdmspace.jl | 1 + src/bases/ndlccspace.jl | 1 + src/bases/ndlcdspace.jl | 1 + src/bases/ndspace.jl | 1 + src/bases/rtspace.jl | 1 + src/composedoperator/composed2.jl | 65 +++++---- src/composedoperator/tracesimplex.jl | 3 +- src/identityop.jl | 18 +-- src/multi-trace/configuration.jl | 2 +- src/multi-trace/interactions.jl | 208 +++++++++++++++++---------- src/quadrature/quadrule.jl | 48 +++---- 17 files changed, 221 insertions(+), 144 deletions(-) diff --git a/examples/ex_globalmultitrace.jl b/examples/ex_globalmultitrace.jl index a16f2bc2..699ff19f 100644 --- a/examples/ex_globalmultitrace.jl +++ b/examples/ex_globalmultitrace.jl @@ -23,7 +23,7 @@ k0 = 3.0 κ = [sqrt(ϵr1*μr1)*κ₀, sqrt(ϵr2*μr2)*κ₀] # Description of the domain boundaries -h = 0.125 +h = 0.2 Γ1 = meshcuboid(1.0, 1.0, 1.0, h) Γ2 = -Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))) Γ = [Γ1, Γ2] @@ -32,7 +32,7 @@ h = 0.125 # of the number of domains and their relative positioning # Incident field -Einc = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=im*κ₀) +Einc = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=κ₀) Hinc = -1/(im*κ₀)*curl(Einc) # Definition of the boundary integral operators @@ -112,4 +112,4 @@ Htot = Ho + sum(Hi) import Plots Plots.heatmap(Xs, Zs, clamp.(real.(getindex.(Htot,2)),-1,1); colormap=:viridis) -Plots.heatmap(Xs, Zs, real.(getindex.(Htot,2))) \ No newline at end of file +Plots.heatmap(Xs, Zs, imag.(getindex.(Htot,2))) \ No newline at end of file diff --git a/src/BEAST.jl b/src/BEAST.jl index f6f6bd9b..948ef229 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -273,6 +273,8 @@ include("composedoperator/composed2.jl") include("composedoperator/tracesimplex.jl") include("display.jl") +include("Helmholtzhodge/hhhexc.jl") +include("Helmholtzhodge/hhhnearfield.jl") const x̂ = point(1,0,0) const ŷ = point(0,1,0) diff --git a/src/bases/bdm3dspace.jl b/src/bases/bdm3dspace.jl index cabb8774..f535d896 100644 --- a/src/bases/bdm3dspace.jl +++ b/src/bases/bdm3dspace.jl @@ -3,6 +3,7 @@ mutable struct BDM3DBasis{T,M,P} <: Space{T} fns::Vector{Vector{Shape{T}}} pos::Vector{P} end +redefine_geometrie(basis::BDM3DBasis{T,M,P},geo::F) where {T,M,P,F}= BDM3DBasis{T,F,P}(geo,basis.fns,basis.pos) refspace(s::BDM3DBasis{T}) where {T} = BDM3DRefSpace{T}() diff --git a/src/bases/bdmdiv.jl b/src/bases/bdmdiv.jl index 7865825d..05f56c68 100644 --- a/src/bases/bdmdiv.jl +++ b/src/bases/bdmdiv.jl @@ -3,6 +3,7 @@ struct BDMBasis{T,M,P} <: Space{T} fns::Vector{Vector{Shape{T}}} pos::Vector{P} end +redefine_geometrie(basis::BDMBasis{T,M,P},geo::F) where {T,M,P,F}= BDMBasis{T,F,P}(geo,basis.fns,basis.pos) BDMBasis(geo, fns) = BDMBasis(geo, fns, Vector{vertextype(geo)}(undef,length(fns))) diff --git a/src/bases/lagrange.jl b/src/bases/lagrange.jl index 790492e3..9b44607d 100644 --- a/src/bases/lagrange.jl +++ b/src/bases/lagrange.jl @@ -16,7 +16,7 @@ mutable struct LagrangeBasis{D,C,M,T,NF,P} <: Space{T} fns::Vector{Vector{Shape{T}}} pos::Vector{P} end - +redefine_geometrie(basis::LagrangeBasis{D,C,M,T,NF,P},geo::F) where {D,C,M,T,NF,P,F} = LagrangeBasis{D,C,F,T,NF,P}(geo,basis.fns,basis.pos) # Constructor that automatically deduces MeshType and ScalarType but requires specification diff --git a/src/bases/local/laglocal.jl b/src/bases/local/laglocal.jl index db176107..af27bc79 100644 --- a/src/bases/local/laglocal.jl +++ b/src/bases/local/laglocal.jl @@ -33,7 +33,7 @@ function (f::LagrangeRefSpace{T,1,3})(t) where T tu = tangents(t,1) tv = tangents(t,2) j = jacobian(t)*sign(dot(normal(t),tu×tv)) - p = t.patch + p = chart(t) SVector( (value=u, curl=(p[3]-p[2])/j), (value=v, curl=(p[1]-p[3])/j), @@ -152,7 +152,7 @@ function restrict(f::LagrangeRefSpace{T,1}, dom1, dom2) where T # for each point of the new domain for i in 1:D - v = dom2.vertices[i] + v = verticeslist(dom2)[i] # find the barycentric coordinates in dom1 uvn = carttobary(dom1, v) diff --git a/src/bases/ncrossbdmspace.jl b/src/bases/ncrossbdmspace.jl index c5ed0364..466bfb4e 100644 --- a/src/bases/ncrossbdmspace.jl +++ b/src/bases/ncrossbdmspace.jl @@ -3,6 +3,7 @@ struct NCrossBDMBasis{T,M,P} <: Space{T} fns::Vector{Vector{Shape{T}}} pos::Vector{P} end +redefine_geometrie(basis::NCrossBDMBasis{T,M,P},geo::F) where {T,M,P,F}= NCrossBDMBasis{T,F,P}(geo,basis.fns,basis.pos) NCrossBDMBasis(geo, fns) = NCrossBDMBasis(geo, fns, Vector{vertextype(geo)}(undef,length(fns))) diff --git a/src/bases/ndlccspace.jl b/src/bases/ndlccspace.jl index aabea3e6..a562779d 100644 --- a/src/bases/ndlccspace.jl +++ b/src/bases/ndlccspace.jl @@ -3,6 +3,7 @@ mutable struct NDLCCBasis{T,M,P} <: Space{T} fns::Vector{Vector{Shape{T}}} pos::Vector{P} end +redefine_geometrie(basis::NDLCCBasis{T,M,P},geo::F) where {T,M,P,F}= NDLCCBasis{T,F,P}(geo,basis.fns,basis.pos) NDLCCBasis(geo, fns) = NDLCCBasis(geo, fns, Vector{vertextype(geo)}(undef,length(fns))) diff --git a/src/bases/ndlcdspace.jl b/src/bases/ndlcdspace.jl index 11d43b81..7bda83ca 100644 --- a/src/bases/ndlcdspace.jl +++ b/src/bases/ndlcdspace.jl @@ -3,6 +3,7 @@ mutable struct NDLCDBasis{T,M,P} <: Space{T} fns::Vector{Vector{Shape{T}}} pos::Vector{P} end +redefine_geometrie(basis::NDLCDBasis{T,M,P},geo::F) where {T,M,P,F}= NDLCDBasis{T,F,P}(geo,basis.fns,basis.pos) NDLCDBasis(geo, fns) = NDLCDBasis(geo, fns, Vector{vertextype(geo)}(undef,length(fns))) diff --git a/src/bases/ndspace.jl b/src/bases/ndspace.jl index 0393e5bb..ef9f740e 100644 --- a/src/bases/ndspace.jl +++ b/src/bases/ndspace.jl @@ -3,6 +3,7 @@ struct NDBasis{T,M,P} <: Space{T} fns::Vector{Vector{Shape{T}}} pos::Vector{P} end +redefine_geometrie(basis::NDBasis{T,M,P},geo::F) where {T,M,P,F}= NDBasis{T,F,P}(geo,basis.fns,basis.pos) NDBasis(geo, fns) = NDBasis(geo, fns, Vector{vertextype(geo)}(undef,length(fns))) diff --git a/src/bases/rtspace.jl b/src/bases/rtspace.jl index b6a280a6..991cecef 100644 --- a/src/bases/rtspace.jl +++ b/src/bases/rtspace.jl @@ -5,6 +5,7 @@ mutable struct RTBasis{T,M,P} <: Space{T} fns::Vector{Vector{Shape{T}}} pos::Vector{P} end +redefine_geometrie(basis::RTBasis{T,M,P},geo::F) where {T,M,P,F}= RTBasis{T,F,P}(geo,basis.fns,basis.pos) RTBasis(geo, fns) = RTBasis(geo, fns, Vector{vertextype(geo)}(undef,length(fns))) diff --git a/src/composedoperator/composed2.jl b/src/composedoperator/composed2.jl index 621255c5..a48f3e4f 100644 --- a/src/composedoperator/composed2.jl +++ b/src/composedoperator/composed2.jl @@ -2,7 +2,7 @@ import Base: *, div import LinearAlgebra: ×, ⋅ - +#TODO add ref of cross etc to eliminate brackets in notation. #const i4pi = 1 / (4pi) abstract type ComposedOperatorLocal <: LocalOperator end @@ -12,18 +12,20 @@ ComposedOperator = Union{ComposedOperatorIntegral,ComposedOperatorLocal} struct BasisFunction <: ComposedOperatorLocal end struct DivBasisFunction <: ComposedOperatorLocal end -const B = BasisFunction +const B = BasisFunction() export B struct TestNormal <: ComposedOperatorLocal end struct TrialNormal <: ComposedOperatorLocal end struct TraceDirection <: ComposedOperatorLocal end -scalartype(op::Union{TestNormal,TrialNormal,BasisFunction,TraceDirection}) = Float16 +scalartype(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction,TraceDirection}) = Float16 const nt = TestNormal() - +const nb = TrialNormal() +export nt +export nb struct Potential{T} <: AbstractOperator operator::T surface @@ -80,7 +82,7 @@ struct CrossIntegral{U,V} <: ComposedOperatorIntegral rhs::V end -function TimesLocal(lhs::LinearCombinationOfOperators,rhs::Union{ComposedOperator,LinearCombinationOfOperators}) +function TimesLocal(lhs::LinearCombinationOfOperators,rhs::Union{Union{ComposedOperator,NormalVector},LinearCombinationOfOperators}) out = ZeroOperator() for (op,coeff) in zip(lhs.ops,lhs.coeffs) out += coeff*TimesLocal(op,rhs) @@ -88,7 +90,7 @@ function TimesLocal(lhs::LinearCombinationOfOperators,rhs::Union{ComposedOperato return out end -function TimesLocal(lhs::ComposedOperator,rhs::LinearCombinationOfOperators) +function TimesLocal(lhs::Union{ComposedOperator,NormalVector},rhs::LinearCombinationOfOperators) out = ZeroOperator() for (op,coeff) in zip(rhs.ops,rhs.coeffs) out += coeff*TimesLocal(lhs,op) @@ -96,7 +98,7 @@ function TimesLocal(lhs::ComposedOperator,rhs::LinearCombinationOfOperators) return out end -function DotLocal(lhs::LinearCombinationOfOperators,rhs::Union{ComposedOperator,LinearCombinationOfOperators}) +function DotLocal(lhs::LinearCombinationOfOperators,rhs::Union{Union{ComposedOperator,NormalVector},LinearCombinationOfOperators}) out = ZeroOperator() for (op,coeff) in zip(lhs.ops,lhs.coeffs) out += coeff*DotLocal(op,rhs) @@ -104,7 +106,7 @@ function DotLocal(lhs::LinearCombinationOfOperators,rhs::Union{ComposedOperator, return out end -function DotLocal(lhs::ComposedOperator,rhs::LinearCombinationOfOperators) +function DotLocal(lhs::Union{ComposedOperator,NormalVector},rhs::LinearCombinationOfOperators) out = ZeroOperator() for (op,coeff) in zip(rhs.ops,rhs.coeffs) out += coeff*DotLocal(lhs,op) @@ -112,7 +114,7 @@ function DotLocal(lhs::ComposedOperator,rhs::LinearCombinationOfOperators) return out end -function CrossLocal(lhs::LinearCombinationOfOperators,rhs::Union{ComposedOperator,LinearCombinationOfOperators}) +function CrossLocal(lhs::LinearCombinationOfOperators,rhs::Union{Union{ComposedOperator,NormalVector},LinearCombinationOfOperators}) out = ZeroOperator() for (op,coeff) in zip(lhs.ops,lhs.coeffs) out += coeff*CrossLocal(op,rhs) @@ -120,7 +122,7 @@ function CrossLocal(lhs::LinearCombinationOfOperators,rhs::Union{ComposedOperato return out end -function CrossLocal(lhs::ComposedOperator,rhs::LinearCombinationOfOperators) +function CrossLocal(lhs::Union{ComposedOperator,NormalVector},rhs::LinearCombinationOfOperators) out = ZeroOperator() for (op,coeff) in zip(rhs.ops,rhs.coeffs) out += coeff*CrossLocal(lhs,op) @@ -138,21 +140,21 @@ OperationsLocal = Union{TimesLocal,DotLocal,CrossLocal} OperationsIntegral = Union{TimesIntegral,DotIntegral,CrossIntegral} Operations = Union{OperationsIntegral,OperationsLocal} -TimesLocal(a::ComposedOperatorIntegral,b::ComposedOperatorLocal) = TimesIntegral(a,b) -TimesLocal(a::ComposedOperatorLocal,b::ComposedOperatorIntegral) = TimesIntegral(a,b) +TimesLocal(a::ComposedOperatorIntegral,b::Union{ComposedOperatorLocal,NormalVector}) = TimesIntegral(a,b) +TimesLocal(a::Union{ComposedOperatorLocal,NormalVector},b::ComposedOperatorIntegral) = TimesIntegral(a,b) TimesLocal(a::ComposedOperatorIntegral,b::ComposedOperatorIntegral) = TimesIntegral(a,b) -DotLocal(a::ComposedOperatorIntegral,b::ComposedOperatorLocal) = DotIntegral(a,b) -DotLocal(a::ComposedOperatorLocal,b::ComposedOperatorIntegral) = DotIntegral(a,b) +DotLocal(a::ComposedOperatorIntegral,b::Union{ComposedOperatorLocal,NormalVector}) = DotIntegral(a,b) +DotLocal(a::Union{ComposedOperatorLocal,NormalVector},b::ComposedOperatorIntegral) = DotIntegral(a,b) DotLocal(a::ComposedOperatorIntegral,b::ComposedOperatorIntegral) = DotIntegral(a,b) -CrossLocal(a::ComposedOperatorIntegral,b::ComposedOperatorLocal) = CrossIntegral(a,b) -CrossLocal(a::ComposedOperatorLocal,b::ComposedOperatorIntegral) = CrossIntegral(a,b) +CrossLocal(a::ComposedOperatorIntegral,b::Union{ComposedOperatorLocal,NormalVector}) = CrossIntegral(a,b) +CrossLocal(a::Union{ComposedOperatorLocal,NormalVector},b::ComposedOperatorIntegral) = CrossIntegral(a,b) CrossLocal(a::ComposedOperatorIntegral,b::ComposedOperatorIntegral) = CrossIntegral(a,b) -×(a::ComposedOperator,b::ComposedOperator) = CrossLocal(a,b) -⋅(a::ComposedOperator,b::ComposedOperator) = DotLocal(a,b) -*(a::ComposedOperator,b::ComposedOperator) = TimesLocal(a,b) +×(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators}) = CrossLocal(a,b) +⋅(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators}) = DotLocal(a,b) +*(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators}) = TimesLocal(a,b) Base.div(::BasisFunction) = DivBasisFunction() @@ -207,14 +209,28 @@ end function γ(op::Potential,direction::CompScienceMeshes.AbstractMesh,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise check_if_coincide(op.surface,surface) || return op.operator - newop = γ(op.operator,sign) + newop = nt × (γ(op.operator,sign) × nt) return TraceOperator(Potential(newop,op.surface),direction,surface) end function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise γ(op,surface,surface,sign) end +function γₛ(op::Potential,direction::CompScienceMeshes.AbstractMesh,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise + check_if_coincide(op.surface,surface) || return op.operator + newop = nt × γ(op.operator,sign) + return TraceOperator(Potential(newop,op.surface),direction,surface) +end +function γₙ(op::Potential,direction::CompScienceMeshes.AbstractMesh,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise + check_if_coincide(op.surface,surface) || return op.operator + newop = nt ⋅ γ(op.operator,sign) + return TraceOperator(Potential(newop,op.surface),direction,surface) +end - +function τ(op::Potential,direction::CompScienceMeshes.AbstractMesh,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise + check_if_coincide(op.surface,surface) || return op.operator + newop = γ(op.operator,sign) + return TraceOperator(Potential(newop,op.surface),direction,surface) +end # γₜᶜ(op::Potential,surface) = nt×(γ(op,surface,-1)×nt) # γₜ(op::Potential,surface) = nt×(γ(op,surface,1)×nt) @@ -343,8 +359,7 @@ function assemble!(op::Potential, test_functions::Space, trial_functions::Space, nsurf = normal_surface(op) surf = geometry(trial_functions) @assert same_geometry(nsurf,surf) - trial = typeof(trial_functions).name.wrapper - trial_functions = trial(OrientedMesh(surf,nsurf),trial_functions.fns,trial_functions.pos) + trial_functions = redefine_geometrie(trial_functions,OrientedMesh(surf,nsurf)) assemble!(op.operator, test_functions, trial_functions, store, threading; quadstrat = quadstrat) @@ -360,9 +375,9 @@ function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Sp @assert same_geometry(nsurf,dsurf) @assert same_geometry(nsurf,surf) - test = typeof(test_functions).name.wrapper + - test_functions = test(TraceMesh(OrientedMesh(surf,nsurf),dsurf),test_functions.fns,test_functions.pos) + test_functions = redefine_geometrie(test_functions,TraceMesh(OrientedMesh(surf,nsurf),dsurf)) assemble!(op.operator, test_functions, trial_functions, store, threading; quadstrat = quadstrat) diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index 40496270..d0c41346 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -20,7 +20,7 @@ CompScienceMeshes.normal(p::TraceMeshPointNM) = normal(p.neighborhood) tracedirection(p::TraceMeshPointNM) = p.sign*normal(p) CompScienceMeshes.jacobian(p::TraceMeshPointNM) = jacobian(p.neighborhood) CompScienceMeshes.tangents(p::TraceMeshPointNM,i) = tangents(p.neighborhood,i) - +CompScienceMeshes.barycentric(a::TraceMeshPointNM) = barycentric(a.neighborhood) coordtype(p::TraceSimplex) = coordtype(p.simp) @@ -104,3 +104,4 @@ CompScienceMeshes.volume(a::TraceSimplex) = volume(simplex(a)) CompScienceMeshes.dimension(a::TraceSimplex) = dimension(simplex(a)) CompScienceMeshes.tangents(a::TraceSimplex,i::Int) = tangents(simplex(a),i) CompScienceMeshes.carttobary(a::TraceSimplex,b::SVector{T}) where {T} = carttobary(simplex(a),b) + diff --git a/src/identityop.jl b/src/identityop.jl index 4eb878ab..9d32fbe3 100644 --- a/src/identityop.jl +++ b/src/identityop.jl @@ -23,8 +23,8 @@ end const LinearRefSpaceTriangle = Union{RTRefSpace, NDRefSpace, BDMRefSpace, NCrossBDMRefSpace} defaultquadstrat(::LocalOperator, ::LinearRefSpaceTriangle, ::LinearRefSpaceTriangle) = SingleNumQStrat(6) -function quaddata(op::LocalOperator, g::LinearRefSpaceTriangle, f::LinearRefSpaceTriangle, tels, bels, - qs::SingleNumQStrat) +function quaddata(op::LocalOperator, g::Union{LinearRefSpaceTriangle,LagrangeRefSpace{T,Deg,3}}, f::Union{LagrangeRefSpace,LinearRefSpaceTriangle}, tels, bels, + qs::SingleNumQStrat) where{T,Deg} u, w = trgauss(qs.quad_rule) qd = [(w[i],SVector(u[1,i],u[2,i])) for i in 1:length(w)] @@ -66,14 +66,14 @@ function quaddata(op::LocalOperator, g::LagrangeRefSpace{T,Deg,2} where {T,Deg}, end defaultquadstrat(::LocalOperator, ::LagrangeRefSpace{T,D1,3}, ::LagrangeRefSpace{T,D2,3}) where {T,D1,D2} = SingleNumQStrat(6) -function quaddata(op::LocalOperator, g::LagrangeRefSpace{T,Deg,3} where {T,Deg}, - f::LagrangeRefSpace, tels::Vector, bels::Vector, qs::SingleNumQStrat) +# function quaddata(op::LocalOperator, g::LagrangeRefSpace{T,Deg,3} where {T,Deg}, +# f::LagrangeRefSpace, tels::Vector, bels::Vector, qs::SingleNumQStrat) - u, w = trgauss(qs.quad_rule) - qd = [(w[i], SVector(u[1,i], u[2,i])) for i in 1:length(w)] - A = _alloc_workspace(qd, g, f, tels, bels) - return qd, A -end +# u, w = trgauss(qs.quad_rule) +# qd = [(w[i], SVector(u[1,i], u[2,i])) for i in 1:length(w)] +# A = _alloc_workspace(qd, g, f, tels, bels) +# return qd, A +# end defaultquadstrat(::LocalOperator, ::LagrangeRefSpace{T,D1,4}, ::LagrangeRefSpace{T,D2,4}) where {T,D1,D2} = SingleNumQStrat(6) function quaddata(op::LocalOperator, g::LagrangeRefSpace{T,Deg,4} where {T,Deg}, diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl index 29f13261..6443c14a 100644 --- a/src/multi-trace/configuration.jl +++ b/src/multi-trace/configuration.jl @@ -235,7 +235,7 @@ function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) out = interaction_matrix(config,0,strat) for (id,Ω) in config.domains id==0 && continue - out += interaction_matrix(config,id,strat) + out += Ω.data.coeff* interaction_matrix(config,id,strat) end return out end diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index a099e513..a00dac37 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -1,5 +1,5 @@ - +using LinearAlgebra """ Write for each type of interaction this type of function. """ @@ -10,72 +10,72 @@ function (int::Interaction{<:Domain{BackgroundDomain},})() return nothing end -function alpha(Ω1,Ω2) - +# function alpha(Ω1,Ω2) -end -""" -cauchylimit needs to be applied before the normalorient function -""" -function cauchylimit(operator::AbstractOperator;Ω1,Ω2,Ω3) -#check first if touching is non empty -@assert is_child_of(Ω1,Ω3)||Ω1===Ω3 -@assert is_child_of(Ω2,Ω3)||Ω2===Ω3 - # if Ω2!==Ω3 - # sign = -1 - # elseif Ω2===Ω3 - # sign = 1 - # end - @warn "correct sign for inside is 1?" - sign = 1 +# end +# """ +# cauchylimit needs to be applied before the normalorient function +# """ + +# function cauchylimit(operator::AbstractOperator;Ω1,Ω2,Ω3) +# #check first if touching is non empty +# @assert is_child_of(Ω1,Ω3)||Ω1===Ω3 +# @assert is_child_of(Ω2,Ω3)||Ω2===Ω3 +# # if Ω2!==Ω3 +# # sign = -1 +# # elseif Ω2===Ω3 +# # sign = 1 +# # end +# @warn "correct sign for inside is 1?" +# sign = 1 - trace(operator,sign) +# trace(operator,sign) -end +# end -function trace(op::AbstractOperator,sign) - @warn "general abstract opterator trace function called returning pv of operator!: "*string(typeof(op)) - return op -end -function normalorient(op::AbstractOperator,signtest,signtrial) - @warn "normalorient not implemented for: "*string(typeof(op)) - return op -end -trace(op::ZeroOperator,s) = op +# function trace(op::AbstractOperator,sign) +# @warn "general abstract opterator trace function called returning pv of operator!: "*string(typeof(op)) +# return op +# end +# function normalorient(op::AbstractOperator,signtest,signtrial) +# @warn "normalorient not implemented for: "*string(typeof(op)) +# return op +# end +# trace(op::ZeroOperator,s) = op -function trace(op::LinearCombinationOfOperators,sign) - result = ZeroOperator() - for (c,o) in zip(op.coeffs,op.ops) - result += c*trace(o,sign) - end - return result -end +# function trace(op::LinearCombinationOfOperators,sign) +# result = ZeroOperator() +# for (c,o) in zip(op.coeffs,op.ops) +# result += c*trace(o,sign) +# end +# return result +# end -function normalorient(op::LinearCombinationOfOperators,signtest,signtrial) - result = ZeroOperator() - for (c,o) in zip(op.coeffs,op.ops) - result += c*normalorient(o,signtest,signtrial) - end - return result -end +# function normalorient(op::LinearCombinationOfOperators,signtest,signtrial) +# result = ZeroOperator() +# for (c,o) in zip(op.coeffs,op.ops) +# result += c*normalorient(o,signtest,signtrial) +# end +# return result +# end -function normalorient(operator::AbstractOperator;Ω1,Ω2,Ω3) - if Ω1===Ω3 - sign_test_normal = 1 - else - sign_test_normal = -1 - end - if Ω2===Ω3 - sign_trial_normal = 1 - else - sign_trial_normal = -1 - end - normalorient(operator,sign_test_normal,sign_trial_normal) -end +# function normalorient(operator::AbstractOperator;Ω1,Ω2,Ω3) +# if Ω1===Ω3 +# sign_test_normal = 1 +# else +# sign_test_normal = -1 +# end +# if Ω2===Ω3 +# sign_trial_normal = 1 +# else +# sign_trial_normal = -1 +# end +# normalorient(operator,sign_test_normal,sign_trial_normal) +# end -normalorient(op::ZeroOperator,a,b) = op +# normalorient(op::ZeroOperator,a,b) = op ###### Interactions struct VectorStrat <: BEAST.NumericalStrategy end @@ -147,39 +147,91 @@ end # end +# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<:Union{RootDomain,SubDomain}})(::VectorStrat) +# p = physicalconstants(int.embedvol.data) +# k = sqrt(p.ϵ*p.μ)*p.ω +# G = BEAST.greenhh3d(wavenumber=k) +# ∇G = BEAST.∇(G) +# Ω1=int.testvol +# Ω2=int.trialvol +# Ω3=int.embedvol +# bs = Ω2.data.trialbasises[1].geo +# ts = Ω1.data.testbasises[1].geo + +# ∇Gx = BEAST.build_potential(∇G×B,bs) +# Gn = BEAST.build_potential(G*n*B,bs) +# Gnx = BEAST.build_potential(G*n × B,bs) +# ∇G = BEAST.build_potential(∇G*B,bs) +# ∇Gdotn = BEAST.build_potential(∇G⋅n*B,bs) +# ∇Gdot = BEAST.build_potential(∇G⋅B,bs) + +# Gr = BEAST.build_potential(G*B,bs) +# ∇G∇B = BEAST.build_potential(∇G*∇(B),bs) +# ∇Gxn = BEAST.build_potential(∇G×n*B,bs) + +# if Ω1==Ω2 +# a = -[γₛ(∇Gx,ts) γₛ(Gn,ts) -γₛ(Gnx,ts) γₛ(∇G,ts) +# BEAST.ZeroOperator() -τ(∇Gdotn,ts) τ(∇Gdot,ts) k^2*τ(Gr,ts) +# -γₛ(∇G∇B,ts)-k^2*γₛ(Gr,ts) -γₛ(∇Gxn,ts) γₛ(∇Gx,ts) BEAST.ZeroOperator() +# -γₙ(∇Gx,ts) -γₙ(Gn,ts) γₙ(Gr,ts) -γₙ(∇G,ts)] +# else +# a = -[γₛᶜ(∇Gx,ts) γₛᶜ(Gn,ts) -γₛᶜ(Gnx,ts) γₛᶜ(∇G,ts) +# BEAST.ZeroOperator() -τᶜ(∇Gdotn,ts) τᶜ(∇Gdot,ts) k^2*τᶜ(Gr,ts) +# -γₛᶜ(∇G∇B,ts)-k^2*γₛᶜ(Gr,ts) -γₛᶜ(∇Gxn,ts) γₛᶜ(∇Gx,ts) BEAST.ZeroOperator() +# -γₙᶜ(∇Gx,ts) -γₙᶜ(Gn,ts) γₙᶜ(Gr,ts) -γₙᶜ(∇G,ts)] +# end + + +# #a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + +# return a + +# end + function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<:Union{RootDomain,SubDomain}})(::VectorStrat) p = physicalconstants(int.embedvol.data) k = sqrt(p.ϵ*p.μ)*p.ω G = BEAST.greenhh3d(wavenumber=k) - ∇G = BEAST.∇(G) + gradG = BEAST.∇(G) Ω1=int.testvol Ω2=int.trialvol Ω3=int.embedvol - ∇Gx = BEAST.build_potential(∇G×B,Ω2.data.trialbasises[1].geo) - Gn = BEAST.build_potential(G*n*B,Ω2.data.trialbasises[1].geo) - Gnx = BEAST.build_potential(G*n × B,Ω2.data.trialbasises[1].geo) - ∇G = BEAST.build_potential(∇G*B,Ω2.data.trialbasises[1].geo) - ∇Gdotn = BEAST.build_potential(∇G⋅n*B,Ω2.data.trialbasises[1].geo) - ∇Gdot = BEAST.build_potential(∇G⋅B,Ω2.data.trialbasises[1].geo) + bs = Ω2.data.trialbasises[1].geo + ts = Ω1.data.testbasises[1].geo + + ∇Gx = BEAST.build_potential(gradG×B,bs) + Gn = BEAST.build_potential(G*(n*B),bs) + Gnx = BEAST.build_potential(G*(n × B),bs) + ∇G = BEAST.build_potential(gradG*B,bs) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) + ∇Gdot = BEAST.build_potential(gradG⋅B,bs) - Gr = BEAST.build_potential(G*B,Ω2.data.trialbasises[1].geo) - ∇G∇B = BEAST.build_potential(∇G*∇(B),Ω2.data.trialbasises[1].geo) - ∇Gxn = BEAST.build_potential(∇G×n*B,Ω2.data.trialbasises[1].geo) - testsurf = Ω1.data.testbasises[1].geo - if Ω1==Ω2 - a = -[γₛ(∇Gx,testsurf) γₛ(Gn,testsurf) -γₛ(Gnx,testsurf) γₛ(∇G,testsurf) - BEAST.ZeroOperator() -τ(∇Gdotn,testsurf) τ(∇Gdot,testsurf) k^2*τ(Gr,testsurf) - -γₛ(∇G∇B,testsurf)-k^2*γₛ(Gr,testsurf) -γₛ(∇Gxn,testsurf) γₛ(∇Gx,testsurf) BEAST.ZeroOperator() - -γₙ(∇Gx,testsurf) -γₙ(Gn,testsurf) γₙ(Gr,testsurf) -γₙ(∇G,testsurf)] + Gr = BEAST.build_potential(G*B,bs) + ∇G∇B = BEAST.build_potential(gradG*div(B),bs) + ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) + sign = 1 + if Ω1==Ω2==Ω3 + + elseif Ω1==Ω2!=Ω3 + ts = -ts + bs = -bs + + elseif Ω1!=Ω2 + ts = -ts + bs = -bs + sign = -1 + else - a = -[γₛᶜ(∇Gx,testsurf) γₛᶜ(Gn,testsurf) -γₛᶜ(Gnx,testsurf) γₛᶜ(∇G,testsurf) - BEAST.ZeroOperator() -τᶜ(∇Gdotn,testsurf) τᶜ(∇Gdot,testsurf) k^2*τᶜ(Gr,testsurf) - -γₛᶜ(∇G∇B,testsurf)-k^2*γₛᶜ(Gr,testsurf) -γₛᶜ(∇Gxn,testsurf) γₛᶜ(∇Gx,testsurf) BEAST.ZeroOperator() - -γₙᶜ(∇Gx,testsurf) -γₙᶜ(Gn,testsurf) γₙᶜ(Gr,testsurf) -γₙᶜ(∇G,testsurf)] + @error "none of previous" + end + a = -[γₛ(∇Gx,ts,ts,sign) γₛ(Gn,ts,ts,sign) -γₛ(Gnx,ts,ts,sign) γₛ(∇G,ts,ts,sign) + BEAST.ZeroOperator() -τ(∇Gdotn,ts,ts,sign) τ(∇Gdot,ts,ts,sign) k^2*τ(Gr,ts,ts,sign) + -γₛ(∇G∇B,ts,ts,sign)-k^2*γₛ(Gr,ts,ts,sign) -γₛ(∇Gxn,ts,ts,sign) γₛ(∇Gx,ts,ts,sign) BEAST.ZeroOperator() + -γₙ(∇Gx,ts,ts,sign) -γₙ(Gn,ts,ts,sign) γₙ(Gr,ts,ts,sign) -γₙ(∇G,ts,ts,sign)] - a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + #a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) return a diff --git a/src/quadrature/quadrule.jl b/src/quadrature/quadrule.jl index a7ad862c..7f7e72ac 100644 --- a/src/quadrature/quadrule.jl +++ b/src/quadrature/quadrule.jl @@ -1,7 +1,7 @@ # This file contains kernel independent implementations of quadrule for # the various quadrature strategies defined in quadstrats.jl -function quadrule(op::IntegralOperator, g::RTRefSpace, f::RTRefSpace, i, τ, j, σ, qd, +function quadrule(op::IntegralOperator, g::Union{RTRefSpace,LagrangeRefSpace}, f::Union{RTRefSpace,LagrangeRefSpace}, i, τ, j, σ, qd, qs::DoubleNumSauterQstrat) T = eltype(eltype(verticeslist(τ))) @@ -26,26 +26,26 @@ function quadrule(op::IntegralOperator, g::RTRefSpace, f::RTRefSpace, i, τ, j, end -function quadrule(op::IntegralOperator, g::LagrangeRefSpace, f::LagrangeRefSpace, i, τ, j, σ, qd, - qs::DoubleNumSauterQstrat) - - T = eltype(eltype(verticeslist(τ))) - hits = 0 - dtol = 1.0e3 * eps(T) - dmin2 = floatmax(T) - for t in verticeslist(τ) - for s in verticeslist(σ) - d2 = LinearAlgebra.norm_sqr(t-s) - dmin2 = min(dmin2, d2) - hits += (d2 < dtol) - end - end - - hits == 3 && return SauterSchwabQuadrature.CommonFace(qd.gausslegendre[3]) - hits == 2 && return SauterSchwabQuadrature.CommonEdge(qd.gausslegendre[2]) - hits == 1 && return SauterSchwabQuadrature.CommonVertex(qd.gausslegendre[1]) - - return DoubleQuadRule( - qd.tpoints[1,i], - qd.bpoints[1,j],) -end \ No newline at end of file +# function quadrule(op::IntegralOperator, g::LagrangeRefSpace, f::LagrangeRefSpace, i, τ, j, σ, qd, +# qs::DoubleNumSauterQstrat) + +# T = eltype(eltype(verticeslist(τ))) +# hits = 0 +# dtol = 1.0e3 * eps(T) +# dmin2 = floatmax(T) +# for t in verticeslist(τ) +# for s in verticeslist(σ) +# d2 = LinearAlgebra.norm_sqr(t-s) +# dmin2 = min(dmin2, d2) +# hits += (d2 < dtol) +# end +# end + +# hits == 3 && return SauterSchwabQuadrature.CommonFace(qd.gausslegendre[3]) +# hits == 2 && return SauterSchwabQuadrature.CommonEdge(qd.gausslegendre[2]) +# hits == 1 && return SauterSchwabQuadrature.CommonVertex(qd.gausslegendre[1]) + +# return DoubleQuadRule( +# qd.tpoints[1,i], +# qd.bpoints[1,j],) +# end \ No newline at end of file From 33180e2be629a899f663a0ebc7778cc5a436eca6 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 7 Nov 2023 16:46:29 +0100 Subject: [PATCH 057/110] new interpretation of trace by inserting infinitisimal gap --- examples/pmchwt.jl | 6 +- src/BEAST.jl | 3 +- src/composedoperator/composed2.jl | 141 +++++++++++++++++++-------- src/composedoperator/tracesimplex.jl | 51 +++++----- src/localop.jl | 4 +- src/multi-trace/interactions.jl | 2 +- test/test_composed_operator.jl | 24 ++--- 7 files changed, 151 insertions(+), 80 deletions(-) diff --git a/examples/pmchwt.jl b/examples/pmchwt.jl index 7e170fa5..da950ec2 100644 --- a/examples/pmchwt.jl +++ b/examples/pmchwt.jl @@ -27,7 +27,7 @@ radius = 1.0 λ = 2.9979563769321627 ω = 2π*c/λ -Ω = CompScienceMeshes.tetmeshsphere(radius,0.4*radius) +Ω = CompScienceMeshes.tetmeshsphere(radius,0.2*radius) Γ = boundary(Ω) X = raviartthomas(Γ) @show numfunctions(X) @@ -46,7 +46,7 @@ T′ = Maxwell3D.singlelayer(wavenumber=κ′) K = Maxwell3D.doublelayer(wavenumber=κ) K′ = Maxwell3D.doublelayer(wavenumber=κ′) -E = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=im*κ) +E = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=κ) H = -1/(im*κ*η)*curl(E) e = (n × E) × n @@ -99,7 +99,7 @@ Plotly.plot(patch(Γ, norm.(fcrm))) Z = range(-6,6,length=200) Y = range(-4,4,length=200) -nfpoints = [point(0,y,z) for z in Z, y in Y] +nfpoints = [point(0,y,z) for y in Y, z in Z] import Base.Threads: @spawn task1 = @spawn nearfield(u[m],u[j],X,X,κ,η,nfpoints,E,H) diff --git a/src/BEAST.jl b/src/BEAST.jl index 948ef229..eba04e26 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -269,8 +269,9 @@ include("multi-trace/interactions.jl") include("multi-trace/postprocessing.jl") #suport for displaying operators -include("composedoperator/composed2.jl") include("composedoperator/tracesimplex.jl") +include("composedoperator/composed2.jl") + include("display.jl") include("Helmholtzhodge/hhhexc.jl") diff --git a/src/composedoperator/composed2.jl b/src/composedoperator/composed2.jl index a48f3e4f..24b62695 100644 --- a/src/composedoperator/composed2.jl +++ b/src/composedoperator/composed2.jl @@ -14,6 +14,7 @@ struct BasisFunction <: ComposedOperatorLocal end struct DivBasisFunction <: ComposedOperatorLocal end const B = BasisFunction() export B +export BasisFunction struct TestNormal <: ComposedOperatorLocal end @@ -28,10 +29,10 @@ export nt export nb struct Potential{T} <: AbstractOperator operator::T - surface + surface::TraceMesh end -normal_surface(p::Potential) = p.surface -function Potential(linop::LinearCombinationOfOperators,surface) +surface(p::Potential) = p.surface +function Potential(linop::LinearCombinationOfOperators,surface::TraceMesh) out = ZeroOperator() for (op,coeff) in zip(linop.ops,linop.coeffs) out += coeff*Potential(op,surface) @@ -40,18 +41,18 @@ function Potential(linop::LinearCombinationOfOperators,surface) end struct TraceOperator{T} <: AbstractOperator operator::T - directionsurface - normalsurface + surface::TraceMesh end -function TraceOperator(linop::LinearCombinationOfOperators,dsurf,nsurf) +function TraceOperator(linop::LinearCombinationOfOperators,surf::TraceMesh) out = ZeroOperator() for (op,coeff) in zip(linop.ops,linop.coeffs) - out += coeff*TraceOperator(op,dsurf,nsurf) + out += coeff*TraceOperator(op,surf) end return out end -normal_surface(p::TraceOperator) = p.normalsurface -direction_surface(p::TraceOperator) = p.directionsurface +# normal_surface(p::TraceOperator) = p.normalsurface +# direction_surface(p::TraceOperator) = p.directionsurface +surface(p::TraceOperator) = p.surface struct TimesLocal{U,V} <: ComposedOperatorLocal lhs::U rhs::V @@ -193,43 +194,107 @@ replace_normal_by_trialnormal(op::NormalVector) = TrialNormal() function build_potential(op::ComposedOperator,surface::CompScienceMeshes.Mesh) + newop = replace_normal_by_trialnormal(op) + Potential(newop,TraceMesh(surface)) +end +function build_potential(op::ComposedOperator,surface::TraceMesh) newop = replace_normal_by_trialnormal(op) Potential(newop,surface) end -function γ(op::Operations,sign) +function γ(op::Operations) - return get_constructor(op)(γ(op.lhs,sign),γ(op.rhs,sign)) + return get_constructor(op)(γ(op.lhs),γ(op.rhs)) end -γ(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction},sign) = op +γ(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction}) = op function check_if_coincide(a,b) @warn "all meshes coincide" return true end -function γ(op::Potential,direction::CompScienceMeshes.AbstractMesh,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise +function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise check_if_coincide(op.surface,surface) || return op.operator - newop = nt × (γ(op.operator,sign) × nt) - return TraceOperator(Potential(newop,op.surface),direction,surface) + newop = nt × (γ(op.operator) × nt) + direction = [] + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) end -function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise - γ(op,surface,surface,sign) +function γ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise + check_if_coincide(op.surface,surface) || return op.operator + newop = nt × (γ(op.operator) × nt) + direction = [] + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) +end + + +function γₛ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise + check_if_coincide(op.surface,surface) || return op.operator + newop = nt × γ(op.operator) + direction = [] + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) end -function γₛ(op::Potential,direction::CompScienceMeshes.AbstractMesh,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise +function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise check_if_coincide(op.surface,surface) || return op.operator - newop = nt × γ(op.operator,sign) - return TraceOperator(Potential(newop,op.surface),direction,surface) + newop = nt × γ(op.operator) + direction = [] + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) +end + +function γₙ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise + check_if_coincide(op.surface,surface) || return op.operator + newop = nt ⋅ γ(op.operator) + direction = [] + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) end -function γₙ(op::Potential,direction::CompScienceMeshes.AbstractMesh,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise +function γₙ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise check_if_coincide(op.surface,surface) || return op.operator - newop = nt ⋅ γ(op.operator,sign) - return TraceOperator(Potential(newop,op.surface),direction,surface) + newop = nt ⋅ γ(op.operator) + direction = [] + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) end -function τ(op::Potential,direction::CompScienceMeshes.AbstractMesh,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise +function τ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise check_if_coincide(op.surface,surface) || return op.operator - newop = γ(op.operator,sign) - return TraceOperator(Potential(newop,op.surface),direction,surface) + newop = γ(op.operator) + direction = [] + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) +end +function τ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise + check_if_coincide(op.surface,surface) || return op.operator + newop = γ(op.operator) + direction = [] + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) end # γₜᶜ(op::Potential,surface) = nt×(γ(op,surface,-1)×nt) # γₜ(op::Potential,surface) = nt×(γ(op,surface,1)×nt) @@ -288,8 +353,8 @@ function (op::GradGreenHH3D)(x,y,g) Ref(gradgreen) end -γ(op::GreenHH3D,sign::Int) = op -γ(op::GradGreenHH3D,sign::Int) = op + sign*1/2*TraceDirection() +γ(op::GreenHH3D) = op +γ(op::GradGreenHH3D) = op + 1/2*TraceDirection() grad(G::GreenHH3D) = GradGreenHH3D(G.gamma) @@ -319,7 +384,7 @@ function (op::TestNormal)(x,y,g) Ref(normal(x)) end function (op::TraceDirection)(x,y,g) - Ref(tracedirection(x)) + Ref(sign(dot(normal(x),(direction(x)-direction(y))))*normal(x)) end function (op::BasisFunction)(x,y,g) getvalue(g) @@ -356,10 +421,11 @@ function assemble!(op::Potential, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; quadstrat = defaultquadstrat(op, test_functions, trial_functions)) - nsurf = normal_surface(op) + dsurf = surface(op) surf = geometry(trial_functions) - @assert same_geometry(nsurf,surf) - trial_functions = redefine_geometrie(trial_functions,OrientedMesh(surf,nsurf)) + @assert same_geometry(dsurf,surf) + nsurf = mesh(dsurf) + trial_functions = redefine_geometrie(trial_functions,TraceMesh(OrientedMesh(surf,nsurf),direction(dsurf))) assemble!(op.operator, test_functions, trial_functions, store, threading; quadstrat = quadstrat) @@ -369,15 +435,12 @@ function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Sp store, threading = Threading{:multi}; quadstrat = defaultquadstrat(op, test_functions, trial_functions)) - nsurf = normal_surface(op) - dsurf = direction_surface(op) + dsurf = surface(op) surf = geometry(test_functions) - @assert same_geometry(nsurf,dsurf) - @assert same_geometry(nsurf,surf) - + @assert same_geometry(dsurf,surf) + nsurf = mesh(dsurf) - - test_functions = redefine_geometrie(test_functions,TraceMesh(OrientedMesh(surf,nsurf),dsurf)) + test_functions = redefine_geometrie(test_functions,TraceMesh(OrientedMesh(surf,nsurf),direction(dsurf))) assemble!(op.operator, test_functions, trial_functions, store, threading; quadstrat = quadstrat) diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index d0c41346..bd47558b 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -1,23 +1,23 @@ import Base.sign -struct TraceSimplex{T} +struct TraceSimplex{T,U} simp::T - sign::Int + direction::SVector{3,U} end simplex(t::TraceSimplex) = t.simp -sign(t::TraceSimplex) = t.sign -struct TraceMeshPointNM{T} +direction(t::TraceSimplex) = t.direction +struct TraceMeshPointNM{T,U} neighborhood::T - sign::Int + direction::SVector{3,U} end - +direction(p::TraceMeshPointNM) = p.direction function CompScienceMeshes.neighborhood(p::TraceSimplex, bary) - TraceMeshPointNM(neighborhood(p.simp,bary),p.sign) + TraceMeshPointNM(neighborhood(p.simp,bary),p.direction) end CompScienceMeshes.cartesian(p::TraceMeshPointNM) = cartesian(p.neighborhood) CompScienceMeshes.parametric(p::TraceMeshPointNM) = parametric(p.neighborhood) chart(p::TraceMeshPointNM) = chart(p.neighborhood) CompScienceMeshes.normal(p::TraceMeshPointNM) = normal(p.neighborhood) -tracedirection(p::TraceMeshPointNM) = p.sign*normal(p) + CompScienceMeshes.jacobian(p::TraceMeshPointNM) = jacobian(p.neighborhood) CompScienceMeshes.tangents(p::TraceMeshPointNM,i) = tangents(p.neighborhood,i) CompScienceMeshes.barycentric(a::TraceMeshPointNM) = barycentric(a.neighborhood) @@ -31,8 +31,15 @@ struct OrientedMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} end struct TraceMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} mesh::CompScienceMeshes.AbstractMesh{U,D1,T} - direction::CompScienceMeshes.AbstractMesh{U,D1,T} + direction::SVector end +TraceMesh(a::CompScienceMeshes.AbstractMesh{U,D,T}) where {U,D,T} = TraceMesh(a,zeros(SVector{numcells(a),SVector{3,T}})) ++(a::TraceMesh{U,D,T},b::SVector{3,T}) where {U,D,T} = TraceMesh(mesh(a),direction(a).+Ref(b)) ++(a::TraceMesh,b::SVector) = TraceMesh(mesh(a),a.direction+b) ++(a::SVector,b::TraceMesh) = b+a + + + mesh(p::OrientedMesh) = p.mesh mesh(p::TraceMesh) = p.mesh CompScienceMeshes.normal(p::OrientedMesh) = p.normalmesh @@ -49,10 +56,8 @@ function CompScienceMeshes.chart(p::OrientedMesh,i) end function CompScienceMeshes.chart(p::TraceMesh,i) c = chart(mesh(p),i) - d = chart(direction(p),i) - p = dot(normal(c),normal(d)) - @assert abs(p) ≈ 1.0 - TraceSimplex(c,Int(sign(p))) + d = direction(p)[i] + TraceSimplex(c,d) end function same_geometry(m1,m2) @@ -62,9 +67,11 @@ end _ispermutation(a,b) = sort(a)==sort(b) CompScienceMeshes.cells(p::OrientedMesh) = cells(mesh(p)) CompScienceMeshes.cells(p::TraceMesh) = cells(mesh(p)) - +CompScienceMeshes.vertices(p::TraceMesh) = vertices(mesh(p)) CompScienceMeshes.domain(ch::TraceSimplex) = CompScienceMeshes.domain(simplex(ch)) +CompScienceMeshes.dimension(::Type{TraceSimplex{CompScienceMeshes.Simplex{U,D,C,N,T},T}}) where {U,D,C,N,T} = D +CompScienceMeshes.coordtype(::Type{TraceSimplex{CompScienceMeshes.Simplex{U,D,C,N,T},T}}) where {U,D,C,N,T} = T function CompScienceMeshes.quadpoints(chart::TraceSimplex, rule) @@ -76,29 +83,29 @@ function CompScienceMeshes.quadpoints(chart::TraceSimplex, rule) end end CompScienceMeshes.verticeslist(p::TraceSimplex) = verticeslist(simplex(p)) -CompScienceMeshes.permute_vertices(simp::TraceSimplex,I) = TraceSimplex(CompScienceMeshes.permute_vertices(simplex(simp),I),sign(simp)) +CompScienceMeshes.permute_vertices(simp::TraceSimplex,I) = TraceSimplex(CompScienceMeshes.permute_vertices(simplex(simp),I),direction(simp)) CompScienceMeshes.overlap(a::TraceSimplex,b::TraceSimplex) = overlap(simplex(a),simplex(b)) CompScienceMeshes.overlap(a::CompScienceMeshes.Simplex,b::TraceSimplex) = overlap(a,simplex(b)) CompScienceMeshes.overlap(a::TraceSimplex,b::CompScienceMeshes.Simplex) = overlap(simplex(a),b) CompScienceMeshes.intersection(a::CompScienceMeshes.Simplex,b::TraceSimplex) = intersection(a,simplex(b)) -function CompScienceMeshes.intersection(a::TraceSimplex,b::Union{TraceSimplex,CompScienceMeshes.Simplex}) - int = intersection(simplex(a),b) - TraceSimplex.(int,sign(a)) -end +# function CompScienceMeshes.intersection(a::TraceSimplex,b::Union{TraceSimplex,CompScienceMeshes.Simplex}) +# int = intersection(simplex(a),b) +# TraceSimplex.(int,sign(a)) +# end function CompScienceMeshes.intersection2(a::TraceSimplex,b::TraceSimplex) int = intersection2(simplex(a),simplex(b)) - return [(TraceSimplex(i[1],sign(a)),TraceSimplex(i[2],sign(b))) for i in int] + return [(TraceSimplex(i[1],direction(a)),TraceSimplex(i[2],direction(b))) for i in int] end function CompScienceMeshes.intersection2(a::CompScienceMeshes.Simplex,b::TraceSimplex) int = intersection2(a,simplex(b)) - return [(i[1],TraceSimplex(i[2],sign(b))) for i in int] + return [(TraceSimplex(i[1],direction(b)*0),TraceSimplex(i[2],direction(b))) for i in int] end function CompScienceMeshes.intersection2(a::TraceSimplex,b::CompScienceMeshes.Simplex) int = intersection2(simplex(a),b) - return [(TraceSimplex(i[1],sign(a)),i[2]) for i in int] + return [(TraceSimplex(i[1],direction(a)),TraceSimplex(i[2],direction(a)*0)) for i in int] end CompScienceMeshes.volume(a::TraceSimplex) = volume(simplex(a)) CompScienceMeshes.dimension(a::TraceSimplex) = dimension(simplex(a)) diff --git a/src/localop.jl b/src/localop.jl index f54ad860..126ed725 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -248,7 +248,7 @@ function elementstree(elements) ncells = length(elements) @assert !isempty(elements) - P = eltype(elements[1].vertices) + P = eltype(verticeslist(elements[1])) T = coordtype(eltype(elements)) points = zeros(P, ncells) @@ -256,7 +256,7 @@ function elementstree(elements) for i in 1 : ncells - verts = elements[i].vertices + verts = verticeslist(elements[i]) bary = verts[1] for j in 2:length(verts) diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index a00dac37..268260f7 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -204,7 +204,7 @@ function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDom Gnx = BEAST.build_potential(G*(n × B),bs) ∇G = BEAST.build_potential(gradG*B,bs) ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) - ∇Gdot = BEAST.build_potential(gradG⋅B,bs) + ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) Gr = BEAST.build_potential(G*B,bs) ∇G∇B = BEAST.build_potential(gradG*div(B),bs) diff --git a/test/test_composed_operator.jl b/test/test_composed_operator.jl index cd83bd81..78a42b92 100644 --- a/test/test_composed_operator.jl +++ b/test/test_composed_operator.jl @@ -17,10 +17,10 @@ TM = KM +1/2*CM G = BEAST.greenhh3d(wavenumber=k) -KC = BEAST.build_potential(∇(G)×B(),m) -KCT1 = BEAST.γ(KC,m,m,1) +KC = BEAST.build_potential(∇(G)×BasisFunction(),m) +KCT1 = BEAST.γ(KC,m,1) TCM1 = assemble(KCT1,r,r) -KCT2 = BEAST.γ(KC,-m,m,-1) +KCT2 = BEAST.γ(KC,-m,-1) TCM2 = assemble(KCT2,r,r) @test TM ≈ TCM1 atol=eps() @@ -31,10 +31,10 @@ TM = KM -1/2*CM G = BEAST.greenhh3d(wavenumber=k) -KC = BEAST.build_potential(∇(G)×B(),m) -KCT1 = BEAST.γ(KC,m,m,-1) +KC = BEAST.build_potential(∇(G)×BasisFunction(),m) +KCT1 = BEAST.γ(KC,m,-1) TCM1 = assemble(KCT1,r,r) -KCT2 = BEAST.γ(KC,-m,m,1) +KCT2 = BEAST.γ(KC,-m,1) TCM2 = assemble(KCT2,r,r) @test TM ≈ TCM1 atol=eps() @@ -59,10 +59,10 @@ TM = KM +1/2*CM G = BEAST.greenhh3d(wavenumber=k) -KC = BEAST.build_potential(∇(G)×B(),m2) -KCT1 = BEAST.γ(KC,m1,m1,1) +KC = BEAST.build_potential(∇(G)×BasisFunction(),m2) +KCT1 = BEAST.γ(KC,m1,1) TCM1 = assemble(KCT1,r1,r2) -KCT2 = BEAST.γ(KC,-m1,m1,-1) +KCT2 = BEAST.γ(KC,-m1,-1) TCM2 = assemble(KCT2,r1,r2) @test TM ≈ TCM1 atol=eps() @@ -73,10 +73,10 @@ TM = KM -1/2*CM G = BEAST.greenhh3d(wavenumber=k) -KC = BEAST.build_potential(∇(G)×B(),m2) -KCT1 = BEAST.γ(KC,m1,m1,-1) +KC = BEAST.build_potential(∇(G)×BasisFunction(),m2) +KCT1 = BEAST.γ(KC,m1,-1) TCM1 = assemble(KCT1,r1,r2) -KCT2 = BEAST.γ(KC,-m1,m1,1) +KCT2 = BEAST.γ(KC,-m1,1) TCM2 = assemble(KCT2,r1,r2) @test TM ≈ TCM1 atol=eps() From 99f586ed285830249f2fdde353695c241ae97973 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 8 Nov 2023 16:54:21 +0100 Subject: [PATCH 058/110] cleanup --- .gitignore | 1 + src/BEAST.jl | 8 +- .../{composed2.jl => composedoperator.jl} | 74 ++--- src/composedoperator/composeoperator.jl | 218 -------------- src/composedoperator/tracesimplex.jl | 91 +++--- src/localop.jl | 25 +- src/multi-trace/configuration.jl | 272 ------------------ .../design of the multi-trace approach.txt | 11 - src/multi-trace/interactions.jl | 238 --------------- src/multi-trace/postprocessing.jl | 118 -------- 10 files changed, 106 insertions(+), 950 deletions(-) rename src/composedoperator/{composed2.jl => composedoperator.jl} (89%) delete mode 100644 src/composedoperator/composeoperator.jl delete mode 100644 src/multi-trace/configuration.jl delete mode 100644 src/multi-trace/design of the multi-trace approach.txt delete mode 100644 src/multi-trace/interactions.jl delete mode 100644 src/multi-trace/postprocessing.jl diff --git a/.gitignore b/.gitignore index 7c4505e4..a023f4f4 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ profile/ programs/ results/ src/todo.txt + diff --git a/src/BEAST.jl b/src/BEAST.jl index eba04e26..adc32852 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -264,13 +264,13 @@ include("utils/plotlyglue.jl") #suport for multi-trace -include("multi-trace/configuration.jl") -include("multi-trace/interactions.jl") -include("multi-trace/postprocessing.jl") +# include("multi-trace/configuration.jl") +# include("multi-trace/interactions.jl") +# include("multi-trace/postprocessing.jl") #suport for displaying operators include("composedoperator/tracesimplex.jl") -include("composedoperator/composed2.jl") +include("composedoperator/composedoperator.jl") include("display.jl") diff --git a/src/composedoperator/composed2.jl b/src/composedoperator/composedoperator.jl similarity index 89% rename from src/composedoperator/composed2.jl rename to src/composedoperator/composedoperator.jl index 24b62695..c527ea10 100644 --- a/src/composedoperator/composed2.jl +++ b/src/composedoperator/composedoperator.jl @@ -13,6 +13,8 @@ ComposedOperator = Union{ComposedOperatorIntegral,ComposedOperatorLocal} struct BasisFunction <: ComposedOperatorLocal end struct DivBasisFunction <: ComposedOperatorLocal end const B = BasisFunction() +Base.div(::BasisFunction) = DivBasisFunction() + export B export BasisFunction @@ -20,7 +22,6 @@ export BasisFunction struct TestNormal <: ComposedOperatorLocal end struct TrialNormal <: ComposedOperatorLocal end struct TraceDirection <: ComposedOperatorLocal end -scalartype(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction,TraceDirection}) = Float16 const nt = TestNormal() @@ -39,6 +40,7 @@ function Potential(linop::LinearCombinationOfOperators,surface::TraceMesh) end return out end + struct TraceOperator{T} <: AbstractOperator operator::T surface::TraceMesh @@ -50,9 +52,8 @@ function TraceOperator(linop::LinearCombinationOfOperators,surf::TraceMesh) end return out end -# normal_surface(p::TraceOperator) = p.normalsurface -# direction_surface(p::TraceOperator) = p.directionsurface surface(p::TraceOperator) = p.surface + struct TimesLocal{U,V} <: ComposedOperatorLocal lhs::U rhs::V @@ -157,8 +158,9 @@ CrossLocal(a::ComposedOperatorIntegral,b::ComposedOperatorIntegral) = CrossInteg ⋅(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators}) = DotLocal(a,b) *(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators}) = TimesLocal(a,b) -Base.div(::BasisFunction) = DivBasisFunction() + +scalartype(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction,TraceDirection}) = Float16 scalartype(op::Operations) = promote_type(scalartype(op.lhs),scalartype(op.rhs)) scalartype(op::Potential) = scalartype(op.operator) scalartype(op::TraceOperator) = scalartype(op.operator) @@ -203,17 +205,18 @@ function build_potential(op::ComposedOperator,surface::TraceMesh) end function γ(op::Operations) - return get_constructor(op)(γ(op.lhs),γ(op.rhs)) end + γ(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction}) = op -function check_if_coincide(a,b) - @warn "all meshes coincide" - return true -end + +# function check_if_coincide(a,b) +# @warn "all meshes coincide" +# return true +# end function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise - check_if_coincide(op.surface,surface) || return op.operator +# check_if_coincide(op.surface,surface) || return op.operator newop = nt × (γ(op.operator) × nt) direction = [] for i in 1:numcells(surface) @@ -223,7 +226,7 @@ function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# si return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) end function γ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise - check_if_coincide(op.surface,surface) || return op.operator +# check_if_coincide(op.surface,surface) || return op.operator newop = nt × (γ(op.operator) × nt) direction = [] for i in 1:numcells(surface) @@ -235,7 +238,7 @@ end function γₛ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise - check_if_coincide(op.surface,surface) || return op.operator +# check_if_coincide(op.surface,surface) || return op.operator newop = nt × γ(op.operator) direction = [] for i in 1:numcells(surface) @@ -245,7 +248,7 @@ function γₛ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) end function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise - check_if_coincide(op.surface,surface) || return op.operator +# check_if_coincide(op.surface,surface) || return op.operator newop = nt × γ(op.operator) direction = [] for i in 1:numcells(surface) @@ -256,7 +259,7 @@ function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according end function γₙ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise - check_if_coincide(op.surface,surface) || return op.operator +# check_if_coincide(op.surface,surface) || return op.operator newop = nt ⋅ γ(op.operator) direction = [] for i in 1:numcells(surface) @@ -266,7 +269,7 @@ function γₙ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) end function γₙ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise - check_if_coincide(op.surface,surface) || return op.operator +# check_if_coincide(op.surface,surface) || return op.operator newop = nt ⋅ γ(op.operator) direction = [] for i in 1:numcells(surface) @@ -277,7 +280,7 @@ function γₙ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according end function τ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise - check_if_coincide(op.surface,surface) || return op.operator +# check_if_coincide(op.surface,surface) || return op.operator newop = γ(op.operator) direction = [] for i in 1:numcells(surface) @@ -287,7 +290,7 @@ function τ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# si return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) end function τ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise - check_if_coincide(op.surface,surface) || return op.operator +# check_if_coincide(op.surface,surface) || return op.operator newop = γ(op.operator) direction = [] for i in 1:numcells(surface) @@ -296,31 +299,25 @@ function τ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to end return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) end -# γₜᶜ(op::Potential,surface) = nt×(γ(op,surface,-1)×nt) -# γₜ(op::Potential,surface) = nt×(γ(op,surface,1)×nt) -# γₛ(op::Potential,surface) = nt×γ(op,surface,1) -# γₛᶜ(op::Potential,surface) = nt×γ(op,surface,-1) -# γₙ(op::Potential,surface) = nt⋅γ(op,surface,1) -# γₙᶜ(op::Potential,surface) = nt⋅γ(op,surface,-1) -# τ(op::Potential,surface) = γ(op,surface,1) -# τᶜ(op::Potential,surface) = γ(op,surface,-1) + +#### Define new greens functions below function greenhh3d(; gamma=nothing, wavenumber=nothing) -gamma, wavenumber = gamma_wavenumber_handler(gamma, wavenumber) -@assert gamma !== nothing -GreenHH3D(gamma) + gamma, wavenumber = gamma_wavenumber_handler(gamma, wavenumber) + @assert gamma !== nothing + GreenHH3D(gamma) end function gradgreenhh3d(; gamma=nothing, wavenumber=nothing) -gamma, wavenumber = gamma_wavenumber_handler(gamma, wavenumber) -@assert gamma !== nothing -GradGreenHH3D(gamma) + gamma, wavenumber = gamma_wavenumber_handler(gamma, wavenumber) + @assert gamma !== nothing + GradGreenHH3D(gamma) end struct GreenHH3D{T} <: Kernel @@ -350,7 +347,12 @@ function (op::GradGreenHH3D)(x,y,g) iR = 1/R green = exp(-gamma*R)*(iR*i4pi) gradgreen = -(gamma + iR) * green * (iR * r) - Ref(gradgreen) + tt = Ref(gradgreen) + + if maximum(abs.(gradgreen)) === NaN + display(R) + end + return tt end γ(op::GreenHH3D) = op @@ -362,11 +364,13 @@ function (::Nabla)(G::Kernel) grad(G) end - scalartype(G::GreenHH3D{T}) where {T} = T scalartype(G::GradGreenHH3D{T}) where {T} = T + + + function (op::Union{TimesIntegral,TimesLocal})(x,y,g) op.lhs(x,y,g).*op.rhs(x,y,g) end @@ -406,10 +410,10 @@ end defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(6,7,5,5,4,3) defaultquadstrat(op::ComposedOperatorLocal,testspace::Space,trialpsace::Space) = SingleNumQStrat(6) -sign_upon_permutation(op::ComposedOperator,I,J) = Combinatorics.levicivita(I)^count_test_normals(op)*Combinatorics.levicivita(J)^count_trial_normals(op) +#sign_upon_permutation(op::ComposedOperator,I,J) = Combinatorics.levicivita(I)^count_test_normals(op)*Combinatorics.levicivita(J)^count_trial_normals(op) -normalorient(op::ComposedOperator,sign_test_normal,sign_trial_normal) = sign_test_normal^count_test_normals*sign_trial_normal^count_trial_normals +#normalorient(op::ComposedOperator,sign_test_normal,sign_trial_normal) = sign_test_normal^count_test_normals*sign_trial_normal^count_trial_normals defaultquadstrat(op::TraceOperator,test,trial) = defaultquadstrat(op.operator,test,trial) diff --git a/src/composedoperator/composeoperator.jl b/src/composedoperator/composeoperator.jl deleted file mode 100644 index 1c54313c..00000000 --- a/src/composedoperator/composeoperator.jl +++ /dev/null @@ -1,218 +0,0 @@ -import Base: * -import LinearAlgebra: ×, ⋅ -import BEAST -abstract type ComposedOperatorLocal <: LocalOperator end -abstract type ComposedOperatorIntegral <: IntegralOperator end - - - -struct BasisFunction end -struct DivBasisFunction end - -struct TestFunctionLocal{T <: ComposedOperatorLocal} <: ComposedOperatorLocal - inner::T -end -struct TestFunctionIntegral{T <: ComposedOperatorIntegral} <: ComposedOperatorIntegral - inner::T -end -TestFunctionLocal(inner::ComposedOperatorIntegral) = TestFunctionIntegral(inner) - -struct DivTestFunctionLocal{T <: ComposedOperatorLocal} <: ComposedOperatorLocal - inner::T -end -struct DivTestFunctionIntegral{T <: ComposedOperatorIntegral} <: ComposedOperatorIntegral - inner::T -end - -function TestFunctionLocal(inner::LinearCombinationOfOperators) - out = ZeroOperator() - for op in inner.ops - out += TestFunctionLocal(op) - end - return out -end - -function DivTestFunctionLocal(inner::LinearCombinationOfOperators) - out = ZeroOperator() - for op in inner.ops - out += DivTestFunctionLocal(op) - end - return out -end - - -struct CurlBasisFunction end - -const b = BasisFunction() -const t = TestFunctionLocal -export t -export b - -×(::Nabla,::BasisFunction) = CurlBasisFunction() -⋅(::Nabla,::BasisFunction) = DivBasisFunction() -⋅(::Nabla,::Type{TestFunctionLocal}) = DivTestFunctionLocal -⋅(::Nabla,::Type{TestFunctionIntegral}) = DivTestFunctionIntegral - -struct TestNormalLocal{T,O,P} <: ComposedOperatorLocal -inner::T -operation::O -factor::P -end - - -struct TrialNormalLocal{T,O,P} <: ComposedOperatorLocal -inner::T -operation::O -factor::P -end - - -*(a::Number,b::TrialNormalLocal) = TrialNormalLocal(b.inner,b.operation,a*b.factor) -*(a::Number,b::TestNormalLocal) = TestNormalLocal(b.inner,b.operation,a*b.factor) -struct TestNormalIntegral{T,O,P} <: ComposedOperatorIntegral - inner::T - operation::O - factor::P - -end - -TestNormalLocal(inner::ComposedOperatorIntegral,op) = TestNormalIntegral(inner,op) - -struct TrialNormalIntegral{T,O,P} <: ComposedOperatorIntegral - inner::T - operation::O - factor::P -end -TrialNormalIntegral(a,b) = TrialNormalIntegral(a,b,1.0) -TestNormalIntegral(a,b) = TestNormalIntegral(a,b,1.0) -TestNormalLocal(a,b) = TestNormalLocal(a,b,1.0) -TestNormalIntegral(a,b) = TestNormalIntegral(a,b,1.0) -TrialNormalLocal(inner::ComposedOperatorIntegral,op) = TrialNormalIntegral(inner,op) - -*(a::Number,b::TrialNormalIntegral) = TrialNormalIntegral(b.inner,b.operation,a*b.factor) -*(a::Number,b::TestNormalIntegral) = TestNormalIntegral(b.inner,b.operation,a*b.factor) -const nt = TestNormalLocal -const nb = TrialNormalLocal - -abstract type Kern end - - -struct Kernel{T,O,P <: Kern} <: ComposedOperatorIntegral - inner::T - operation::O - Kern::P -end - -function (k::Kern)(operation) -return x -> Kernel(x,operation,k) -end - - -function (a::Type{<: ComposedOperatorLocal})(operation) -return x->dist(a,x,operation) -end - -function dist(a::Type{<: ComposedOperatorLocal},x::Union{ComposedOperatorIntegral,ComposedOperatorLocal},operation) - return a(x,operation) -end -function dist(a::Type{<: ComposedOperatorLocal},x::LinearCombinationOfOperators,operation) - out = ZeroOperator() - for op in x.ops - out += a(op,operation) - end - return out -end - -struct HH3DGreen{T} <: Kern - gamma::T -end -struct HH3DGradGreen{T} <: Kern - gamma::T -end -function (::Nabla)(G::HH3DGreen) - HH3DGradGreen(G.wavenumber) -end -function (G::Kernel{T,O,HH3DGreen{Q}})(testnb,trialnb,f,g) where {T,O,Q} - green = - return G.operation.(Ref(green),G.inner(testnb,trialnb,f,g)) -end -function (G::Kernel{T,O,HH3DGradGreen{Q}})(testnb,trialnb,f,g) where {T,O,Q} - gradgreen = - return G.operation.(Ref(gradgreen),G.inner(testnb,trialnb)) -end - -#define with respect to from inside omega. -function traceterm(G::HH3DGreen) -ZeroOperator() -end - -function traceterm(G::HH3DGradGreen) -1/2*nt(G.inner,G.operation) -end - - - - -function (igd::Integrand{<:ComposedOperatorIntegral})(x,y,f,g) -op = igd.operator -op(x,y,f,g) -end - -function (op::Union{TestFunctionIntegral,TestFunctionLocal})(x,y,f,g) - _krondot(getvalue(f),op(x,y,g)) -end -function (op::Union{DivTestFunctionIntegral,DivTestFunctionLocal})(x,y,f,g) - _krondot(getdivergence(f),op(x,y,g)) -end - -function integrand(op::ComposedOperatorLocal,kernel,x,y,f,g) - op(x,y,f,g) -end - -function (op::Union{TestNormalIntegral,TestNormalLocal})(x,y,g) - op.operation(normal(x),op.inner(x,y,g)) -end - -function (op::Union{TrialNormalIntegral,TrialNormalLocal})(x,y,g) - op.factor*op.operation(normal(y),op.inner(x,y,g)) -end - -function (op::BasisFunction)(x,y,g) - getvalue(g) -end -function (op::DivBasisFunction)(x,y,g) - getdivergence(g) -end -function (op::CurlBasisFunction)(x,y,g) - getcurl(g) -end - - -#### support for traces to find equivalent operator. -""" -inside positive, outside negative -""" -struct Trace -direction -end - -function (t::Trace)(operator) -operator+t.direction*traceterm(operator) -end - - - - - -const γₜᶜ = nt((x -> -x ∘ ×))∘ nt(×)∘Trace(-1) -const γₜ = nt((x -> -x ∘ ×))∘ nt(×)∘Trace(1) - -const γₛ = nt(×)∘Trace(1) -const γₛᶜ = nt(×)∘Trace(-1) -const γₙ = nt(⋅)∘Trace(1) -const γₙᶜ = nt(⋅)∘Trace(-1) - -export γₙ -export γₙᶜ -export γₜ -export γₜᶜ \ No newline at end of file diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index bd47558b..7df8528c 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -10,18 +10,56 @@ struct TraceMeshPointNM{T,U} direction::SVector{3,U} end direction(p::TraceMeshPointNM) = p.direction -function CompScienceMeshes.neighborhood(p::TraceSimplex, bary) - TraceMeshPointNM(neighborhood(p.simp,bary),p.direction) + +CompScienceMeshes.neighborhood(p::TraceSimplex, bary) = TraceMeshPointNM(neighborhood(p.simp,bary),p.direction) +CompScienceMeshes.coordtype(p::TraceSimplex) = coordtype(p.simp) +CompScienceMeshes.domain(ch::TraceSimplex) = CompScienceMeshes.domain(simplex(ch)) +CompScienceMeshes.dimension(::Type{TraceSimplex{CompScienceMeshes.Simplex{U,D,C,N,T},T}}) where {U,D,C,N,T} = D +CompScienceMeshes.coordtype(::Type{TraceSimplex{CompScienceMeshes.Simplex{U,D,C,N,T},T}}) where {U,D,C,N,T} = T +CompScienceMeshes.verticeslist(p::TraceSimplex) = verticeslist(simplex(p)) +CompScienceMeshes.permute_vertices(simp::TraceSimplex,I) = TraceSimplex(CompScienceMeshes.permute_vertices(simplex(simp),I),direction(simp)) +CompScienceMeshes.overlap(a::TraceSimplex,b::TraceSimplex) = overlap(simplex(a),simplex(b)) +CompScienceMeshes.overlap(a::CompScienceMeshes.Simplex,b::TraceSimplex) = overlap(a,simplex(b)) +CompScienceMeshes.overlap(a::TraceSimplex,b::CompScienceMeshes.Simplex) = overlap(simplex(a),b) +CompScienceMeshes.intersection(a::CompScienceMeshes.Simplex,b::TraceSimplex) = intersection(a,simplex(b)) +CompScienceMeshes.volume(a::TraceSimplex) = volume(simplex(a)) +CompScienceMeshes.dimension(a::TraceSimplex) = dimension(simplex(a)) +CompScienceMeshes.tangents(a::TraceSimplex,i::Int) = tangents(simplex(a),i) +CompScienceMeshes.carttobary(a::TraceSimplex,b::SVector{T}) where {T} = carttobary(simplex(a),b) + +function CompScienceMeshes.quadpoints(chart::TraceSimplex, rule) + PV = quadpoints(CompScienceMeshes.domain(chart), rule) + map(PV) do pv + q = neighborhood(chart, pv[1]) + w = jacobian(q)*pv[2] + (q,w) + end +end + +function CompScienceMeshes.intersection2(a::TraceSimplex,b::TraceSimplex) + int = intersection2(simplex(a),simplex(b)) + return [(TraceSimplex(i[1],direction(a)),TraceSimplex(i[2],direction(b))) for i in int] +end +function CompScienceMeshes.intersection2(a::CompScienceMeshes.Simplex,b::TraceSimplex) + int = intersection2(a,simplex(b)) + return [(TraceSimplex(i[1],direction(b)*0),TraceSimplex(i[2],direction(b))) for i in int] +end +function CompScienceMeshes.intersection2(a::TraceSimplex,b::CompScienceMeshes.Simplex) + int = intersection2(simplex(a),b) + return [(TraceSimplex(i[1],direction(a)),TraceSimplex(i[2],direction(a)*0)) for i in int] end + + + + CompScienceMeshes.cartesian(p::TraceMeshPointNM) = cartesian(p.neighborhood) CompScienceMeshes.parametric(p::TraceMeshPointNM) = parametric(p.neighborhood) -chart(p::TraceMeshPointNM) = chart(p.neighborhood) +CompScienceMeshes.chart(p::TraceMeshPointNM) = chart(p.neighborhood) CompScienceMeshes.normal(p::TraceMeshPointNM) = normal(p.neighborhood) - CompScienceMeshes.jacobian(p::TraceMeshPointNM) = jacobian(p.neighborhood) CompScienceMeshes.tangents(p::TraceMeshPointNM,i) = tangents(p.neighborhood,i) CompScienceMeshes.barycentric(a::TraceMeshPointNM) = barycentric(a.neighborhood) -coordtype(p::TraceSimplex) = coordtype(p.simp) + @@ -38,8 +76,6 @@ TraceMesh(a::CompScienceMeshes.AbstractMesh{U,D,T}) where {U,D,T} = TraceMesh(a, +(a::TraceMesh,b::SVector) = TraceMesh(mesh(a),a.direction+b) +(a::SVector,b::TraceMesh) = b+a - - mesh(p::OrientedMesh) = p.mesh mesh(p::TraceMesh) = p.mesh CompScienceMeshes.normal(p::OrientedMesh) = p.normalmesh @@ -69,46 +105,5 @@ CompScienceMeshes.cells(p::OrientedMesh) = cells(mesh(p)) CompScienceMeshes.cells(p::TraceMesh) = cells(mesh(p)) CompScienceMeshes.vertices(p::TraceMesh) = vertices(mesh(p)) -CompScienceMeshes.domain(ch::TraceSimplex) = CompScienceMeshes.domain(simplex(ch)) -CompScienceMeshes.dimension(::Type{TraceSimplex{CompScienceMeshes.Simplex{U,D,C,N,T},T}}) where {U,D,C,N,T} = D -CompScienceMeshes.coordtype(::Type{TraceSimplex{CompScienceMeshes.Simplex{U,D,C,N,T},T}}) where {U,D,C,N,T} = T - - -function CompScienceMeshes.quadpoints(chart::TraceSimplex, rule) - PV = quadpoints(CompScienceMeshes.domain(chart), rule) - map(PV) do pv - q = neighborhood(chart, pv[1]) - w = jacobian(q)*pv[2] - (q,w) - end -end -CompScienceMeshes.verticeslist(p::TraceSimplex) = verticeslist(simplex(p)) -CompScienceMeshes.permute_vertices(simp::TraceSimplex,I) = TraceSimplex(CompScienceMeshes.permute_vertices(simplex(simp),I),direction(simp)) -CompScienceMeshes.overlap(a::TraceSimplex,b::TraceSimplex) = overlap(simplex(a),simplex(b)) -CompScienceMeshes.overlap(a::CompScienceMeshes.Simplex,b::TraceSimplex) = overlap(a,simplex(b)) -CompScienceMeshes.overlap(a::TraceSimplex,b::CompScienceMeshes.Simplex) = overlap(simplex(a),b) - -CompScienceMeshes.intersection(a::CompScienceMeshes.Simplex,b::TraceSimplex) = intersection(a,simplex(b)) -# function CompScienceMeshes.intersection(a::TraceSimplex,b::Union{TraceSimplex,CompScienceMeshes.Simplex}) -# int = intersection(simplex(a),b) -# TraceSimplex.(int,sign(a)) -# end - -function CompScienceMeshes.intersection2(a::TraceSimplex,b::TraceSimplex) - int = intersection2(simplex(a),simplex(b)) - return [(TraceSimplex(i[1],direction(a)),TraceSimplex(i[2],direction(b))) for i in int] -end -function CompScienceMeshes.intersection2(a::CompScienceMeshes.Simplex,b::TraceSimplex) - int = intersection2(a,simplex(b)) - return [(TraceSimplex(i[1],direction(b)*0),TraceSimplex(i[2],direction(b))) for i in int] -end -function CompScienceMeshes.intersection2(a::TraceSimplex,b::CompScienceMeshes.Simplex) - int = intersection2(simplex(a),b) - return [(TraceSimplex(i[1],direction(a)),TraceSimplex(i[2],direction(a)*0)) for i in int] -end -CompScienceMeshes.volume(a::TraceSimplex) = volume(simplex(a)) -CompScienceMeshes.dimension(a::TraceSimplex) = dimension(simplex(a)) -CompScienceMeshes.tangents(a::TraceSimplex,i::Int) = tangents(simplex(a),i) -CompScienceMeshes.carttobary(a::TraceSimplex,b::SVector{T}) where {T} = carttobary(simplex(a),b) diff --git a/src/localop.jl b/src/localop.jl index 126ed725..7de22e04 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -126,15 +126,17 @@ function assemble_local_matched!(biop::LocalOperator, tfs::Space, bfs::Space, st verbose = length(tels) > 10_000 verbose && print(string(typeof(biop))*" dots out of 20: ") todo, done, pctg = length(tels), 0, 0 + # locmat = zeros(scalartype(biop, trefs, brefs), numfunctions(trefs), numfunctions(brefs)) for (p,tcell) in enumerate(tels) P = ta2g[p] - bcell = bels[P] - - @assert same_cell(bcell,tcell) + q = bg2a[P] q == 0 && continue + bcell = bels[q] + @assert same_cell(bcell,tcell) + qr = quadrule(biop, trefs, brefs, tcell, bcell,qd, quadstrat) # fill!(locmat, 0) @@ -221,15 +223,26 @@ end function assemble_local_matched!(biop::LocalOperator, tfs::subdBasis, bfs::subdBasis, store; quadstrat=defaultquadstrat(biop, tfs, bfs)) - tels, tad = assemblydata(tfs) - bels, bad = assemblydata(bfs) + tels, tad, ta2g = assemblydata(tfs) + bels, bad, ba2g = assemblydata(bfs) + + bg2a = zeros(Int, length(geometry(bfs))) + for (i,j) in enumerate(ba2g) bg2a[j] = i end + trefs = refspace(tfs) brefs = refspace(bfs) qd = quaddata(biop, trefs, brefs, tels, bels, quadstrat) for (p,tcell) in enumerate(tels) - bcell = bels[p] + # bcell = bels[p] + + P = ta2g[p] + + q = bg2a[P] + q == 0 && continue + bcell = bels[q] + @assert same_cell(bcell,tcell) qr = quadrule(biop, trefs, brefs, tcell,bcell, qd, quadstrat) locmat = cellinteractions(biop, trefs, brefs, tcell,bcell, qr) diff --git a/src/multi-trace/configuration.jl b/src/multi-trace/configuration.jl deleted file mode 100644 index 6443c14a..00000000 --- a/src/multi-trace/configuration.jl +++ /dev/null @@ -1,272 +0,0 @@ -abstract type DomainData end -abstract type Domain{T<:DomainData} end -using PrettyTables -""" -A is the type of the test structure, B is the type of the trial structure, C the type of ths structure embedding -""" -struct Interaction{A,B,C}# wordt gecrieerd bij de itteratie over alle volumes. - config - testvol::A - trialvol::B - embedvol::C -end -# abstract type PhysicalInformation end #depends on the strategy -""" -subtypes of the NumericalStrategy type descirbe the followed strategy. for example a preconditioning strategy for a vector potential based problem, - a vector potential based problem, a fields based problem,... -""" -abstract type NumericalStrategy end - -export NumericalStrategy -mutable struct HomogeneousDomain <: DomainData -physicalinformation -testbasises -trialbasises -coeff -testindex -trialindex -HomogeneousDomain(a,b,c,d) = new(a,b,c,d,[],[]) -end - -struct BackgroundDomain <: DomainData - physicalinformation - coeff -end -physicalconstants(d::DomainData) = d.physicalinformation -physicalconstants(d::Domain) = physicalconstants(d.data) -testspace(d::DomainData) = d.testbasises -trialspace(d::DomainData) = d.trialbasises - -mutable struct SubDomain{T} <: Domain{T} - id::Int - children::Vector{Domain} - parent::Domain - data::T - excitation - results -end -mutable struct RootDomain{T} <: Domain{T} - id::Int - children::Vector{Domain} - data::T - excitation -end - -mutable struct Configuration #TODO add dict contining all subbasis info af touching objects - domains::Dict{Int,Domain} - root::RootDomain - touching::Dict{Tuple{Int,Int},Vector} - testdirectproductspace - trialdirectproductspace -end -Configuration(dom,root,touching) = Configuration(dom,root,touching,nothing,nothing) - - -function _adddomain(config::Configuration, newdom::Domain) - id = newdom.id - @assert !(id in keys(config.domains)) - dom = newdom.parent - config.domains[id] = newdom - for space in newdom.data.testbasises - config.testdirectproductspace = config.testdirectproductspace × space - push!(newdom.data.testindex,length(config.testdirectproductspace.factors)) - end - for space in newdom.data.trialbasises - config.trialdirectproductspace = config.trialdirectproductspace × space - push!(newdom.data.trialindex,length(config.trialdirectproductspace.factors)) - end - push!(dom.children,newdom) -end - -function _createdomain(config::Configuration,id::Int,parentid::Int,values;excitation) - dom = SubDomain(id,Domain[],config.domains[parentid],values::DomainData,excitation,[]) - return dom -end -function _createdomain(config::Configuration,id::Int,parentdom::Domain,values;excitation) - _createdomain(config,id,parentdom.id,values;excitation) -end - -function createdomain(config::Configuration,id::Int,parent::Union{Int,Domain},values::DomainData;excitation=Dict()) - _adddomain(config,_createdomain(config,id,parent,values;excitation)) -end -""" -a child of b -""" -function is_child_of(a,b) - return a∈b.children -end - -function brothers(a,b) -return is_child_of(a,b.parent) -end -function createconfiguration(data::BackgroundDomain,excitation=Dict()) - r = RootDomain(0,Domain[],data,excitation) - Configuration(Dict{Int,Domain}(0=>r),r,Dict{Tuple{Int,Int},Any}()) # typle of the indices, returns the spaces: [test1,trial1,test2,trial2] -end - -function createdomains(config::Configuration,confdict::Dict) end#the confdict is the dictionary containing the information about the mesh, physical parameters,... - -""" -all objects in a domain touch each other, not with subdomains, well with the boundary - -""" -function alltouching(config::Configuration) - for i in keys(config.domains) - #config.touching[(i,i)] = [config.domains[i].data.testbasises,config.domains[i].data.trialbasises,config.domains[i].data.testbasises,config.domains[i].data.trialbasises] - for child in config.domains[i].children - j = child.id - if typeof(config.domains[i]) <: SubDomain - config.touching[(i,j)] = [config.domains[i].data.testbasises,config.domains[i].data.trialbasises,child.data.testbasises,child.data.trialbasises] - config.touching[(j,i)] = [config.touching[(i,j)][3],config.touching[(i,j)][4],config.touching[(i,j)][1],config.touching[(i,j)][2]] - end - for child2 in config.domains[i].children - k = child2.id - config.touching[(j,k)] = [child.data.testbasises,child.data.trialbasises,child2.data.testbasises,child2.data.trialbasises] - config.touching[(k,j)] = [child2.data.testbasises,child2.data.trialbasises,child.data.testbasises,child.data.trialbasises] - end - end - end -end - -function (dom::Domain)(n::NormalVector,dom2::Domain) - if dom==dom2 - return 1.0 - elseif dom2 ∈ dom.children - return -1.0 - else - @error "domain is not in children of parent domain" - end - -end - -function generate_configuration(typelist,id_of_parentlist,background,backgroundexcitation=Dict()) - conf = createconfiguration(background,backgroundexcitation) - l = length(typelist) - for (ind,t,parent_id) in zip(1:l,typelist,id_of_parentlist) - createdomain(conf,ind,parent_id,t) - end - return conf -end -# function _create_bilform(operator_matrix,test_direct_productspace,trial_direct_productspace) -# #TODO create the bilform - -# end -#function convert_inside_to_outside_basis(Ωchild,Ωparent,strat) end -function interaction_matrix(config::Configuration,id,strat::NumericalStrategy) - @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) - N = length(config.testdirectproductspace.factors) - OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) - indexen = [] - Ω = config.domains[id] - if id != 0 - indexen = [indexen; Ω.data.testindex] - inter = Interaction(config,Ω,Ω,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) - for child in Ω.children - inter = Interaction(config,Ω,child,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat) - inter = Interaction(config,child,Ω,Ω) - OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) - end - - end - for Ω1 in Ω.children - indexen = [indexen; Ω1.data.testindex] - inter = Interaction(config,Ω1,Ω1,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += inter(strat) - - for Ω2 in Ω.children - if Ω1!==Ω2 - inter = Interaction(config,Ω1,Ω2,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter(strat) - end - end - end - - - id = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) - for i in 1:N - i∈indexen && (id[i,i] = Identity()) - end - pretty_table(id-OperatorMatrix, noheader=true, backend=Val(:latex)) - return assemble(dot(config.testdirectproductspace,id-OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) -end - -# function generate_problem_lhs(config::Configuration,strat::NumericalStrategy)#Make more correct by assambling for eacht domain an add with coeffeicient, add idetity at that place -# @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) -# N = length(config.testdirectproductspace.factors) -# OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) -# for (id,Ω) in config.domains -# c = Ω.data.coeff -# if id != 0 -# inter = Interaction(config,Ω,Ω,Ω) -# OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) -# for child in Ω.children -# inter = Interaction(config,Ω,child,Ω) -# OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += c*inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat) -# inter = Interaction(config,child,Ω,Ω) -# OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) -# end - -# end -# for Ω1 in Ω.children - -# inter = Interaction(config,Ω1,Ω1,Ω) -# OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += c*inter(strat) - -# for Ω2 in Ω.children -# if Ω1!==Ω2 -# inter = Interaction(config,Ω1,Ω2,Ω) -# OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += c*inter(strat) -# end -# end -# end - -# end -# id = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) -# for i in 1:N -# id[i,i] = 2*Identity() -# end -# pretty_table(id-OperatorMatrix, noheader=true, backend=Val(:latex)) -# return assemble(dot(config.testdirectproductspace,id-OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) - -# end -function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) - out = interaction_matrix(config,0,strat) - for (id,Ω) in config.domains - id==0 && continue - out += Ω.data.coeff* interaction_matrix(config,id,strat) - end - return out -end - -function generate_problem_rhs(config::Configuration) - linterms = Vector{LinTerm}() - @warn "only excitations in root domain implemented, check first if same aproach for others is appropriate" - for (id,Ω) in config.domains end - - for (key,func) in config.root.excitation - for child in config.root.children - - - push!(linterms,LinTerm(child.data.testindex[key],[],1,func)) - end - end - - return assemble(LinForm([],linterms),config.testdirectproductspace) -end - -function map_solution_to_volumes!(config,solution) - for (id,dom) in config.domains - id==0 && continue - out = [] - for i in dom.data.trialindex - push!(out,solution[Block(i)]) - end - dom.results = out - end -end - - - - diff --git a/src/multi-trace/design of the multi-trace approach.txt b/src/multi-trace/design of the multi-trace approach.txt deleted file mode 100644 index a65637f9..00000000 --- a/src/multi-trace/design of the multi-trace approach.txt +++ /dev/null @@ -1,11 +0,0 @@ -design of the multi-trace approach: - -structure is devided in a tree like domain of open domains, there is the free space, domain 1, and then all other domains are in this free space. (mesh object is a domain, thus when you ask in which domain it is it gives the upstream domain). The basis of a mesh object is in the domain of the mesh object. - -Object interacts with every object in the domain and with the boundary of the domain it is in. - -object domain:(Physical information, test and trial bases boundary, mesh, touching information: for each object it returns the subd test and trial basis, also for the object itself!!!!) - -intersect(\Omega1, \Omega2) = (subd test, trial 1), (subd test,trial 2) - -work with strategies, \ No newline at end of file diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl deleted file mode 100644 index 268260f7..00000000 --- a/src/multi-trace/interactions.jl +++ /dev/null @@ -1,238 +0,0 @@ - -using LinearAlgebra -""" -Write for each type of interaction this type of function. -""" -function (int::Interaction{<:Domain{BackgroundDomain},})() - i = [] #interaction matrix - normalorient.(i,Ω1,Ω2,Ω3) # example - - return nothing -end - -# function alpha(Ω1,Ω2) - - -# end -# """ -# cauchylimit needs to be applied before the normalorient function -# """ - -# function cauchylimit(operator::AbstractOperator;Ω1,Ω2,Ω3) -# #check first if touching is non empty -# @assert is_child_of(Ω1,Ω3)||Ω1===Ω3 -# @assert is_child_of(Ω2,Ω3)||Ω2===Ω3 -# # if Ω2!==Ω3 -# # sign = -1 -# # elseif Ω2===Ω3 -# # sign = 1 -# # end -# @warn "correct sign for inside is 1?" -# sign = 1 - -# trace(operator,sign) - -# end - -# function trace(op::AbstractOperator,sign) -# @warn "general abstract opterator trace function called returning pv of operator!: "*string(typeof(op)) -# return op -# end -# function normalorient(op::AbstractOperator,signtest,signtrial) -# @warn "normalorient not implemented for: "*string(typeof(op)) -# return op -# end -# trace(op::ZeroOperator,s) = op - -# function trace(op::LinearCombinationOfOperators,sign) -# result = ZeroOperator() -# for (c,o) in zip(op.coeffs,op.ops) -# result += c*trace(o,sign) -# end -# return result -# end - - -# function normalorient(op::LinearCombinationOfOperators,signtest,signtrial) -# result = ZeroOperator() -# for (c,o) in zip(op.coeffs,op.ops) -# result += c*normalorient(o,signtest,signtrial) -# end -# return result -# end - -# function normalorient(operator::AbstractOperator;Ω1,Ω2,Ω3) -# if Ω1===Ω3 -# sign_test_normal = 1 -# else -# sign_test_normal = -1 -# end -# if Ω2===Ω3 -# sign_trial_normal = 1 -# else -# sign_trial_normal = -1 -# end -# normalorient(operator,sign_test_normal,sign_trial_normal) -# end - -# normalorient(op::ZeroOperator,a,b) = op - -###### Interactions -struct VectorStrat <: BEAST.NumericalStrategy end - -function convert_outside_to_inside_basis(child,parent,::VectorStrat) - p = physicalconstants(parent.data) - c = physicalconstants(child.data) - a = [-1 0 0 0 - 0 1 0 0 - 0 0 -c.μ/p.μ 0 - 0 0 0 -p.ϵ/c.ϵ] - - return a -end - - - - -# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: RootDomain})(::VectorStrat) -# p = physicalconstants(int.embedvol.data) -# k = sqrt(p.ϵ*p.μ)*p.ω -# green = HHH.green(wavenumber=k) -# gradgreen = HHH.gradgreen(wavenumber=k) -# b = basisfunction() -# @warn "check if extra - in front of a is correct, describtion of As from paper asumes n outward so inward in outer domain?" -# a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen -# BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) -# -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() -# -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] -# id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() -# ZeroOperator() Identity() ZeroOperator() ZeroOperator() -# ZeroOperator() ZeroOperator() Identity() ZeroOperator() -# ZeroOperator() ZeroOperator() ZeroOperator() Identity()] -# #a = id - a - -# if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) -# println("cauchy limit taken") -# a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) -# end -# a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) - -# return a - -# end -# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: SubDomain})(::VectorStrat) -# p = physicalconstants(int.embedvol.data) -# k = sqrt(p.ϵ*p.μ)*p.ω -# green = HHH.green(wavenumber=k) -# gradgreen = HHH.gradgreen(wavenumber=k) -# b = basisfunction() - -# a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen -# BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) -# -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() -# -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] -# id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() -# ZeroOperator() Identity() ZeroOperator() ZeroOperator() -# ZeroOperator() ZeroOperator() Identity() ZeroOperator() -# ZeroOperator() ZeroOperator() ZeroOperator() Identity()] -# #a = id - a - -# if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) -# println("cauchy limit taken") -# a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) -# end -# a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) -# return a - -# end - - -# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<:Union{RootDomain,SubDomain}})(::VectorStrat) -# p = physicalconstants(int.embedvol.data) -# k = sqrt(p.ϵ*p.μ)*p.ω -# G = BEAST.greenhh3d(wavenumber=k) -# ∇G = BEAST.∇(G) -# Ω1=int.testvol -# Ω2=int.trialvol -# Ω3=int.embedvol -# bs = Ω2.data.trialbasises[1].geo -# ts = Ω1.data.testbasises[1].geo - -# ∇Gx = BEAST.build_potential(∇G×B,bs) -# Gn = BEAST.build_potential(G*n*B,bs) -# Gnx = BEAST.build_potential(G*n × B,bs) -# ∇G = BEAST.build_potential(∇G*B,bs) -# ∇Gdotn = BEAST.build_potential(∇G⋅n*B,bs) -# ∇Gdot = BEAST.build_potential(∇G⋅B,bs) - -# Gr = BEAST.build_potential(G*B,bs) -# ∇G∇B = BEAST.build_potential(∇G*∇(B),bs) -# ∇Gxn = BEAST.build_potential(∇G×n*B,bs) - -# if Ω1==Ω2 -# a = -[γₛ(∇Gx,ts) γₛ(Gn,ts) -γₛ(Gnx,ts) γₛ(∇G,ts) -# BEAST.ZeroOperator() -τ(∇Gdotn,ts) τ(∇Gdot,ts) k^2*τ(Gr,ts) -# -γₛ(∇G∇B,ts)-k^2*γₛ(Gr,ts) -γₛ(∇Gxn,ts) γₛ(∇Gx,ts) BEAST.ZeroOperator() -# -γₙ(∇Gx,ts) -γₙ(Gn,ts) γₙ(Gr,ts) -γₙ(∇G,ts)] -# else -# a = -[γₛᶜ(∇Gx,ts) γₛᶜ(Gn,ts) -γₛᶜ(Gnx,ts) γₛᶜ(∇G,ts) -# BEAST.ZeroOperator() -τᶜ(∇Gdotn,ts) τᶜ(∇Gdot,ts) k^2*τᶜ(Gr,ts) -# -γₛᶜ(∇G∇B,ts)-k^2*γₛᶜ(Gr,ts) -γₛᶜ(∇Gxn,ts) γₛᶜ(∇Gx,ts) BEAST.ZeroOperator() -# -γₙᶜ(∇Gx,ts) -γₙᶜ(Gn,ts) γₙᶜ(Gr,ts) -γₙᶜ(∇G,ts)] -# end - - -# #a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) - -# return a - -# end - -function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<:Union{RootDomain,SubDomain}})(::VectorStrat) - p = physicalconstants(int.embedvol.data) - k = sqrt(p.ϵ*p.μ)*p.ω - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - Ω1=int.testvol - Ω2=int.trialvol - Ω3=int.embedvol - bs = Ω2.data.trialbasises[1].geo - ts = Ω1.data.testbasises[1].geo - - ∇Gx = BEAST.build_potential(gradG×B,bs) - Gn = BEAST.build_potential(G*(n*B),bs) - Gnx = BEAST.build_potential(G*(n × B),bs) - ∇G = BEAST.build_potential(gradG*B,bs) - ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) - ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) - - Gr = BEAST.build_potential(G*B,bs) - ∇G∇B = BEAST.build_potential(gradG*div(B),bs) - ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) - sign = 1 - if Ω1==Ω2==Ω3 - - elseif Ω1==Ω2!=Ω3 - ts = -ts - bs = -bs - - elseif Ω1!=Ω2 - ts = -ts - bs = -bs - sign = -1 - - else - @error "none of previous" - - end - - a = -[γₛ(∇Gx,ts,ts,sign) γₛ(Gn,ts,ts,sign) -γₛ(Gnx,ts,ts,sign) γₛ(∇G,ts,ts,sign) - BEAST.ZeroOperator() -τ(∇Gdotn,ts,ts,sign) τ(∇Gdot,ts,ts,sign) k^2*τ(Gr,ts,ts,sign) - -γₛ(∇G∇B,ts,ts,sign)-k^2*γₛ(Gr,ts,ts,sign) -γₛ(∇Gxn,ts,ts,sign) γₛ(∇Gx,ts,ts,sign) BEAST.ZeroOperator() - -γₙ(∇Gx,ts,ts,sign) -γₙ(Gn,ts,ts,sign) γₙ(Gr,ts,ts,sign) -γₙ(∇G,ts,ts,sign)] - - #a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) - - return a - -end \ No newline at end of file diff --git a/src/multi-trace/postprocessing.jl b/src/multi-trace/postprocessing.jl deleted file mode 100644 index 317734ab..00000000 --- a/src/multi-trace/postprocessing.jl +++ /dev/null @@ -1,118 +0,0 @@ -import Base.Threads: @spawn -function nearfield_A(dom::Domain{HomogeneousDomain},pts,strat::VectorStrat) - p = physicalconstants(dom) - parent_const = physicalconstants(dom.parent) - k = sqrt(p.ϵ*p.μ)*p.ω - - nxb_out1,σ_out1,a_out1,γ_out1 = dom.results - nxb1,σ1,a1,γ1 = dom.data.trialbasises - - vector_potential = p.μ/parent_const.μ* potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out1,a1) .- - potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out1,nxb1) .- - parent_const.ϵ/p.ϵ*potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out1,γ1) .-#compensatie omdat normal naar buiten wijst - potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out1,σ1); - - for Ω in dom.children - nxb_out,σ_out,a_out,γ_out = Ω.results - nxb,σ,a,γ = Ω.data.trialbasises - vector_potential = vector_potential .+ -1*potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out,a) .+ - potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out,nxb) .+ - potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out,γ) .+#compensatie omdat normal naar buiten wijst - potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); - end - return vector_potential -end -function nearfield_A(dom::Domain{BackgroundDomain},pts,strat::VectorStrat) - p = physicalconstants(dom) - k = sqrt(p.ϵ*p.μ)*p.ω - vector_potential = zeros(SVector{3,Complex},size(pts)) - for Ω in dom.children - nxb_out,σ_out,a_out,γ_out = Ω.results - nxb,σ,a,γ = Ω.data.trialbasises - vector_potential = vector_potential + -1*potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out,a) + - potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out,nxb) + - potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out,γ) +#compensatie omdat normal naar buiten wijst - potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); - end - return vector_potential -end -function nearfield_A(config::Configuration,points,strat::VectorStrat) - tasks = [] - for (id,dom) in config.domains - push!(tasks,@spawn nearfield_A(dom,points,strat)) - end - fields = fetch.(tasks) - out = zeros(SVector{3,Complex},size(points)) - for field in fields - out = out .+ field - end - return out -end -function nearfield_B(dom::Domain{HomogeneousDomain},pts,strat::VectorStrat) - p = physicalconstants(dom) - parent_const = physicalconstants(dom.parent) - k = sqrt(p.ϵ*p.μ)*p.ω - - nxb_out1,σ_out1,a_out1,γ_out1 = dom.results - nxb1,σ1,a1,γ1 = dom.data.trialbasises - - BField = p.μ/parent_const.μ* potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out1,a1) .- - (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out1,nxb1)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out1,nxb1)) .- - potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out1,σ1); - - for Ω in dom.children - nxb_out,σ_out,a_out,γ_out = Ω.results - nxb,σ,a,γ = Ω.data.trialbasises - BField = BField .+ -1*potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out,a) .+ - (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out,nxb)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out,nxb)) .+ - potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); - end - return BField -end - -function nearfield_H(dom::Domain{HomogeneousDomain},points,strat::VectorStrat) - nearfield_B(dom,points,strat)./physicalconstants(dom).μ -end - - -function nearfield_B(dom::Domain{BackgroundDomain},pts,strat::VectorStrat) - p = physicalconstants(dom) - k = sqrt(p.ϵ*p.μ)*p.ω - BField = zeros(SVector{3,Complex},size(pts)) - for Ω in dom.children - nxb_out,σ_out,a_out,γ_out = Ω.results - nxb,σ,a,γ = Ω.data.trialbasises - BField = BField + -1*potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out,a) + - (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out,nxb)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out,nxb)) + - potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ) - end - return BField -end -function nearfield_B(config::Configuration,points,strat::VectorStrat) - tasks = [] - for (id,dom) in config.domains - push!(tasks,@spawn nearfield_B(dom,points,strat)) - end - fields = fetch.(tasks) - out = zeros(SVector{3,Complex},size(points)) - for field in fields - out = out .+ field - end - return out -end -function nearfield_H(dom::Domain{BackgroundDomain},points,strat::VectorStrat) - nearfield_B(dom,points,strat)./physicalconstants(dom).μ -end - -function nearfield_H(config::Configuration,points,strat::VectorStrat) - tasks = [] - for (id,dom) in config.domains - push!(tasks,nearfield_H(dom,points,strat)) - end - #fields = fetch.(tasks) - out = zeros(SVector{3,Complex},size(points)) - for field in tasks - out = out .+ field - end - return out -end \ No newline at end of file From b6b5f4016d96c46402c96b7a67a4caa9ff3cc2ba Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 8 Nov 2023 16:55:19 +0100 Subject: [PATCH 059/110] update --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a023f4f4..7f5faa08 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,4 @@ profile/ programs/ results/ src/todo.txt - +src/multi-trace From 388b961f26031f38e8b1d6abd68333e0959cf500 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 9 Nov 2023 10:53:06 +0100 Subject: [PATCH 060/110] cleanup --- src/BEAST.jl | 2 +- src/display.jl | 105 ------------------------------------------------- 2 files changed, 1 insertion(+), 106 deletions(-) delete mode 100644 src/display.jl diff --git a/src/BEAST.jl b/src/BEAST.jl index adc32852..56cb45f0 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -273,7 +273,7 @@ include("composedoperator/tracesimplex.jl") include("composedoperator/composedoperator.jl") -include("display.jl") +#include("display.jl") include("Helmholtzhodge/hhhexc.jl") include("Helmholtzhodge/hhhnearfield.jl") diff --git a/src/display.jl b/src/display.jl deleted file mode 100644 index fd6a7b4c..00000000 --- a/src/display.jl +++ /dev/null @@ -1,105 +0,0 @@ -import Base: show, print - -Base.show(io::IO,::MIME"text/plain",op::AbstractOperator) = print(io,op) - -function Base.print(io::IO,op::LinearCombinationOfOperators) - l = length(op.coeffs) - for (ind,coef,operator) in zip(1:l,op.coeffs,op.ops) - if typeof(coef) <: Complex - imag(coef) ≈ 0.0 && (coef=real(coef)) - end - if typeof(coef) <: Real - if ind == 1 && coef < 0 - print(io," -") - end - if ind > 1 && coef >=0 - print(io, " + ") - end - if ind > 1 && coef < 0 - print(io, " - ") - end - - if !(abs(coef) ≈ 1.0) - print(io,abs(coef)) - end - - print(io,operator) - - else - if ind > 1 - print(io," + ") - end - print(io,coef) - print(io,operator) - - - end - - end -end - -Base.print(io::IO, op::Identity) = print(io,"I") -Base.print(io::IO, op::ZeroOperator) = print(io,"Zero") -# function Base.print(io::IO, op::BasisOperatorLeft) -# print(io,"f*") -# print(io,op.operator) -# end -# function Base.print(io::IO, op::BasisOperatorRight) -# print(io,op.operator) -# print(io,"*f") -# end - -# function Base.print(io::IO, op::HHHgreen) -# if !(op.α ≈ 1.0) -# @warn "alpha is not 1 and not printed" -# end -# print(io,"S[$(abs(op.γ))]") -# print(io,op.op) -# end -# function Base.print(io::IO, op::HHHgradgreen) -# if !(op.α ≈ 1.0) -# @warn "alpha is not 1 and not printed" -# end -# print(io,"∇S[$(abs(op.γ))]") -# print(io,op.op) -# end -# function Base.print(io::IO, op::HHHgradgreenDot) -# if !(op.α ≈ 1.0) -# @warn "alpha is not 1 and not printed" -# end -# print(io,"∇S⋅[$(abs(op.γ))]") -# print(io,op.op) -# end -# function Base.print(io::IO, op::HHHgradgreenCross) -# if !(op.α ≈ 1.0) -# @warn "alpha is not 1 and not printed" -# end -# print(io,"∇S×[$(abs(op.γ))]×") -# print(io,op.op) -# end -# function Base.print(io::IO, op::Union{HHHNtestCross,HHHNtestCrossLocal}) -# print(io,"nₜₑ×") -# print(io,op.op) -# end -# function Base.print(io::IO, op::Union{HHHNbasisCross,HHHNbasisCrossLocal}) -# print(io,"nₜᵣ×") -# print(io,op.op) -# end -# function Base.print(io::IO, op::Union{HHHNtestDot,HHHNtestDotLocal}) -# print(io,"nₜₑ⋅") -# print(io,op.op) -# end -# function Base.print(io::IO, op::Union{HHHNbasisnormal,HHHNbasisnormalLocal}) -# print(io,"nₜᵣ") -# print(io,op.op) -# end -# function Base.print(io::IO, op::Union{HHHNbasisdot,HHHNbasisdotLocal}) -# print(io,"nₜᵣ⋅") -# print(io,op.op) -# end -# function Base.print(io::IO, op::Union{HHHIdentity,HHHIdentityLocal}) -# print(io,"B") -# end -# function Base.print(io::IO, op::Union{HHHDivergence,HHHDivergenceLocal}) -# print(io,"∇⋅B") -# end \ No newline at end of file From 95afc62a507720a252a539b6b9c1f9b2e1960f9e Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 9 Nov 2023 10:53:31 +0100 Subject: [PATCH 061/110] undo changes on subdBasis --- src/localop.jl | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/localop.jl b/src/localop.jl index 7de22e04..a2e48a23 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -222,30 +222,21 @@ end function assemble_local_matched!(biop::LocalOperator, tfs::subdBasis, bfs::subdBasis, store; quadstrat=defaultquadstrat(biop, tfs, bfs)) + + @assert !(biop <: ComposedOperator) - tels, tad, ta2g = assemblydata(tfs) - bels, bad, ba2g = assemblydata(bfs) - - bg2a = zeros(Int, length(geometry(bfs))) - for (i,j) in enumerate(ba2g) bg2a[j] = i end - + tels, tad = assemblydata(tfs) + bels, bad = assemblydata(bfs) trefs = refspace(tfs) brefs = refspace(bfs) qd = quaddata(biop, trefs, brefs, tels, bels, quadstrat) - for (p,tcell) in enumerate(tels) + for (p,cell) in enumerate(tels) # bcell = bels[p] - P = ta2g[p] - - q = bg2a[P] - q == 0 && continue - bcell = bels[q] - - @assert same_cell(bcell,tcell) - qr = quadrule(biop, trefs, brefs, tcell,bcell, qd, quadstrat) - locmat = cellinteractions(biop, trefs, brefs, tcell,bcell, qr) + qr = quadrule(biop, trefs, brefs, cell,cell, qd, quadstrat) + locmat = cellinteractions(biop, trefs, brefs, cell,cell, qr) for i in 1 : size(locmat, 1), j in 1 : size(locmat, 2) for (m,a) in tad[p][i], (n,b) in bad[p][j] From b6a08f78a19908bc9d9cafe51553a86e7c629d5b Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 9 Nov 2023 11:00:21 +0100 Subject: [PATCH 062/110] update bug --- src/localop.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/localop.jl b/src/localop.jl index a2e48a23..91d8069b 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -222,8 +222,8 @@ end function assemble_local_matched!(biop::LocalOperator, tfs::subdBasis, bfs::subdBasis, store; quadstrat=defaultquadstrat(biop, tfs, bfs)) - - @assert !(biop <: ComposedOperator) + + @assert !(typeof(biop) <: ComposedOperator) tels, tad = assemblydata(tfs) bels, bad = assemblydata(bfs) From 3b8d1cf0132f8151409a773eda4990eb89aaf49b Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 14 Nov 2023 10:16:07 +0100 Subject: [PATCH 063/110] sauterschwab support for non matching triangles --- src/integralop.jl | 40 +++++++++++++++++++++++++++++- src/quadrature/sauterschwabints.jl | 30 ++++++++++++++++++++++ test/runtests.jl | 2 ++ test/test_assemblerow.jl | 4 +-- test/test_momintegrals_overlap.jl | 25 +++++++++++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 test/test_momintegrals_overlap.jl diff --git a/src/integralop.jl b/src/integralop.jl index 73f3a95f..e4fce3d8 100644 --- a/src/integralop.jl +++ b/src/integralop.jl @@ -109,7 +109,8 @@ function assemblechunk_body!(biop, test_shapes, test_elements, test_assembly_data, trial_shapes, trial_elements, trial_assembly_data, qd, zlocal, store; quadstrat) - + println(typeof(test_elements)) + println(typeof(trial_elements)) myid = Threads.threadid() myid == 1 && print(string(typeof(biop))*" dots out of 10: ") todo, done, pctg = length(test_elements), 0, 0 @@ -119,6 +120,7 @@ function assemblechunk_body!(biop, fill!(zlocal, 0) qrule = quadrule(biop, test_shapes, trial_shapes, p, tcell, q, bcell, qd, quadstrat) momintegrals!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, qrule) + I = length(test_assembly_data[p]) J = length(trial_assembly_data[q]) for j in 1 : J, i in 1 : I @@ -137,7 +139,43 @@ function assemblechunk_body!(biop, end end myid == 1 && println("") end +function assemblechunk_body!(biop, + test_shapes, test_elements::Vector{CompScienceMeshes.Simplex{3,2,1,3,U}}, test_assembly_data, + trial_shapes, trial_elements::Vector{CompScienceMeshes.Simplex{3,2,1,3,V}}, trial_assembly_data, + qd, zlocal, store; quadstrat) where {U,V} + + @info "triangle assemblechunk_body used" + myid = Threads.threadid() + myid == 1 && print(string(typeof(biop))*" dots out of 10: ") + todo, done, pctg = length(test_elements), 0, 0 + for (p,tcell) in enumerate(test_elements) + for (q,bcell) in enumerate(trial_elements) + fill!(zlocal, 0) + if overlap(tcell,bcell) + momintegrals_overlap!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, quadstrat) + else + qrule = quadrule(biop, test_shapes, trial_shapes, p, tcell, q, bcell, qd, quadstrat) + momintegrals!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, qrule) + end + I = length(test_assembly_data[p]) + J = length(trial_assembly_data[q]) + for j in 1 : J, i in 1 : I + zij = zlocal[i,j] + for (n,b) in trial_assembly_data[q][j] + zb = zij*b + for (m,a) in test_assembly_data[p][i] + store(a*zb, m, n) + end end end end + + done += 1 + new_pctg = round(Int, done / todo * 100) + if new_pctg > pctg + 9 + myid == 1 && print(".") + pctg = new_pctg + end end + myid == 1 && println("") +end function assemblechunk_body_test_refines_trial!(biop, test_functions, test_charts, test_assembly_data, test_cells, diff --git a/src/quadrature/sauterschwabints.jl b/src/quadrature/sauterschwabints.jl index 6321cbc2..4a165aa0 100644 --- a/src/quadrature/sauterschwabints.jl +++ b/src/quadrature/sauterschwabints.jl @@ -204,3 +204,33 @@ function momintegrals_trial_refines_test!(out, op, end end end end end + +function momintegrals_overlap!(biop, + test_shapes, trial_shapes, + tcell, bcell, + out, quadstrat) + tcells, bcells = CompScienceMeshes.complementary_mesh(tcell,bcell) + + qd = quaddata(biop,test_shapes,trial_shapes,tcells,bcells,quadstrat) + + Nt = numfunctions(test_shapes) + Nb = numfunctions(trial_shapes) + + + for (p,tsubcell) in enumerate(tcells) + for (q,bsubcell) in enumerate(bcells) + zlocal = zero(out) + qrule = quadrule(biop, test_shapes, trial_shapes, p, tsubcell, q, bsubcell, qd, quadstrat) + momintegrals!(biop, test_shapes, trial_shapes, tsubcell, bsubcell, zlocal, qrule) + Qt = restrict(test_shapes,tcell,tsubcell) + Qb = restrict(trial_shapes,bcell,bsubcell) + for j in 1:Nb + for i in 1:Nt + for m in 1:Nb + for n in 1:Nt + out[i,j] += Qt[i,n] * zlocal[n,m] * Qb[j,m] + end end end end + end + end + +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 1d4e0b76..d661dafb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -73,6 +73,8 @@ include("test_td_tensoroperator.jl") include("test_variational.jl") include("test_composed_operator.jl") +include("test_momintegrals_overlap.jl") + try Pkg.installed("BogaertInts10") @info "`BogaertInts10` detected. Including relevant tests." diff --git a/test/test_assemblerow.jl b/test/test_assemblerow.jl index 8e82630a..235510ec 100644 --- a/test/test_assemblerow.jl +++ b/test/test_assemblerow.jl @@ -43,7 +43,7 @@ for T in [Float32, Float64] quadrature_data, zlocal, store, quadstrat=qs) T1 = assemble(t,X1,X1) - @test T1 == T2 + @test T1 ≈ T2 # @time BEAST.assembleblock_body!(t, # X, I, test_elements, test_assembly_data, @@ -58,7 +58,7 @@ for T in [Float32, Float64] blkasm(I,I,store3) T4 = assemble(t,X,X) - @test T3 == T4[I,I] + @test T3 ≈ T4[I,I] # @time blkasm(I,I) # @time assemble(t,X1,X1) diff --git a/test/test_momintegrals_overlap.jl b/test/test_momintegrals_overlap.jl new file mode 100644 index 00000000..4758133a --- /dev/null +++ b/test/test_momintegrals_overlap.jl @@ -0,0 +1,25 @@ +using BEAST +using CompScienceMeshes +using StaticArrays +using Test + +tcell = simplex((@SVector [1.0,0.0,0.0]), (@SVector [0.0,1.0,0.0]),(@SVector [0.0,0.0,0.0])) +bcell = simplex((@SVector [0.0,0.8,0.0]),(@SVector [1.0,1.0,0.0]),(@SVector [0.9,0.0,0.0])) + +bshapes = BEAST.RTRefSpace{Float64}() +tshapes = BEAST.LagrangeRefSpace{Float64,1,3,3}() + +biop = BEAST.DotLocal(nt,(BEAST.DoubleIntegralR{Float64}()×B)) + +quadstrat = BEAST.DoubleNumSauterQstrat(6,7,6,6,6,6) + +qd = quaddata(biop, tshapes, bshapes, [tcell], [bcell], quadstrat) +zlocal1 = zeros(Float64, 6, 6) +zlocal2 = zeros(Float64, 6, 6) +##without subdevision +qrule = quadrule(biop, tshapes, bshapes, 1, tcell, 1, bcell, qd, quadstrat) +BEAST.momintegrals!(biop, tshapes, bshapes, tcell, bcell, zlocal1, qrule) + +##with subdevision +BEAST.momintegrals_overlap!(biop, tshapes, bshapes, tcell, bcell, zlocal2, quadstrat) +@test zlocal1 ≈ zlocal2 \ No newline at end of file From c7220b369aec21b3616c6e2e601879dfd2cf55e1 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 14 Nov 2023 10:25:13 +0100 Subject: [PATCH 064/110] reset examples --- examples/ex_globalmultitrace.jl | 27 ++++++--------------------- examples/junction_calderon.jl | 3 +-- examples/pmchwt.jl | 19 ++++++++----------- 3 files changed, 15 insertions(+), 34 deletions(-) diff --git a/examples/ex_globalmultitrace.jl b/examples/ex_globalmultitrace.jl index 699ff19f..8b9a5efc 100644 --- a/examples/ex_globalmultitrace.jl +++ b/examples/ex_globalmultitrace.jl @@ -3,28 +3,15 @@ using BEAST using LinearAlgebra import Plotly - -# ϵ0 = 8.854e-12 -# μ0 = 4π*1e-7 -ϵr1 = 2.0 -μr1 = 2.0 -ϵr2 = 3.0 -μr2 = 3.0 -# c = 1/√(ϵ0*μ0) -# λ = 2.9979563769321627 -# ω = 2π*c/λ -# k0 = ω*sqrt(ϵ0*μ0) -k0 = 3.0 - # Exterior wavenumber -κ₀ = k0 +κ₀ = 3.0 # This is where the number of domains enters the problem description -κ = [sqrt(ϵr1*μr1)*κ₀, sqrt(ϵr2*μr2)*κ₀] +κ = [1.5κ₀, 2.5κ₀] # Description of the domain boundaries -h = 0.2 -Γ1 = meshcuboid(1.0, 1.0, 1.0, h) +h = 0.125 +Γ1 = meshcuboid(0.5, 1.0, 1.0, h) Γ2 = -Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))) Γ = [Γ1, Γ2] @@ -32,7 +19,7 @@ h = 0.2 # of the number of domains and their relative positioning # Incident field -Einc = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=κ₀) +Einc = Maxwell3D.planewave(direction=(x̂+ẑ)/√2, polarization=ŷ, wavenumber=κ₀) Hinc = -1/(im*κ₀)*curl(Einc) # Definition of the boundary integral operators @@ -110,6 +97,4 @@ Etot = Eo + sum(Ei) Htot = Ho + sum(Hi) import Plots -Plots.heatmap(Xs, Zs, clamp.(real.(getindex.(Htot,2)),-1,1); colormap=:viridis) - -Plots.heatmap(Xs, Zs, imag.(getindex.(Htot,2))) \ No newline at end of file +Plots.heatmap(Xs, Zs, clamp.(real.(getindex.(Etot,2)),-2.0,2.0); colormap=:viridis) \ No newline at end of file diff --git a/examples/junction_calderon.jl b/examples/junction_calderon.jl index 52429607..bc4db4a8 100644 --- a/examples/junction_calderon.jl +++ b/examples/junction_calderon.jl @@ -36,8 +36,7 @@ Nxy = assemble(@discretise(BEAST.diag(N)[p,q], p∈X, q∈Y)) Dyx = BEAST.GMRESSolver(Nxy, tol=2e-12, restart=250, verbose=false) Dxy = BEAST.GMRESSolver(transpose(Nxy), tol=2e-12, restart=250, verbose=false) Syy = BEAST.assemble(@discretise BEAST.diag(SL)[p,q] p∈Y q∈Y) -#P = Dxy * Syy * Dyx -P = Syy * Dyx +P = Dxy * Syy * Dyx # Solve system without and with preconditioner u1, ch1 = solve(BEAST.GMRESSolver(Sxx,tol=2e-5, restart=250), ex) diff --git a/examples/pmchwt.jl b/examples/pmchwt.jl index da950ec2..a4838b86 100644 --- a/examples/pmchwt.jl +++ b/examples/pmchwt.jl @@ -23,17 +23,17 @@ end ϵ0 = 8.854e-12 μ0 = 4π*1e-7 c = 1/√(ϵ0*μ0) -radius = 1.0 + λ = 2.9979563769321627 ω = 2π*c/λ -Ω = CompScienceMeshes.tetmeshsphere(radius,0.2*radius) +Ω = CompScienceMeshes.tetmeshsphere(λ,0.1*λ) Γ = boundary(Ω) X = raviartthomas(Γ) @show numfunctions(X) -ϵr = 2.0*0+5.0 -μr = 10.0 +ϵr = 2.0 +μr = 1.0 κ, η = ω/c, √(μ0/ϵ0) κ′, η′ = κ*√(ϵr*μr), η*√(μr/ϵr) @@ -99,7 +99,7 @@ Plotly.plot(patch(Γ, norm.(fcrm))) Z = range(-6,6,length=200) Y = range(-4,4,length=200) -nfpoints = [point(0,y,z) for y in Y, z in Z] +nfpoints = [point(0,y,z) for z in Z, y in Y] import Base.Threads: @spawn task1 = @spawn nearfield(u[m],u[j],X,X,κ,η,nfpoints,E,H) @@ -116,11 +116,8 @@ Plots.contour(real.(getindex.(H_tot,2))) Plots.heatmap(Z, Y, clamp.(real.(getindex.(E_tot,1)),-1.5,1.5)) Plots.heatmap(Z, Y, clamp.(imag.(getindex.(E_tot,1)),-1.5,1.5)) -display(Plots.heatmap(Z, Y, real.(getindex.(H_tot,2)))) -display(Plots.heatmap(Z, Y, imag.(getindex.(H_tot,2)))) +Plots.heatmap(Z, Y, real.(getindex.(H_tot,2))) +Plots.heatmap(Z, Y, imag.(getindex.(H_tot,2))) Plots.plot(real.(getindex.(E_tot[:,51],1))) -Plots.plot(real.(getindex.(H_tot[:,51],2))) - - - +Plots.plot(real.(getindex.(H_tot[:,51],2))) \ No newline at end of file From 44f5ae521defac82873e86de01c6aec274f5431b Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 14 Nov 2023 11:04:37 +0100 Subject: [PATCH 065/110] cleanup --- src/BEAST.jl | 20 +- src/Helmholtzhodge/helmholtzhodge.jl | 39 --- src/Helmholtzhodge/hhhexc.jl | 35 -- src/Helmholtzhodge/hhhnearfield.jl | 165 --------- src/Helmholtzhodge/hhhop.jl | 427 ----------------------- src/bases/basis.jl | 2 - src/composedoperator/composedoperator.jl | 7 + src/integralop.jl | 2 - src/localop.jl | 2 +- src/solvers/solver.jl | 34 +- test/test_HHHoperators.jl | 34 -- test/test_local_storage.jl | 6 +- 12 files changed, 38 insertions(+), 735 deletions(-) delete mode 100644 src/Helmholtzhodge/helmholtzhodge.jl delete mode 100644 src/Helmholtzhodge/hhhexc.jl delete mode 100644 src/Helmholtzhodge/hhhnearfield.jl delete mode 100644 src/Helmholtzhodge/hhhop.jl delete mode 100644 test/test_HHHoperators.jl diff --git a/src/BEAST.jl b/src/BEAST.jl index 56cb45f0..4997eb1e 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -274,8 +274,8 @@ include("composedoperator/composedoperator.jl") #include("display.jl") -include("Helmholtzhodge/hhhexc.jl") -include("Helmholtzhodge/hhhnearfield.jl") +# include("Helmholtzhodge/hhhexc.jl") +# include("Helmholtzhodge/hhhnearfield.jl") const x̂ = point(1,0,0) const ŷ = point(0,1,0) @@ -289,14 +289,14 @@ const ∇ = Nabla() export ∇ -export Interaction -export Domain -export HomogeneousDomain -export RootDomain -export SubDomain +# export Interaction +# export Domain +# export HomogeneousDomain +# export RootDomain +# export SubDomain -export FunctionExcitation -export NdotExcitation -export NcrossExcitation +# export FunctionExcitation +# export NdotExcitation +# export NcrossExcitation end # module diff --git a/src/Helmholtzhodge/helmholtzhodge.jl b/src/Helmholtzhodge/helmholtzhodge.jl deleted file mode 100644 index 89a5f77c..00000000 --- a/src/Helmholtzhodge/helmholtzhodge.jl +++ /dev/null @@ -1,39 +0,0 @@ -module HHH - using ..BEAST - Mod = BEAST - - function green(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end - end - Mod.HHHgreen(alpha,gamma,Mod.hhhidentity()) - end - - function gradgreen(; - alpha=nothing, - gamma=nothing, - wavenumber=nothing) - - gamma, wavenumber = Mod.gamma_wavenumber_handler(gamma, wavenumber) - - if alpha === nothing - if gamma !== nothing - alpha = one(gamma) - else - alpha = 1.0 # Default to double precision - end - end - Mod.HHHgradgreen(alpha,gamma,Mod.hhhidentity()) -end - -end \ No newline at end of file diff --git a/src/Helmholtzhodge/hhhexc.jl b/src/Helmholtzhodge/hhhexc.jl deleted file mode 100644 index da89f1fc..00000000 --- a/src/Helmholtzhodge/hhhexc.jl +++ /dev/null @@ -1,35 +0,0 @@ -abstract type HHHFunctional{T} <: Functional end - -mutable struct FunctionExcitation{T} <: HHHFunctional{T} - f::Function - coeff::T -end -mutable struct NdotExcitation{T} <: HHHFunctional{T} - e::HHHFunctional{T} -end -mutable struct NcrossExcitation{T} <: HHHFunctional{T} - e::HHHFunctional{T} -end - -FunctionExcitation(f) = FunctionExcitation(f,f([0.0,0.0,0.0])) - -function (e::FunctionExcitation)(p) - x = cartesian(p) - e.f(x) -end -function (e::NdotExcitation)(p) - n = normal(p) - dot(n,e.e(p)) -end -function (e::NcrossExcitation)(p) - n = normal(p) - cross(n,e.e(p)) -end - - - -integrand(::HHHFunctional,test_vals, field_val) = dot(test_vals.value,field_val) - - -scalartype(e::HHHFunctional{T}) where {T<:Number} = T -scalartype(e::HHHFunctional{Vector{T}}) where {T<:Number} = T \ No newline at end of file diff --git a/src/Helmholtzhodge/hhhnearfield.jl b/src/Helmholtzhodge/hhhnearfield.jl deleted file mode 100644 index f31c0d92..00000000 --- a/src/Helmholtzhodge/hhhnearfield.jl +++ /dev/null @@ -1,165 +0,0 @@ -mutable struct HHHGreenField{T,U} - gamma::T - op::U -end -mutable struct HHHGradGreenField{T,U} - gamma::T - op::U -end -mutable struct HHHGradGreenCrossField{T,U} - gamma::T - op::U -end -mutable struct HHHGradGreenDotField{T,U} - gamma::T - op::U -end - -mutable struct HHHBasisNtimesField{U} - op::U -end -mutable struct HHHIdentityField end -mutable struct HHHDivergenceField end - -function HHHGreenField(; - gamma=nothing, - wavenumber=nothing -) - - if (gamma === nothing) && (wavenumber === nothing) - error("Supply one of (not both) gamma or wavenumber") - end - - if (gamma !== nothing) && (wavenumber !== nothing) - error("Supply one of (not both) gamma or wavenumber") - end - - if gamma === nothing - if iszero(real(wavenumber)) - gamma = -imag(wavenumber) - else - gamma = im*wavenumber - end - end - - @assert gamma !== nothing - - HHHGreenField(gamma,HHHIdentityField()) -end -function HHHGradGreenField(; - gamma=nothing, - wavenumber=nothing -) - - if (gamma === nothing) && (wavenumber === nothing) - error("Supply one of (not both) gamma or wavenumber") - end - - if (gamma !== nothing) && (wavenumber !== nothing) - error("Supply one of (not both) gamma or wavenumber") - end - - if gamma === nothing - if iszero(real(wavenumber)) - gamma = -imag(wavenumber) - else - gamma = im*wavenumber - end - end - - @assert gamma !== nothing - - HHHGradGreenField(gamma,HHHIdentityField()) -end -function HHHGradGreenCrossField(; - gamma=nothing, - wavenumber=nothing -) - - if (gamma === nothing) && (wavenumber === nothing) - error("Supply one of (not both) gamma or wavenumber") - end - - if (gamma !== nothing) && (wavenumber !== nothing) - error("Supply one of (not both) gamma or wavenumber") - end - - if gamma === nothing - if iszero(real(wavenumber)) - gamma = -imag(wavenumber) - else - gamma = im*wavenumber - end - end - - @assert gamma !== nothing - - HHHGradGreenCrossField(gamma,HHHIdentityField()) -end -function HHHGradGreenDotField(; - gamma=nothing, - wavenumber=nothing -) - - if (gamma === nothing) && (wavenumber === nothing) - error("Supply one of (not both) gamma or wavenumber") - end - - if (gamma !== nothing) && (wavenumber !== nothing) - error("Supply one of (not both) gamma or wavenumber") - end - - if gamma === nothing - if iszero(real(wavenumber)) - gamma = -imag(wavenumber) - else - gamma = im*wavenumber - end - end - - @assert gamma !== nothing - - HHHGradGreenDotField(gamma,HHHIdentityField()) -end - -const HHHField = Union{HHHGreenField,HHHGradGreenField,HHHGradGreenCrossField} -defaultquadstrat(op::HHHField, basis) = SingleNumQStrat(2) -quaddata(op::HHHField,rs,els,qs::SingleNumQStrat) = quadpoints(rs,els,(qs.quad_rule,)) -quadrule(op::HHHField,refspace,p,y,q,el,qdata,qs::SingleNumQStrat) = qdata[1,q] - -function kernelvals(op::HHHField,y,p) - - γ = op.gamma - r = y - cartesian(p) - R = norm(r) - - γR = γ*R - expn = exp(-γR) - green = expn / (4pi*R) - gradgreen = -(γ + 1/R) * green / R * r - - krn = (trans=r, dist=R, green=green, gradgreen=gradgreen) -end - -function integrand(op::HHHGreenField, krn, y, fp, p) -G = krn.green -G*integrand(op.op, krn, y, fp, p) -end - -function integrand(op::HHHBasisNtimesField, krn, y, fp, p) - n = normal(p) - n*integrand(op.op, krn, y, fp, p) -end -integrand(op::HHHIdentityField, krn,y,fp,p) = fp.value -integrand(op::HHHDivergenceField,krn,y,fp,p) = fp.divergence - -function integrand(op::HHHGradGreenField, krn, y, fp, p) - integrand(op.op, krn,y,fp,p)*krn.gradgreen -end - -function integrand(op::HHHGradGreenCrossField, krn, y, fp, p) - cross(krn.gradgreen,integrand(op.op, krn,y,fp,p)) -end -function integrand(op::HHHGradGreenDotField, krn, y, fp, p) - dot(integrand(op.op, krn,y,fp,p),krn.gradgreen) -end \ No newline at end of file diff --git a/src/Helmholtzhodge/hhhop.jl b/src/Helmholtzhodge/hhhop.jl deleted file mode 100644 index 050d76c7..00000000 --- a/src/Helmholtzhodge/hhhop.jl +++ /dev/null @@ -1,427 +0,0 @@ -import LinearAlgebra: ×, ⋅ -abstract type HHHLocalOperator <: LocalOperator end -abstract type HHHOperator <: IntegralOperator end -abstract type HHHtestOperator{U} <: HHHOperator end -abstract type HHHbasisOperator <: HHHOperator end -abstract type HHHkernelOperator{T,K,U} <: HHHOperator end -# scalartype(op::HHHOperator{T,K}) where {T, K <: Nothing} = T -# scalartype(op::HHHOperator{T,K}) where {T, K} = promote_type(T, K) -# scalartype(op::HHHOperator{T,K}) where {T, K <: Nothing} = T -# scalartype(op::HHHOperator) = ComplexF64 -scalartype(op::HHHLocalOperator) = Union{} - -scalartype(op::HHHkernelOperator{T,K,U}) where {T, K,U} = promote_type(T, K) -scalartype(op::HHHtestOperator{U}) where {U} = scalartype(U) - -scalartype(op::Type{<: HHHtestOperator{U}}) where {U} =scalartype(U) - -scalartype(op::Type{<: HHHkernelOperator{T,K,U}}) where {T,K,U} = promote_type(T, K) -#const i4pi = 1 / (4pi) -struct HHHgreen{T,K,U} <: HHHkernelOperator{T,K,U} - α::K - γ::T - op::U -end - -struct HHHgradgreen{T,K,U} <: HHHkernelOperator{T,K,U} - α::K - γ::T - op::U -end - -struct HHHgradgreenDot{T,K,U} <: HHHkernelOperator{T,K,U} - α::K - γ::T - op::U -end - - -struct HHHgradgreenCross{T,K,U} <: HHHkernelOperator{T,K,U} - α::K - γ::T - op::U -end - - - -abstract type HHHdata end -struct HHHvector <:HHHdata end -struct HHHscalar <:HHHdata end - - -struct HHHNtestCross{U} <: HHHtestOperator{U} - op::U -end - - -struct HHHNbasisCross{U} <: HHHbasisOperator - op::U -end - -struct HHHNtestDot{U} <: HHHtestOperator{U} - op::U -end - -struct HHHNbasisnormal{U} <: HHHbasisOperator - op::U -end -struct HHHNbasisdot{U} <: HHHbasisOperator - op::U -end -struct HHHIdentity <: HHHbasisOperator -end -struct HHHDivergence <: HHHbasisOperator -end - - -mutable struct HHHNtestCrossLocal{U <: HHHLocalOperator} <: HHHLocalOperator - op::U -end - - -mutable struct HHHNbasisCrossLocal{U <: HHHLocalOperator} <: HHHLocalOperator - op::U -end - -mutable struct HHHNtestDotLocal{U <: HHHLocalOperator} <: HHHLocalOperator - op::U -end - -mutable struct HHHNbasisnormalLocal{U <: HHHLocalOperator} <: HHHLocalOperator - op::U -end -mutable struct HHHNbasisdotLocal{U <: HHHLocalOperator} <: HHHLocalOperator - op::U -end -mutable struct HHHIdentityLocal <: HHHLocalOperator -end -mutable struct HHHDivergenceLocal <: HHHLocalOperator end - -hhhidentity() = HHHIdentity() -hhhdivergence() = HHHDivergence() - -export HHH -struct BasisFunction end -struct DivBasisFunction end -basisfunction() = BasisFunction() -export basisfunction -VectorToVector = Union{HHHNtestCross,HHHNbasisCross,HHHgradgreenCross,HHHgreen} -ScalarToVector = Union{HHHNbasisnormal,HHHgradgreen} -VectorToScalar = Union{HHHNtestDot,HHHgradgreenDot,HHHNbasisdot} -ScalarToScalar = Union{HHHgreen} -inversemap(op::VectorToVector,::HHHvector) = inversemap(op.op,HHHvector()) -inversemap(op::ScalarToVector,::HHHvector) = inversemap(op.op,HHHscalar()) -inversemap(op::VectorToScalar,::HHHscalar) = inversemap(op.op,HHHvector()) -inversemap(op::ScalarToScalar,::HHHscalar) = HHHscalar() -inversemap(::HHHOperator,::HHHdata) = @error "trying to convert scalar to vector or vector to scalar" -inversemap(::HHHIdentity,data::HHHdata) = data -inversemap(::HHHDivergence,::HHHscalar) = HHHvector() -##### Operator building - -strace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestCross(op) -ntrace(op::Union{HHHkernelOperator,HHHtestOperator}) = HHHNtestDot(op) -×(op::HHHgradgreen,::Nothing) = HHHgradgreenCross(op.α,op.γ,op.op) -⋅(op::HHHgradgreen,::Nothing) = HHHgradgreenDot(op.α,op.γ,op.op) -#×(op::HHHgradgreen,::NormalVector) = HHHgradgreenCross(op.α,op.γ,op.op)(HHHNbasisnormal(hhhidentity())) -×(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = strace(op) -⋅(::NormalVector,op::Union{HHHkernelOperator,HHHtestOperator}) = ntrace(op) -*(::NormalVector,::BasisFunction) = HHHNbasisnormal(hhhidentity()) -⋅(::Nabla,::BasisFunction) = hhhdivergence() -*(::NormalVector,::DivBasisFunction) = HHHNbasisnormal(hhhdivergence()) -⋅(::NormalVector,::BasisFunction) = HHHNbasisdot(hhhidentity()) -×(::NormalVector,::BasisFunction) = HHHNbasisCross(hhhidentity()) -×(::NormalVector,op::HHHbasisOperator) = HHHNbasisCross(op) -⋅(::NormalVector,op::HHHbasisOperator) = HHHNbasisdot(op) - - -function (op::HHHkernelOperator)(Basisop::HHHbasisOperator) - return (Base.typename(typeof(op)).wrapper)(op.α,op.γ,Basisop) -end - - -### TODO make sure this function can be used, unpack everything and make new structure. -function (op::HHHOperator)(BasisOperator::HHHbasisOperator) - op.op = BasisOperator -end - -# ##### to generate integrand -# extract(a::Type{HHHNbasisCross{T}}) where {T} = [HHHNbasisCross;extract(T)] -# extract(a::Type{HHHNbasisdot{T}}) where {T} = [HHHNbasisdot;extract(T)] -# extract(a::Type{HHHNbasisnormal{T}}) where {T} = [HHHNbasisnormal;extract(T)] -# extract(a::Type{HHHNtestCross{T}}) where {T} = [HHHNtestCross;extract(T)] -# extract(a::Type{HHHNtestDot{T}}) where {T} = [HHHNtestDot;extract(T)] -# extract(a::Type{HHHgradgreen{T}}) where {T} = [HHHgradgreen;extract(T)] -# extract(a::Type{HHHgradgreenCross{T}}) where {T} = [HHHgradgreenCross;extract(T)] -# extract(a::Type{HHHgreen{T}}) where {T} = [HHHgreen;extract(T)] -# extract(a::Type{HHHIdentity}) = HHHIdentity -# extract(a::Type{HHHDivergence}) = HHHDivergence - - -# @generated function hhhintegrand(op,x,y,g) -# println("integrand generated") -# typelist = extract(typeof(op)) - - - -# end - - - -##### Integrand definitions -function (igd::Integrand{<:HHHOperator})(x,y,f,g) - op = igd.operator - -test = getvalue(f) -_krondot(test,op(x,y,g)) - -end -function (op::HHHNtestCross)(x,y,g) - nx = normal(x) - cross.(Ref(nx),op.op(x,y,g)) - -end -function (op::HHHNtestDot)(x,y,g) - nx = normal(x) - dot.(Ref(nx),op.op(x,y,g)) -end -function (op::HHHNbasisnormal)(x,y,g) - ny = normal(y) - Ref(ny).*op.op(x,y,g) -end -function (op::HHHNbasisdot)(x,y,g) - ny = normal(y) - dot.(Ref(ny),op.op(x,y,g)) -end -function (op::HHHNbasisCross)(x,y,g) - ny = normal(y) - cross.(Ref(ny),op.op(x,y,g)) -end -function (op::HHHIdentity)(x,y,g) - getvalue(g) -end -function (op::HHHDivergence)(x,y,g) - getdivergence(g) -end -function (op::HHHgreen)(x,y,g) - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = op.α * exp(-op.γ*R)*(iR*i4pi) - green*op.op(x,y,g) -end -# mydot(a::SVector{N,<:SVector},b::Base.RefValue) where {N} = dot.(a,b) -# function mydot(a::SVector,b::Base.RefValue) -# a.*b -# end -function (op::HHHgradgreen)(x,y,g) - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = op.α * exp(-op.γ*R)*(iR*i4pi) - gradgreen = -(op.γ + iR) * green * (iR * r) - - op.op(x,y,g).*Ref(gradgreen) -end -function (op::HHHgradgreenDot)(x,y,g) - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = op.α * exp(-op.γ*R)*(iR*i4pi) - gradgreen = -(op.γ + iR) * green * (iR * r) - - dot.(op.op(x,y,g),Ref(gradgreen)) -end -function (op::HHHgradgreenCross)(x,y,g) - - r = cartesian(x) - cartesian(y) - R = norm(r) - iR = 1/R - green = op.α * exp(-op.γ*R)*(iR*i4pi) - gradgreen = -(op.γ + iR) * green * (iR * r) - cross.(Ref(gradgreen),op.op(x,y,g)) - - -end -identify(::VectorSurfaceSpace) = HHHvector() -identify(::ScalarSurfaceSpace) = HHHscalar() -kernel(op::HHHtestOperator) = kernel(op.op) -kernel(op::HHHkernelOperator) = op - -function defaultquadstrat(op::HHHOperator,testspace::Space,basisspace::Space) -@assert identify(basisspace) == inversemap(op,identify(testspace)) -defaultquadstrat(op,identify(testspace),identify(basisspace)) -end -defaultquadstrat(op::HHHOperator,::HHHdata,::HHHdata) = DoubleNumSauterQstrat(6,7,5,5,4,3) #TODO implement strategy that is stronger for nearby triangles - - -sign_upon_permutation(op::Union{HHHIdentity,HHHDivergence},I,J) = 1 -sign_upon_permutation(op::HHHkernelOperator,I,J) = sign_upon_permutation(op.op,I,J) -sign_upon_permutation(op::Union{HHHNtestCross,HHHNtestDot},I,J) = Combinatorics.levicivita(I)*sign_upon_permutation(op.op,I,J) -sign_upon_permutation(op::Union{HHHNbasisnormal,HHHNbasisCross,HHHNbasisdot},I,J) = Combinatorics.levicivita(J)*sign_upon_permutation(op.op,I,J) - -""" -(number of test normals,number of trial normals) -""" -function number_of_normals(op::HHHOperator) end - - -number_of_normals(op::Union{HHHNtestCross,HHHNtestCrossLocal,HHHNtestDot,HHHNtestDotLocal}) = [1,0]+number_of_normals(op.op) -number_of_normals(op::HHHkernelOperator) = number_of_normals(op.op) -number_of_normals(op::Union{HHHNbasisCross,HHHNbasisCrossLocal,HHHNbasisdot,HHHNbasisdotLocal,HHHNbasisnormal,HHHNbasisnormalLocal}) = [0,1]+number_of_normals(op.op) -number_of_normals(op::Union{HHHIdentity,HHHIdentityLocal,HHHDivergence,HHHDivergenceLocal}) = [0,0] - - - -#### trace definition - - - -alpha(op::HHHtestOperator) = alpha(op.op) -alpha(op::HHHkernelOperator) = op.α - -hhhntestcrosslocal(op::ZeroOperator) = op -hhhntestcrosslocal(op::HHHLocalOperator) = HHHNtestCrossLocal(op) -hhhntestcrosslocal(op::Union{HHHNbasisnormalLocal}) = ZeroOperator() - -hhhntestdotlocal(op::ZeroOperator) = op -hhhntestdotlocal(op::HHHLocalOperator) = HHHNtestDotLocal(op) -hhhntestdotlocal(op::Union{HHHNtestCrossLocal,HHHNbasisCrossLocal}) = ZeroOperator() -#hhhntestdotlocal(op::HHHNbasisnormalLocal) = localoperator(op.op) - -hhhnbasiscrosslocal(op::ZeroOperator) = op -hhhnbasiscrosslocal(op::HHHLocalOperator) = HHHNbasisCrossLocal(op) -hhhnbasiscrosslocal(op::Union{HHHNbasisnormalLocal}) = ZeroOperator() - -hhhnbasisdotlocal(op::ZeroOperator) = op -hhhnbasisdotlocal(op::HHHLocalOperator) = HHHNbasisdotLocal(op) -hhhnbasisdotlocal(op::HHHDivergenceLocal) = HHHNbasisnormalLocal(op) -hhhnbasisdotlocal(op::Union{HHHNtestCrossLocal,HHHNbasisCrossLocal}) = ZeroOperator() -function hhhnbasisdotlocal(op::HHHIdentityLocal) - @warn "assumed basisfunction is tangential to surface" -ZeroOperator() -end - -hhhnbasisdotlocal(op::HHHNbasisnormalLocal) = op.op - -hhhnbasisnormal(op::ZeroOperator) = op -hhhnbasisnormal(op::HHHLocalOperator) = HHHNbasisnormalLocal(op) - -localoperator(op::HHHNtestCross) = hhhntestcrosslocal(localoperator(op.op)) -localoperator(op::HHHNtestDot) = hhhntestdotlocal(localoperator(op.op)) -localoperator(op::HHHNbasisCross) = hhhnbasiscrosslocal(localoperator(op.op)) -localoperator(op::HHHNbasisdot) = hhhnbasisdotlocal(localoperator(op.op)) -localoperator(op::HHHNbasisnormal) = hhhnbasisnormal(localoperator(op.op)) -localoperator(op::HHHIdentity) = HHHIdentityLocal() -localoperator(op::HHHDivergence) = HHHDivergenceLocal() - -localoperator(op::HHHgreen) = ZeroOperator() -localoperator(op::HHHgradgreen) = hhhnbasisnormal(localoperator(op.op)) -localoperator(op::HHHgradgreenDot) = hhhnbasisdotlocal(localoperator(op.op)) -localoperator(op::HHHgradgreenCross) = hhhnbasiscrosslocal(localoperator(op.op)) - -function trace(op::HHHOperator,sign) - l = localoperator(op) - if typeof(l) == HHHNbasisnormalLocal{HHHIdentityLocal} || typeof(l) == HHHNbasisnormalLocal{HHHDivergenceLocal} - @warn "assumed test function is tangential to surface" - l = ZeroOperator() - end - - localop = 1/2*sign*alpha(op)*localoperator(op) - - return op + localop -end -function normalorient(op::Union{HHHOperator,HHHLocalOperator},signtest,signtrial) -test,trial = number_of_normals(op) -signtest^test*signtrial^trial*op -end - -##### defining integrand of those local operators: - - -function integrand(op::HHHLocalOperator,kernel,x,g,f,nt,nb) - -dot(g.value,op(x,f,nt,nb)) -end - -function (op::HHHNtestCrossLocal)(x,f,nt,nb) - nt×op.op(x,f,nt,nb) -end -function (op::HHHNtestDotLocal)(x,f,nt,nb) - dot(nt,op.op(x,f,nt,nb)) -end -function (op::HHHNbasisCrossLocal)(x,f,nt,nb) - nb×op.op(x,f,nt,nb) -end -function (op::HHHNbasisdotLocal)(x,f,nt,nb) - dot(nb,op.op(x,f,nt,nb)) -end -function (op::HHHNbasisnormalLocal)(x,f,nt,nb) - nb*op.op(x,f,nt,nb) -end -function (op::HHHIdentityLocal)(x,f,nt,nb) - return f.value -end -function (op::HHHDivergenceLocal)(x,f,nt,nb) - return f.divergence -end - -function cellinteractions(biop::HHHLocalOperator, trefs::U, brefs::V, cell,qr,tcell,bcell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} - - num_tshs = length(qr[1][3]) - num_bshs = length(qr[1][4]) - - zlocal = zeros(T, num_tshs, num_bshs) - nt = normal(tcell) - nb = normal(bcell) - for q in qr - - w, mp, tvals, bvals = q[1], q[2], q[3], q[4] - j = w * jacobian(mp) - # kernel = kernelvals(biop, mp) - kernel = nothing - for m in 1 : num_tshs - tval = tvals[m] - - for n in 1 : num_bshs - bval = bvals[n] - - igd = integrand(biop, kernel, mp, tval, bval,nt,nb) - zlocal[m,n] += j * igd - - end - end - end - - return zlocal -end -function cellinteractions_matched!(zlocal, biop::HHHLocalOperator, trefs, brefs, cell, qr,tcell=nothing,bcell=nothing) - - num_tshs = length(qr[1][3]) - num_bshs = length(qr[1][4]) - nt = normal(tcell) - nb = normal(bcell) - # zlocal = zeros(Float64, num_tshs, num_bshs) - for q in qr - - w, mp, tvals, bvals = q[1], q[2], q[3], q[4] - j = w * jacobian(mp) - #kernel = kernelvals(biop, mp) - kernel = nothing - nt = normal(tcell) - nb = normal(bcell) - for n in 1 : num_bshs - bval = bvals[n] - for m in 1 : num_tshs - tval = tvals[m] - - igd = integrand(biop, kernel, mp, tval, bval,nt,nb) - zlocal[m,n] += j * igd - end - end - end - - return zlocal -end \ No newline at end of file diff --git a/src/bases/basis.jl b/src/bases/basis.jl index 0634bd44..a5064075 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -84,9 +84,7 @@ function Base.:+(x::AbstractSpace...) T = scalartype(x...) return DirectProductSpace{T, AbstractSpace}([x...]) end -cross(a::Nothing,b::Space{T}) where {T}= DirectProductSpace{T,Space{T}}(Space{T}[b]) cross(a::Space{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}(Space{T}[a,b]) -cross(a::Space{T}, b::Nothing) where {T} = a cross(a::DirectProductSpace{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b]) cross(a::DirectProductSpace{T}, b::DirectProductSpace{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b.factors]) numfunctions(S::DirectProductSpace) = sum([numfunctions(s) for s in S.factors]) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index c527ea10..974651f6 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -368,7 +368,14 @@ scalartype(G::GreenHH3D{T}) where {T} = T scalartype(G::GradGreenHH3D{T}) where {T} = T +struct DoubleIntegralR{T} <: Kernel end +function (op::DoubleIntegralR)(x,y,g) + r = cartesian(x) - cartesian(y) + Ref(r) +end +scalartype(G::DoubleIntegralR{T}) where {T} = T +γ(op::DoubleIntegralR) = op function (op::Union{TimesIntegral,TimesLocal})(x,y,g) diff --git a/src/integralop.jl b/src/integralop.jl index e4fce3d8..97ad38ba 100644 --- a/src/integralop.jl +++ b/src/integralop.jl @@ -109,8 +109,6 @@ function assemblechunk_body!(biop, test_shapes, test_elements, test_assembly_data, trial_shapes, trial_elements, trial_assembly_data, qd, zlocal, store; quadstrat) - println(typeof(test_elements)) - println(typeof(trial_elements)) myid = Threads.threadid() myid == 1 && print(string(typeof(biop))*" dots out of 10: ") todo, done, pctg = length(test_elements), 0, 0 diff --git a/src/localop.jl b/src/localop.jl index 91d8069b..3a87fb48 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -443,7 +443,7 @@ function cellinteractions(biop, trefs::U, brefs::V, cellt,cellb,qr) where {U<:Re return zlocal end function getvalue(list::Matrix{T}) where {T} - + display(list) return SVector{length(list),T}([i for i in list]) end # function cellinteractions(biop, trefs::U, brefs::V, cell,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} diff --git a/src/solvers/solver.jl b/src/solvers/solver.jl index 5bcabb5d..3b4ca859 100644 --- a/src/solvers/solver.jl +++ b/src/solvers/solver.jl @@ -430,24 +430,24 @@ end # end function LinearAlgebra.dot(test::DirectProductSpace,op::Matrix{AbstractOperator},trial::DirectProductSpace) -test_length = length(test.factors) -trial_length = length(trial.factors) -@assert size(op)==(test_length,trial_length) -terms = Vector{BilTerm}() -test_space_dict = Dict() -trial_space_dict = Dict() -for (i,space) in enumerate(test.factors) - test_space_dict[i]=space -end -for (i,space) in enumerate(trial.factors) - trial_space_dict[i]=space -end + test_length = length(test.factors) + trial_length = length(trial.factors) + @assert size(op)==(test_length,trial_length) + terms = Vector{BilTerm}() + test_space_dict = Dict() + trial_space_dict = Dict() + for (i,space) in enumerate(test.factors) + test_space_dict[i]=space + end + for (i,space) in enumerate(trial.factors) + trial_space_dict[i]=space + end -for i in 1:test_length - for j in 1:trial_length - push!(terms,BilTerm(i,j,[],[],1.0,op[i,j])) + for i in 1:test_length + for j in 1:trial_length + push!(terms,BilTerm(i,j,[],[],1.0,op[i,j])) + end end -end -BilForm([],[],terms) + BilForm([],[],terms) end diff --git a/test/test_HHHoperators.jl b/test/test_HHHoperators.jl deleted file mode 100644 index 19c8b41d..00000000 --- a/test/test_HHHoperators.jl +++ /dev/null @@ -1,34 +0,0 @@ -using BEAST -using StaticArrays -using CompScienceMeshes -using Test -k = 1.0 - -green = HHH.green(wavenumber=k) -gradgreen = HHH.gradgreen(wavenumber=k) -b = basisfunction() -green -gradgreen -n×green -n×gradgreen -gradgreen×nothing -gradgreen×n -gradgreen(n×b) -gradgreen(n*b) -n×gradgreen(n×b) - - -Γ1 = boundary(Mesh([SVector{3}([0.0,0.0,0.0]),SVector{3}([1.0,0.0,0.0]),SVector{3}([0.0,1.0,0.0]),SVector{3}([0.0,0.0,1.0])],[SVector{4}([1,2,3,4])])) -Γ2 = CompScienceMeshes.translate(Γ1,[0.0,0.0,0.0]) - -X1 = raviartthomas(Γ1) -X2 = raviartthomas(Γ2) -X3 = lagrangec0d1(Γ1) - -m1 = assemble(n×(n×(gradgreen×nothing)(n×(n×b))),X1,X2) -m2 = assemble((gradgreen)(n⋅(n×b)),X1,X2) -m3 = assemble(n⋅(gradgreen)(n⋅(n×b)),X3,X2) -m4 = assemble((green)(n×(n*b)),X1,X3) -dl = assemble(Maxwell3D.doublelayer(wavenumber=k),X1,X2) - -@test abs(sum(m1-dl)+sum(m2)+sum(m3)+sum(m4)) < 10^(-16) \ No newline at end of file diff --git a/test/test_local_storage.jl b/test/test_local_storage.jl index 61fc6d71..7e186ae1 100644 --- a/test/test_local_storage.jl +++ b/test/test_local_storage.jl @@ -3,11 +3,11 @@ using BEAST using CompScienceMeshes using SparseArrays for T in [Float32, Float64] - fn = joinpath(@__DIR__, "assets/sphere5.in") - m = readmesh(fn, T=T) + local fn = joinpath(@__DIR__, "assets/sphere5.in") + local m = readmesh(fn, T=T) Id = BEAST.Identity() - X = BEAST.raviartthomas(m) + local X = BEAST.raviartthomas(m) Z1 = assemble(Id, X, X, storage_policy=Val{:densestorage}) Z2 = assemble(Id, X, X, storage_policy=Val{:bandedstorage}) From 611bfb9dbb6fe76f0e8088cb0b2537126fd7c264 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 29 Nov 2023 14:48:26 +0100 Subject: [PATCH 066/110] update --- Project.toml | 1 + src/BEAST.jl | 22 ------------------- src/bases/local/ndlocal.jl | 4 ++-- src/composedoperator/composedoperator.jl | 2 +- src/composedoperator/tracesimplex.jl | 2 +- src/quadrature/doublenumwiltonsauterqstrat.jl | 6 ++--- 6 files changed, 8 insertions(+), 29 deletions(-) diff --git a/Project.toml b/Project.toml index 7a6f4f18..83c7a82b 100644 --- a/Project.toml +++ b/Project.toml @@ -33,6 +33,7 @@ SparseMatrixDicts = "5cb6c4b0-9b79-11e8-24c9-f9621d252589" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" TableView = "40c74d1a-b44c-5b06-a7c1-6cbea58ea978" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" WiltonInts84 = "a3e2863e-c0ee-5ff6-a523-307a4cdc8724" [compat] diff --git a/src/BEAST.jl b/src/BEAST.jl index 01dc1bab..cfa359f2 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -267,21 +267,10 @@ include("solvers/itsolver.jl") include("utils/plotlyglue.jl") - -#suport for multi-trace -# include("multi-trace/configuration.jl") -# include("multi-trace/interactions.jl") -# include("multi-trace/postprocessing.jl") - -#suport for displaying operators include("composedoperator/tracesimplex.jl") include("composedoperator/composedoperator.jl") -#include("display.jl") -# include("Helmholtzhodge/hhhexc.jl") -# include("Helmholtzhodge/hhhnearfield.jl") - const x̂ = point(1,0,0) const ŷ = point(0,1,0) const ẑ = point(0,0,1) @@ -293,15 +282,4 @@ export n const ∇ = Nabla() export ∇ - -# export Interaction -# export Domain -# export HomogeneousDomain -# export RootDomain -# export SubDomain - -# export FunctionExcitation -# export NdotExcitation -# export NcrossExcitation - end # module diff --git a/src/bases/local/ndlocal.jl b/src/bases/local/ndlocal.jl index 45e6b3df..ed373a01 100644 --- a/src/bases/local/ndlocal.jl +++ b/src/bases/local/ndlocal.jl @@ -41,8 +41,8 @@ function restrict(ϕ::NDRefSpace{T}, dom1, dom2) where T for i in 1:K # find the center of edge i of dom2 - a = dom2.vertices[mod1(i+1,D+1)] - b = dom2.vertices[mod1(i+2,D+1)] + a = verticeslist(dom2)[mod1(i+1,D+1)] + b = verticeslist(dom2)[mod1(i+2,D+1)] c = (a + b) / 2 # find the tangent in this point to the edge diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 974651f6..b775a778 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -429,7 +429,7 @@ defaultquadstrat(op::Potential,test,trial) = defaultquadstrat(op.operator,test,t function assemble!(op::Potential, test_functions::Space, trial_functions::Space, - store, threading = Threading{:multi}; + store, threading = Threading{:multi}; quadstrat = defaultquadstrat(op, test_functions, trial_functions)) dsurf = surface(op) diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index 7df8528c..1ceca634 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -88,7 +88,7 @@ function CompScienceMeshes.chart(p::OrientedMesh,i) d = dot(n1,n2) @assert abs(d) ≈ 1.0 sign(d) == 1 && return c - return flip_normal(c) + return mirror(c) end function CompScienceMeshes.chart(p::TraceMesh,i) c = chart(mesh(p),i) diff --git a/src/quadrature/doublenumwiltonsauterqstrat.jl b/src/quadrature/doublenumwiltonsauterqstrat.jl index ad9dbb6b..bfc65f13 100644 --- a/src/quadrature/doublenumwiltonsauterqstrat.jl +++ b/src/quadrature/doublenumwiltonsauterqstrat.jl @@ -19,12 +19,12 @@ end function quadrule(op::IntegralOperator, g::RefSpace, f::RefSpace, i, τ, j, σ, qd, qs::DoubleNumWiltonSauterQStrat) - T = eltype(eltype(τ.vertices)) + T = eltype(eltype(verticeslist(τ))) hits = 0 dtol = 1.0e3 * eps(T) dmin2 = floatmax(T) - for t in τ.vertices - for s in σ.vertices + for t in verticeslist(τ) + for s in verticeslist(σ) d2 = LinearAlgebra.norm_sqr(t-s) dmin2 = min(dmin2, d2) hits += (d2 < dtol) From 5867ff1c0241cd4df24481c1367942e8d86ec0b8 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 30 Nov 2023 11:21:11 +0100 Subject: [PATCH 067/110] update --- Project.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Project.toml b/Project.toml index 7b1adabe..09969c90 100644 --- a/Project.toml +++ b/Project.toml @@ -22,6 +22,8 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" NestedUnitRanges = "032820ab-dc03-4b49-91f4-7d58d4da98b3" Plotly = "58dd65bb-95f3-509e-9936-c39a10fdeae7" +PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" +PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" Requires = "ae029012-a4dd-5104-9daa-d747884805df" Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" From 32c3557c19c9eddc42010ca3dca122c2d4eb1acd Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Dec 2023 14:23:22 +0100 Subject: [PATCH 068/110] update, implemented multi-trace approach --- examples/pmchwt.jl | 14 +-- src/BEAST.jl | 10 ++ src/bases/basis.jl | 9 +- src/bases/local/laglocal.jl | 1 + src/composedoperator/composedoperator.jl | 66 +++++++++++-- src/composedoperator/excitation.jl | 0 src/composedoperator/postprocessing.jl | 36 +++++++ src/composedoperator/tracesimplex.jl | 8 +- src/excitation.jl | 10 +- src/integralop.jl | 74 +++++++------- src/quadrature/doublenumsauterqstrat.jl | 6 +- test/runtests.jl | 1 + test/test_multi-trace_VP.jl | 121 +++++++++++++++++++++++ 13 files changed, 295 insertions(+), 61 deletions(-) create mode 100644 src/composedoperator/excitation.jl create mode 100644 src/composedoperator/postprocessing.jl create mode 100644 test/test_multi-trace_VP.jl diff --git a/examples/pmchwt.jl b/examples/pmchwt.jl index a4838b86..721e1ba6 100644 --- a/examples/pmchwt.jl +++ b/examples/pmchwt.jl @@ -20,14 +20,8 @@ function nearfield(um,uj,Xm,Xj,κ,η,points, return E, H end -ϵ0 = 8.854e-12 -μ0 = 4π*1e-7 -c = 1/√(ϵ0*μ0) -λ = 2.9979563769321627 -ω = 2π*c/λ - -Ω = CompScienceMeshes.tetmeshsphere(λ,0.1*λ) +Ω = CompScienceMeshes.tetmeshsphere(λ,0.3*λ) Γ = boundary(Ω) X = raviartthomas(Γ) @show numfunctions(X) @@ -99,7 +93,7 @@ Plotly.plot(patch(Γ, norm.(fcrm))) Z = range(-6,6,length=200) Y = range(-4,4,length=200) -nfpoints = [point(0,y,z) for z in Z, y in Y] +nfpoints = [point(0,y,z) for y in Y, z in Z] import Base.Threads: @spawn task1 = @spawn nearfield(u[m],u[j],X,X,κ,η,nfpoints,E,H) @@ -116,8 +110,8 @@ Plots.contour(real.(getindex.(H_tot,2))) Plots.heatmap(Z, Y, clamp.(real.(getindex.(E_tot,1)),-1.5,1.5)) Plots.heatmap(Z, Y, clamp.(imag.(getindex.(E_tot,1)),-1.5,1.5)) -Plots.heatmap(Z, Y, real.(getindex.(H_tot,2))) -Plots.heatmap(Z, Y, imag.(getindex.(H_tot,2))) +display(Plots.heatmap(Y, Z, real.(getindex.(H_tot,2)))) +display(Plots.heatmap(Y, Z, imag.(getindex.(H_tot,2)))) Plots.plot(real.(getindex.(E_tot[:,51],1))) Plots.plot(real.(getindex.(H_tot[:,51],2))) \ No newline at end of file diff --git a/src/BEAST.jl b/src/BEAST.jl index 0b439401..30d26f27 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -265,7 +265,17 @@ include("utils/plotlyglue.jl") include("composedoperator/tracesimplex.jl") include("composedoperator/composedoperator.jl") +include("composedoperator/postprocessing.jl") +include("multi-trace/interactions.jl") +include("multi-trace/postprocessing.jl") +include("multi-trace/VectorPotential.jl") + + +# include("multi-trace/multi-trace-old/interactions.jl") +# include("multi-trace/multi-trace-old/configuration.jl") + +# include("multi-trace/multi-trace-old/postprocessing.jl") const x̂ = point(1,0,0) const ŷ = point(0,1,0) diff --git a/src/bases/basis.jl b/src/bases/basis.jl index a5064075..9cbe39c5 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -2,6 +2,10 @@ abstract type RefSpace{T,D} end abstract type AbstractSpace end abstract type Space{T} <: AbstractSpace end +struct EmptySpace{Nothing} <: Space{Nothing} end +numfunctions(::EmptySpace) = 0 + + Base.length(s::AbstractSpace) = numfunctions(s) Base.in(x, s::AbstractSpace) = (x => s) @@ -43,8 +47,6 @@ function scalartype end scalartype(x1, xs...) = Base.promote_type(scalartype(x1), scalartype(xs...)) scalartype(x1::Number) = typeof(x1) scalartype(T::Type, x) = Base.promote_type(T, scalartype(x)) - - """ geometry(basis) @@ -84,9 +86,10 @@ function Base.:+(x::AbstractSpace...) T = scalartype(x...) return DirectProductSpace{T, AbstractSpace}([x...]) end +cross(a::Nothing,b::AbstractSpace) = b cross(a::Space{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}(Space{T}[a,b]) cross(a::DirectProductSpace{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b]) -cross(a::DirectProductSpace{T}, b::DirectProductSpace{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b.factors]) +#cross(a::DirectProductSpace{T}, b::DirectProductSpace{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b.factors]) numfunctions(S::DirectProductSpace) = sum([numfunctions(s) for s in S.factors]) Base.length(S::DirectProductSpace) = numfunctions(S) scalartype(s::DirectProductSpace{T}) where {T} = T diff --git a/src/bases/local/laglocal.jl b/src/bases/local/laglocal.jl index b9cc6d2d..33cfc002 100644 --- a/src/bases/local/laglocal.jl +++ b/src/bases/local/laglocal.jl @@ -34,6 +34,7 @@ function (f::LagrangeRefSpace{T,1,3})(t) where T tv = tangents(t,2) j = jacobian(t)*sign(dot(normal(t),tu×tv)) p = chart(t) + σ = sign(dot(normal(t), cross(p[1]-p[3],p[2]-p[3]))) SVector( (value=u, curl=σ*(p[3]-p[2])/j), (value=v, curl=σ*(p[1]-p[3])/j), diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index b775a778..ff3295c6 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -258,6 +258,27 @@ function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) end +function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise + # check_if_coincide(op.surface,surface) || return op.operator + newop = -nt × nt × γ(op.operator) + direction = [] + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) + end + function γₜ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise + # check_if_coincide(op.surface,surface) || return op.operator + newop = -nt × nt × γ(op.operator) + direction = [] + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) + end + function γₙ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = nt ⋅ γ(op.operator) @@ -338,6 +359,15 @@ function (op::GreenHH3D)(x,y,g) green = exp(-gamma*R)*(i4pi*iR) Ref(green) end +function (op::GreenHH3D)(x::Union{SVector,Vector},y,g) + gamma = op.gamma + + r = x - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-gamma*R)*(i4pi*iR) + Ref(green) +end function (op::GradGreenHH3D)(x,y,g) gamma = op.gamma @@ -354,9 +384,24 @@ function (op::GradGreenHH3D)(x,y,g) end return tt end +function (op::GradGreenHH3D)(x::Union{SVector,Vector},y,g) + gamma = op.gamma + + r = x - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-gamma*R)*(iR*i4pi) + gradgreen = -(gamma + iR) * green * (iR * r) + tt = Ref(gradgreen) + + if maximum(abs.(gradgreen)) === NaN + display(R) + end + return tt +end γ(op::GreenHH3D) = op -γ(op::GradGreenHH3D) = op + 1/2*TraceDirection() +γ(op::GradGreenHH3D) = op - 1/2*TraceDirection() grad(G::GreenHH3D) = GradGreenHH3D(G.gamma) @@ -382,7 +427,7 @@ function (op::Union{TimesIntegral,TimesLocal})(x,y,g) op.lhs(x,y,g).*op.rhs(x,y,g) end function (op::Union{DotIntegral,DotLocal})(x,y,g) - dot.(op.lhs(x,y,g),op.rhs(x,y,g)) + transpose.(op.lhs(x,y,g)).*op.rhs(x,y,g) end function (op::Union{CrossIntegral,CrossLocal})(x,y,g) cross.(op.lhs(x,y,g),op.rhs(x,y,g)) @@ -395,7 +440,7 @@ function (op::TestNormal)(x,y,g) Ref(normal(x)) end function (op::TraceDirection)(x,y,g) - Ref(sign(dot(normal(x),(direction(x)-direction(y))))*normal(x)) + Ref(approx_sign(dot(normal(x),(direction(x)-direction(y))))*normal(x)) end function (op::BasisFunction)(x,y,g) getvalue(g) @@ -403,7 +448,10 @@ end function (op::DivBasisFunction)(x,y,g) getdivergence(g) end - +function approx_sign(a::T; tol=eps(T)) where {T <: Number} + abs(a) < tol && return zero(T) + return sign(a) +end function (igd::Integrand{<:ComposedOperatorIntegral})(x,y,f,g) @@ -413,8 +461,15 @@ end function integrand(op::ComposedOperatorLocal,kernel,x,y,f,g) _krondot(getvalue(f),op(x,y,g)) end +function integrand(op::ComposedOperator,kernel, y, f, x) + r = op(y,x,f) + return r +end +kernelvals(op::ComposedOperatorIntegral, y,x) = nothing +quaddata(op::ComposedOperatorIntegral,rs,els,qs::SingleNumQStrat) = quadpoints(rs,els,(qs.quad_rule,)) +quadrule(op::ComposedOperatorIntegral,refspace,p,y,q,el,qdata,qs::SingleNumQStrat) = qdata[1,q] - +defaultquadstrat(op::ComposedOperatorIntegral, basis) = SingleNumQStrat(3) defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(6,7,5,5,4,3) defaultquadstrat(op::ComposedOperatorLocal,testspace::Space,trialpsace::Space) = SingleNumQStrat(6) #sign_upon_permutation(op::ComposedOperator,I,J) = Combinatorics.levicivita(I)^count_test_normals(op)*Combinatorics.levicivita(J)^count_trial_normals(op) @@ -457,4 +512,3 @@ function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Sp quadstrat = quadstrat) end -kernelvals(op::ComposedOperator,a) = nothing \ No newline at end of file diff --git a/src/composedoperator/excitation.jl b/src/composedoperator/excitation.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/composedoperator/postprocessing.jl b/src/composedoperator/postprocessing.jl new file mode 100644 index 00000000..6697b5d5 --- /dev/null +++ b/src/composedoperator/postprocessing.jl @@ -0,0 +1,36 @@ +struct FunctionExcitation{T} <: Functional + f +end + +kernelvals(op::ComposedOperator,a) = nothing + + + +function (func::FunctionExcitation)(x) + return func.f(x) +end +function (func::FunctionExcitation)(x::CompScienceMeshes.MeshPointNM) + return func.f(cartesian(x)) +end +scalartype(ff::FunctionExcitation{T}) where {T} = T +cross(::NormalVector, p::FunctionExcitation) = CrossTraceMW(p) +integrand(::FunctionExcitation,tval,fval) = tval[1]*fval +export FunctionExcitation + + +function farfieldlocal!(zlocal,op::ComposedOperatorIntegral,refspace,y,el,qr) + + for q in qr + x = q.point + F = q.value + dx = q.weight + + krn = kernelvals(op, y, x) + int = integrand(op,krn,y,F,x) * dx + for (i,j) in enumerate(int) + zlocal[i] += j + end + + end + +end \ No newline at end of file diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index 1ceca634..97720859 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -3,6 +3,7 @@ struct TraceSimplex{T,U} simp::T direction::SVector{3,U} end +TraceSimplex(t::TraceSimplex,d::SVector{3,U}) where {U} = TraceSimplex(simplex(t),direction(t)+d) simplex(t::TraceSimplex) = t.simp direction(t::TraceSimplex) = t.direction struct TraceMeshPointNM{T,U} @@ -26,7 +27,8 @@ CompScienceMeshes.volume(a::TraceSimplex) = volume(simplex(a)) CompScienceMeshes.dimension(a::TraceSimplex) = dimension(simplex(a)) CompScienceMeshes.tangents(a::TraceSimplex,i::Int) = tangents(simplex(a),i) CompScienceMeshes.carttobary(a::TraceSimplex,b::SVector{T}) where {T} = carttobary(simplex(a),b) - +CompScienceMeshes.center(a::TraceSimplex) = TraceMeshPointNM(center(simplex(a)),direction(a)) +CompScienceMeshes.normal(a::TraceSimplex) = normal(simplex(a)) function CompScienceMeshes.quadpoints(chart::TraceSimplex, rule) PV = quadpoints(CompScienceMeshes.domain(chart), rule) map(PV) do pv @@ -75,6 +77,10 @@ TraceMesh(a::CompScienceMeshes.AbstractMesh{U,D,T}) where {U,D,T} = TraceMesh(a, +(a::TraceMesh{U,D,T},b::SVector{3,T}) where {U,D,T} = TraceMesh(mesh(a),direction(a).+Ref(b)) +(a::TraceMesh,b::SVector) = TraceMesh(mesh(a),a.direction+b) +(a::SVector,b::TraceMesh) = b+a +CompScienceMeshes.indices(t::TraceMesh,i::Int) = CompScienceMeshes.indices(mesh(t),i) +CompScienceMeshes.numvertices(t::TraceMesh) = CompScienceMeshes.numvertices(mesh(t)) +CompScienceMeshes.vertextype(t::TraceMesh) = CompScienceMeshes.vertextype(mesh(t)) +CompScienceMeshes.universedimension(t::TraceMesh) = CompScienceMeshes.universedimension(mesh(t)) mesh(p::OrientedMesh) = p.mesh mesh(p::TraceMesh) = p.mesh diff --git a/src/excitation.jl b/src/excitation.jl index 165894a7..cd46d5ca 100644 --- a/src/excitation.jl +++ b/src/excitation.jl @@ -15,13 +15,21 @@ Assemble the vector of test coefficients corresponding to functional """ function assemble(field::Functional, tfs; quadstrat=defaultquadstrat(field, tfs)) - + R = scalartype(tfs) b = zeros(Complex{R}, numfunctions(tfs)) store(v,m) = (b[m] += v) assemble!(field, tfs, store; quadstrat) return b end +function assemble(n::Number, tfs) + + R = scalartype(tfs) + + b = zeros(Complex{R}, numfunctions(tfs)) + fill!(b,n) + return b +end function assemble!(field::Functional, tfs::DirectProductSpace, store; quadstrat=defaultquadstrat(field, tfs)) diff --git a/src/integralop.jl b/src/integralop.jl index 7eb44b80..c38323b0 100644 --- a/src/integralop.jl +++ b/src/integralop.jl @@ -138,43 +138,43 @@ function assemblechunk_body!(biop, end end myid == 1 && println("") end -function assemblechunk_body!(biop, - test_shapes, test_elements::Vector{CompScienceMeshes.Simplex{3,2,1,3,U}}, test_assembly_data, - trial_shapes, trial_elements::Vector{CompScienceMeshes.Simplex{3,2,1,3,V}}, trial_assembly_data, - qd, zlocal, store; quadstrat) where {U,V} - - @info "triangle assemblechunk_body used" - myid = Threads.threadid() - myid == 1 && print(string(typeof(biop))*" dots out of 10: ") - todo, done, pctg = length(test_elements), 0, 0 - for (p,tcell) in enumerate(test_elements) - for (q,bcell) in enumerate(trial_elements) - - fill!(zlocal, 0) - if overlap(tcell,bcell) - momintegrals_overlap!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, quadstrat) - else - qrule = quadrule(biop, test_shapes, trial_shapes, p, tcell, q, bcell, qd, quadstrat) - momintegrals!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, qrule) - end - I = length(test_assembly_data[p]) - J = length(trial_assembly_data[q]) - for j in 1 : J, i in 1 : I - zij = zlocal[i,j] - for (n,b) in trial_assembly_data[q][j] - zb = zij*b - for (m,a) in test_assembly_data[p][i] - store(a*zb, m, n) - end end end end - - done += 1 - new_pctg = round(Int, done / todo * 100) - if new_pctg > pctg + 9 - myid == 1 && print(".") - pctg = new_pctg - end end - myid == 1 && println("") -end +# function assemblechunk_body!(biop, +# test_shapes, test_elements::Vector{CompScienceMeshes.Simplex{3,2,1,3,U}}, test_assembly_data, +# trial_shapes, trial_elements::Vector{CompScienceMeshes.Simplex{3,2,1,3,V}}, trial_assembly_data, +# qd, zlocal, store; quadstrat) where {U,V} + +# @info "triangle assemblechunk_body used" +# myid = Threads.threadid() +# myid == 1 && print(string(typeof(biop))*" dots out of 10: ") +# todo, done, pctg = length(test_elements), 0, 0 +# for (p,tcell) in enumerate(test_elements) +# for (q,bcell) in enumerate(trial_elements) + +# fill!(zlocal, 0) +# if overlap(tcell,bcell) +# momintegrals_overlap!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, quadstrat) +# else +# qrule = quadrule(biop, test_shapes, trial_shapes, p, tcell, q, bcell, qd, quadstrat) +# momintegrals!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, qrule) +# end +# I = length(test_assembly_data[p]) +# J = length(trial_assembly_data[q]) +# for j in 1 : J, i in 1 : I +# zij = zlocal[i,j] +# for (n,b) in trial_assembly_data[q][j] +# zb = zij*b +# for (m,a) in test_assembly_data[p][i] +# store(a*zb, m, n) +# end end end end + +# done += 1 +# new_pctg = round(Int, done / todo * 100) +# if new_pctg > pctg + 9 +# myid == 1 && print(".") +# pctg = new_pctg +# end end +# myid == 1 && println("") +# end function assemblechunk_body_test_refines_trial!(biop, test_functions, test_charts, test_assembly_data, test_cells, diff --git a/src/quadrature/doublenumsauterqstrat.jl b/src/quadrature/doublenumsauterqstrat.jl index 825cc5b6..2fa62f27 100644 --- a/src/quadrature/doublenumsauterqstrat.jl +++ b/src/quadrature/doublenumsauterqstrat.jl @@ -24,12 +24,12 @@ end function quadrule(op::IntegralOperator, g::RefSpace, f::RefSpace, i, τ, j, σ, qd, qs::DoubleNumSauterQstrat) - T = eltype(eltype(τ.vertices)) + T = eltype(eltype(verticeslist(τ))) hits = 0 dtol = 1.0e3 * eps(T) dmin2 = floatmax(T) - for t in τ.vertices - for s in σ.vertices + for t in verticeslist(τ) + for s in verticeslist(σ) d2 = LinearAlgebra.norm_sqr(t-s) dmin2 = min(dmin2, d2) hits += (d2 < dtol) diff --git a/test/runtests.jl b/test/runtests.jl index d661dafb..7a502e16 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -74,6 +74,7 @@ include("test_variational.jl") include("test_composed_operator.jl") include("test_momintegrals_overlap.jl") +inlcude("test_multi-trace_VP.jl") try Pkg.installed("BogaertInts10") diff --git a/test/test_multi-trace_VP.jl b/test/test_multi-trace_VP.jl new file mode 100644 index 00000000..eea76676 --- /dev/null +++ b/test/test_multi-trace_VP.jl @@ -0,0 +1,121 @@ +using BEAST +using CompScienceMeshes +using BlockArrays +using LinearAlgebra +# import Plots + +radius = 1.0 +hh=0.15 +ϵ0 = 8.854e-12 +μ0 = 4π*1e-7 +ϵr = 2.0 +μr = 3.0 +c = 1/√(ϵ0*μ0) +λ = 2.9979563769321627 +ω = 2π*c/λ + +k0 = ω*sqrt(ϵ0*μ0) +T = boundary(CompScienceMeshes.tetmeshsphere(radius,hh)) + +S = BEAST.HOM(T,ϵ0*ϵr,μ0*μr,ω) +F = BEAST.FreeSpace(ϵ0,μ0,ω) +world = BEAST.create_world([2,0],[S,F]) +strat = BEAST.VP() +BEAST.assign_basis!(world,strat) + +lhs = BEAST.discretise_lhs(world,strat) + +A(x) = [1.0,0.0,0.0]*1im/ω*exp(-1.0im*k0*x[3]) +∇xA(x) = [0.0,1.0,0.0]*k0/ω*exp(-1.0im*k0*x[3]) +∇A(x) = 0.0+0.0im + +ex = BEAST.VPExcitation(A,∇xA,∇A,[2]) +rhs = BEAST.discretise_rhs(world,ex,strat) + +t =lhs[1]+lhs[2] +u = BEAST.gmres_ch(rhs[1]+rhs[2],t,world.trialdirectproductspace) + +Bf = BEAST.BField(world,u[1],[1,2]) +nx, nz = 100, 100 +xs, zs = range(-4,stop=4,length=nx), range(-6,stop=6,length=nz) +pts = [point(0,x,z) for x in xs, z in zs] + +BField = BEAST.calculate_field(pts,Bf,strat) +# display(Plots.heatmap(xs, zs, real.(getindex.(BField.field,2).+getindex.(∇xA.(pts),2)),show=true)) +# display(Plots.heatmap(xs, zs, imag.(getindex.(BField.field,2).+getindex.(∇xA.(pts),2)),show=true)) + + + + + + +function nearfield(um,uj,Xm,Xj,κ,η,points, + Einc=(x->point(0,0,0)), + Hinc=(x->point(0,0,0))) + + K = BEAST.MWDoubleLayerField3D(wavenumber=κ) + T = BEAST.MWSingleLayerField3D(wavenumber=κ) + + Em = potential(K, points, um, Xm) + Ej = potential(T, points, uj, Xj) + E = -Em + η * Ej + Einc.(points) + + Hm = potential(T, points, um, Xm) + Hj = potential(K, points, uj, Xj) + H = 1/η*Hm + Hj + Hinc.(points) + + return E, H +end + + + +X = raviartthomas(T) + +κ, η = ω/c, √(μ0/ϵ0) +κ′, η′ = κ*√(ϵr*μr), η*√(μr/ϵr) + +T = Maxwell3D.singlelayer(wavenumber=κ) +T′ = Maxwell3D.singlelayer(wavenumber=κ′) +K = Maxwell3D.doublelayer(wavenumber=κ) +K′ = Maxwell3D.doublelayer(wavenumber=κ′) + +E = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=κ) +H = -1/(im*κ*η)*curl(E) + +e = (n × E) × n +h = (n × H) × n + +@hilbertspace j m +@hilbertspace k l + +α, α′ = 1/η, 1/η′ +pmchwt = @discretise( + (η*T+η′*T′)[k,j] - (K+K′)[k,m] + + (K+K′)[l,j] + (α*T+α′*T′)[l,m] == -e[k] - h[l], + j∈X, m∈X, k∈X, l∈X) + +uu = solve(pmchwt) + +import Base.Threads: @spawn +task1 = @spawn nearfield(uu[m],uu[j],X,X,κ,η,pts,E,H) +task2 = @spawn nearfield(-uu[m],-uu[j],X,X,κ′,η′,pts) + +E_ex, H_ex = fetch(task1) +E_in, H_in = fetch(task2) + +B_tot = H_in*μ0*μr + H_ex*μ0 + +# display(Plots.heatmap(xs, zs, real.(getindex.(B_tot,2)))) +# display(Plots.heatmap(xs, zs, imag.(getindex.(B_tot,2)))) + +# maximum(norm.(B_tot-BField.field-∇xA.(pts))./norm.(B_tot)) + +# display(Plots.heatmap(xs,zs,norm.(B_tot-BField.field-∇xA.(pts))./maximum(norm.(B_tot)))) +# display(Plots.heatmap(xs,zs,norm.(B_tot))) + +# import PlotlyJS + +# PlotlyJS.plot(PlotlyJS.heatmap(x=xs,y=zs,z=norm.(B_tot))) + +# old = 0.008153372950474812 +@test norm.(B_tot-BField.field-∇xA.(pts)))/sum(norm.(B_tot) < 0.01 \ No newline at end of file From e862e5f76070971d64d94f87d75b3ff75e843e52 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 18 Dec 2023 13:25:33 +0100 Subject: [PATCH 069/110] update --- src/composedoperator/composedoperator.jl | 84 +++++++++++++++++++++--- src/composedoperator/tracesimplex.jl | 2 +- src/excitation.jl | 35 ++++++++-- 3 files changed, 103 insertions(+), 18 deletions(-) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index ff3295c6..25d41351 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -28,9 +28,9 @@ const nt = TestNormal() const nb = TrialNormal() export nt export nb -struct Potential{T} <: AbstractOperator +struct Potential{T,M} <: AbstractOperator operator::T - surface::TraceMesh + surface::M end surface(p::Potential) = p.surface function Potential(linop::LinearCombinationOfOperators,surface::TraceMesh) @@ -41,16 +41,23 @@ function Potential(linop::LinearCombinationOfOperators,surface::TraceMesh) return out end -struct TraceOperator{T} <: AbstractOperator +struct TraceOperator{T,M} <: AbstractOperator operator::T - surface::TraceMesh + surface::M end function TraceOperator(linop::LinearCombinationOfOperators,surf::TraceMesh) out = ZeroOperator() for (op,coeff) in zip(linop.ops,linop.coeffs) out += coeff*TraceOperator(op,surf) end -return out + return out +end +function TraceOperator(linop::LinearCombinationOfOperators) + out = ZeroOperator() + for (op,coeff) in zip(linop.ops,linop.coeffs) + out += coeff*TraceOperator(op) + end + return out end surface(p::TraceOperator) = p.surface @@ -195,7 +202,7 @@ replace_normal_by_trialnormal(op::NormalVector) = TrialNormal() -function build_potential(op::ComposedOperator,surface::CompScienceMeshes.Mesh) +function build_potential(op::ComposedOperator,surface::CompScienceMeshes.AbstractMesh) newop = replace_normal_by_trialnormal(op) Potential(newop,TraceMesh(surface)) end @@ -203,6 +210,10 @@ function build_potential(op::ComposedOperator,surface::TraceMesh) newop = replace_normal_by_trialnormal(op) Potential(newop,surface) end +function build_potential(op::ComposedOperator) + newop = replace_normal_by_trialnormal(op) + Potential(newop,nothing) +end function γ(op::Operations) return get_constructor(op)(γ(op.lhs),γ(op.rhs)) @@ -225,6 +236,27 @@ function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# si end return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) end +function γₜ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# check_if_coincide(op.surface,surface) || return op.operator + newop = nt × (γ(op.operator) × nt) + return TraceOperator(Potential(newop,op.surface),sign) +end +function γₛ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# check_if_coincide(op.surface,surface) || return op.operator + newop = nt × γ(op.operator) + return TraceOperator(Potential(newop,op.surface),sign) +end +function γₙ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# check_if_coincide(op.surface,surface) || return op.operator + newop = nt ⋅ γ(op.operator) + return TraceOperator(Potential(newop,op.surface),sign) +end +function τ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# check_if_coincide(op.surface,surface) || return op.operator + newop = γ(op.operator) + return TraceOperator(Potential(newop,op.surface),sign) +end + function γ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = nt × (γ(op.operator) × nt) @@ -260,7 +292,7 @@ end function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator - newop = -nt × nt × γ(op.operator) + newop = -nt × (nt × γ(op.operator)) direction = [] for i in 1:numcells(surface) c = chart(surface,i) @@ -270,7 +302,7 @@ function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# end function γₜ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator - newop = -nt × nt × γ(op.operator) + newop = -nt × (nt × γ(op.operator)) direction = [] for i in 1:numcells(surface) c = chart(surface,i) @@ -440,6 +472,7 @@ function (op::TestNormal)(x,y,g) Ref(normal(x)) end function (op::TraceDirection)(x,y,g) + #println(direction(x)-direction(y)) Ref(approx_sign(dot(normal(x),(direction(x)-direction(y))))*normal(x)) end function (op::BasisFunction)(x,y,g) @@ -470,7 +503,7 @@ quaddata(op::ComposedOperatorIntegral,rs,els,qs::SingleNumQStrat) = quadpoints(r quadrule(op::ComposedOperatorIntegral,refspace,p,y,q,el,qdata,qs::SingleNumQStrat) = qdata[1,q] defaultquadstrat(op::ComposedOperatorIntegral, basis) = SingleNumQStrat(3) -defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(6,7,5,5,4,3) +defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(7,8,6,6,5,4) defaultquadstrat(op::ComposedOperatorLocal,testspace::Space,trialpsace::Space) = SingleNumQStrat(6) #sign_upon_permutation(op::ComposedOperator,I,J) = Combinatorics.levicivita(I)^count_test_normals(op)*Combinatorics.levicivita(J)^count_trial_normals(op) @@ -496,6 +529,16 @@ function assemble!(op::Potential, test_functions::Space, trial_functions::Space, assemble!(op.operator, test_functions, trial_functions, store, threading; quadstrat = quadstrat) end +function assemble!(op::Potential{T,Nothing}, test_functions::Space, trial_functions::Space, + store, threading = Threading{:multi}; + quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} + + surf = geometry(trial_functions) + trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) + + assemble!(op.operator, test_functions, trial_functions, store, threading; + quadstrat = quadstrat) +end function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; @@ -503,6 +546,8 @@ function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Sp dsurf = surface(op) surf = geometry(test_functions) + println(typeof(surf)) + println(typeof(mesh(dsurf))) @assert same_geometry(dsurf,surf) nsurf = mesh(dsurf) @@ -511,4 +556,23 @@ function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Sp assemble!(op.operator, test_functions, trial_functions, store, threading; quadstrat = quadstrat) end - +function assemble!(op::TraceOperator{T,Int}, test_functions::Space, trial_functions::Space, + store, threading = Threading{:multi}; + quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} + println("assemble") + surface = geometry(test_functions) + direction = [] + sign = op.surface + println("loop") + for i in 1:numcells(surface) + c = chart(surface,i) + push!(direction,sign*normal(c)/3) + end + println("hang1") + surf = TraceMesh(surface,direction) + println("ttt") + test_functions = redefine_geometrie(test_functions,surf) + println(typeof(op.operator)) + assemble!(op.operator, test_functions, trial_functions, store, threading; + quadstrat = quadstrat) +end diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index 97720859..3c448b9a 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -71,7 +71,7 @@ struct OrientedMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} end struct TraceMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} mesh::CompScienceMeshes.AbstractMesh{U,D1,T} - direction::SVector + direction end TraceMesh(a::CompScienceMeshes.AbstractMesh{U,D,T}) where {U,D,T} = TraceMesh(a,zeros(SVector{numcells(a),SVector{3,T}})) +(a::TraceMesh{U,D,T},b::SVector{3,T}) where {U,D,T} = TraceMesh(mesh(a),direction(a).+Ref(b)) diff --git a/src/excitation.jl b/src/excitation.jl index cd46d5ca..2344245f 100644 --- a/src/excitation.jl +++ b/src/excitation.jl @@ -1,7 +1,28 @@ - +import Base: +,*,- abstract type Functional end +struct LinearCombinationOfFunctionals{T} <: Functional + coeffs::Vector{T} + ops::Vector +end + ++(a::LinearCombinationOfFunctionals,b::LinearCombinationOfFunctionals) = LinearCombinationOfFunctionals([a.coeffs;b.coeffs],[a.ops;b.ops]) ++(a::LinearCombinationOfFunctionals,b::Functional) = LinearCombinationOfFunctionals([a.coeffs;[1.0]],[a.ops;[b]]) ++(b::Functional,a::LinearCombinationOfFunctionals) = a+b ++(b::Functional,a::Functional) = LinearCombinationOfFunctionals([1.0,1.0],[a,b]) +*(n::Number,a::Functional) = LinearCombinationOfFunctionals([n],[a]) +*(n::Number,a::LinearCombinationOfFunctionals) = LinearCombinationOfFunctionals(a.coeffs*n,a.ops) +scalartype(a::LinearCombinationOfFunctionals{T}) where {T} = promote_type(T,scalartype.(a.ops)...) +function assemble(field::LinearCombinationOfFunctionals,tfs; + quadstrat=defaultquadstrat(field, tfs)) + out = [] + for (c,func) in zip(field.coeffs,field.ops) + push!(out,c*assemble(func,tfs;quadstrat=quadstrat)) + end + return sum(out) +end + defaultquadstrat(fn::Functional, basis) = SingleNumQStrat(8) quaddata(fn::Functional, refs, cells, qs::SingleNumQStrat) = quadpoints(refs, cells, [qs.quad_rule]) @@ -22,14 +43,14 @@ function assemble(field::Functional, tfs; assemble!(field, tfs, store; quadstrat) return b end -function assemble(n::Number, tfs) +# function assemble(n::Number, tfs) - R = scalartype(tfs) +# R = scalartype(tfs) - b = zeros(Complex{R}, numfunctions(tfs)) - fill!(b,n) - return b -end +# b = zeros(Complex{R}, numfunctions(tfs)) +# fill!(b,n) +# return b +# end function assemble!(field::Functional, tfs::DirectProductSpace, store; quadstrat=defaultquadstrat(field, tfs)) From 6d079ed72b0896efb48140cb7c76e4dbfa60c469 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 18 Dec 2023 14:18:54 +0100 Subject: [PATCH 070/110] update --- Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Project.toml b/Project.toml index 7b1adabe..3a11f7b3 100644 --- a/Project.toml +++ b/Project.toml @@ -14,6 +14,7 @@ Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838" FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" +GmshTools = "82e2f556-b1bd-5f1a-9576-f93c0da5f0ee" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" Lazy = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" From 1b0e763e81b36394dd8fc13a63052768c4f6def6 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 18 Dec 2023 14:22:08 +0100 Subject: [PATCH 071/110] adding multie-trace support --- .gitignore | 2 +- src/multi-trace/PMCHWT.jl | 0 src/multi-trace/VectorPotential.jl | 443 ++++++++++++++++++ src/multi-trace/efie.jl | 0 src/multi-trace/interactions.jl | 414 ++++++++++++++++ src/multi-trace/mfie.jl | 0 .../multi-trace-old/configuration.jl | 272 +++++++++++ .../design of the multi-trace approach.txt | 11 + .../multi-trace-old/interactions.jl | 238 ++++++++++ .../multi-trace-old/postprocessing.jl | 118 +++++ src/multi-trace/postprocessing.jl | 81 ++++ src/multi-trace/test_multi-trace_VP.jl | 121 +++++ 12 files changed, 1699 insertions(+), 1 deletion(-) create mode 100644 src/multi-trace/PMCHWT.jl create mode 100644 src/multi-trace/VectorPotential.jl create mode 100644 src/multi-trace/efie.jl create mode 100644 src/multi-trace/interactions.jl create mode 100644 src/multi-trace/mfie.jl create mode 100644 src/multi-trace/multi-trace-old/configuration.jl create mode 100644 src/multi-trace/multi-trace-old/design of the multi-trace approach.txt create mode 100644 src/multi-trace/multi-trace-old/interactions.jl create mode 100644 src/multi-trace/multi-trace-old/postprocessing.jl create mode 100644 src/multi-trace/postprocessing.jl create mode 100644 src/multi-trace/test_multi-trace_VP.jl diff --git a/.gitignore b/.gitignore index 7f5faa08..a023f4f4 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,4 @@ profile/ programs/ results/ src/todo.txt -src/multi-trace + diff --git a/src/multi-trace/PMCHWT.jl b/src/multi-trace/PMCHWT.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/multi-trace/VectorPotential.jl b/src/multi-trace/VectorPotential.jl new file mode 100644 index 00000000..8726b47e --- /dev/null +++ b/src/multi-trace/VectorPotential.jl @@ -0,0 +1,443 @@ +# TODO +# Make it possible to measure the complement error +# Cleanup the code, different file for post processing +# other branch Make connection with single-layer operator in different file called: connections with maxwell3D +# later Make PMCHWT, EFIE, MFIE description in the same way +# Include PEC +# Write test files +# Niet plat ding in sheets steken, halve sfeer. --> werkt (hier valt verschil efie-cfie mss nog te halen) +struct PRECVP <: Interaction + trace::Int +end +PRECVP() = PRECVP(1) + +function testbasis(obj::Object{T}, ::VP) where {T <: HOM} + Γ = obj.type.mesh + x1 = raviartthomas(Γ) + x2 = BEAST.lagrangec0d1(Γ) + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x1,x2,x3,x4]) +end + +function trialbasis(obj::Object{T}, ::VP) where {T <: HOM} + Γ = obj.type.mesh + x1 = raviartthomas(Γ) + x2 = BEAST.lagrangec0d1(Γ) + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x1,x2,x3,x4]) +end +function testbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} + Γ = obj.type.mesh + x1 = buffachristiansen(Γ) + x2 = BEAST.lagrangec0d1(Γ) + x3 = buffachristiansen(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x1,x2,x3,x4]) +end + +function trialbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} + Γ = obj.type.mesh + x1 = buffachristiansen(Γ) + x2 = BEAST.lagrangec0d1(Γ) + x3 = buffachristiansen(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x1,x2,x3,x4]) +end + +function testbasis(obj::Object{T}, ::VP) where {T <: PECEFIE} + Γ = obj.type.mesh + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end + +function trialbasis(obj::Object{T}, ::VP) where {T <: PECEFIE} + Γ = obj.type.mesh + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end +function testbasis(obj::Object{T}, ::VP) where {T <: PECMFIE} + Γ = obj.type.mesh + x3 = buffachristiansen(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end + +function trialbasis(obj::Object{T}, ::VP) where {T <: PECMFIE} + Γ = obj.type.mesh + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end + +function testbasis(obj::Object{T}, ::PRECVP) where {T <: PECEFIE} + Γ = obj.type.mesh + x3 = buffachristiansen(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end + +function trialbasis(obj::Object{T}, ::PRECVP) where {T <: PECEFIE} + Γ = obj.type.mesh + x3 = buffachristiansen(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end + +function testbasis(obj::Object{T}, ::PRECVP) where {T <: PECMFIE} + Γ = obj.type.mesh + x3 = buffachristiansen(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end + +function trialbasis(obj::Object{T}, ::PRECVP) where {T <: PECMFIE} + Γ = obj.type.mesh + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end + +# function interaction(testobj::Union{Object,Inside}, +# trialobj::Inside{Object{<:Union{FreeSpace,HOM}}}, embobj::Object, strat::VP) + +# a = -[1 0 0 0; +# 0 1 0 0; +# 0 0 mu(trialobj)/mu(parent(trialobj)) 0; +# 0 0 0 epsilon(parent(trialobj.object))/epsilon(trialobj)] +# return interaction(testobj,trialobj.object,embobj,strat)*a +# end + + +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::Inside,trialtype,strat::Union{PRECVP,VP}; sign=1) + a = [1 0 0 0; + 0 1 0 0; + 0 0 mu(testobj)/mu(parent(testobj)) 0; + 0 0 0 epsilon(parent(testobj))/epsilon(testobj)] + a * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign) +end + +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::PECCFIE,trialtype,strat::Union{PRECVP,VP}; sign=1) + + testtype.alpha*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[1:2,:]+ + (1-testtype.alpha)*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[3:4,:] +end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::PECEFIE,trialtype,strat::Union{PRECVP,VP}; sign=1) + + interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[1:2,:] +end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::PECMFIE,trialtype,strat::Union{PRECVP,VP}; sign=1) + interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[3:4,:] +end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::ObjectType,trialtype::Inside,strat::Union{PRECVP,VP}; sign=1) + a = -[1 0 0 0; + 0 1 0 0; + 0 0 mu(trialobj)/mu(parent(trialobj)) 0; + 0 0 0 epsilon(parent(trialobj))/epsilon(trialobj)] + interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign)*a +end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::ObjectType,trialtype::PEC,strat::Union{PRECVP,VP}; sign=1) + interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign)[:,3:4] +end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP}; sign=1) + interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign) +end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::HOM,trialtype,strat::Union{PRECVP,VP}; sign=1) + interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign) +end +# function interaction(testobj::Object, trialobj::Object, embobj::Object, +# testtype::ObjectType,trialtype::ObjectType,strat::VP; sign=1) +# trace = sign*strat.trace +# k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) +# G = BEAST.greenhh3d(wavenumber=k) +# gradG = BEAST.∇(G) + +# bs = geometry(trialobj) +# ts = geometry(testobj) + +# ∇Gx = BEAST.build_potential(gradG×B,bs) +# Gn = BEAST.build_potential(G*(n*B),bs) +# #Gnx = BEAST.build_potential(G*(n × B),bs) +# ∇G = BEAST.build_potential(gradG*B,bs) +# ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) +# ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) + +# Gr = BEAST.build_potential(G*B,bs) +# ∇G∇B = BEAST.build_potential(gradG*div(B),bs) +# ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) + +# #gebruik gamma^c --> sign = + +# # #without extra ncross +# # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); +# # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); +# # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); +# # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] +# # #with extra ncross +# int = [-γₜ(∇Gx,ts,trace) γₜ(Gn,ts,trace) -γₜ(Gr,ts,trace) γₜ(∇G,ts,trace); +# ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); +# -γₜ(∇G∇B,ts,trace)-k^2*γₜ(Gr,ts,trace) γₜ(∇Gxn,ts,trace) -γₜ(∇Gx,ts,trace) ZeroOperator(); +# γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] +# return int +# end +function interaction(testobj::Object, trialobj::Object, embobj::Object, + testtype::ObjectType,trialtype::ObjectType,strat::VP; sign=1) + trace = sign*strat.trace + k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + + + ∇Gx = BEAST.build_potential(gradG×B) + Gn = BEAST.build_potential(G*(n*B)) + #Gnx = BEAST.build_potential(G*(n × B),bs) + ∇G = BEAST.build_potential(gradG*B) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B)) + ∇Gdot = BEAST.build_potential(B ⋅ gradG) + + Gr = BEAST.build_potential(G*B,bs) + ∇G∇B = BEAST.build_potential(gradG*div(B)) + ∇Gxn = BEAST.build_potential(gradG×(n*B)) + + #gebruik gamma^c --> sign = + + # #without extra ncross + # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); + # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); + # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); + # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] + # #with extra ncross + int = [-γₜ(∇Gx,trace) γₜ(Gn,trace) -γₜ(Gr,trace) γₜ(∇G,trace); + ZeroOperator() -τ(∇Gdotn,trace) τ(∇Gdot,trace) k^2*τ(Gr,trace); + -γₜ(∇G∇B,trace)-k^2*γₜ(Gr,trace) γₜ(∇Gxn,trace) -γₜ(∇Gx,trace) ZeroOperator(); + γₙ(∇Gx,trace) -γₙ(Gn,trace) γₙ(Gr,trace) -γₙ(∇G,trace)] + return int +end + +function interaction(testobj::Object, trialobj::Object, embobj::Object, + testtype::ObjectType,trialtype::ObjectType,strat::PRECVP; sign=1) + trace = sign*strat.trace + k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + + bs = barycentric_refinement(geometry(trialobj); sort = :spacefillingcurve) + ts = barycentric_refinement(geometry(testobj); sort = :spacefillingcurve) + + bss = geometry(trialobj) + tss = geometry(testobj) + + + ∇Gx = BEAST.build_potential(gradG×B,bs)# + Gn = BEAST.build_potential(G*(n*B),bss)# + #Gnx = BEAST.build_potential(G*(n × B),bs) + ∇G = BEAST.build_potential(gradG*B,bss)# + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bss)# + ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs)# + + Gr = BEAST.build_potential(G*B,bs)# + Grs = BEAST.build_potential(G*B,bss)# + ∇G∇B = BEAST.build_potential(gradG*div(B),bs)# + ∇Gxn = BEAST.build_potential(gradG×(n*B),bss)# + + int = [-γₜ(∇Gx,ts,trace) γₜ(Gn,ts,trace) -γₜ(Gr,ts,trace) γₜ(∇G,ts,trace); + ZeroOperator() -τ(∇Gdotn,tss,trace) τ(∇Gdot,tss,trace) k^2*τ(Grs,tss,trace); + -γₜ(∇G∇B,ts,trace)-k^2*γₜ(Gr,ts,trace) γₜ(∇Gxn,ts,trace) -γₜ(∇Gx,ts,trace) ZeroOperator(); + γₙ(∇Gx,tss,trace) -γₙ(Gn,tss,trace) γₙ(Gr,tss,trace) -γₙ(∇G,tss,trace)] + return int +end +function _identity(::ObjectType,strat::PRECVP) + [NCross() ZeroOperator() ZeroOperator() ZeroOperator(); + ZeroOperator() Identity() ZeroOperator() ZeroOperator(); + ZeroOperator() ZeroOperator() NCross() ZeroOperator(); + ZeroOperator() ZeroOperator() ZeroOperator() Identity()] +end +_identity(p::PEC,strat::PRECVP) = _identity(p.inside,strat)[1:2,1:2] + +function identity(objtype::ObjectType,strat::VP) + [NCross() ZeroOperator() ZeroOperator() ZeroOperator(); + ZeroOperator() Identity() ZeroOperator() ZeroOperator(); + ZeroOperator() ZeroOperator() NCross() ZeroOperator(); + ZeroOperator() ZeroOperator() ZeroOperator() Identity()] +end +function identity(objtype::ObjectType,strat::PRECVP) + -[NCross() ZeroOperator() ZeroOperator() ZeroOperator(); + ZeroOperator() Identity() ZeroOperator() ZeroOperator(); + ZeroOperator() ZeroOperator() NCross() ZeroOperator(); + ZeroOperator() ZeroOperator() ZeroOperator() Identity()] +end +function identity(objtype::PECCFIE,strat::Union{PRECVP,VP}) + (1-objtype.alpha)*identity(objtype.inside,strat)[3:4,3:4] +end +function identity(objtype::PECMFIE,strat::Union{PRECVP,VP}) + identity(objtype.inside,strat)[3:4,3:4] +end +function identity(objtype::PECEFIE,strat::Union{PRECVP,VP}) + [ZeroOperator() ZeroOperator(); + ZeroOperator() ZeroOperator()] +end +identity(o::HOM,strat::Union{PRECVP,VP}) = identity(o.inside,strat) +# function interaction(testobj::Inside{Object{<:Union{FreeSpace,HOM}}}, +# trialobj::Object, embobj::Object, +# strat::VP) + +# trace = -strat.trace +# a = [1 0 0 0; +# 0 1 0 0; +# 0 0 mu(testobj)/mu(parent(testobj)) 0; +# 0 0 0 epsilon(parent(testobj.object))/epsilon(testobj)] + +# k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) +# G = BEAST.greenhh3d(wavenumber=k) +# gradG = BEAST.∇(G) + +# bs = geometry(trialobj) +# ts = geometry(testobj) + +# ∇Gx = BEAST.build_potential(gradG×B,bs) +# Gn = BEAST.build_potential(G*(n*B),bs) +# #Gnx = BEAST.build_potential(G*(n × B),bs) +# ∇G = BEAST.build_potential(gradG*B,bs) +# ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) +# ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) + +# Gr = BEAST.build_potential(G*B,bs) +# ∇G∇B = BEAST.build_potential(gradG*div(B),bs) +# ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) + +# #gebruik gamma^c --> sign = - +# int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); +# ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); +# γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); +# γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] +# return (a^-1)*int +# end + +# function interaction(testobj::Object, trialobj::Object, embobj::Object, strat::VP) +# trace = strat.trace +# k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) +# G = BEAST.greenhh3d(wavenumber=k) +# gradG = BEAST.∇(G) + +# bs = geometry(trialobj) +# ts = geometry(testobj) + +# ∇Gx = BEAST.build_potential(gradG×B,bs) +# Gn = BEAST.build_potential(G*(n*B),bs) +# #Gnx = BEAST.build_potential(G*(n × B),bs) +# ∇G = BEAST.build_potential(gradG*B,bs) +# ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) +# ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) + +# Gr = BEAST.build_potential(G*B,bs) +# ∇G∇B = BEAST.build_potential(gradG*div(B),bs) +# ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) + +# #gebruik gamma^c --> sign = + +# int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); +# ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); +# γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); +# γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] +# return int + +# end + +function excitation(obj::Object,emb::Object,objtype::ObjectType,ex::VPExcitation,strat::VP) + emb.index ∉ ex.objectids && return [0,0,0,0] + a = [-1* ((n × FunctionExcitation{ComplexF64}(ex.A))×n), + FunctionExcitation{ComplexF64}(ex.divA), + -1* ((n × FunctionExcitation{ComplexF64}(ex.curlA))×n), + NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(ex.A))] + @warn "fix this type" + return a +end +function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation,strat::VP) + a = [1 0 0 0; + 0 1 0 0; + 0 0 mu(testobj)/mu(parent(testobj)) 0; + 0 0 0 epsilon(parent(testobj))/epsilon(testobj)] + return a*excitation(testobj,emb,objtype.inside,ex,strat) +end +function excitation(testobj::Object,emb::Object,objtype::PECCFIE,ex::VPExcitation,strat::VP) + + objtype.alpha*excitation(testobj,emb,objtype.inside,ex,strat)[1:2]+ + (1-objtype.alpha)*excitation(testobj,emb,objtype.inside,ex,strat)[3:4] +end +function excitation(testobj::Object,emb::Object,objtype::PECEFIE,ex::VPExcitation,strat::VP) + + excitation(testobj,emb,objtype.inside,ex,strat)[1:2] +end +function excitation(testobj::Object,emb::Object,objtype::PECMFIE,ex::VPExcitation,strat::VP) + + excitation(testobj,emb,objtype.inside,ex,strat)[3:4] +end +excitation(testobj::Object,emb::Object,objtype::HOM,ex::VPExcitation,strat::VP) = excitation(testobj,emb,objtype.inside,ex,strat) + + +### Post Processing +function list_of_operators(embobj::Object,basisobj::Object{<:HOM},::AField,::VP) + k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + + ∇Gx = gradG×B + Gn = G*(nb*B) + ∇G = gradG*B + Gr = G*B + + return [∇Gx, -Gn, Gr, -∇G] +end + +function list_of_operators(embobj::Object,basisobj::Object{<:HOM}, ::BField, ::VP) + k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + + ∇Gx = gradG×B + Gr = G*B + ∇G∇B = gradG*div(B) + ∇Gxn = gradG×(nb*B) + return [∇G∇B+k^2*Gr, -∇Gxn, ∇Gx, ZeroOperator()] +end +function list_of_operators(embobj::Object,basisobj::Object{<:PEC},::AField,::VP) + k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + + ∇Gx = gradG×B + Gn = G*(nb*B) + ∇G = gradG*B + Gr = G*B + + return [Gr, -∇G] +end + +function list_of_operators(embobj::Object,basisobj::Object{<:PEC}, ::BField, ::VP) + k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + + ∇Gx = gradG×B + Gr = G*B + ∇G∇B = gradG*div(B) + ∇Gxn = gradG×(nb*B) + return [∇Gx, ZeroOperator()] +end +function transform(obj,strat::VP) + a = -[1 0 0 0; + 0 1 0 0; + 0 0 mu(obj)/mu(parent(obj)) 0; + 0 0 0 epsilon(parent(obj))/epsilon(obj)] + return a +end + + diff --git a/src/multi-trace/efie.jl b/src/multi-trace/efie.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl new file mode 100644 index 00000000..50620e72 --- /dev/null +++ b/src/multi-trace/interactions.jl @@ -0,0 +1,414 @@ +using BEAST +using Combinatorics +import Base: +,-,* +import Base +@hilbertspace b[1:4] +@hilbertspace t[1:4] + +# nodig: 1) functies die gegeven 2 objecten(volumes) en hilbertspacede linforms teruggeven. +# ok 2) volumes hebben een type, PEC of HOMOGEEN +# 3) maak een interactie aan en geef deze ook telkens mee, vb: mfie, efie, pmchwt, cfie, vectorpotential +# ok 4) multi-trace struct als wrapper voor deze types +# ok 5) normal is outward pointing --> opslaan in object of het een outward of inward normal object is +# 6) detector for this normal +# ok 7) functie die matrix kan maken voor gegeven object. +# 8) functie die matrices combineert in 1 grote. +# 9) preconditioner als wrapper +# 10) post processing of a volume + +@hilbertspace a +@hilbertspace b + +@hilbertspace c +@hilbertspace d + +t = BEAST.Identity() +q = t[a,b] + +struct Zero end ++(a,b::Zero) = a ++(a::Zero,b) = b ++(a::Zero,b::Zero) = a +*(a::Zero,b) = a +*(b,a::Zero) = a + +struct ObjectType end + +struct Inside{T} + inside::T +end +struct PECEFIE + mesh + ω + inside +end +PECEFIE(a,b) = PECEFIE(a,b,ObjectType()) +struct PECMFIE + mesh + ω + inside +end +PECMFIE(a,b) = PECMFIE(a,b,ObjectType()) +struct PECCFIE + mesh + ω + alpha + inside +end +PECCFIE(a,b,c) = PECCFIE(a,b,c,ObjectType()) +PEC = Union{PECEFIE,PECMFIE} +struct CavityPEC + mesh + ω + inside + +end + + +struct HOM{T} + mesh + ϵ::T + μ::T + ω::T + inside + +end +HOM(a,b,c,d) = HOM(a,b,c,d,ObjectType()) +struct FreeSpace{T} + ϵ::T + μ::T + ω::T + inside +end +FreeSpace(a,b,c) = FreeSpace(a,b,c,ObjectType()) +mutable struct Object{T} + index::Int + type::T + children::Vector{} + parent +end +children(obj::Object) = obj.children +parent(obj::Object) = obj.parent + +mutable struct World + objecttree + objectarray + testhilbertspace + trialhilbertspace + testhilbertspacemap# given an index yields basis index, TODO write function that can be used in both directions + trialhilbertspacemap + testdirectproductspace + trialdirectproductspace +end +World(a,b,c,d,e,f) = World(a,b,c,d,e,f,nothing,nothing) +Base.copy(w::World) = World(w.objecttree,w.objectarray, +w.testhilbertspace,w.trialhilbertspace, +w.testhilbertspacemap,w.trialhilbertspacemap, +w.testdirectproductspace,w.trialdirectproductspace) + +function add_child!(obj,child) + push!(obj.children,child) +end +function add_parent!(obj,parent) + obj.parent = parent +end +""" + +parent at 0 means no parent. +""" +function create_world(embeddings::Vector{Int}, objecttypes::Vector) + @assert length(embeddings) == length(objecttypes) + + objectarray = [Object(i,objecttypes[i],[],nothing) for i in 1:length(objecttypes)] + testhilbertspacemap = zeros(Int,length(embeddings)) + trialhilbertspacemap = zeros(Int,length(embeddings)) + #embeddings[embeddings.==0] = embeddings[embeddings.==0] .+ length(embeddings) .+ 1 + counter = 1 + for (ind,parent) in enumerate(embeddings[1:end]) + parent==0 && continue + add_child!(objectarray[parent],objectarray[ind]) + add_parent!(objectarray[ind],objectarray[parent]) + if typeof(objecttypes[ind]) != FreeSpace + testhilbertspacemap[ind] = counter + trialhilbertspacemap[ind] = counter + counter += 1 + end + end + testhilbertspace = BEAST.hilbertspace(:t, counter-1) + trialhilbertspace = BEAST.hilbertspace(:b, counter-1) + return World(objectarray[end],objectarray,testhilbertspace,trialhilbertspace,testhilbertspacemap,trialhilbertspacemap) +end + +function assign_basis!(w::World, strat) + w.testdirectproductspace = BEAST.DirectProductSpace([testbasis(w.objectarray[i],strat) for (i,j) in enumerate(w.testhilbertspacemap) if j!=0]) + w.trialdirectproductspace = BEAST.DirectProductSpace([trialbasis(w.objectarray[i],strat) for (i,j) in enumerate(w.trialhilbertspacemap) if j!=0]) +end + + +abstract type Interaction end + +struct VP <: Interaction + trace::Int +end # VectorPotential + +VP() = VP(1) + +abstract type Excitation end +struct EHExcitation <: Excitation end +struct CurrentExcitation <: Excitation end +struct VPExcitation <: Excitation + A + curlA + divA + objectids +end + + + +# struct Outside{T} +# object::T +# end +parent(obj::Inside) = parent(obj.object) + +epsilon(o::Union{HOM,FreeSpace}) = o.ϵ +epsilon(o::Object) = epsilon(o.type) +epsilon(o::Inside) = epsilon(o.inside) + +mu(o::Union{HOM,FreeSpace}) = o.μ +mu(o::Object) = mu(o.type) +mu(o::Inside) = mu(o.inside) + +omega(o::Union{HOM,FreeSpace,PEC}) = o.ω +omega(o::Object) = omega(o.type) +omega(o::Inside) = omega(o.inside) + +geometry(o::Object) = geometry(o.type) +geometry(o::Union{HOM,FreeSpace,PEC}) = o.mesh +geometry(o::Inside) = geometry(o.inside) + +function matrix_to_bilform(mat) + nrows,ncols = size(mat) + tin = BEAST.hilbertspace(:tin,nrows) + bin = BEAST.hilbertspace(:bin,ncols) + terms = [mat[i,j][tin[i],bin[j]] for i in 1:nrows, j in 1:ncols if typeof(mat[i,j]) != ZeroOperator] + if length(terms) > 0 + return sum(terms) + else + return ZeroOperator()[tin[1],bin[1]] + end +end + +function array_to_linform(array) + nrows = length(array) + tin = BEAST.hilbertspace(:tin,nrows) + println(sum([array[i][tin[i]] for i in 1:nrows])) + return sum([array[i][tin[i]] for i in 1:nrows]) +end + +# function discretise_rhs(w::World, ex::Excitation, strat::Interaction) +# out = [] +# l = length(w.objectarray)-1 # no bases for the free space +# test = [] +# testb = BEAST.DirectProductSpace([testbasis(obj,strat) for obj in w.objectarray]) +# for obj in w.objectarray + +# if !inside_interaction_matters(obj.type) +# push!(out,0) +# continue +# end +# t = test[obj.index] +# lins = array_to_linform(excitation(obj.type,obj.type,ex,strat))[t] +# for c in children(obj) +# tc = test[c.index] +# lins += array_to_linform(excitation(c.type,obj.type,ex,strat))[tc] +# end +# push!(out,assemble(lins,testb)) +# end +# return out +# end + +function discretise_rhs(w::World, ex::Excitation, strat::Interaction) + tesths = w.testhilbertspace + + testb = w.testdirectproductspace + + maptesths = w.testhilbertspacemap + + out = _discretise_rhs_matrix.(w.objectarray,Ref(tesths),Ref(testb),Ref(maptesths),Ref(ex),Ref(strat)) + return out +end +function _discretise_rhs_matrix(obj::Object{T},tesths,testb,mapt,ex,strat) where {T <: FreeSpace} + out = [] + for child in children(obj) + + u = tesths[mapt[child.index]] + + push!(out,array_to_linform(excitation(child,obj,child.type,ex,strat))[u]) + + end + x = assemble(sum(out),testb) + return x +end +function _discretise_rhs_matrix(obj::Object{T},tesths,testb,mapt,ex,strat) where {T <: HOM} + out = [] + push!(out,array_to_linform(excitation(obj,obj,Inside(obj.type),ex,strat))[tesths[mapt[obj.index]]]) + for child in children(obj) + u = tesths[mapt[child.index]] + push!(out,array_to_linform(excitation(child,obj,child.type,ex,strat))[u]) + end + s = sum(out) + return assemble(s,testb) +end +function _discretise_rhs_matrix(obj::Object{T},tesths,testb,mapt,ex,strat) where {T <: PEC} + return Zero() +end +function identity(w1::World,w2::World,strat) + t = w1.trialhilbertspace + b = w2.testhilbertspace + @assert length(t) == length(b) + bil = Zero() + + for (k,(tt,bb)) in enumerate(zip(t,b)) + ind = findfirst(==(k),w1.trialhilbertspacemap) + bil += matrix_to_bilform(_identity(w1.objectarray[ind].type,strat))[tt,bb] + end + println(t) + return assemble(bil,w1.trialdirectproductspace,w2.testdirectproductspace) +end + +function diag_prec(w::World, strat::Interaction) + l = length(w.objectarray)-1 # no bases for the free space + tesths = w.testhilbertspace + basishs = w.trialhilbertspace + testb = w.testdirectproductspace + trialb = w.trialdirectproductspace + maptesths = w.testhilbertspacemap + maptrialhs = w.trialhilbertspacemap + out = _diag_prec.(w.objectarray,Ref(tesths),Ref(basishs),Ref(testb),Ref(trialb),Ref(maptesths),Ref(maptrialhs),Ref(strat)) + return out + +end + +function discretise_lhs(w::World, strat::Interaction) + + l = length(w.objectarray)-1 # no bases for the free space + tesths = w.testhilbertspace + basishs = w.trialhilbertspace + testb = w.testdirectproductspace + trialb = w.trialdirectproductspace + maptesths = w.testhilbertspacemap + maptrialhs = w.trialhilbertspacemap + out = _discretise_lhs_matrix.(w.objectarray,Ref(tesths),Ref(basishs),Ref(testb),Ref(trialb),Ref(maptesths),Ref(maptrialhs),Ref(strat)) + return out +# returned the assambled matrices for each struct +end +function _discretise_lhs_matrix(obj::Object{<:HOM},tesths,basishs,testb,trialb,mapt,mapb,strat) + t = tesths[mapt[obj.index]] + b = basishs[mapb[obj.index]] + # bils = BEAST.BlockDiagonalOperator(Identity())[t,b] + bils = matrix_to_bilform(identity(obj.type,strat))[t,b] + println(bils) + bils -= matrix_to_bilform(interaction(obj,obj,obj,Inside(obj.type),Inside(obj.type),strat))[t,b] + for child in children(obj) + u = tesths[mapt[child.index]] + v = basishs[mapb[child.index]] + bils += matrix_to_bilform(identity(child.type,strat))[u,v] + bils -= matrix_to_bilform(interaction(obj,child,obj,Inside(obj.type),child.type,strat))[t,v] + bils -= matrix_to_bilform(interaction(child,obj,obj,child.type,Inside(obj.type),strat))[u,b] + bils -= matrix_to_bilform(interaction(child,child,obj,child.type,child.typ,strat))[u,v] + end + if length(children(obj)) > 1 + for (c1,c2) in combinations(children(obj),2) + t1 = tesths[mapt[c1.index]] + t2 = tesths[mapt[c2.index]] + b1 = basishs[mapb[c1.index]] + b2 = basishs[mapb[c2.index]] + bils -= matrix_to_bilform(interaction(c1,c2,obj,c1.type,c2.type,strat))[t1,b2] + bils -= matrix_to_bilform(interaction(c2,c1,obj,c1.type,c2.type,strat))[t2,b1] + end + end + println(typeof(bils.terms[1])) + println(typeof(testb.factors[1])) + return assemble(bils,testb,trialb) +end +function _diag_prec(obj::Object{<:HOM},tesths,basishs,testb,trialb,mapt,mapb,strat) + t = tesths[mapt[obj.index]] + b = basishs[mapb[obj.index]] + # bils = BEAST.BlockDiagonalOperator(Identity())[t,b] + bils = matrix_to_bilform(identity(obj.type,strat))[t,b] + println(bils) + bils -= matrix_to_bilform(interaction(obj,obj,obj,Inside(obj.type),Inside(obj.type),strat))[t,b] + for child in children(obj) + u = tesths[mapt[child.index]] + v = basishs[mapb[child.index]] + bils += matrix_to_bilform(identity(child.type,strat))[u,v] + bils -= matrix_to_bilform(interaction(child,child,obj,child.type,child.typ,strat))[u,v] + end + return assemble(bils,testb,trialb) +end +function _diag_prec(obj::Object{<:PEC},tesths,basishs,testb,trialb,mapt,mapb,strat) + return Zero() +end + +function _discretise_lhs_matrix(obj::Object{<:PEC},tesths,basishs,testb,trialb,mapt,mapb,strat) + return Zero() +end +function _discretise_lhs_matrix(obj::Object{<:FreeSpace},tesths,basishs,testb,trialb,mapt,mapb,strat) + bilslist = [] + for child in children(obj) + u = tesths[mapt[child.index]] + v = basishs[mapb[child.index]] + push!(bilslist,matrix_to_bilform(identity(child.type,strat))[u,v]) + push!(bilslist,-matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat))[u,v]) + end + bils = sum(bilslist) + if length(children(obj)) > 1 + for (c1,c2) in combinations(children(obj),2) + t1 = tesths[mapt[c1.index]] + t2 = tesths[mapt[c2.index]] + b1 = basishs[mapb[c1.index]] + b2 = basishs[mapb[c2.index]] + bils -= matrix_to_bilform(interaction(c1,c2,obj,c1.type,c2.type,strat))[t1,b2] + bils -= matrix_to_bilform(interaction(c2,c1,obj,c1.type,c2.type,strat))[t2,b1] + end + end + return assemble(bils,testb,trialb) +end +function _diag_prec(obj::Object{<:FreeSpace},tesths,basishs,testb,trialb,mapt,mapb,strat) + bilslist = [] + for child in children(obj) + u = tesths[mapt[child.index]] + v = basishs[mapb[child.index]] + push!(bilslist,matrix_to_bilform(identity(child.type,strat))[u,v]) + push!(bilslist,-matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat))[u,v]) + end + bils = sum(bilslist) + return assemble(bils,testb,trialb) +end + + + +# inside_interaction_matters(obj::PEC) = false +# inside_interaction_matters(obj::ObjectType) = true + +#create these type of functions +# function testbasis(obj::ObjectType,::VP) +# return +# end +# function trialbasis(obj::ObjectType,::VP) +# end + +# # function interaction(testobj::ObjectType,basisobj::Inside{PEC},embedobj::HOM,::VP) +# # return 0 +# # end + +# function interaction() + +# end + +# function excitation(testobj::ObjectType,embedobj::FreeSpace,ex::VPExcitation,::VP) + +# end +# excitation(testobj::ObjectType,embedobj::ObjectType,ex::VPExcitation,::VP) = 0 + + diff --git a/src/multi-trace/mfie.jl b/src/multi-trace/mfie.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/multi-trace/multi-trace-old/configuration.jl b/src/multi-trace/multi-trace-old/configuration.jl new file mode 100644 index 00000000..6443c14a --- /dev/null +++ b/src/multi-trace/multi-trace-old/configuration.jl @@ -0,0 +1,272 @@ +abstract type DomainData end +abstract type Domain{T<:DomainData} end +using PrettyTables +""" +A is the type of the test structure, B is the type of the trial structure, C the type of ths structure embedding +""" +struct Interaction{A,B,C}# wordt gecrieerd bij de itteratie over alle volumes. + config + testvol::A + trialvol::B + embedvol::C +end +# abstract type PhysicalInformation end #depends on the strategy +""" +subtypes of the NumericalStrategy type descirbe the followed strategy. for example a preconditioning strategy for a vector potential based problem, + a vector potential based problem, a fields based problem,... +""" +abstract type NumericalStrategy end + +export NumericalStrategy +mutable struct HomogeneousDomain <: DomainData +physicalinformation +testbasises +trialbasises +coeff +testindex +trialindex +HomogeneousDomain(a,b,c,d) = new(a,b,c,d,[],[]) +end + +struct BackgroundDomain <: DomainData + physicalinformation + coeff +end +physicalconstants(d::DomainData) = d.physicalinformation +physicalconstants(d::Domain) = physicalconstants(d.data) +testspace(d::DomainData) = d.testbasises +trialspace(d::DomainData) = d.trialbasises + +mutable struct SubDomain{T} <: Domain{T} + id::Int + children::Vector{Domain} + parent::Domain + data::T + excitation + results +end +mutable struct RootDomain{T} <: Domain{T} + id::Int + children::Vector{Domain} + data::T + excitation +end + +mutable struct Configuration #TODO add dict contining all subbasis info af touching objects + domains::Dict{Int,Domain} + root::RootDomain + touching::Dict{Tuple{Int,Int},Vector} + testdirectproductspace + trialdirectproductspace +end +Configuration(dom,root,touching) = Configuration(dom,root,touching,nothing,nothing) + + +function _adddomain(config::Configuration, newdom::Domain) + id = newdom.id + @assert !(id in keys(config.domains)) + dom = newdom.parent + config.domains[id] = newdom + for space in newdom.data.testbasises + config.testdirectproductspace = config.testdirectproductspace × space + push!(newdom.data.testindex,length(config.testdirectproductspace.factors)) + end + for space in newdom.data.trialbasises + config.trialdirectproductspace = config.trialdirectproductspace × space + push!(newdom.data.trialindex,length(config.trialdirectproductspace.factors)) + end + push!(dom.children,newdom) +end + +function _createdomain(config::Configuration,id::Int,parentid::Int,values;excitation) + dom = SubDomain(id,Domain[],config.domains[parentid],values::DomainData,excitation,[]) + return dom +end +function _createdomain(config::Configuration,id::Int,parentdom::Domain,values;excitation) + _createdomain(config,id,parentdom.id,values;excitation) +end + +function createdomain(config::Configuration,id::Int,parent::Union{Int,Domain},values::DomainData;excitation=Dict()) + _adddomain(config,_createdomain(config,id,parent,values;excitation)) +end +""" +a child of b +""" +function is_child_of(a,b) + return a∈b.children +end + +function brothers(a,b) +return is_child_of(a,b.parent) +end +function createconfiguration(data::BackgroundDomain,excitation=Dict()) + r = RootDomain(0,Domain[],data,excitation) + Configuration(Dict{Int,Domain}(0=>r),r,Dict{Tuple{Int,Int},Any}()) # typle of the indices, returns the spaces: [test1,trial1,test2,trial2] +end + +function createdomains(config::Configuration,confdict::Dict) end#the confdict is the dictionary containing the information about the mesh, physical parameters,... + +""" +all objects in a domain touch each other, not with subdomains, well with the boundary + +""" +function alltouching(config::Configuration) + for i in keys(config.domains) + #config.touching[(i,i)] = [config.domains[i].data.testbasises,config.domains[i].data.trialbasises,config.domains[i].data.testbasises,config.domains[i].data.trialbasises] + for child in config.domains[i].children + j = child.id + if typeof(config.domains[i]) <: SubDomain + config.touching[(i,j)] = [config.domains[i].data.testbasises,config.domains[i].data.trialbasises,child.data.testbasises,child.data.trialbasises] + config.touching[(j,i)] = [config.touching[(i,j)][3],config.touching[(i,j)][4],config.touching[(i,j)][1],config.touching[(i,j)][2]] + end + for child2 in config.domains[i].children + k = child2.id + config.touching[(j,k)] = [child.data.testbasises,child.data.trialbasises,child2.data.testbasises,child2.data.trialbasises] + config.touching[(k,j)] = [child2.data.testbasises,child2.data.trialbasises,child.data.testbasises,child.data.trialbasises] + end + end + end +end + +function (dom::Domain)(n::NormalVector,dom2::Domain) + if dom==dom2 + return 1.0 + elseif dom2 ∈ dom.children + return -1.0 + else + @error "domain is not in children of parent domain" + end + +end + +function generate_configuration(typelist,id_of_parentlist,background,backgroundexcitation=Dict()) + conf = createconfiguration(background,backgroundexcitation) + l = length(typelist) + for (ind,t,parent_id) in zip(1:l,typelist,id_of_parentlist) + createdomain(conf,ind,parent_id,t) + end + return conf +end +# function _create_bilform(operator_matrix,test_direct_productspace,trial_direct_productspace) +# #TODO create the bilform + +# end +#function convert_inside_to_outside_basis(Ωchild,Ωparent,strat) end +function interaction_matrix(config::Configuration,id,strat::NumericalStrategy) + @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) + N = length(config.testdirectproductspace.factors) + OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) + indexen = [] + Ω = config.domains[id] + if id != 0 + indexen = [indexen; Ω.data.testindex] + inter = Interaction(config,Ω,Ω,Ω) + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) + for child in Ω.children + inter = Interaction(config,Ω,child,Ω) + OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat) + inter = Interaction(config,child,Ω,Ω) + OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) + end + + end + for Ω1 in Ω.children + indexen = [indexen; Ω1.data.testindex] + inter = Interaction(config,Ω1,Ω1,Ω) + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += inter(strat) + + for Ω2 in Ω.children + if Ω1!==Ω2 + inter = Interaction(config,Ω1,Ω2,Ω) + OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter(strat) + end + end + end + + + id = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) + for i in 1:N + i∈indexen && (id[i,i] = Identity()) + end + pretty_table(id-OperatorMatrix, noheader=true, backend=Val(:latex)) + return assemble(dot(config.testdirectproductspace,id-OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) +end + +# function generate_problem_lhs(config::Configuration,strat::NumericalStrategy)#Make more correct by assambling for eacht domain an add with coeffeicient, add idetity at that place +# @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) +# N = length(config.testdirectproductspace.factors) +# OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) +# for (id,Ω) in config.domains +# c = Ω.data.coeff +# if id != 0 +# inter = Interaction(config,Ω,Ω,Ω) +# OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) +# for child in Ω.children +# inter = Interaction(config,Ω,child,Ω) +# OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += c*inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat) +# inter = Interaction(config,child,Ω,Ω) +# OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) +# end + +# end +# for Ω1 in Ω.children + +# inter = Interaction(config,Ω1,Ω1,Ω) +# OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += c*inter(strat) + +# for Ω2 in Ω.children +# if Ω1!==Ω2 +# inter = Interaction(config,Ω1,Ω2,Ω) +# OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += c*inter(strat) +# end +# end +# end + +# end +# id = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) +# for i in 1:N +# id[i,i] = 2*Identity() +# end +# pretty_table(id-OperatorMatrix, noheader=true, backend=Val(:latex)) +# return assemble(dot(config.testdirectproductspace,id-OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) + +# end +function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) + out = interaction_matrix(config,0,strat) + for (id,Ω) in config.domains + id==0 && continue + out += Ω.data.coeff* interaction_matrix(config,id,strat) + end + return out +end + +function generate_problem_rhs(config::Configuration) + linterms = Vector{LinTerm}() + @warn "only excitations in root domain implemented, check first if same aproach for others is appropriate" + for (id,Ω) in config.domains end + + for (key,func) in config.root.excitation + for child in config.root.children + + + push!(linterms,LinTerm(child.data.testindex[key],[],1,func)) + end + end + + return assemble(LinForm([],linterms),config.testdirectproductspace) +end + +function map_solution_to_volumes!(config,solution) + for (id,dom) in config.domains + id==0 && continue + out = [] + for i in dom.data.trialindex + push!(out,solution[Block(i)]) + end + dom.results = out + end +end + + + + diff --git a/src/multi-trace/multi-trace-old/design of the multi-trace approach.txt b/src/multi-trace/multi-trace-old/design of the multi-trace approach.txt new file mode 100644 index 00000000..a65637f9 --- /dev/null +++ b/src/multi-trace/multi-trace-old/design of the multi-trace approach.txt @@ -0,0 +1,11 @@ +design of the multi-trace approach: + +structure is devided in a tree like domain of open domains, there is the free space, domain 1, and then all other domains are in this free space. (mesh object is a domain, thus when you ask in which domain it is it gives the upstream domain). The basis of a mesh object is in the domain of the mesh object. + +Object interacts with every object in the domain and with the boundary of the domain it is in. + +object domain:(Physical information, test and trial bases boundary, mesh, touching information: for each object it returns the subd test and trial basis, also for the object itself!!!!) + +intersect(\Omega1, \Omega2) = (subd test, trial 1), (subd test,trial 2) + +work with strategies, \ No newline at end of file diff --git a/src/multi-trace/multi-trace-old/interactions.jl b/src/multi-trace/multi-trace-old/interactions.jl new file mode 100644 index 00000000..268260f7 --- /dev/null +++ b/src/multi-trace/multi-trace-old/interactions.jl @@ -0,0 +1,238 @@ + +using LinearAlgebra +""" +Write for each type of interaction this type of function. +""" +function (int::Interaction{<:Domain{BackgroundDomain},})() + i = [] #interaction matrix + normalorient.(i,Ω1,Ω2,Ω3) # example + + return nothing +end + +# function alpha(Ω1,Ω2) + + +# end +# """ +# cauchylimit needs to be applied before the normalorient function +# """ + +# function cauchylimit(operator::AbstractOperator;Ω1,Ω2,Ω3) +# #check first if touching is non empty +# @assert is_child_of(Ω1,Ω3)||Ω1===Ω3 +# @assert is_child_of(Ω2,Ω3)||Ω2===Ω3 +# # if Ω2!==Ω3 +# # sign = -1 +# # elseif Ω2===Ω3 +# # sign = 1 +# # end +# @warn "correct sign for inside is 1?" +# sign = 1 + +# trace(operator,sign) + +# end + +# function trace(op::AbstractOperator,sign) +# @warn "general abstract opterator trace function called returning pv of operator!: "*string(typeof(op)) +# return op +# end +# function normalorient(op::AbstractOperator,signtest,signtrial) +# @warn "normalorient not implemented for: "*string(typeof(op)) +# return op +# end +# trace(op::ZeroOperator,s) = op + +# function trace(op::LinearCombinationOfOperators,sign) +# result = ZeroOperator() +# for (c,o) in zip(op.coeffs,op.ops) +# result += c*trace(o,sign) +# end +# return result +# end + + +# function normalorient(op::LinearCombinationOfOperators,signtest,signtrial) +# result = ZeroOperator() +# for (c,o) in zip(op.coeffs,op.ops) +# result += c*normalorient(o,signtest,signtrial) +# end +# return result +# end + +# function normalorient(operator::AbstractOperator;Ω1,Ω2,Ω3) +# if Ω1===Ω3 +# sign_test_normal = 1 +# else +# sign_test_normal = -1 +# end +# if Ω2===Ω3 +# sign_trial_normal = 1 +# else +# sign_trial_normal = -1 +# end +# normalorient(operator,sign_test_normal,sign_trial_normal) +# end + +# normalorient(op::ZeroOperator,a,b) = op + +###### Interactions +struct VectorStrat <: BEAST.NumericalStrategy end + +function convert_outside_to_inside_basis(child,parent,::VectorStrat) + p = physicalconstants(parent.data) + c = physicalconstants(child.data) + a = [-1 0 0 0 + 0 1 0 0 + 0 0 -c.μ/p.μ 0 + 0 0 0 -p.ϵ/c.ϵ] + + return a +end + + + + +# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: RootDomain})(::VectorStrat) +# p = physicalconstants(int.embedvol.data) +# k = sqrt(p.ϵ*p.μ)*p.ω +# green = HHH.green(wavenumber=k) +# gradgreen = HHH.gradgreen(wavenumber=k) +# b = basisfunction() +# @warn "check if extra - in front of a is correct, describtion of As from paper asumes n outward so inward in outer domain?" +# a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen +# BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) +# -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() +# -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] +# id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() +# ZeroOperator() Identity() ZeroOperator() ZeroOperator() +# ZeroOperator() ZeroOperator() Identity() ZeroOperator() +# ZeroOperator() ZeroOperator() ZeroOperator() Identity()] +# #a = id - a + +# if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) +# println("cauchy limit taken") +# a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) +# end +# a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + +# return a + +# end +# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: SubDomain})(::VectorStrat) +# p = physicalconstants(int.embedvol.data) +# k = sqrt(p.ϵ*p.μ)*p.ω +# green = HHH.green(wavenumber=k) +# gradgreen = HHH.gradgreen(wavenumber=k) +# b = basisfunction() + +# a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen +# BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) +# -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() +# -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] +# id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() +# ZeroOperator() Identity() ZeroOperator() ZeroOperator() +# ZeroOperator() ZeroOperator() Identity() ZeroOperator() +# ZeroOperator() ZeroOperator() ZeroOperator() Identity()] +# #a = id - a + +# if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) +# println("cauchy limit taken") +# a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) +# end +# a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) +# return a + +# end + + +# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<:Union{RootDomain,SubDomain}})(::VectorStrat) +# p = physicalconstants(int.embedvol.data) +# k = sqrt(p.ϵ*p.μ)*p.ω +# G = BEAST.greenhh3d(wavenumber=k) +# ∇G = BEAST.∇(G) +# Ω1=int.testvol +# Ω2=int.trialvol +# Ω3=int.embedvol +# bs = Ω2.data.trialbasises[1].geo +# ts = Ω1.data.testbasises[1].geo + +# ∇Gx = BEAST.build_potential(∇G×B,bs) +# Gn = BEAST.build_potential(G*n*B,bs) +# Gnx = BEAST.build_potential(G*n × B,bs) +# ∇G = BEAST.build_potential(∇G*B,bs) +# ∇Gdotn = BEAST.build_potential(∇G⋅n*B,bs) +# ∇Gdot = BEAST.build_potential(∇G⋅B,bs) + +# Gr = BEAST.build_potential(G*B,bs) +# ∇G∇B = BEAST.build_potential(∇G*∇(B),bs) +# ∇Gxn = BEAST.build_potential(∇G×n*B,bs) + +# if Ω1==Ω2 +# a = -[γₛ(∇Gx,ts) γₛ(Gn,ts) -γₛ(Gnx,ts) γₛ(∇G,ts) +# BEAST.ZeroOperator() -τ(∇Gdotn,ts) τ(∇Gdot,ts) k^2*τ(Gr,ts) +# -γₛ(∇G∇B,ts)-k^2*γₛ(Gr,ts) -γₛ(∇Gxn,ts) γₛ(∇Gx,ts) BEAST.ZeroOperator() +# -γₙ(∇Gx,ts) -γₙ(Gn,ts) γₙ(Gr,ts) -γₙ(∇G,ts)] +# else +# a = -[γₛᶜ(∇Gx,ts) γₛᶜ(Gn,ts) -γₛᶜ(Gnx,ts) γₛᶜ(∇G,ts) +# BEAST.ZeroOperator() -τᶜ(∇Gdotn,ts) τᶜ(∇Gdot,ts) k^2*τᶜ(Gr,ts) +# -γₛᶜ(∇G∇B,ts)-k^2*γₛᶜ(Gr,ts) -γₛᶜ(∇Gxn,ts) γₛᶜ(∇Gx,ts) BEAST.ZeroOperator() +# -γₙᶜ(∇Gx,ts) -γₙᶜ(Gn,ts) γₙᶜ(Gr,ts) -γₙᶜ(∇G,ts)] +# end + + +# #a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + +# return a + +# end + +function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<:Union{RootDomain,SubDomain}})(::VectorStrat) + p = physicalconstants(int.embedvol.data) + k = sqrt(p.ϵ*p.μ)*p.ω + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + Ω1=int.testvol + Ω2=int.trialvol + Ω3=int.embedvol + bs = Ω2.data.trialbasises[1].geo + ts = Ω1.data.testbasises[1].geo + + ∇Gx = BEAST.build_potential(gradG×B,bs) + Gn = BEAST.build_potential(G*(n*B),bs) + Gnx = BEAST.build_potential(G*(n × B),bs) + ∇G = BEAST.build_potential(gradG*B,bs) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) + ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) + + Gr = BEAST.build_potential(G*B,bs) + ∇G∇B = BEAST.build_potential(gradG*div(B),bs) + ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) + sign = 1 + if Ω1==Ω2==Ω3 + + elseif Ω1==Ω2!=Ω3 + ts = -ts + bs = -bs + + elseif Ω1!=Ω2 + ts = -ts + bs = -bs + sign = -1 + + else + @error "none of previous" + + end + + a = -[γₛ(∇Gx,ts,ts,sign) γₛ(Gn,ts,ts,sign) -γₛ(Gnx,ts,ts,sign) γₛ(∇G,ts,ts,sign) + BEAST.ZeroOperator() -τ(∇Gdotn,ts,ts,sign) τ(∇Gdot,ts,ts,sign) k^2*τ(Gr,ts,ts,sign) + -γₛ(∇G∇B,ts,ts,sign)-k^2*γₛ(Gr,ts,ts,sign) -γₛ(∇Gxn,ts,ts,sign) γₛ(∇Gx,ts,ts,sign) BEAST.ZeroOperator() + -γₙ(∇Gx,ts,ts,sign) -γₙ(Gn,ts,ts,sign) γₙ(Gr,ts,ts,sign) -γₙ(∇G,ts,ts,sign)] + + #a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) + + return a + +end \ No newline at end of file diff --git a/src/multi-trace/multi-trace-old/postprocessing.jl b/src/multi-trace/multi-trace-old/postprocessing.jl new file mode 100644 index 00000000..317734ab --- /dev/null +++ b/src/multi-trace/multi-trace-old/postprocessing.jl @@ -0,0 +1,118 @@ +import Base.Threads: @spawn +function nearfield_A(dom::Domain{HomogeneousDomain},pts,strat::VectorStrat) + p = physicalconstants(dom) + parent_const = physicalconstants(dom.parent) + k = sqrt(p.ϵ*p.μ)*p.ω + + nxb_out1,σ_out1,a_out1,γ_out1 = dom.results + nxb1,σ1,a1,γ1 = dom.data.trialbasises + + vector_potential = p.μ/parent_const.μ* potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out1,a1) .- + potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out1,nxb1) .- + parent_const.ϵ/p.ϵ*potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out1,γ1) .-#compensatie omdat normal naar buiten wijst + potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out1,σ1); + + for Ω in dom.children + nxb_out,σ_out,a_out,γ_out = Ω.results + nxb,σ,a,γ = Ω.data.trialbasises + vector_potential = vector_potential .+ -1*potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out,a) .+ + potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out,nxb) .+ + potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out,γ) .+#compensatie omdat normal naar buiten wijst + potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); + end + return vector_potential +end +function nearfield_A(dom::Domain{BackgroundDomain},pts,strat::VectorStrat) + p = physicalconstants(dom) + k = sqrt(p.ϵ*p.μ)*p.ω + vector_potential = zeros(SVector{3,Complex},size(pts)) + for Ω in dom.children + nxb_out,σ_out,a_out,γ_out = Ω.results + nxb,σ,a,γ = Ω.data.trialbasises + vector_potential = vector_potential + -1*potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out,a) + + potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out,nxb) + + potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out,γ) +#compensatie omdat normal naar buiten wijst + potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); + end + return vector_potential +end +function nearfield_A(config::Configuration,points,strat::VectorStrat) + tasks = [] + for (id,dom) in config.domains + push!(tasks,@spawn nearfield_A(dom,points,strat)) + end + fields = fetch.(tasks) + out = zeros(SVector{3,Complex},size(points)) + for field in fields + out = out .+ field + end + return out +end +function nearfield_B(dom::Domain{HomogeneousDomain},pts,strat::VectorStrat) + p = physicalconstants(dom) + parent_const = physicalconstants(dom.parent) + k = sqrt(p.ϵ*p.μ)*p.ω + + nxb_out1,σ_out1,a_out1,γ_out1 = dom.results + nxb1,σ1,a1,γ1 = dom.data.trialbasises + + BField = p.μ/parent_const.μ* potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out1,a1) .- + (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out1,nxb1)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out1,nxb1)) .- + potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out1,σ1); + + for Ω in dom.children + nxb_out,σ_out,a_out,γ_out = Ω.results + nxb,σ,a,γ = Ω.data.trialbasises + BField = BField .+ -1*potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out,a) .+ + (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out,nxb)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out,nxb)) .+ + potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); + end + return BField +end + +function nearfield_H(dom::Domain{HomogeneousDomain},points,strat::VectorStrat) + nearfield_B(dom,points,strat)./physicalconstants(dom).μ +end + + +function nearfield_B(dom::Domain{BackgroundDomain},pts,strat::VectorStrat) + p = physicalconstants(dom) + k = sqrt(p.ϵ*p.μ)*p.ω + BField = zeros(SVector{3,Complex},size(pts)) + for Ω in dom.children + nxb_out,σ_out,a_out,γ_out = Ω.results + nxb,σ,a,γ = Ω.data.trialbasises + BField = BField + -1*potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out,a) + + (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out,nxb)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out,nxb)) + + potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ) + end + return BField +end +function nearfield_B(config::Configuration,points,strat::VectorStrat) + tasks = [] + for (id,dom) in config.domains + push!(tasks,@spawn nearfield_B(dom,points,strat)) + end + fields = fetch.(tasks) + out = zeros(SVector{3,Complex},size(points)) + for field in fields + out = out .+ field + end + return out +end +function nearfield_H(dom::Domain{BackgroundDomain},points,strat::VectorStrat) + nearfield_B(dom,points,strat)./physicalconstants(dom).μ +end + +function nearfield_H(config::Configuration,points,strat::VectorStrat) + tasks = [] + for (id,dom) in config.domains + push!(tasks,nearfield_H(dom,points,strat)) + end + #fields = fetch.(tasks) + out = zeros(SVector{3,Complex},size(points)) + for field in tasks + out = out .+ field + end + return out +end \ No newline at end of file diff --git a/src/multi-trace/postprocessing.jl b/src/multi-trace/postprocessing.jl new file mode 100644 index 00000000..70139491 --- /dev/null +++ b/src/multi-trace/postprocessing.jl @@ -0,0 +1,81 @@ + +#### Post processing +abstract type PostField end +struct AField <: PostField + world::World + result::PseudoBlockVector + volumes::Vector{Int} +end + +struct BField <: PostField + world::World + result::PseudoBlockVector + volumes::Vector{Int} +end +struct Field{T} + field::T +end +import Base ++(a::Field,b::Field) = Field(a.field + b.field) ++(a::Field{<:Nothing},b::Field) = b ++(a::Field,b::Field{<:Nothing}) = a ++(a::Field{<:Nothing},b::Field{<:Nothing}) = a +*(a::Number,b::Field) = Field(a*b.field) +*(a::Number,b::Field{<:Nothing}) = b + + +function calculate_field(points,f::PostField,strat) + out = [] + for v in f.volumes + obj = f.world.objectarray[v] + push!(out,_calculate_field(points,obj,f,strat)) + end + return sum(out) +end + +function _calculate_field(points,obj::Object{<:FreeSpace},f::PostField,strat) + map = f.world.trialhilbertspacemap + out = [] + for c in children(obj) + push!(out,sum(_calculate_field.(Ref(points),list_of_operators(obj,c,f,strat),BlockArrays.blocks(f.result[Block(map[c.index])]), f.world.trialdirectproductspace.factors[map[c.index]].factors))) + end + return sum(out) +end + +function _calculate_field(points,obj::Object{<:HOM},f::PostField,strat) + map = f.world.trialhilbertspacemap + typeof(f.result) + out = sum(_calculate_field.(Ref(points),transform(obj,strat)*list_of_operators(obj,obj,f,strat),BlockArrays.blocks(f.result[Block(map[obj.index])]), f.world.trialdirectproductspace.factors[map[obj.index]].factors)) + for c in children(obj) + out += sum(_calculate_field.(Ref(points),list_of_operators(obj,c,f,strat),BlockArrays.blocks(f.result[Block(map[c.index])]), f.world.trialdirectproductspace.factors[map[c.index]].factors)) + end + return out +end +function _calculate_field(points,obj::Object{<:PEC},f::PostField,strat) + return Field(nothing) +end + +function _calculate_field(points,operator::LinearCombinationOfOperators,coeffs,basis) + out = [] + for (coeff,op) in zip(operator.coeffs,operator.ops) + push!(out,coeff*_calculate_field(points,op,coeffs,basis)) + end + return sum(out) +end +function _calculate_field(points,operator::ComposedOperator,coeffs,basis) + x = potential(operator,points,coeffs,basis) + + return Field(x) +end +function _calculate_field(points,operator::ZeroOperator,coeffs,basis) + return Field(nothing) +end + +#### complement error +function complement_error(world,solution,volume::Vector{Int},strat::T) where {T} + @warn "not tested yet" + newstrat = T(-strat.trace) + lhs = discretise_lhs(world,newstrat) + out = lhs[volume].*Ref(solution) + return norm(sum(out))/norm(solution) +end \ No newline at end of file diff --git a/src/multi-trace/test_multi-trace_VP.jl b/src/multi-trace/test_multi-trace_VP.jl new file mode 100644 index 00000000..eea76676 --- /dev/null +++ b/src/multi-trace/test_multi-trace_VP.jl @@ -0,0 +1,121 @@ +using BEAST +using CompScienceMeshes +using BlockArrays +using LinearAlgebra +# import Plots + +radius = 1.0 +hh=0.15 +ϵ0 = 8.854e-12 +μ0 = 4π*1e-7 +ϵr = 2.0 +μr = 3.0 +c = 1/√(ϵ0*μ0) +λ = 2.9979563769321627 +ω = 2π*c/λ + +k0 = ω*sqrt(ϵ0*μ0) +T = boundary(CompScienceMeshes.tetmeshsphere(radius,hh)) + +S = BEAST.HOM(T,ϵ0*ϵr,μ0*μr,ω) +F = BEAST.FreeSpace(ϵ0,μ0,ω) +world = BEAST.create_world([2,0],[S,F]) +strat = BEAST.VP() +BEAST.assign_basis!(world,strat) + +lhs = BEAST.discretise_lhs(world,strat) + +A(x) = [1.0,0.0,0.0]*1im/ω*exp(-1.0im*k0*x[3]) +∇xA(x) = [0.0,1.0,0.0]*k0/ω*exp(-1.0im*k0*x[3]) +∇A(x) = 0.0+0.0im + +ex = BEAST.VPExcitation(A,∇xA,∇A,[2]) +rhs = BEAST.discretise_rhs(world,ex,strat) + +t =lhs[1]+lhs[2] +u = BEAST.gmres_ch(rhs[1]+rhs[2],t,world.trialdirectproductspace) + +Bf = BEAST.BField(world,u[1],[1,2]) +nx, nz = 100, 100 +xs, zs = range(-4,stop=4,length=nx), range(-6,stop=6,length=nz) +pts = [point(0,x,z) for x in xs, z in zs] + +BField = BEAST.calculate_field(pts,Bf,strat) +# display(Plots.heatmap(xs, zs, real.(getindex.(BField.field,2).+getindex.(∇xA.(pts),2)),show=true)) +# display(Plots.heatmap(xs, zs, imag.(getindex.(BField.field,2).+getindex.(∇xA.(pts),2)),show=true)) + + + + + + +function nearfield(um,uj,Xm,Xj,κ,η,points, + Einc=(x->point(0,0,0)), + Hinc=(x->point(0,0,0))) + + K = BEAST.MWDoubleLayerField3D(wavenumber=κ) + T = BEAST.MWSingleLayerField3D(wavenumber=κ) + + Em = potential(K, points, um, Xm) + Ej = potential(T, points, uj, Xj) + E = -Em + η * Ej + Einc.(points) + + Hm = potential(T, points, um, Xm) + Hj = potential(K, points, uj, Xj) + H = 1/η*Hm + Hj + Hinc.(points) + + return E, H +end + + + +X = raviartthomas(T) + +κ, η = ω/c, √(μ0/ϵ0) +κ′, η′ = κ*√(ϵr*μr), η*√(μr/ϵr) + +T = Maxwell3D.singlelayer(wavenumber=κ) +T′ = Maxwell3D.singlelayer(wavenumber=κ′) +K = Maxwell3D.doublelayer(wavenumber=κ) +K′ = Maxwell3D.doublelayer(wavenumber=κ′) + +E = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=κ) +H = -1/(im*κ*η)*curl(E) + +e = (n × E) × n +h = (n × H) × n + +@hilbertspace j m +@hilbertspace k l + +α, α′ = 1/η, 1/η′ +pmchwt = @discretise( + (η*T+η′*T′)[k,j] - (K+K′)[k,m] + + (K+K′)[l,j] + (α*T+α′*T′)[l,m] == -e[k] - h[l], + j∈X, m∈X, k∈X, l∈X) + +uu = solve(pmchwt) + +import Base.Threads: @spawn +task1 = @spawn nearfield(uu[m],uu[j],X,X,κ,η,pts,E,H) +task2 = @spawn nearfield(-uu[m],-uu[j],X,X,κ′,η′,pts) + +E_ex, H_ex = fetch(task1) +E_in, H_in = fetch(task2) + +B_tot = H_in*μ0*μr + H_ex*μ0 + +# display(Plots.heatmap(xs, zs, real.(getindex.(B_tot,2)))) +# display(Plots.heatmap(xs, zs, imag.(getindex.(B_tot,2)))) + +# maximum(norm.(B_tot-BField.field-∇xA.(pts))./norm.(B_tot)) + +# display(Plots.heatmap(xs,zs,norm.(B_tot-BField.field-∇xA.(pts))./maximum(norm.(B_tot)))) +# display(Plots.heatmap(xs,zs,norm.(B_tot))) + +# import PlotlyJS + +# PlotlyJS.plot(PlotlyJS.heatmap(x=xs,y=zs,z=norm.(B_tot))) + +# old = 0.008153372950474812 +@test norm.(B_tot-BField.field-∇xA.(pts)))/sum(norm.(B_tot) < 0.01 \ No newline at end of file From cf41a9da06277211e63420151c99af7331c63982 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 19 Dec 2023 16:06:43 +0100 Subject: [PATCH 072/110] debug multi-trace update --- src/composedoperator/composedoperator.jl | 9 +++++++-- src/composedoperator/tracesimplex.jl | 2 +- src/excitation.jl | 12 ++++++------ src/multi-trace/VectorPotential.jl | 2 +- src/multi-trace/interactions.jl | 1 + 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 25d41351..6de58de4 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -560,6 +560,7 @@ function assemble!(op::TraceOperator{T,Int}, test_functions::Space, trial_functi store, threading = Threading{:multi}; quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} println("assemble") + #@warn "NO MULTI TRACE YET" surface = geometry(test_functions) direction = [] sign = op.surface @@ -569,8 +570,12 @@ function assemble!(op::TraceOperator{T,Int}, test_functions::Space, trial_functi push!(direction,sign*normal(c)/3) end println("hang1") - surf = TraceMesh(surface,direction) - println("ttt") + if typeof(surface) <: TraceMesh + surf = surface + direction + else + surf = TraceMesh(surface,direction) + end + println(typeof(surf)) test_functions = redefine_geometrie(test_functions,surf) println(typeof(op.operator)) assemble!(op.operator, test_functions, trial_functions, store, threading; diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index 3c448b9a..ae348cd1 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -75,7 +75,7 @@ struct TraceMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} end TraceMesh(a::CompScienceMeshes.AbstractMesh{U,D,T}) where {U,D,T} = TraceMesh(a,zeros(SVector{numcells(a),SVector{3,T}})) +(a::TraceMesh{U,D,T},b::SVector{3,T}) where {U,D,T} = TraceMesh(mesh(a),direction(a).+Ref(b)) -+(a::TraceMesh,b::SVector) = TraceMesh(mesh(a),a.direction+b) ++(a::TraceMesh,b::Vector) = TraceMesh(mesh(a),a.direction+b) +(a::SVector,b::TraceMesh) = b+a CompScienceMeshes.indices(t::TraceMesh,i::Int) = CompScienceMeshes.indices(mesh(t),i) CompScienceMeshes.numvertices(t::TraceMesh) = CompScienceMeshes.numvertices(mesh(t)) diff --git a/src/excitation.jl b/src/excitation.jl index 2344245f..df3ce36b 100644 --- a/src/excitation.jl +++ b/src/excitation.jl @@ -43,14 +43,14 @@ function assemble(field::Functional, tfs; assemble!(field, tfs, store; quadstrat) return b end -# function assemble(n::Number, tfs) +function assemble(n::Number, tfs) -# R = scalartype(tfs) + R = scalartype(tfs) -# b = zeros(Complex{R}, numfunctions(tfs)) -# fill!(b,n) -# return b -# end + b = zeros(Complex{R}, numfunctions(tfs)) + fill!(b,n) + return b +end function assemble!(field::Functional, tfs::DirectProductSpace, store; quadstrat=defaultquadstrat(field, tfs)) diff --git a/src/multi-trace/VectorPotential.jl b/src/multi-trace/VectorPotential.jl index 8726b47e..40752ab3 100644 --- a/src/multi-trace/VectorPotential.jl +++ b/src/multi-trace/VectorPotential.jl @@ -205,7 +205,7 @@ function interaction(testobj::Object, trialobj::Object, embobj::Object, ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B)) ∇Gdot = BEAST.build_potential(B ⋅ gradG) - Gr = BEAST.build_potential(G*B,bs) + Gr = BEAST.build_potential(G*B) ∇G∇B = BEAST.build_potential(gradG*div(B)) ∇Gxn = BEAST.build_potential(gradG×(n*B)) diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 50620e72..0e188438 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -257,6 +257,7 @@ function _discretise_rhs_matrix(obj::Object{T},tesths,testb,mapt,ex,strat) where push!(out,array_to_linform(excitation(child,obj,child.type,ex,strat))[u]) end s = sum(out) + println(s) return assemble(s,testb) end function _discretise_rhs_matrix(obj::Object{T},tesths,testb,mapt,ex,strat) where {T <: PEC} From d42e20cc757ac95cc6d52a695b80abbc9a3f111d Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 19 Dec 2023 17:11:23 +0100 Subject: [PATCH 073/110] debug --- src/multi-trace/interactions.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 0e188438..7d435db8 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -316,7 +316,7 @@ function _discretise_lhs_matrix(obj::Object{<:HOM},tesths,basishs,testb,trialb,m bils += matrix_to_bilform(identity(child.type,strat))[u,v] bils -= matrix_to_bilform(interaction(obj,child,obj,Inside(obj.type),child.type,strat))[t,v] bils -= matrix_to_bilform(interaction(child,obj,obj,child.type,Inside(obj.type),strat))[u,b] - bils -= matrix_to_bilform(interaction(child,child,obj,child.type,child.typ,strat))[u,v] + bils -= matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat))[u,v] end if length(children(obj)) > 1 for (c1,c2) in combinations(children(obj),2) From 0d2ea8856c29fce87d8c31356db06693dc0b5e4f Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 20 Dec 2023 16:16:59 +0100 Subject: [PATCH 074/110] debug --- src/composedoperator/composedoperator.jl | 4 ++-- src/multi-trace/VectorPotential.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 6de58de4..16919aa4 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -433,7 +433,7 @@ function (op::GradGreenHH3D)(x::Union{SVector,Vector},y,g) end γ(op::GreenHH3D) = op -γ(op::GradGreenHH3D) = op - 1/2*TraceDirection() +γ(op::GradGreenHH3D) = op + 1/2*TraceDirection() grad(G::GreenHH3D) = GradGreenHH3D(G.gamma) @@ -473,7 +473,7 @@ function (op::TestNormal)(x,y,g) end function (op::TraceDirection)(x,y,g) #println(direction(x)-direction(y)) - Ref(approx_sign(dot(normal(x),(direction(x)-direction(y))))*normal(x)) + Ref(approx_sign(dot(normal(x),(direction(y)-direction(x))))*normal(x)) end function (op::BasisFunction)(x,y,g) getvalue(g) diff --git a/src/multi-trace/VectorPotential.jl b/src/multi-trace/VectorPotential.jl index 40752ab3..5a64901f 100644 --- a/src/multi-trace/VectorPotential.jl +++ b/src/multi-trace/VectorPotential.jl @@ -118,7 +118,7 @@ function interaction(testobj::Object,trialobj::Object,embobj::Object, 0 1 0 0; 0 0 mu(testobj)/mu(parent(testobj)) 0; 0 0 0 epsilon(parent(testobj))/epsilon(testobj)] - a * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign) + a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign) end function interaction(testobj::Object,trialobj::Object,embobj::Object, From 45cb989bfc7a1ada72da8514eedbdf1ec8c642f1 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 21 Dec 2023 15:42:39 +0100 Subject: [PATCH 075/110] update complement error --- src/multi-trace/interactions.jl | 16 ++++++++-------- src/multi-trace/postprocessing.jl | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 7d435db8..6477be09 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -290,7 +290,7 @@ function diag_prec(w::World, strat::Interaction) end -function discretise_lhs(w::World, strat::Interaction) +function discretise_lhs(w::World, strat::Interaction;id=1.0) l = length(w.objectarray)-1 # no bases for the free space tesths = w.testhilbertspace @@ -299,21 +299,21 @@ function discretise_lhs(w::World, strat::Interaction) trialb = w.trialdirectproductspace maptesths = w.testhilbertspacemap maptrialhs = w.trialhilbertspacemap - out = _discretise_lhs_matrix.(w.objectarray,Ref(tesths),Ref(basishs),Ref(testb),Ref(trialb),Ref(maptesths),Ref(maptrialhs),Ref(strat)) + out = _discretise_lhs_matrix.(w.objectarray,Ref(tesths),Ref(basishs),Ref(testb),Ref(trialb),Ref(maptesths),Ref(maptrialhs),Ref(strat);id = id) return out # returned the assambled matrices for each struct end -function _discretise_lhs_matrix(obj::Object{<:HOM},tesths,basishs,testb,trialb,mapt,mapb,strat) +function _discretise_lhs_matrix(obj::Object{<:HOM},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0) t = tesths[mapt[obj.index]] b = basishs[mapb[obj.index]] # bils = BEAST.BlockDiagonalOperator(Identity())[t,b] - bils = matrix_to_bilform(identity(obj.type,strat))[t,b] + bils = id*matrix_to_bilform(identity(obj.type,strat))[t,b] println(bils) bils -= matrix_to_bilform(interaction(obj,obj,obj,Inside(obj.type),Inside(obj.type),strat))[t,b] for child in children(obj) u = tesths[mapt[child.index]] v = basishs[mapb[child.index]] - bils += matrix_to_bilform(identity(child.type,strat))[u,v] + bils += id*matrix_to_bilform(identity(child.type,strat))[u,v] bils -= matrix_to_bilform(interaction(obj,child,obj,Inside(obj.type),child.type,strat))[t,v] bils -= matrix_to_bilform(interaction(child,obj,obj,child.type,Inside(obj.type),strat))[u,b] bils -= matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat))[u,v] @@ -351,15 +351,15 @@ function _diag_prec(obj::Object{<:PEC},tesths,basishs,testb,trialb,mapt,mapb,str return Zero() end -function _discretise_lhs_matrix(obj::Object{<:PEC},tesths,basishs,testb,trialb,mapt,mapb,strat) +function _discretise_lhs_matrix(obj::Object{<:PEC},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0) return Zero() end -function _discretise_lhs_matrix(obj::Object{<:FreeSpace},tesths,basishs,testb,trialb,mapt,mapb,strat) +function _discretise_lhs_matrix(obj::Object{<:FreeSpace},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0) bilslist = [] for child in children(obj) u = tesths[mapt[child.index]] v = basishs[mapb[child.index]] - push!(bilslist,matrix_to_bilform(identity(child.type,strat))[u,v]) + push!(bilslist,id*matrix_to_bilform(identity(child.type,strat))[u,v]) push!(bilslist,-matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat))[u,v]) end bils = sum(bilslist) diff --git a/src/multi-trace/postprocessing.jl b/src/multi-trace/postprocessing.jl index 70139491..dbf44a80 100644 --- a/src/multi-trace/postprocessing.jl +++ b/src/multi-trace/postprocessing.jl @@ -75,7 +75,7 @@ end function complement_error(world,solution,volume::Vector{Int},strat::T) where {T} @warn "not tested yet" newstrat = T(-strat.trace) - lhs = discretise_lhs(world,newstrat) + lhs = discretise_lhs(world,newstrat;id=0.0) out = lhs[volume].*Ref(solution) return norm(sum(out))/norm(solution) end \ No newline at end of file From bf7518330bd1c2b1c70c90bf7c67c8092dc22b84 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 8 Jan 2024 10:39:23 +0100 Subject: [PATCH 076/110] update --- src/composedoperator/composedoperator.jl | 10 +- src/composedoperator/tracesimplex.jl | 2 +- src/multi-trace/VectorPotential.jl | 209 +++++++++++++---------- src/multi-trace/interactions.jl | 28 +-- src/multi-trace/postprocessing.jl | 16 +- src/solvers/itsolver.jl | 5 +- 6 files changed, 156 insertions(+), 114 deletions(-) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 16919aa4..98ab8126 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -292,7 +292,7 @@ end function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator - newop = -nt × (nt × γ(op.operator)) + newop = (nt × γ(op.operator)) × nt direction = [] for i in 1:numcells(surface) c = chart(surface,i) @@ -302,7 +302,7 @@ function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# end function γₜ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator - newop = -nt × (nt × γ(op.operator)) + newop = (nt × γ(op.operator)) × nt direction = [] for i in 1:numcells(surface) c = chart(surface,i) @@ -502,9 +502,9 @@ kernelvals(op::ComposedOperatorIntegral, y,x) = nothing quaddata(op::ComposedOperatorIntegral,rs,els,qs::SingleNumQStrat) = quadpoints(rs,els,(qs.quad_rule,)) quadrule(op::ComposedOperatorIntegral,refspace,p,y,q,el,qdata,qs::SingleNumQStrat) = qdata[1,q] -defaultquadstrat(op::ComposedOperatorIntegral, basis) = SingleNumQStrat(3) -defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(7,8,6,6,5,4) -defaultquadstrat(op::ComposedOperatorLocal,testspace::Space,trialpsace::Space) = SingleNumQStrat(6) +defaultquadstrat(op::ComposedOperatorIntegral, basis) = SingleNumQStrat(6) +defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(7,8,6,7,6,6) +defaultquadstrat(op::ComposedOperatorLocal,testspace::Space,trialpsace::Space) = SingleNumQStrat(8) #sign_upon_permutation(op::ComposedOperator,I,J) = Combinatorics.levicivita(I)^count_test_normals(op)*Combinatorics.levicivita(J)^count_trial_normals(op) diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index ae348cd1..3c448b9a 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -75,7 +75,7 @@ struct TraceMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} end TraceMesh(a::CompScienceMeshes.AbstractMesh{U,D,T}) where {U,D,T} = TraceMesh(a,zeros(SVector{numcells(a),SVector{3,T}})) +(a::TraceMesh{U,D,T},b::SVector{3,T}) where {U,D,T} = TraceMesh(mesh(a),direction(a).+Ref(b)) -+(a::TraceMesh,b::Vector) = TraceMesh(mesh(a),a.direction+b) ++(a::TraceMesh,b::SVector) = TraceMesh(mesh(a),a.direction+b) +(a::SVector,b::TraceMesh) = b+a CompScienceMeshes.indices(t::TraceMesh,i::Int) = CompScienceMeshes.indices(mesh(t),i) CompScienceMeshes.numvertices(t::TraceMesh) = CompScienceMeshes.numvertices(mesh(t)) diff --git a/src/multi-trace/VectorPotential.jl b/src/multi-trace/VectorPotential.jl index 5a64901f..f6423f77 100644 --- a/src/multi-trace/VectorPotential.jl +++ b/src/multi-trace/VectorPotential.jl @@ -113,48 +113,114 @@ end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::Inside,trialtype,strat::Union{PRECVP,VP}; sign=1) + testtype::Inside,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) a = [1 0 0 0; 0 1 0 0; 0 0 mu(testobj)/mu(parent(testobj)) 0; 0 0 0 epsilon(parent(testobj))/epsilon(testobj)] - a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign) + a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign,dual=dual,trace=trace) end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::PECCFIE,trialtype,strat::Union{PRECVP,VP}; sign=1) + testtype::PECCFIE,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) testtype.alpha*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[1:2,:]+ - (1-testtype.alpha)*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[3:4,:] + (1-testtype.alpha)*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::PECEFIE,trialtype,strat::Union{PRECVP,VP}; sign=1) + testtype::PECEFIE,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) - interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[1:2,:] + interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[1:2,:] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::PECMFIE,trialtype,strat::Union{PRECVP,VP}; sign=1) - interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[3:4,:] + testtype::PECMFIE,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::Inside,strat::Union{PRECVP,VP}; sign=1) + testtype::ObjectType,trialtype::Inside,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) a = -[1 0 0 0; 0 1 0 0; 0 0 mu(trialobj)/mu(parent(trialobj)) 0; 0 0 0 epsilon(parent(trialobj))/epsilon(trialobj)] - interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign)*a + interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)*a end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::PEC,strat::Union{PRECVP,VP}; sign=1) - interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign)[:,3:4] + testtype::ObjectType,trialtype::PEC,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)[:,3:4] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP}; sign=1) - interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign) + testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace) end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::HOM,trialtype,strat::Union{PRECVP,VP}; sign=1) - interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign) + testtype::HOM,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace) +end +function interaction(testobj::Object, trialobj::Object, embobj::Object, + testtype::ObjectType,trialtype::ObjectType,strat::VP; sign=1,dual=true,trace=true) + tr = sign*strat.trace + k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + + bs = geometry(trialobj) + ts = geometry(testobj) + if trace + ∇Gx = BEAST.build_potential(gradG×B,bs) + Gn = BEAST.build_potential(G*(n*B),bs) + #Gnx = BEAST.build_potential(G*(n × B),bs) + ∇G = BEAST.build_potential(gradG*B,bs) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) + ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) + + Gr = BEAST.build_potential(G*B,bs) + ∇G∇B = BEAST.build_potential(gradG*div(B),bs) + ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) + else + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*div(B) + ∇Gxn = gradG×(nb*B) + + end + #gebruik gamma^c --> sign = + + # #without extra ncross + # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); + # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); + # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); + # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] + # #with extra ncross + if dual && trace + int = [-γₜ(∇Gx,ts,tr) γₜ(Gn,ts,tr) -γₜ(Gr,ts,tr) γₜ(∇G,ts,tr); + ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr); + -γₜ(∇G∇B,ts,tr)-k^2*γₜ(Gr,ts,tr) γₜ(∇Gxn,ts,tr) -γₜ(∇Gx,ts,tr) ZeroOperator(); + γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr)] + return int + elseif dual + int = [nt×(nt×(∇Gx)) -nt×(nt×(Gn)) nt×(nt×(Gr)) nt×(nt×(∇G)); + ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr); + nt×(nt×(∇G∇B))+k^2*nt×(nt×(Gr)) -nt×(nt×(∇Gxn)) nt×(nt×(∇Gx)) ZeroOperator(); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G)] + return int + elseif trace + int = [γₛ(∇Gx,ts,tr) -γₛ(Gn,ts,tr) γₛ(Gr,ts,tr) -γₛ(∇G,ts,tr); + ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr); + γₛ(∇G∇B,ts,tr)+k^2*γₛ(Gr,ts,tr) -γₛ(∇Gxn,ts,tr) γₛ(∇Gx,ts,tr) ZeroOperator(); + γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr)] + return int + else + int = [nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); + ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr); + nt×(∇G∇B)+k^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G)] + return int + end end # function interaction(testobj::Object, trialobj::Object, embobj::Object, # testtype::ObjectType,trialtype::ObjectType,strat::VP; sign=1) @@ -163,19 +229,17 @@ end # G = BEAST.greenhh3d(wavenumber=k) # gradG = BEAST.∇(G) -# bs = geometry(trialobj) -# ts = geometry(testobj) -# ∇Gx = BEAST.build_potential(gradG×B,bs) -# Gn = BEAST.build_potential(G*(n*B),bs) +# ∇Gx = BEAST.build_potential(gradG×B) +# Gn = BEAST.build_potential(G*(n*B)) # #Gnx = BEAST.build_potential(G*(n × B),bs) -# ∇G = BEAST.build_potential(gradG*B,bs) -# ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) -# ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) +# ∇G = BEAST.build_potential(gradG*B) +# ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B)) +# ∇Gdot = BEAST.build_potential(B ⋅ gradG) -# Gr = BEAST.build_potential(G*B,bs) -# ∇G∇B = BEAST.build_potential(gradG*div(B),bs) -# ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) +# Gr = BEAST.build_potential(G*B) +# ∇G∇B = BEAST.build_potential(gradG*div(B)) +# ∇Gxn = BEAST.build_potential(gradG×(n*B)) # #gebruik gamma^c --> sign = + # # #without extra ncross @@ -184,77 +248,45 @@ end # # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); # # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] # # #with extra ncross -# int = [-γₜ(∇Gx,ts,trace) γₜ(Gn,ts,trace) -γₜ(Gr,ts,trace) γₜ(∇G,ts,trace); -# ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); -# -γₜ(∇G∇B,ts,trace)-k^2*γₜ(Gr,ts,trace) γₜ(∇Gxn,ts,trace) -γₜ(∇Gx,ts,trace) ZeroOperator(); -# γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] +# int = [-γₜ(∇Gx,trace) γₜ(Gn,trace) -γₜ(Gr,trace) γₜ(∇G,trace); +# ZeroOperator() -τ(∇Gdotn,trace) τ(∇Gdot,trace) k^2*τ(Gr,trace); +# -γₜ(∇G∇B,trace)-k^2*γₜ(Gr,trace) γₜ(∇Gxn,trace) -γₜ(∇Gx,trace) ZeroOperator(); +# γₙ(∇Gx,trace) -γₙ(Gn,trace) γₙ(Gr,trace) -γₙ(∇G,trace)] # return int # end -function interaction(testobj::Object, trialobj::Object, embobj::Object, - testtype::ObjectType,trialtype::ObjectType,strat::VP; sign=1) - trace = sign*strat.trace - k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - - - ∇Gx = BEAST.build_potential(gradG×B) - Gn = BEAST.build_potential(G*(n*B)) - #Gnx = BEAST.build_potential(G*(n × B),bs) - ∇G = BEAST.build_potential(gradG*B) - ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B)) - ∇Gdot = BEAST.build_potential(B ⋅ gradG) - - Gr = BEAST.build_potential(G*B) - ∇G∇B = BEAST.build_potential(gradG*div(B)) - ∇Gxn = BEAST.build_potential(gradG×(n*B)) - - #gebruik gamma^c --> sign = + - # #without extra ncross - # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); - # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); - # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); - # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] - # #with extra ncross - int = [-γₜ(∇Gx,trace) γₜ(Gn,trace) -γₜ(Gr,trace) γₜ(∇G,trace); - ZeroOperator() -τ(∇Gdotn,trace) τ(∇Gdot,trace) k^2*τ(Gr,trace); - -γₜ(∇G∇B,trace)-k^2*γₜ(Gr,trace) γₜ(∇Gxn,trace) -γₜ(∇Gx,trace) ZeroOperator(); - γₙ(∇Gx,trace) -γₙ(Gn,trace) γₙ(Gr,trace) -γₙ(∇G,trace)] - return int -end -function interaction(testobj::Object, trialobj::Object, embobj::Object, - testtype::ObjectType,trialtype::ObjectType,strat::PRECVP; sign=1) - trace = sign*strat.trace - k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) +# function interaction(testobj::Object, trialobj::Object, embobj::Object, +# testtype::ObjectType,trialtype::ObjectType,strat::PRECVP; sign=1,dual=true) +# trace = sign*strat.trace +# k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) +# G = BEAST.greenhh3d(wavenumber=k) +# gradG = BEAST.∇(G) - bs = barycentric_refinement(geometry(trialobj); sort = :spacefillingcurve) - ts = barycentric_refinement(geometry(testobj); sort = :spacefillingcurve) +# bs = barycentric_refinement(geometry(trialobj); sort = :spacefillingcurve) +# ts = barycentric_refinement(geometry(testobj); sort = :spacefillingcurve) - bss = geometry(trialobj) - tss = geometry(testobj) +# bss = geometry(trialobj) +# tss = geometry(testobj) - ∇Gx = BEAST.build_potential(gradG×B,bs)# - Gn = BEAST.build_potential(G*(n*B),bss)# - #Gnx = BEAST.build_potential(G*(n × B),bs) - ∇G = BEAST.build_potential(gradG*B,bss)# - ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bss)# - ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs)# +# ∇Gx = BEAST.build_potential(gradG×B,bs)# +# Gn = BEAST.build_potential(G*(n*B),bss)# +# #Gnx = BEAST.build_potential(G*(n × B),bs) +# ∇G = BEAST.build_potential(gradG*B,bss)# +# ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bss)# +# ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs)# - Gr = BEAST.build_potential(G*B,bs)# - Grs = BEAST.build_potential(G*B,bss)# - ∇G∇B = BEAST.build_potential(gradG*div(B),bs)# - ∇Gxn = BEAST.build_potential(gradG×(n*B),bss)# +# Gr = BEAST.build_potential(G*B,bs)# +# Grs = BEAST.build_potential(G*B,bss)# +# ∇G∇B = BEAST.build_potential(gradG*div(B),bs)# +# ∇Gxn = BEAST.build_potential(gradG×(n*B),bss)# - int = [-γₜ(∇Gx,ts,trace) γₜ(Gn,ts,trace) -γₜ(Gr,ts,trace) γₜ(∇G,ts,trace); - ZeroOperator() -τ(∇Gdotn,tss,trace) τ(∇Gdot,tss,trace) k^2*τ(Grs,tss,trace); - -γₜ(∇G∇B,ts,trace)-k^2*γₜ(Gr,ts,trace) γₜ(∇Gxn,ts,trace) -γₜ(∇Gx,ts,trace) ZeroOperator(); - γₙ(∇Gx,tss,trace) -γₙ(Gn,tss,trace) γₙ(Gr,tss,trace) -γₙ(∇G,tss,trace)] - return int -end +# int = [-γₜ(∇Gx,ts,trace) γₜ(Gn,ts,trace) -γₜ(Gr,ts,trace) γₜ(∇G,ts,trace); +# ZeroOperator() -τ(∇Gdotn,tss,trace) τ(∇Gdot,tss,trace) k^2*τ(Grs,tss,trace); +# -γₜ(∇G∇B,ts,trace)-k^2*γₜ(Gr,ts,trace) γₜ(∇Gxn,ts,trace) -γₜ(∇Gx,ts,trace) ZeroOperator(); +# γₙ(∇Gx,tss,trace) -γₙ(Gn,tss,trace) γₙ(Gr,tss,trace) -γₙ(∇G,tss,trace)] +# return int +# end function _identity(::ObjectType,strat::PRECVP) [NCross() ZeroOperator() ZeroOperator() ZeroOperator(); ZeroOperator() Identity() ZeroOperator() ZeroOperator(); @@ -365,6 +397,7 @@ function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation 0 1 0 0; 0 0 mu(testobj)/mu(parent(testobj)) 0; 0 0 0 epsilon(parent(testobj))/epsilon(testobj)] + return a*excitation(testobj,emb,objtype.inside,ex,strat) end function excitation(testobj::Object,emb::Object,objtype::PECCFIE,ex::VPExcitation,strat::VP) diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 6477be09..95ff1ab6 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -290,7 +290,7 @@ function diag_prec(w::World, strat::Interaction) end -function discretise_lhs(w::World, strat::Interaction;id=1.0) +function discretise_lhs(w::World, strat::Interaction;id=1.0,dual=true,trace=true) l = length(w.objectarray)-1 # no bases for the free space tesths = w.testhilbertspace @@ -299,24 +299,24 @@ function discretise_lhs(w::World, strat::Interaction;id=1.0) trialb = w.trialdirectproductspace maptesths = w.testhilbertspacemap maptrialhs = w.trialhilbertspacemap - out = _discretise_lhs_matrix.(w.objectarray,Ref(tesths),Ref(basishs),Ref(testb),Ref(trialb),Ref(maptesths),Ref(maptrialhs),Ref(strat);id = id) + out = _discretise_lhs_matrix.(w.objectarray,Ref(tesths),Ref(basishs),Ref(testb),Ref(trialb),Ref(maptesths),Ref(maptrialhs),Ref(strat);id = id,dual=dual,trace=trace) return out # returned the assambled matrices for each struct end -function _discretise_lhs_matrix(obj::Object{<:HOM},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0) +function _discretise_lhs_matrix(obj::Object{<:HOM},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0,dual=true, trace=true) t = tesths[mapt[obj.index]] b = basishs[mapb[obj.index]] # bils = BEAST.BlockDiagonalOperator(Identity())[t,b] bils = id*matrix_to_bilform(identity(obj.type,strat))[t,b] println(bils) - bils -= matrix_to_bilform(interaction(obj,obj,obj,Inside(obj.type),Inside(obj.type),strat))[t,b] + bils -= matrix_to_bilform(interaction(obj,obj,obj,Inside(obj.type),Inside(obj.type),strat;dual=dual,trace=trace))[t,b] for child in children(obj) u = tesths[mapt[child.index]] v = basishs[mapb[child.index]] bils += id*matrix_to_bilform(identity(child.type,strat))[u,v] - bils -= matrix_to_bilform(interaction(obj,child,obj,Inside(obj.type),child.type,strat))[t,v] - bils -= matrix_to_bilform(interaction(child,obj,obj,child.type,Inside(obj.type),strat))[u,b] - bils -= matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat))[u,v] + bils -= matrix_to_bilform(interaction(obj,child,obj,Inside(obj.type),child.type,strat;dual=dual,trace=trace))[t,v] + bils -= matrix_to_bilform(interaction(child,obj,obj,child.type,Inside(obj.type),strat;dual=dual,trace=trace))[u,b] + bils -= matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat;dual=dual,trace=trace))[u,v] end if length(children(obj)) > 1 for (c1,c2) in combinations(children(obj),2) @@ -324,8 +324,8 @@ function _discretise_lhs_matrix(obj::Object{<:HOM},tesths,basishs,testb,trialb,m t2 = tesths[mapt[c2.index]] b1 = basishs[mapb[c1.index]] b2 = basishs[mapb[c2.index]] - bils -= matrix_to_bilform(interaction(c1,c2,obj,c1.type,c2.type,strat))[t1,b2] - bils -= matrix_to_bilform(interaction(c2,c1,obj,c1.type,c2.type,strat))[t2,b1] + bils -= matrix_to_bilform(interaction(c1,c2,obj,c1.type,c2.type,strat;dual=dual,trace=trace))[t1,b2] + bils -= matrix_to_bilform(interaction(c2,c1,obj,c1.type,c2.type,strat;dual=dual,trace=trace))[t2,b1] end end println(typeof(bils.terms[1])) @@ -351,16 +351,16 @@ function _diag_prec(obj::Object{<:PEC},tesths,basishs,testb,trialb,mapt,mapb,str return Zero() end -function _discretise_lhs_matrix(obj::Object{<:PEC},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0) +function _discretise_lhs_matrix(obj::Object{<:PEC},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0,dual=true,trace=true) return Zero() end -function _discretise_lhs_matrix(obj::Object{<:FreeSpace},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0) +function _discretise_lhs_matrix(obj::Object{<:FreeSpace},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0,dual=true,trace=true) bilslist = [] for child in children(obj) u = tesths[mapt[child.index]] v = basishs[mapb[child.index]] push!(bilslist,id*matrix_to_bilform(identity(child.type,strat))[u,v]) - push!(bilslist,-matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat))[u,v]) + push!(bilslist,-matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat;dual=dual,trace=trace))[u,v]) end bils = sum(bilslist) if length(children(obj)) > 1 @@ -369,8 +369,8 @@ function _discretise_lhs_matrix(obj::Object{<:FreeSpace},tesths,basishs,testb,tr t2 = tesths[mapt[c2.index]] b1 = basishs[mapb[c1.index]] b2 = basishs[mapb[c2.index]] - bils -= matrix_to_bilform(interaction(c1,c2,obj,c1.type,c2.type,strat))[t1,b2] - bils -= matrix_to_bilform(interaction(c2,c1,obj,c1.type,c2.type,strat))[t2,b1] + bils -= matrix_to_bilform(interaction(c1,c2,obj,c1.type,c2.type,strat;dual=dual,trace=trace))[t1,b2] + bils -= matrix_to_bilform(interaction(c2,c1,obj,c1.type,c2.type,strat;dual=dual,trace=trace))[t2,b1] end end return assemble(bils,testb,trialb) diff --git a/src/multi-trace/postprocessing.jl b/src/multi-trace/postprocessing.jl index dbf44a80..2317dbcb 100644 --- a/src/multi-trace/postprocessing.jl +++ b/src/multi-trace/postprocessing.jl @@ -72,10 +72,18 @@ function _calculate_field(points,operator::ZeroOperator,coeffs,basis) end #### complement error -function complement_error(world,solution,volume::Vector{Int},strat::T) where {T} - @warn "not tested yet" +function complement_error(world,solution,volume::Vector{Int},strat::T;trace=true) where {T} + @warn "exclude free space!!!" newstrat = T(-strat.trace) - lhs = discretise_lhs(world,newstrat;id=0.0) + @assert T <: VP + lhs = discretise_lhs(world,newstrat;id=0.0,dual=false,trace=trace) out = lhs[volume].*Ref(solution) - return norm(sum(out))/norm(solution) + g = BlockDiagonalOperator(BlockDiagonalOperator(Identity())) + G = assemble(g,world.testdirectproductspace,world.testdirectproductspace) + G2 = assemble(g,world.trialdirectproductspace,world.trialdirectproductspace) + println("started inversion") + ttt = Ref(G).\Vector.(out) + println("G inverted") + return dot.(Vector.(out),ttt)/dot(solution,G2,solution),ttt,out,G,dot(solution,G2,solution) + # norm(sum(out))/norm(solution) end \ No newline at end of file diff --git a/src/solvers/itsolver.jl b/src/solvers/itsolver.jl index 7b917ce7..8e516ce6 100644 --- a/src/solvers/itsolver.jl +++ b/src/solvers/itsolver.jl @@ -97,7 +97,8 @@ function gmres_ch(eq::DiscreteEquation; maxiter=0, restart=0, tol=0) if tol == 0 invZ = GMRESSolver(Z, maxiter=maxiter, restart=restart) else - invZ = GMRESSolver(Z, maxiter=maxiter, restart=restart, tol=tol) + T = real(eltype(Z)) + invZ = GMRESSolver(Z, maxiter=maxiter, restart=restart, reltol=T(tol)) end x, ch = solve(invZ, b) # x = invZ * b @@ -110,7 +111,7 @@ function gmres_ch(b,Z,trial_direct_product_space; maxiter=0, restart=0, tol=0) if tol == 0 invZ = GMRESSolver(Z, maxiter=maxiter, restart=restart) else - invZ = GMRESSolver(Z, maxiter=maxiter, restart=restart, tol=tol) + invZ = GMRESSolver(Z, maxiter=maxiter, restart=restart, reltol=tol) end x, ch = solve(invZ, b) # x = invZ * b From 4152143b34611d449f60d7e679fab9d5a6cce568 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 9 Jan 2024 15:23:41 +0100 Subject: [PATCH 077/110] pmchwt support --- src/composedoperator/composedoperator.jl | 2 +- src/multi-trace/VectorPotential.jl | 130 +++++++++++++++++++++-- 2 files changed, 122 insertions(+), 10 deletions(-) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 98ab8126..28b08658 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -503,7 +503,7 @@ quaddata(op::ComposedOperatorIntegral,rs,els,qs::SingleNumQStrat) = quadpoints(r quadrule(op::ComposedOperatorIntegral,refspace,p,y,q,el,qdata,qs::SingleNumQStrat) = qdata[1,q] defaultquadstrat(op::ComposedOperatorIntegral, basis) = SingleNumQStrat(6) -defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(7,8,6,7,6,6) +defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(7,8,5,5,4,3) defaultquadstrat(op::ComposedOperatorLocal,testspace::Space,trialpsace::Space) = SingleNumQStrat(8) #sign_upon_permutation(op::ComposedOperator,I,J) = Combinatorics.levicivita(I)^count_test_normals(op)*Combinatorics.levicivita(J)^count_trial_normals(op) diff --git a/src/multi-trace/VectorPotential.jl b/src/multi-trace/VectorPotential.jl index f6423f77..a22104f6 100644 --- a/src/multi-trace/VectorPotential.jl +++ b/src/multi-trace/VectorPotential.jl @@ -9,14 +9,18 @@ struct PRECVP <: Interaction trace::Int end +struct VPPMCHWT <: Interaction + trace::Int +end +VPPMCHWT() = VPPMCHWT(1) PRECVP() = PRECVP(1) function testbasis(obj::Object{T}, ::VP) where {T <: HOM} Γ = obj.type.mesh x1 = raviartthomas(Γ) - x2 = BEAST.lagrangec0d1(Γ) + x2 = BEAST.duallagrangecxd0(Γ) x3 = raviartthomas(Γ) - x4 = BEAST.lagrangec0d1(Γ) + x4 = BEAST.duallagrangec0d1(Γ) return BEAST.DirectProductSpace([x1,x2,x3,x4]) end @@ -25,9 +29,26 @@ function trialbasis(obj::Object{T}, ::VP) where {T <: HOM} x1 = raviartthomas(Γ) x2 = BEAST.lagrangec0d1(Γ) x3 = raviartthomas(Γ) + x4 = BEAST.lagrangecxd0(Γ) + return BEAST.DirectProductSpace([x1,x2,x3,x4]) +end +function testbasis(obj::Object{T}, ::VPPMCHWT) where {T <: HOM} + Γ = obj.type.mesh + x1 = raviartthomas(Γ) + x2 = BEAST.lagrangecxd0(Γ) + x3 = raviartthomas(Γ) x4 = BEAST.lagrangec0d1(Γ) return BEAST.DirectProductSpace([x1,x2,x3,x4]) end + +function trialbasis(obj::Object{T}, ::VPPMCHWT) where {T <: HOM} + Γ = obj.type.mesh + x1 = raviartthomas(Γ) + x2 = BEAST.lagrangec0d1(Γ) + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangecxd0(Γ) + return BEAST.DirectProductSpace([x1,x2,x3,x4]) +end function testbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} Γ = obj.type.mesh x1 = buffachristiansen(Γ) @@ -120,6 +141,14 @@ function interaction(testobj::Object,trialobj::Object,embobj::Object, 0 0 0 epsilon(parent(testobj))/epsilon(testobj)] a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign,dual=dual,trace=trace) end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::Inside,trialtype,strat::Union{VPPMCHWT}; sign=1,dual=true,trace=true) + a = [1 0 0 0; + 0 epsilon(parent(testobj))/epsilon(testobj) 0 0; + 0 0 mu(testobj)/mu(parent(testobj)) 0; + 0 0 0 1] + a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign,dual=dual,trace=trace) +end function interaction(testobj::Object,trialobj::Object,embobj::Object, testtype::PECCFIE,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) @@ -137,7 +166,7 @@ function interaction(testobj::Object,trialobj::Object,embobj::Object, interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::Inside,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + testtype::ObjectType,trialtype::Inside,strat::Union{PRECVP,VP,VPPMCHWT}; sign=1,dual=true,trace=true) a = -[1 0 0 0; 0 1 0 0; 0 0 mu(trialobj)/mu(parent(trialobj)) 0; @@ -149,11 +178,11 @@ function interaction(testobj::Object,trialobj::Object,embobj::Object, interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)[:,3:4] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP,PMCHWT}; sign=1,dual=true,trace=true) interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace) end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::HOM,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + testtype::HOM,trialtype,strat::Union{PRECVP,VP.PMCHWT}; sign=1,dual=true,trace=true) interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace) end function interaction(testobj::Object, trialobj::Object, embobj::Object, @@ -222,6 +251,72 @@ function interaction(testobj::Object, trialobj::Object, embobj::Object, return int end end +function interaction(testobj::Object, trialobj::Object, embobj::Object, + testtype::ObjectType,trialtype::ObjectType,strat::VPPMCHWT; sign=1,dual=true,trace=true) + tr = sign*strat.trace + k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + + bs = geometry(trialobj) + ts = geometry(testobj) + if trace + ∇Gx = BEAST.build_potential(gradG×B,bs) + Gn = BEAST.build_potential(G*(n*B),bs) + #Gnx = BEAST.build_potential(G*(n × B),bs) + ∇G = BEAST.build_potential(gradG*B,bs) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) + ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) + + Gr = BEAST.build_potential(G*B,bs) + ∇G∇B = BEAST.build_potential(gradG*div(B),bs) + ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) + else + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*div(B) + ∇Gxn = gradG×(nb*B) + + end + #gebruik gamma^c --> sign = + + # #without extra ncross + # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); + # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); + # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); + # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] + # #with extra ncross + if dual && trace + int = [-γₜ(∇Gx,ts,tr) γₜ(Gn,ts,tr) -γₜ(Gr,ts,tr) γₜ(∇G,ts,tr); + γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr); + -γₜ(∇G∇B,ts,tr)-k^2*γₜ(Gr,ts,tr) γₜ(∇Gxn,ts,tr) -γₜ(∇Gx,ts,tr) ZeroOperator(); + ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr)] + return int + elseif dual + int = [nt×(nt×(∇Gx)) -nt×(nt×(Gn)) nt×(nt×(Gr)) nt×(nt×(∇G)); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); + nt×(nt×(∇G∇B))+k^2*nt×(nt×(Gr)) -nt×(nt×(∇Gxn)) nt×(nt×(∇Gx)) ZeroOperator(); + ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr)] + return int + elseif trace + int = [γₛ(∇Gx,ts,tr) -γₛ(Gn,ts,tr) γₛ(Gr,ts,tr) -γₛ(∇G,ts,tr); + γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr); + γₛ(∇G∇B,ts,tr)+k^2*γₛ(Gr,ts,tr) -γₛ(∇Gxn,ts,tr) γₛ(∇Gx,ts,tr) ZeroOperator(); + ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr)] + return int + else + int = [nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); + nt×(∇G∇B)+k^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); + ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr)] + return int + end +end # function interaction(testobj::Object, trialobj::Object, embobj::Object, # testtype::ObjectType,trialtype::ObjectType,strat::VP; sign=1) # trace = sign*strat.trace @@ -295,7 +390,7 @@ function _identity(::ObjectType,strat::PRECVP) end _identity(p::PEC,strat::PRECVP) = _identity(p.inside,strat)[1:2,1:2] -function identity(objtype::ObjectType,strat::VP) +function identity(objtype::ObjectType,strat::Union{VP,VPPMCHWT}) [NCross() ZeroOperator() ZeroOperator() ZeroOperator(); ZeroOperator() Identity() ZeroOperator() ZeroOperator(); ZeroOperator() ZeroOperator() NCross() ZeroOperator(); @@ -317,7 +412,7 @@ function identity(objtype::PECEFIE,strat::Union{PRECVP,VP}) [ZeroOperator() ZeroOperator(); ZeroOperator() ZeroOperator()] end -identity(o::HOM,strat::Union{PRECVP,VP}) = identity(o.inside,strat) +identity(o::HOM,strat::Union{PRECVP,VP,VPPMCHWT}) = identity(o.inside,strat) # function interaction(testobj::Inside{Object{<:Union{FreeSpace,HOM}}}, # trialobj::Object, embobj::Object, # strat::VP) @@ -392,13 +487,30 @@ function excitation(obj::Object,emb::Object,objtype::ObjectType,ex::VPExcitation @warn "fix this type" return a end +function excitation(obj::Object,emb::Object,objtype::ObjectType,ex::VPExcitation,strat::VPPMCHWT) + emb.index ∉ ex.objectids && return [0,0,0,0] + a = [-1* ((n × FunctionExcitation{ComplexF64}(ex.A))×n), + NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(ex.A)), + -1* ((n × FunctionExcitation{ComplexF64}(ex.curlA))×n), + FunctionExcitation{ComplexF64}(ex.divA)] + @warn "fix this type" + return a +end function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation,strat::VP) a = [1 0 0 0; 0 1 0 0; 0 0 mu(testobj)/mu(parent(testobj)) 0; 0 0 0 epsilon(parent(testobj))/epsilon(testobj)] - return a*excitation(testobj,emb,objtype.inside,ex,strat) + return a^-1*excitation(testobj,emb,objtype.inside,ex,strat) +end +function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation,strat::VP) + a = [1 0 0 0; + 0 epsilon(parent(testobj))/epsilon(testobj) 0 0; + 0 0 mu(testobj)/mu(parent(testobj)) 0; + 0 0 0 1] + + return a^-1*excitation(testobj,emb,objtype.inside,ex,strat) end function excitation(testobj::Object,emb::Object,objtype::PECCFIE,ex::VPExcitation,strat::VP) @@ -413,7 +525,7 @@ function excitation(testobj::Object,emb::Object,objtype::PECMFIE,ex::VPExcitatio excitation(testobj,emb,objtype.inside,ex,strat)[3:4] end -excitation(testobj::Object,emb::Object,objtype::HOM,ex::VPExcitation,strat::VP) = excitation(testobj,emb,objtype.inside,ex,strat) +excitation(testobj::Object,emb::Object,objtype::HOM,ex::VPExcitation,strat::Union{VP,VPPMCHWT}) = excitation(testobj,emb,objtype.inside,ex,strat) ### Post Processing From 5e8ed87b6f8b8bef623051da845fe11b0368f731 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 16 Jan 2024 12:21:17 +0100 Subject: [PATCH 078/110] update --- src/composedoperator/postprocessing.jl | 2 +- src/multi-trace/VectorPotential.jl | 10 +++++----- src/multi-trace/postprocessing.jl | 8 ++++++-- src/solvers/lusolver.jl | 3 ++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/composedoperator/postprocessing.jl b/src/composedoperator/postprocessing.jl index 6697b5d5..a3b94611 100644 --- a/src/composedoperator/postprocessing.jl +++ b/src/composedoperator/postprocessing.jl @@ -9,7 +9,7 @@ kernelvals(op::ComposedOperator,a) = nothing function (func::FunctionExcitation)(x) return func.f(x) end -function (func::FunctionExcitation)(x::CompScienceMeshes.MeshPointNM) +function (func::FunctionExcitation)(x::Union{CompScienceMeshes.MeshPointNM,BEAST.TraceMeshPointNM}) return func.f(cartesian(x)) end scalartype(ff::FunctionExcitation{T}) where {T} = T diff --git a/src/multi-trace/VectorPotential.jl b/src/multi-trace/VectorPotential.jl index a22104f6..781f08ad 100644 --- a/src/multi-trace/VectorPotential.jl +++ b/src/multi-trace/VectorPotential.jl @@ -35,9 +35,9 @@ end function testbasis(obj::Object{T}, ::VPPMCHWT) where {T <: HOM} Γ = obj.type.mesh x1 = raviartthomas(Γ) - x2 = BEAST.lagrangecxd0(Γ) + x2 = BEAST.lagrangec0d1(Γ) x3 = raviartthomas(Γ) - x4 = BEAST.lagrangec0d1(Γ) + x4 = BEAST.lagrangecxd0(Γ) return BEAST.DirectProductSpace([x1,x2,x3,x4]) end @@ -178,11 +178,11 @@ function interaction(testobj::Object,trialobj::Object,embobj::Object, interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)[:,3:4] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP,PMCHWT}; sign=1,dual=true,trace=true) + testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP,VPPMCHWT}; sign=1,dual=true,trace=true) interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace) end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::HOM,trialtype,strat::Union{PRECVP,VP.PMCHWT}; sign=1,dual=true,trace=true) + testtype::HOM,trialtype,strat::Union{PRECVP,VP,VPPMCHWT}; sign=1,dual=true,trace=true) interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace) end function interaction(testobj::Object, trialobj::Object, embobj::Object, @@ -504,7 +504,7 @@ function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation return a^-1*excitation(testobj,emb,objtype.inside,ex,strat) end -function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation,strat::VP) +function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation,strat::VPPMCHWT) a = [1 0 0 0; 0 epsilon(parent(testobj))/epsilon(testobj) 0 0; 0 0 mu(testobj)/mu(parent(testobj)) 0; diff --git a/src/multi-trace/postprocessing.jl b/src/multi-trace/postprocessing.jl index 2317dbcb..74c536fb 100644 --- a/src/multi-trace/postprocessing.jl +++ b/src/multi-trace/postprocessing.jl @@ -75,7 +75,7 @@ end function complement_error(world,solution,volume::Vector{Int},strat::T;trace=true) where {T} @warn "exclude free space!!!" newstrat = T(-strat.trace) - @assert T <: VP + lhs = discretise_lhs(world,newstrat;id=0.0,dual=false,trace=trace) out = lhs[volume].*Ref(solution) g = BlockDiagonalOperator(BlockDiagonalOperator(Identity())) @@ -86,4 +86,8 @@ function complement_error(world,solution,volume::Vector{Int},strat::T;trace=true println("G inverted") return dot.(Vector.(out),ttt)/dot(solution,G2,solution),ttt,out,G,dot(solution,G2,solution) # norm(sum(out))/norm(solution) -end \ No newline at end of file +end + +# x'Zxa = x'xb => b andere volgorde dan a, x' is testvector, x is trialvector --> zelfde doordat b andere volgorde heeft. +# (G-1) Z a = b , integreer b, dit geeft: b xx b +# finaal resultaat, ttt (G-1) ttt, componenten in volgorde van b, \ No newline at end of file diff --git a/src/solvers/lusolver.jl b/src/solvers/lusolver.jl index 7c5ee2e2..5d09950e 100644 --- a/src/solvers/lusolver.jl +++ b/src/solvers/lusolver.jl @@ -22,7 +22,7 @@ using LinearAlgebra Solves a variational equation by simply creating the full system matrix and calling a traditional lu decomposition. """ -function solve(eq) +function solve(eq;Zz=false) time_domain = isa(first(eq.trial_space_dict).second, BEAST.SpaceTimeBasis) time_domain |= isa(first(eq.trial_space_dict).second, BEAST.StagedTimeStep) @@ -57,6 +57,7 @@ function solve(eq) # return u # return PseudoBlockVector(u, blocksizes(Z,2)) ax = nestedrange(Y, 1, numfunctions) + Zz && (return PseudoBlockVector(u, (ax,)), Z) return PseudoBlockVector(u, (ax,)) end From f8679eca7a6431214a07e360fb16121386a1fdd7 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 12 Feb 2024 14:52:53 +0100 Subject: [PATCH 079/110] cleanup composed operator --- src/bases/basis.jl | 2 + src/composedoperator/composedoperator.jl | 119 ++++++++++++----------- src/composedoperator/tracesimplex.jl | 2 +- 3 files changed, 65 insertions(+), 58 deletions(-) diff --git a/src/bases/basis.jl b/src/bases/basis.jl index 9cbe39c5..d8578ad2 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -62,6 +62,8 @@ struct DirectProductSpace{T,S<:AbstractSpace} <: AbstractSpace factors::Vector{S} end + + function DirectProductSpace(factors::Vector{S}) where {S<:AbstractSpace} @assert !isempty(factors) T = scalartype(factors...) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 28b08658..79b8a8c8 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -172,19 +172,19 @@ scalartype(op::Operations) = promote_type(scalartype(op.lhs),scalartype(op.rhs)) scalartype(op::Potential) = scalartype(op.operator) scalartype(op::TraceOperator) = scalartype(op.operator) -function count_test_normals(op::Operations) - count_test_normals(op.lhs) + count_test_normals(op.rhs) -end -count_test_normals(op::Kernel) = 0 -count_test_normals(op::TestNormal) = 1 -count_test_normals(op::TrialNormal) = 0 +# function count_test_normals(op::Operations) +# count_test_normals(op.lhs) + count_test_normals(op.rhs) +# end +# count_test_normals(op::Kernel) = 0 +# count_test_normals(op::TestNormal) = 1 +# count_test_normals(op::TrialNormal) = 0 -function count_trial_normals(op::Operations) - count_trial_normals(op.lhs) + count_trial_normals(op.rhs) -end -count_trial_normals(op::Kernel) = 0 -count_trial_normals(op::TestNormal) = 0 -count_trial_normals(op::TrialNormal) = 1 +# function count_trial_normals(op::Operations) +# count_trial_normals(op.lhs) + count_trial_normals(op.rhs) +# end +# count_trial_normals(op::Kernel) = 0 +# count_trial_normals(op::TestNormal) = 0 +# count_trial_normals(op::TrialNormal) = 1 function replace_normal_by_testnormal(op::Operations) get_constructor(op)(replace_normal_by_testnormal(op.lhs),replace_normal_by_testnormal(op.rhs)) @@ -210,10 +210,11 @@ function build_potential(op::ComposedOperator,surface::TraceMesh) newop = replace_normal_by_trialnormal(op) Potential(newop,surface) end -function build_potential(op::ComposedOperator) - newop = replace_normal_by_trialnormal(op) - Potential(newop,nothing) -end +# function build_potential(op::ComposedOperator) +# newop = replace_normal_by_trialnormal(op) +# Potential(newop,nothing) +# end + function γ(op::Operations) return get_constructor(op)(γ(op.lhs),γ(op.rhs)) @@ -236,26 +237,26 @@ function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# si end return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) end -function γₜ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt × (γ(op.operator) × nt) - return TraceOperator(Potential(newop,op.surface),sign) -end -function γₛ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt × γ(op.operator) - return TraceOperator(Potential(newop,op.surface),sign) -end -function γₙ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt ⋅ γ(op.operator) - return TraceOperator(Potential(newop,op.surface),sign) -end -function τ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = γ(op.operator) - return TraceOperator(Potential(newop,op.surface),sign) -end +# function γₜ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = nt × (γ(op.operator) × nt) +# return TraceOperator(Potential(newop,op.surface),sign) +# end +# function γₛ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = nt × γ(op.operator) +# return TraceOperator(Potential(newop,op.surface),sign) +# end +# function γₙ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = nt ⋅ γ(op.operator) +# return TraceOperator(Potential(newop,op.surface),sign) +# end +# function τ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = γ(op.operator) +# return TraceOperator(Potential(newop,op.surface),sign) +# end function γ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator @@ -272,22 +273,26 @@ end function γₛ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = nt × γ(op.operator) - direction = [] - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) + # direction = [] + # for i in 1:numcells(surface) + # c = chart(surface,i) + # push!(direction,sign*normal(c)/3) + # end + charts = chart.(Ref(surface),1:numcells(surface)) + direction = sign/3*normal.(charts) + return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) end function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = nt × γ(op.operator) - direction = [] - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) + # direction = [] + # for i in 1:numcells(surface) + # c = chart(surface,i) + # push!(direction,sign*normal(c)/3) + # end + charts = chart.(Ref(surface),1:numcells(surface)) + direction = sign/3*normal.(charts) + return TraceOperator(Potential(newop,op.surface),direction+surface) end function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise @@ -519,7 +524,7 @@ defaultquadstrat(op::Potential,test,trial) = defaultquadstrat(op.operator,test,t function assemble!(op::Potential, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; quadstrat = defaultquadstrat(op, test_functions, trial_functions)) - + # checks if surface given in basis is the same as surface given in potential dsurf = surface(op) surf = geometry(trial_functions) @assert same_geometry(dsurf,surf) @@ -529,16 +534,16 @@ function assemble!(op::Potential, test_functions::Space, trial_functions::Space, assemble!(op.operator, test_functions, trial_functions, store, threading; quadstrat = quadstrat) end -function assemble!(op::Potential{T,Nothing}, test_functions::Space, trial_functions::Space, - store, threading = Threading{:multi}; - quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} +# function assemble!(op::Potential{T,Nothing}, test_functions::Space, trial_functions::Space, +# store, threading = Threading{:multi}; +# quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} - surf = geometry(trial_functions) - trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) +# surf = geometry(trial_functions) +# trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) - assemble!(op.operator, test_functions, trial_functions, store, threading; - quadstrat = quadstrat) -end +# assemble!(op.operator, test_functions, trial_functions, store, threading; +# quadstrat = quadstrat) +# end function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index 3c448b9a..829ad15b 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -71,7 +71,7 @@ struct OrientedMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} end struct TraceMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} mesh::CompScienceMeshes.AbstractMesh{U,D1,T} - direction + direction::Vector{SVector{3,T}} end TraceMesh(a::CompScienceMeshes.AbstractMesh{U,D,T}) where {U,D,T} = TraceMesh(a,zeros(SVector{numcells(a),SVector{3,T}})) +(a::TraceMesh{U,D,T},b::SVector{3,T}) where {U,D,T} = TraceMesh(mesh(a),direction(a).+Ref(b)) From f1b4646322dab0da994ee8eed2aec6e3c95caa2f Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 12 Feb 2024 14:53:29 +0100 Subject: [PATCH 080/110] added pmchwt like method to multi-trace vector potential --- src/multi-trace/VectorPotential.jl | 273 ++++++++++++++++++++++++++--- 1 file changed, 253 insertions(+), 20 deletions(-) diff --git a/src/multi-trace/VectorPotential.jl b/src/multi-trace/VectorPotential.jl index 781f08ad..362b6cb4 100644 --- a/src/multi-trace/VectorPotential.jl +++ b/src/multi-trace/VectorPotential.jl @@ -9,18 +9,28 @@ struct PRECVP <: Interaction trace::Int end +struct PRECVPPMCHWT2 <: Interaction + trace::Int + rows + cols +end struct VPPMCHWT <: Interaction trace::Int end VPPMCHWT() = VPPMCHWT(1) +struct VPPMCHWT2 <: Interaction + trace::Int +end +PRECVPPMCHWT2() = PRECVPPMCHWT2(1,[1,2,3,4],[1,2,3,4]) +VPPMCHWT2() = VPPMCHWT2(1) PRECVP() = PRECVP(1) function testbasis(obj::Object{T}, ::VP) where {T <: HOM} Γ = obj.type.mesh x1 = raviartthomas(Γ) - x2 = BEAST.duallagrangecxd0(Γ) + x2 = BEAST.lagrangecxd0(Γ) x3 = raviartthomas(Γ) - x4 = BEAST.duallagrangec0d1(Γ) + x4 = BEAST.lagrangec0d1(Γ) return BEAST.DirectProductSpace([x1,x2,x3,x4]) end @@ -32,6 +42,40 @@ function trialbasis(obj::Object{T}, ::VP) where {T <: HOM} x4 = BEAST.lagrangecxd0(Γ) return BEAST.DirectProductSpace([x1,x2,x3,x4]) end +function testbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} + Γ = obj.type.mesh + x1 = buffachristiansen(Γ) + x2 = BEAST.duallagrangecxd0(Γ) + x3 = buffachristiansen(Γ) + x4 = BEAST.duallagrangec0d1(Γ) + return BEAST.DirectProductSpace([x1,x2,x3,x4]) +end + +function trialbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} + Γ = obj.type.mesh + x1 = buffachristiansen(Γ) + x2 = BEAST.duallagrangec0d1(Γ) + x3 = buffachristiansen(Γ) + x4 = BEAST.duallagrangecxd0(Γ) + return BEAST.DirectProductSpace([x1,x2,x3,x4]) +end +function testbasis(obj::Object{T}, ::PRECVPPMCHWT2) where {T <: HOM} + Γ = obj.type.mesh + x1 = buffachristiansen(Γ) + x2 = BEAST.duallagrangec0d1(Γ) + x3 = buffachristiansen(Γ) + x4 = BEAST.duallagrangecxd0(Γ) + return BEAST.DirectProductSpace([x1,x2,x3,x4]) +end + +function trialbasis(obj::Object{T}, ::PRECVPPMCHWT2) where {T <: HOM} + Γ = obj.type.mesh + x1 = buffachristiansen(Γ) + x2 = BEAST.duallagrangec0d1(Γ) + x3 = buffachristiansen(Γ) + x4 = BEAST.duallagrangecxd0(Γ) + return BEAST.DirectProductSpace([x1,x2,x3,x4]) +end function testbasis(obj::Object{T}, ::VPPMCHWT) where {T <: HOM} Γ = obj.type.mesh x1 = raviartthomas(Γ) @@ -49,23 +93,40 @@ function trialbasis(obj::Object{T}, ::VPPMCHWT) where {T <: HOM} x4 = BEAST.lagrangecxd0(Γ) return BEAST.DirectProductSpace([x1,x2,x3,x4]) end -function testbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} +function testbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: HOM} Γ = obj.type.mesh - x1 = buffachristiansen(Γ) + x1 = raviartthomas(Γ) x2 = BEAST.lagrangec0d1(Γ) - x3 = buffachristiansen(Γ) - x4 = BEAST.lagrangec0d1(Γ) + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangecxd0(Γ) return BEAST.DirectProductSpace([x1,x2,x3,x4]) end -function trialbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} +function trialbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: HOM} Γ = obj.type.mesh - x1 = buffachristiansen(Γ) + x1 = raviartthomas(Γ) x2 = BEAST.lagrangec0d1(Γ) - x3 = buffachristiansen(Γ) - x4 = BEAST.lagrangec0d1(Γ) + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangecxd0(Γ) return BEAST.DirectProductSpace([x1,x2,x3,x4]) end +# function testbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} +# Γ = obj.type.mesh +# x1 = buffachristiansen(Γ) +# x2 = BEAST.lagrangec0d1(Γ) +# x3 = buffachristiansen(Γ) +# x4 = BEAST.lagrangec0d1(Γ) +# return BEAST.DirectProductSpace([x1,x2,x3,x4]) +# end + +# function trialbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} +# Γ = obj.type.mesh +# x1 = buffachristiansen(Γ) +# x2 = BEAST.lagrangec0d1(Γ) +# x3 = buffachristiansen(Γ) +# x4 = BEAST.lagrangec0d1(Γ) +# return BEAST.DirectProductSpace([x1,x2,x3,x4]) +# end function testbasis(obj::Object{T}, ::VP) where {T <: PECEFIE} Γ = obj.type.mesh @@ -134,7 +195,7 @@ end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::Inside,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + testtype::Inside,trialtype,strat::Union{PRECVP,VP,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) a = [1 0 0 0; 0 1 0 0; 0 0 mu(testobj)/mu(parent(testobj)) 0; @@ -149,6 +210,14 @@ function interaction(testobj::Object,trialobj::Object,embobj::Object, 0 0 0 1] a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign,dual=dual,trace=trace) end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::Inside,trialtype,strat::Union{VPPMCHWT2}; sign=1,dual=true,trace=true) + a = [mu(testobj)/mu(parent(testobj)) 0 0 0; + 0 epsilon(parent(testobj))/epsilon(testobj) 0 0; + 0 0 1 0; + 0 0 0 1] + a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign,dual=dual,trace=trace) +end function interaction(testobj::Object,trialobj::Object,embobj::Object, testtype::PECCFIE,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) @@ -166,27 +235,35 @@ function interaction(testobj::Object,trialobj::Object,embobj::Object, interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::Inside,strat::Union{PRECVP,VP,VPPMCHWT}; sign=1,dual=true,trace=true) + testtype::ObjectType,trialtype::Inside,strat::Union{PRECVP,VP,VPPMCHWT,VPPMCHWT2}; sign=1,dual=true,trace=true) a = -[1 0 0 0; 0 1 0 0; 0 0 mu(trialobj)/mu(parent(trialobj)) 0; 0 0 0 epsilon(parent(trialobj))/epsilon(trialobj)] interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)*a end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::ObjectType,trialtype::Inside,strat::Union{PRECVPPMCHWT2}; sign=1,dual=true,trace=true) + a = -[mu(trialobj)/mu(parent(trialobj)) 0 0 0; + 0 epsilon(parent(trialobj))/epsilon(trialobj) 0 0; + 0 0 1 0; + 0 0 0 1] + interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)*a +end function interaction(testobj::Object,trialobj::Object,embobj::Object, testtype::ObjectType,trialtype::PEC,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)[:,3:4] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP,VPPMCHWT}; sign=1,dual=true,trace=true) + testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP,VPPMCHWT,VPPMCHWT2,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace) end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::HOM,trialtype,strat::Union{PRECVP,VP,VPPMCHWT}; sign=1,dual=true,trace=true) + testtype::HOM,trialtype,strat::Union{PRECVP,VP,VPPMCHWT,VPPMCHWT2,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace) end function interaction(testobj::Object, trialobj::Object, embobj::Object, - testtype::ObjectType,trialtype::ObjectType,strat::VP; sign=1,dual=true,trace=true) + testtype::ObjectType,trialtype::ObjectType,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) tr = sign*strat.trace k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) G = BEAST.greenhh3d(wavenumber=k) @@ -251,6 +328,80 @@ function interaction(testobj::Object, trialobj::Object, embobj::Object, return int end end +function interaction(testobj::Object, trialobj::Object, embobj::Object, + testtype::ObjectType,trialtype::ObjectType,strat::Union{PRECVPPMCHWT2}; sign=1,dual=true,trace=true) + tr = sign*strat.trace + k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + switch_collums(mat) = [mat[:,3:4] mat[:,1:2]] + + zer = Matrix{AbstractOperator}(undef,4,4) + fill!(zer,ZeroOperator()) + rows = strat.rows + cols = strat.cols + + bs = geometry(trialobj) + ts = geometry(testobj) + if trace + ∇Gx = BEAST.build_potential(gradG×B,bs) + Gn = BEAST.build_potential(G*(n*B),bs) + #Gnx = BEAST.build_potential(G*(n × B),bs) + ∇G = BEAST.build_potential(gradG*B,bs) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) + ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) + + Gr = BEAST.build_potential(G*B,bs) + ∇G∇B = BEAST.build_potential(gradG*div(B),bs) + ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) + else + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*div(B) + ∇Gxn = gradG×(nb*B) + + end + #gebruik gamma^c --> sign = + + # #without extra ncross + # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); + # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); + # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); + # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] + # #with extra ncross + if dual && trace + int = [-γₜ(∇Gx,ts,tr) γₜ(Gn,ts,tr) -γₜ(Gr,ts,tr) γₜ(∇G,ts,tr); + ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr); + -γₜ(∇G∇B,ts,tr)-k^2*γₜ(Gr,ts,tr) γₜ(∇Gxn,ts,tr) -γₜ(∇Gx,ts,tr) ZeroOperator(); + γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr)] + out = switch_collums(int) + elseif dual + int = [nt×(nt×(∇Gx)) -nt×(nt×(Gn)) nt×(nt×(Gr)) nt×(nt×(∇G)); + ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr); + nt×(nt×(∇G∇B))+k^2*nt×(nt×(Gr)) -nt×(nt×(∇Gxn)) nt×(nt×(∇Gx)) ZeroOperator(); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G)] + out = switch_collums(int) + elseif trace + int = [γₛ(∇Gx,ts,tr) -γₛ(Gn,ts,tr) γₛ(Gr,ts,tr) -γₛ(∇G,ts,tr); + ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr); + γₛ(∇G∇B,ts,tr)+k^2*γₛ(Gr,ts,tr) -γₛ(∇Gxn,ts,tr) γₛ(∇Gx,ts,tr) ZeroOperator(); + γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr)] + out = switch_collums(int) + else + int = [nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); + ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr); + nt×(∇G∇B)+k^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G)] + out = switch_collums(int) + end + zer[rows,cols] .+= out[rows,cols] + return zer +end function interaction(testobj::Object, trialobj::Object, embobj::Object, testtype::ObjectType,trialtype::ObjectType,strat::VPPMCHWT; sign=1,dual=true,trace=true) tr = sign*strat.trace @@ -317,6 +468,72 @@ function interaction(testobj::Object, trialobj::Object, embobj::Object, return int end end +function interaction(testobj::Object, trialobj::Object, embobj::Object, + testtype::ObjectType,trialtype::ObjectType,strat::VPPMCHWT2; sign=1,dual=true,trace=true) + tr = sign*strat.trace + k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) + G = BEAST.greenhh3d(wavenumber=k) + gradG = BEAST.∇(G) + + bs = geometry(trialobj) + ts = geometry(testobj) + if trace + ∇Gx = BEAST.build_potential(gradG×B,bs) + Gn = BEAST.build_potential(G*(n*B),bs) + #Gnx = BEAST.build_potential(G*(n × B),bs) + ∇G = BEAST.build_potential(gradG*B,bs) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) + ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) + + Gr = BEAST.build_potential(G*B,bs) + ∇G∇B = BEAST.build_potential(gradG*div(B),bs) + ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) + else + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*div(B) + ∇Gxn = gradG×(nb*B) + + end + #gebruik gamma^c --> sign = + + # #without extra ncross + # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); + # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); + # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); + # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] + # #with extra ncross + if dual && trace + int = [-γₜ(∇G∇B,ts,tr)-k^2*γₜ(Gr,ts,tr) γₜ(∇Gxn,ts,tr) -γₜ(∇Gx,ts,tr) ZeroOperator(); + γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr); + -γₜ(∇Gx,ts,tr) γₜ(Gn,ts,tr) -γₜ(Gr,ts,tr) γₜ(∇G,ts,tr); + ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr)] + return int + elseif dual + int = [nt×(nt×(∇G∇B))+k^2*nt×(nt×(Gr)) -nt×(nt×(∇Gxn)) nt×(nt×(∇Gx)) ZeroOperator(); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); + nt×(nt×(∇Gx)) -nt×(nt×(Gn)) nt×(nt×(Gr)) nt×(nt×(∇G)); + ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr)] + return int + elseif trace + int = [γₛ(∇G∇B,ts,tr)+k^2*γₛ(Gr,ts,tr) -γₛ(∇Gxn,ts,tr) γₛ(∇Gx,ts,tr) ZeroOperator(); + γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr); + γₛ(∇Gx,ts,tr) -γₛ(Gn,ts,tr) γₛ(Gr,ts,tr) -γₛ(∇G,ts,tr); + ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr)] + return int + else + int = [nt×(∇G∇B)+k^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); + nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); + ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr)] + return int + end +end # function interaction(testobj::Object, trialobj::Object, embobj::Object, # testtype::ObjectType,trialtype::ObjectType,strat::VP; sign=1) # trace = sign*strat.trace @@ -362,7 +579,6 @@ end # bss = geometry(trialobj) # tss = geometry(testobj) - # ∇Gx = BEAST.build_potential(gradG×B,bs)# # Gn = BEAST.build_potential(G*(n*B),bss)# @@ -390,14 +606,14 @@ function _identity(::ObjectType,strat::PRECVP) end _identity(p::PEC,strat::PRECVP) = _identity(p.inside,strat)[1:2,1:2] -function identity(objtype::ObjectType,strat::Union{VP,VPPMCHWT}) +function identity(objtype::ObjectType,strat::Union{VP,VPPMCHWT,VPPMCHWT2,PRECVPPMCHWT2}) [NCross() ZeroOperator() ZeroOperator() ZeroOperator(); ZeroOperator() Identity() ZeroOperator() ZeroOperator(); ZeroOperator() ZeroOperator() NCross() ZeroOperator(); ZeroOperator() ZeroOperator() ZeroOperator() Identity()] end function identity(objtype::ObjectType,strat::PRECVP) - -[NCross() ZeroOperator() ZeroOperator() ZeroOperator(); + [NCross() ZeroOperator() ZeroOperator() ZeroOperator(); ZeroOperator() Identity() ZeroOperator() ZeroOperator(); ZeroOperator() ZeroOperator() NCross() ZeroOperator(); ZeroOperator() ZeroOperator() ZeroOperator() Identity()] @@ -412,7 +628,7 @@ function identity(objtype::PECEFIE,strat::Union{PRECVP,VP}) [ZeroOperator() ZeroOperator(); ZeroOperator() ZeroOperator()] end -identity(o::HOM,strat::Union{PRECVP,VP,VPPMCHWT}) = identity(o.inside,strat) +identity(o::HOM,strat::Union{PRECVP,VP,VPPMCHWT,VPPMCHWT2,PRECVPPMCHWT2}) = identity(o.inside,strat) # function interaction(testobj::Inside{Object{<:Union{FreeSpace,HOM}}}, # trialobj::Object, embobj::Object, # strat::VP) @@ -496,6 +712,15 @@ function excitation(obj::Object,emb::Object,objtype::ObjectType,ex::VPExcitation @warn "fix this type" return a end +function excitation(obj::Object,emb::Object,objtype::ObjectType,ex::VPExcitation,strat::VPPMCHWT2) + emb.index ∉ ex.objectids && return [0,0,0,0] + a = [-1* ((n × FunctionExcitation{ComplexF64}(ex.curlA))×n), + NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(ex.A)), + -1* ((n × FunctionExcitation{ComplexF64}(ex.A))×n), + FunctionExcitation{ComplexF64}(ex.divA)] + @warn "fix this type" + return a +end function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation,strat::VP) a = [1 0 0 0; 0 1 0 0; @@ -512,6 +737,14 @@ function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation return a^-1*excitation(testobj,emb,objtype.inside,ex,strat) end +function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation,strat::VPPMCHWT2) + a = [mu(testobj)/mu(parent(testobj)) 0 0 0; + 0 epsilon(parent(testobj))/epsilon(testobj) 0 0; + 0 0 1 0; + 0 0 0 1] + + return a^-1*excitation(testobj,emb,objtype.inside,ex,strat) +end function excitation(testobj::Object,emb::Object,objtype::PECCFIE,ex::VPExcitation,strat::VP) objtype.alpha*excitation(testobj,emb,objtype.inside,ex,strat)[1:2]+ @@ -525,7 +758,7 @@ function excitation(testobj::Object,emb::Object,objtype::PECMFIE,ex::VPExcitatio excitation(testobj,emb,objtype.inside,ex,strat)[3:4] end -excitation(testobj::Object,emb::Object,objtype::HOM,ex::VPExcitation,strat::Union{VP,VPPMCHWT}) = excitation(testobj,emb,objtype.inside,ex,strat) +excitation(testobj::Object,emb::Object,objtype::HOM,ex::VPExcitation,strat::Union{VP,VPPMCHWT,VPPMCHWT2}) = excitation(testobj,emb,objtype.inside,ex,strat) ### Post Processing From 0acbb46c458e9b3e465e0ea5c217f0d560c06296 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 12 Feb 2024 14:54:08 +0100 Subject: [PATCH 081/110] corrected linearalgebra adjoint and transpose --- src/solvers/itsolver.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solvers/itsolver.jl b/src/solvers/itsolver.jl index 8e516ce6..e504b750 100644 --- a/src/solvers/itsolver.jl +++ b/src/solvers/itsolver.jl @@ -78,8 +78,8 @@ function LinearAlgebra.mul!(y::AbstractVecOrMat, solver::GMRESSolver, x::Abstrac return y end -LinearAlgebra.adjoint(A::GMRESSolver) = GMRESSolver(adjoint(A.linear_operator), A.maxiter, A.restart, A.abstol, A.reltol, A.verbose) -LinearAlgebra.transpose(A::GMRESSolver) = GMRESSolver(transpose(A.linear_operator), A.maxiter, A.restart, A.abstol, A.reltol, A.verbose) +LinearAlgebra.adjoint(A::GMRESSolver) = GMRESSolver(adjoint(A.linear_operator); A.left_preconditioner, A.maxiter, A.restart, A.abstol, A.reltol, A.verbose) +LinearAlgebra.transpose(A::GMRESSolver) = GMRESSolver(transpose(A.linear_operator); A.left_preconditioner, A.maxiter, A.restart, A.abstol, A.reltol, A.verbose) From 0a7072f26a65bfe6b74a8663166ea84d5a33c640 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 12 Feb 2024 14:54:25 +0100 Subject: [PATCH 082/110] added single value basis --- src/bases/lagrange.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/bases/lagrange.jl b/src/bases/lagrange.jl index 9b44607d..a79ee583 100644 --- a/src/bases/lagrange.jl +++ b/src/bases/lagrange.jl @@ -48,6 +48,13 @@ function lagrangecxd0(mesh) LagrangeBasis{0,-1,NF}(geometry, fns, pos) end +function single_unknown(mesh) + space = lagrangecxd0(mesh) + NF = numfunctions(space) + pos = space.pos[1:1] + fns = [[i[1] for i in space.fns]] + LagrangeBasis{0,-1,NF}(space.geo,fns,pos) +end """ lagrangec0d1(mesh[, bnd]) From 4462de7addcaf5a72c0f03386dc436ffa0b1bc30 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 21 Feb 2024 11:01:05 +0100 Subject: [PATCH 083/110] update to make vppmchwt file working --- examples/vppmchwt.jl | 380 +++++++++++++++++++++++ src/bases/bcspace.jl | 1 - src/composedoperator/composedoperator.jl | 168 +++++----- src/composedoperator/postprocessing.jl | 2 +- src/composedoperator/tracesimplex.jl | 24 +- src/operator.jl | 6 +- src/solvers/itsolver.jl | 11 + src/solvers/lusolver.jl | 15 + src/solvers/solver.jl | 1 - src/utils/variational.jl | 95 +++++- 10 files changed, 611 insertions(+), 92 deletions(-) create mode 100644 examples/vppmchwt.jl diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl new file mode 100644 index 00000000..69e79d32 --- /dev/null +++ b/examples/vppmchwt.jl @@ -0,0 +1,380 @@ +using BEAST +using CompScienceMeshes +using LinearAlgebra +using AbstractTrees +using StaticArrays + +function Z(κ;rows=[1,2,3,4],cols=[1,2,3,4],trace=true,dual=true,tr=1) # build to test with nxt in dual true + G = BEAST.greenhh3d(wavenumber=κ) + gradG = BEAST.∇(G) + if trace + ∇Gx = BEAST.build_potential(gradG×B) + Gn = BEAST.build_potential(G*(n*B)) + #Gnx = BEAST.build_potential(G*(n × B)) + ∇G = BEAST.build_potential(gradG*B) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B)) + ∇Gdot = BEAST.build_potential(B ⋅ gradG) + + Gr = BEAST.build_potential(G*B) + ∇G∇B = BEAST.build_potential(gradG*BEAST.div(B)) + ∇Gxn = BEAST.build_potential(gradG×(n*B)) + else + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*BEAST.div(B) + ∇Gxn = gradG×(nb*B) + + end + + if dual && trace + int = -[γₜ(∇G∇B,tr)+κ^2*γₜ(Gr,tr) -γₜ(∇Gxn,tr) γₜ(∇Gx,tr) ZeroOperator(); + γₙ(∇Gx,tr) -γₙ(Gn,tr) γₙ(Gr,tr) -γₙ(∇G,tr); + γₜ(∇Gx,tr) -γₜ(Gn,tr) γₜ(Gr,tr) -γₜ(∇G,tr); + ZeroOperator() -τ(∇Gdotn,tr) τ(∇Gdot,tr) κ^2*τ(Gr,tr)] + + elseif dual + int = -[-nt×(nt×(∇G∇B))-κ^2*nt×(nt×(Gr)) nt×(nt×(∇Gxn)) -nt×(nt×(∇Gx)) ZeroOperator(); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); + -nt×(nt×(∇Gx)) nt×(nt×(Gn)) -nt×(nt×(Gr)) nt×(nt×(∇G)); + ZeroOperator() -(∇Gdotn) (∇Gdot) κ^2*(Gr)] + + elseif trace + int = -[γₛ(∇G∇B,tr)+κ^2*γₛ(Gr,tr) -γₛ(∇Gxn,tr) γₛ(∇Gx,tr) ZeroOperator(); + γₙ(∇Gx,tr) -γₙ(Gn,tr) γₙ(Gr,tr) -γₙ(∇G,tr); + γₛ(∇Gx,tr) -γₛ(Gn,tr) γₛ(Gr,tr) -γₛ(∇G,tr); + ZeroOperator() -τ(∇Gdotn,tr) τ(∇Gdot,tr) κ^2*τ(Gr,tr)] + + else + int = -[nt×(∇G∇B)+κ^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); + nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); + ZeroOperator() -(∇Gdotn) (∇Gdot) κ^2*(Gr)] + + end + return BEAST.matrix_to_bilform(int[rows,cols]) +end +function Zp(κ;rows=[1,2,3,4],cols=[1,2,3,4],trace=true,dual=true,tr=1) # build to test with nxt in dual true + G = BEAST.greenhh3d(wavenumber=κ) + gradG = BEAST.∇(G) + tr *=-1 + if trace + ∇Gx = BEAST.build_potential(gradG×B) + Gn = BEAST.build_potential(G*(n*B)) + #Gnx = BEAST.build_potential(G*(n × B)) + ∇G = BEAST.build_potential(gradG*B) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B)) + ∇Gdot = BEAST.build_potential(B ⋅ gradG) + + Gr = BEAST.build_potential(G*B) + ∇G∇B = BEAST.build_potential(gradG*BEAST.div(B)) + ∇Gxn = BEAST.build_potential(gradG×(n*B)) + else + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*BEAST.div(B) + ∇Gxn = gradG×(nb*B) + + end + + if dual && trace + int = -[γₜ(∇G∇B,tr)+κ^2*γₜ(Gr,tr) -γₜ(∇Gxn,tr) γₜ(∇Gx,tr) ZeroOperator(); + γₙ(∇Gx,tr) -γₙ(Gn,tr) γₙ(Gr,tr) -γₙ(∇G,tr); + γₜ(∇Gx,tr) -γₜ(Gn,tr) γₜ(Gr,tr) -γₜ(∇G,tr); + ZeroOperator() -τ(∇Gdotn,tr) τ(∇Gdot,tr) κ^2*τ(Gr,tr)][[3,4,1,2],[3,4,1,2]] + + elseif dual + int = -[-nt×(nt×(∇G∇B))-κ^2*nt×(nt×(Gr)) nt×(nt×(∇Gxn)) -nt×(nt×(∇Gx)) ZeroOperator(); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); + -nt×(nt×(∇Gx)) nt×(nt×(Gn)) -nt×(nt×(Gr)) nt×(nt×(∇G)); + ZeroOperator() -(∇Gdotn) (∇Gdot) κ^2*(Gr)] + + elseif trace + int = -[γₛ(∇G∇B,tr)+κ^2*γₛ(Gr,tr) -γₛ(∇Gxn,tr) γₛ(∇Gx,tr) ZeroOperator(); + γₙ(∇Gx,tr) -γₙ(Gn,tr) γₙ(Gr,tr) -γₙ(∇G,tr); + γₛ(∇Gx,tr) -γₛ(Gn,tr) γₛ(Gr,tr) -γₛ(∇G,tr); + ZeroOperator() -τ(∇Gdotn,tr) τ(∇Gdot,tr) κ^2*τ(Gr,tr)][[3,4,1,2],[3,4,1,2]] + + else + int = -[nt×(∇G∇B)+κ^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); + nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); + nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); + ZeroOperator() -(∇Gdotn) (∇Gdot) κ^2*(Gr)][[3,4,1,2],[3,4,1,2]] + + end + return BEAST.matrix_to_bilform(int[rows,cols]) +end +function excitation(A,curlA,divA;rows=[1,2,3,4]) + out = [((n × FunctionExcitation{ComplexF64}(curlA))×n), + BEAST.NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(A)), + ((n × FunctionExcitation{ComplexF64}(A))×n), + FunctionExcitation{ComplexF64}(divA)] + return BEAST.array_to_linform(out[rows]) +end +function solve(Z,b,X;strat,kwargs...) + if strat ==:LU + return BEAST.solve(b,Z,X;kwargs...) + elseif strat == :GMRES + return BEAST.gmres_ch(b,Z,X;kwargs...) + end + @error "no existing strategy given, use :LU or :GMRES" +end + +parent(ind,tree) = tree[ind] +children(ind,tree) = findall(==(ind),tree) +### physical constants +ϵ0 = 8.854e-12 +μ0 = 4π*1e-7 +ω = 10.0^8*2*pi +κ0 = ω*sqrt(ϵ0*μ0) + +#### define meshes +hh = 0.3 +Γ1 = meshcuboid(1.0, 1.0, 1.0, hh) +Γ2 = (@SVector [-1.0,0.0,0.0]) + BEAST.TraceMesh(-Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1)))) +Γ3 = (@SVector [0.0,0.0,-1.0]) + BEAST.TraceMesh(-Mesh([point(x,y,-z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1)))) + +Γ = [Γ1,Γ2,Γ3] +Tree = [0,0,0] # give index in which material is + +HOM = [1,2,3] #indices of homogeneous domains (without free space) +HomPars = Dict(0=>(ϵ0,μ0),1=>(ϵ0,μ0*3),2=>(ϵ0*6,μ0*4),3=>(ϵ0*2,μ0*3))#index --> (eps,mu) +κ = Dict(i => ω*sqrt(prod(HomPars[i])) for i in HOM) +EFIE = [] #indices of pec domains modeled with efie +MFIE = [] #indices of pec domains modeled with mfie +CFIE = [] #indices of pec domains modeled with cfie +CFIEPars = Dict()#index --> alpha + +#### Incident field +A(x) = x[1]*[0.0,0.0,1.0]*sqrt(ϵ0*μ0)*exp(-1.0im*κ0*x[3]) +curlA(x) = -[0.0,1.0,0.0]*sqrt(ϵ0*μ0)*exp(-1.0im*κ0 *x[3]) +divA(x) = -im*κ0 *x[1]*sqrt(ϵ0*μ0)*exp(-1.0im*κ0 *x[3]) +#### spaces +Xdi(Γ) = BEAST.DirectProductSpace([raviartthomas(Γ),lagrangec0d1(Γ)]) +Xni(Γ) = BEAST.DirectProductSpace([raviartthomas(Γ),lagrangecxd0(Γ)]) +Ydi(Γ) = BEAST.DirectProductSpace([BEAST.buffachristiansen(Γ),duallagrangec0d1(Γ)]) +Yni(Γ) = BEAST.DirectProductSpace([BEAST.buffachristiansen(Γ),duallagrangecxd0(Γ)]) +Xi(Γ) = BEAST.DirectProductSpace([raviartthomas(Γ),lagrangec0d1(Γ),raviartthomas(Γ),lagrangecxd0(Γ)]) +Yi(Γ) = BEAST.DirectProductSpace([BEAST.buffachristiansen(Γ),duallagrangecxd0(Γ),BEAST.buffachristiansen(Γ),duallagrangec0d1(Γ)])# this one maybe omgedraaid + +#### incident field trace +Xin = excitation(A,curlA,divA) +Xind = excitation(A,curlA,divA;rows = [3,4]) +Xinn = excitation(A,curlA,divA; rows = [1,2]) +#@error "check if correct order of traces" +##### identities +id() = BEAST.matrix_to_bilform(diagm([-NCross(),Identity(),-NCross(),Identity()])) +idN() = BEAST.matrix_to_bilform(diagm([-NCross(),Identity()])) + +##### from here do nothing anymore. +N = length(Γ) +Q = Dict(i=>diagm([1,1,HomPars[parent(i,Tree)][2]/HomPars[i][2],HomPars[i][1]/HomPars[parent(i,Tree)][1]]) for i in HOM) +Qp = Dict(i=>diagm([HomPars[parent(i,Tree)][2]/HomPars[i][2],HomPars[i][1]/HomPars[parent(i,Tree)][1],1,1]) for i in HOM) +t = BEAST.hilbertspace(:t, length(Γ)) +b = BEAST.hilbertspace(:b, length(Γ)) + +##### define space +perm = sortperm([HOM...,EFIE...,CFIE...,MFIE...]) +X = [BEAST.DirectProductSpace[Xi(Γ[i]) for i in HOM];BEAST.DirectProductSpace[Xdi(Γ[i]) for i in [EFIE...,CFIE...,MFIE...]]][perm] +Y = [BEAST.DirectProductSpace[Yi(Γ[i]) for i in HOM];BEAST.DirectProductSpace[Yni(Γ[i]) for i in [EFIE...,CFIE...,MFIE...]]][perm] +##### define equation + +eqs1 = BEAST.Equation[(Qp[i]*Z(κ[i];tr=-1)*(Q[i]^-1))[t[i],b[i]] + + -sum(BEAST.BilForm[(Qp[i]*Z(κ[i];tr=-1))[t[i],b[j]] for j in HOM ∩ children(i,Tree)]) + + -sum(BEAST.BilForm[(Qp[i]*Z(κ[i];cols=[3,4],tr=-1))[t[i],b[j]] for j in [EFIE...,CFIE...,MFIE...] ∩ children(i,Tree)]) ==0 for i in HOM] + +# deqs1 = BEAST.discretise.(eqs1, Ref.((t .∈ X))..., Ref.((b .∈ X))...) + + +##### define equation +eqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ0;cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xin[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end +eqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end +eqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + + -idN()[t[ci],b[ci]] ==-Xinn[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end +eqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == + -α[ci]*Xind[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end +eqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Z(κ0;rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + + -(1-α[ci])*idN()[t[ci],b[ci]] == -(1-α[ci])*Xinn[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end + +# deqs2hom = BEAST.discretise(eqs2hom, (t.∈X),(b.∈X)) +# deqs2efie = BEAST.discretise(eqs2efie, (t.∈X),(b.∈X)) +# deqs2mfie = BEAST.discretise(eqs2mfie, (t.∈Y),(b.∈X)) +# deqs2cefie = BEAST.discretise(eqs2cefie, (t.∈X),(b.∈X)) +# deqs2cmfie = BEAST.discretise(eqs2cmfie, (t.∈Y),(b.∈X)) + + +##### define equation +eqs3hom = begin BEAST.Equation[(Z(κ[i])*(Q[i]^-1))[t[ci],b[i]]+ + -sum(BEAST.BilForm[Z(κ[i])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ[i];cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 + for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end +eqs3efie = begin BEAST.Equation[(Z(κ[i];rows=[3,4])*(Q[i]^-1))[t[ci],b[i]]+ + -sum(BEAST.BilForm[Z(κ[i];rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 + for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end +eqs3mfie = begin BEAST.Equation[(Z(κ[i];rows=[1,2])*(Q[i]^-1))[t[ci],b[i]]+ + -sum(BEAST.BilForm[Z(κ[i];rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + + -idN()[t[ci],b[ci]] ==0 + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end +eqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[3,4])*(Q[i]^-1))[t[ci],b[i]]+ + -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 + for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end +eqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Z(κ[i];rows=[1,2])*(Q[i]^-1))[t[ci],b[i]]+ + -(1-α[ci])* sum(BEAST.BilForm[Z(κ[i];rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -(1-α[ci])*sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + + -(1-α[ci])*idN()[t[ci],b[ci]] == 0 + for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end + +# deqs3hom = BEAST.discretise.(eqs3hom, Ref.((t.∈X))...,Ref.((b.∈X))...) +# deqs3efie = BEAST.discretise.(eqs3efie, (t.∈X),(b.∈X)) +# deqs3mfie = BEAST.discretise.(eqs3mfie, (t.∈Y),(b.∈X)) +# deqs3cefie = BEAST.discretise.(eqs3cefie, (t.∈X),(b.∈X)) +# deqs3cmfie = BEAST.discretise.(eqs3cmfie, (t.∈Y),(b.∈X)) + +## sum the equations in the two parts in a pmchwt fassion, + +symeq = -sum(eqs1)+sum(eqs2cefie)+sum(eqs2efie)+sum(eqs2hom)+sum(eqs3cefie)+sum(eqs3efie)+sum(eqs3hom) +asymeq = sum(eqs2cmfie)+sum(eqs2mfie)+sum(eqs3cmfie)+sum(eqs3mfie) + +symfilled = typeof(symeq) <: BEAST.Equation +asymfilled = typeof(asymeq) <: BEAST.Equation + + +symfilled && (Dsymeq = BEAST.discretise(symeq, (t.∈X)..., (b.∈X)...)) +asymfilled && (Dasymeq = BEAST.discretise(asymeq, (t.∈Y)..., (b.∈X)...)) +#assemble system +Zs,Za,bs,ba = 0,0,0,0 +asymfilled && ((Za,ba,xx,yy) = assemble(Dasymeq)) +symfilled && ((Zs,bs,xx,yy) = assemble(Dsymeq)) + +#unprec system + +Zunprec = Za*I+Zs*I +bunprec = ba .+ bs + +solvestrat = :GMRES +solveargs = Dict( + :maxiter => 20000, + :restart => 20000, + :tol => real(sqrt(eps()))) +outnew = solve(Zunprec,bunprec,yy;strat=solvestrat,solveargs...) + + +#generate_plot_field + + + +#preconditioner + + + + +##### define equation + +peqs1 = BEAST.Equation[(Q[i]*Zp(κ[i];tr=-1)*(Qp[i]^-1))[t[i],b[i]] + + -sum(BEAST.BilForm[(Q[i]*Zp(κ[i];tr=-1))[t[i],b[j]] for j in HOM ∩ children(i,Tree)]) + + -sum(BEAST.BilForm[(Q[i]*Zp(κ[i];cols=[3,4],tr=-1))[t[i],b[j]] for j in [EFIE...,CFIE...,MFIE...] ∩ children(i,Tree)]) ==0 for i in HOM] + +# deqs1 = BEAST.discretise.(eqs1, Ref.((t .∈ X))..., Ref.((b .∈ X))...) + +##### define equation +peqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Zp(κ0;cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xin[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end +peqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0;rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Zp(κ0;rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end +# peqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0;rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -sum(BEAST.BilForm[Zp(κ0;rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + +# -idN()[t[ci],b[ci]] ==-Xinn[t[ci]] +# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end +peqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Zp(κ0;rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -α[ci]*sum(BEAST.BilForm[Zp(κ0;rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == + -α[ci]*Xind[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end +# peqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Zp(κ0;rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -(1-α[ci])*sum(BEAST.BilForm[Zp(κ0;rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + +# -(1-α[ci])*idN()[t[ci],b[ci]] == -(1-α[ci])*Xinn[t[ci]] +# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end + +# deqs2hom = BEAST.discretise(eqs2hom, (t.∈X),(b.∈X)) +# deqs2efie = BEAST.discretise(eqs2efie, (t.∈X),(b.∈X)) +# deqs2mfie = BEAST.discretise(eqs2mfie, (t.∈Y),(b.∈X)) +# deqs2cefie = BEAST.discretise(eqs2cefie, (t.∈X),(b.∈X)) +# deqs2cmfie = BEAST.discretise(eqs2cmfie, (t.∈Y),(b.∈X)) + + +##### define equation +peqs3hom = begin BEAST.Equation[(Zp(κ[i])*(Qp[i]^-1))[t[ci],b[i]]+ + -sum(BEAST.BilForm[Zp(κ[i])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Zp(κ[i];cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 + for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end +peqs3efie = begin BEAST.Equation[(Zp(κ[i];rows=[3,4])*(Qp[i]^-1))[t[ci],b[i]]+ + -sum(BEAST.BilForm[Zp(κ[i];rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Zp(κ[i];rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 + for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end +# peqs3mfie = begin BEAST.Equation[(Zp(κ[i];rows=[1,2])*(Q[i]^-1))[t[ci],b[i]]+ +# -sum(BEAST.BilForm[Zp(κ[i];rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -sum(BEAST.BilForm[Zp(κ[i];rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + +# -idN()[t[ci],b[ci]] ==0 +# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end +peqs3cefie = begin BEAST.Equation[α[ci]*(Zp(κ[i];rows=[3,4])*(Qp[i]^-1))[t[ci],b[i]]+ + -α[ci]*sum(BEAST.BilForm[Zp(κ[i];rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -α[ci]*sum(BEAST.BilForm[Zp(κ[i];rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 + for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end +# peqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Zp(κ[i];rows=[1,2])*(Q[i]^-1))[t[ci],b[i]]+ +# -(1-α[ci])* sum(BEAST.BilForm[Zp(κ[i];rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -(1-α[ci])*sum(BEAST.BilForm[Zp(κ[i];rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + +# -(1-α[ci])*idN()[t[ci],b[ci]] == 0 +# for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end + + +#discretise system +psymeq = -sum(peqs1)+sum(peqs2cefie)+sum(peqs2efie)+sum(peqs2hom)+sum(peqs3cefie)+sum(peqs3efie)+sum(peqs3hom) + + +Dsymeq = BEAST.discretise(psymeq, (t.∈Y)..., (b.∈Y)...) + +Pyy = assemble(Dsymeq.equation.lhs,BEAST.DirectProductSpace(Y),BEAST.DirectProductSpace(Y)) + + +# construct gramm matrix +idtest() = BEAST.matrix_to_bilform(diagm([-NCross(),Identity(),-NCross(),Identity()])) + +idNtest() = BEAST.matrix_to_bilform(diagm([-NCross(),Identity()])) + +gramm = sum([idtest()[t[i],b[i]] for i in HOM])+sum([idNtest()[t[i],b[i]] for i in [EFIE...,CFIE...,MFIE...]]) +Gxy = assemble(gramm,BEAST.DirectProductSpace(X),BEAST.DirectProductSpace(Y)) +Ginvyx = BEAST.GMRESSolver(Gxy;abstol=1e-15, maxiter=1_000, restart=1_000, verbose=false) +Ginvxy = BEAST.GMRESSolver(Gxy';abstol=1e-15, maxiter=1_000, restart=1_000, verbose=false) + +Zprec = Za*I+Ginvxy*Pyy*Ginvyx*Zs*I +bprec = ba .+ Ginvxy*Pyy*Ginvyx*bs + +solvestrat = :GMRES +solveargs = Dict( + :maxiter => 20000, + :restart => 20000, + :tol => real(sqrt(eps()))) +outnewprec = solve(Zprec,bprec,yy;strat=solvestrat,solveargs...) diff --git a/src/bases/bcspace.jl b/src/bases/bcspace.jl index fdd07481..bd1b9dfe 100644 --- a/src/bases/bcspace.jl +++ b/src/bases/bcspace.jl @@ -187,7 +187,6 @@ function buffachristiansen(Γ, γ=mesh(coordtype(Γ),1,3); ibscaled=false, sort= return RTBasis(fine, bcs, pos) end - """ buildhalfbc(fine, supp::Array{SVector{3,Int},1}, v, p) """ diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 79b8a8c8..2dbc3e9e 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -32,6 +32,7 @@ struct Potential{T,M} <: AbstractOperator operator::T surface::M end +Potential(a) = Potential(a,nothing) surface(p::Potential) = p.surface function Potential(linop::LinearCombinationOfOperators,surface::TraceMesh) out = ZeroOperator() @@ -210,10 +211,10 @@ function build_potential(op::ComposedOperator,surface::TraceMesh) newop = replace_normal_by_trialnormal(op) Potential(newop,surface) end -# function build_potential(op::ComposedOperator) -# newop = replace_normal_by_trialnormal(op) -# Potential(newop,nothing) -# end +function build_potential(op::ComposedOperator) + newop = replace_normal_by_trialnormal(op) + Potential(newop,nothing) +end function γ(op::Operations) @@ -237,26 +238,26 @@ function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# si end return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) end -# function γₜ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = nt × (γ(op.operator) × nt) -# return TraceOperator(Potential(newop,op.surface),sign) -# end -# function γₛ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = nt × γ(op.operator) -# return TraceOperator(Potential(newop,op.surface),sign) -# end -# function γₙ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = nt ⋅ γ(op.operator) -# return TraceOperator(Potential(newop,op.surface),sign) -# end -# function τ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = γ(op.operator) -# return TraceOperator(Potential(newop,op.surface),sign) -# end +function γₜ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# check_if_coincide(op.surface,surface) || return op.operator + newop = nt × (γ(op.operator) × nt) + return TraceOperator(Potential(newop,op.surface),sign) +end +function γₛ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# check_if_coincide(op.surface,surface) || return op.operator + newop = nt × γ(op.operator) + return TraceOperator(Potential(newop,op.surface),sign) +end +function γₙ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# check_if_coincide(op.surface,surface) || return op.operator + newop = nt ⋅ γ(op.operator) + return TraceOperator(Potential(newop,op.surface),sign) +end +function τ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# check_if_coincide(op.surface,surface) || return op.operator + newop = γ(op.operator) + return TraceOperator(Potential(newop,op.surface),sign) +end function γ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator @@ -298,67 +299,49 @@ end function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = (nt × γ(op.operator)) × nt - direction = [] - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) + charts = chart.(Ref(surface),1:numcells(surface)) + direction = sign/3*normal.(charts) + return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) end function γₜ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = (nt × γ(op.operator)) × nt - direction = [] - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) + charts = chart.(Ref(surface),1:numcells(surface)) + direction = sign/3*normal.(charts) + return TraceOperator(Potential(newop,op.surface),direction+surface) end function γₙ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = nt ⋅ γ(op.operator) - direction = [] - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) + charts = chart.(Ref(surface),1:numcells(surface)) + direction = sign/3*normal.(charts) + return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) end function γₙ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = nt ⋅ γ(op.operator) - direction = [] - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) + charts = chart.(Ref(surface),1:numcells(surface)) + direction = sign/3*normal.(charts) + return TraceOperator(Potential(newop,op.surface),direction+surface) end function τ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = γ(op.operator) - direction = [] - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) + charts = chart.(Ref(surface),1:numcells(surface)) + direction = sign/3*normal.(charts) + return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) end function τ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = γ(op.operator) - direction = [] - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) + charts = chart.(Ref(surface),1:numcells(surface)) + direction = sign/3*normal.(charts) + return TraceOperator(Potential(newop,op.surface),direction+surface) end - +export γₛ, γₜ, γₙ, γ, τ #### Define new greens functions below function greenhh3d(; @@ -521,6 +504,19 @@ defaultquadstrat(op::Potential,test,trial) = defaultquadstrat(op.operator,test,t +# function assemble!(op::Potential, test_functions::Space, trial_functions::Space, +# store, threading = Threading{:multi}; +# quadstrat = defaultquadstrat(op, test_functions, trial_functions)) +# # checks if surface given in basis is the same as surface given in potential +# dsurf = surface(op) +# surf = geometry(trial_functions) +# @assert same_geometry(dsurf,surf) +# nsurf = mesh(dsurf) +# trial_functions = redefine_geometrie(trial_functions,TraceMesh(OrientedMesh(surf,nsurf),direction(dsurf))) + +# assemble!(op.operator, test_functions, trial_functions, store, threading; +# quadstrat = quadstrat) +# end function assemble!(op::Potential, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; quadstrat = defaultquadstrat(op, test_functions, trial_functions)) @@ -529,7 +525,7 @@ function assemble!(op::Potential, test_functions::Space, trial_functions::Space, surf = geometry(trial_functions) @assert same_geometry(dsurf,surf) nsurf = mesh(dsurf) - trial_functions = redefine_geometrie(trial_functions,TraceMesh(OrientedMesh(surf,nsurf),direction(dsurf))) + trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf,direction(dsurf))) assemble!(op.operator, test_functions, trial_functions, store, threading; quadstrat = quadstrat) @@ -539,7 +535,34 @@ end # quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} # surf = geometry(trial_functions) -# trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) +# trial_functions = redefine_geometrie(trial_functions,TraceMesh(OrientedMesh(surf,surf))) + +# assemble!(op.operator, test_functions, trial_functions, store, threading; +# quadstrat = quadstrat) +# end +function assemble!(op::Potential{T,Nothing}, test_functions::Space, trial_functions::Space, + store, threading = Threading{:multi}; + quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} + + surf = geometry(trial_functions) + trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) + + assemble!(op.operator, test_functions, trial_functions, store, threading; + quadstrat = quadstrat) +end + +# function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, +# store, threading = Threading{:multi}; +# quadstrat = defaultquadstrat(op, test_functions, trial_functions)) + +# dsurf = surface(op) +# surf = geometry(test_functions) +# println(typeof(surf)) +# println(typeof(mesh(dsurf))) +# @assert same_geometry(dsurf,surf) +# nsurf = mesh(dsurf) + +# test_functions = redefine_geometrie(test_functions,TraceMesh(OrientedMesh(surf,nsurf),direction(dsurf))) # assemble!(op.operator, test_functions, trial_functions, store, threading; # quadstrat = quadstrat) @@ -556,7 +579,7 @@ function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Sp @assert same_geometry(dsurf,surf) nsurf = mesh(dsurf) - test_functions = redefine_geometrie(test_functions,TraceMesh(OrientedMesh(surf,nsurf),direction(dsurf))) + test_functions = redefine_geometrie(test_functions,TraceMesh(surf,direction(dsurf))) assemble!(op.operator, test_functions, trial_functions, store, threading; quadstrat = quadstrat) @@ -564,25 +587,20 @@ end function assemble!(op::TraceOperator{T,Int}, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} - println("assemble") - #@warn "NO MULTI TRACE YET" + surface = geometry(test_functions) - direction = [] + sign = op.surface - println("loop") - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - println("hang1") + direction = [sign*normal(c)/3 for c in chart.(Ref(surface),1:numcells(surface))] + if typeof(surface) <: TraceMesh surf = surface + direction else surf = TraceMesh(surface,direction) end - println(typeof(surf)) + test_functions = redefine_geometrie(test_functions,surf) - println(typeof(op.operator)) + assemble!(op.operator, test_functions, trial_functions, store, threading; quadstrat = quadstrat) end diff --git a/src/composedoperator/postprocessing.jl b/src/composedoperator/postprocessing.jl index a3b94611..effd6722 100644 --- a/src/composedoperator/postprocessing.jl +++ b/src/composedoperator/postprocessing.jl @@ -1,7 +1,7 @@ struct FunctionExcitation{T} <: Functional f end - +export FunctionExcitation kernelvals(op::ComposedOperator,a) = nothing diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index 829ad15b..3206a491 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -1,4 +1,5 @@ import Base.sign +import Base.getindex struct TraceSimplex{T,U} simp::T direction::SVector{3,U} @@ -29,6 +30,7 @@ CompScienceMeshes.tangents(a::TraceSimplex,i::Int) = tangents(simplex(a),i) CompScienceMeshes.carttobary(a::TraceSimplex,b::SVector{T}) where {T} = carttobary(simplex(a),b) CompScienceMeshes.center(a::TraceSimplex) = TraceMeshPointNM(center(simplex(a)),direction(a)) CompScienceMeshes.normal(a::TraceSimplex) = normal(simplex(a)) +CompScienceMeshes.barytocart(a::TraceSimplex,b) = barytocart(simplex(a),b) function CompScienceMeshes.quadpoints(chart::TraceSimplex, rule) PV = quadpoints(CompScienceMeshes.domain(chart), rule) map(PV) do pv @@ -73,10 +75,11 @@ struct TraceMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} mesh::CompScienceMeshes.AbstractMesh{U,D1,T} direction::Vector{SVector{3,T}} end -TraceMesh(a::CompScienceMeshes.AbstractMesh{U,D,T}) where {U,D,T} = TraceMesh(a,zeros(SVector{numcells(a),SVector{3,T}})) +TraceMesh(a::TraceMesh,b::Vector{SVector{3,T}}) where {T} = a+b +TraceMesh(a::CompScienceMeshes.AbstractMesh{U,D,T}) where {U,D,T} = TraceMesh(a,zeros(SVector{3,T},(numcells(a)))) +(a::TraceMesh{U,D,T},b::SVector{3,T}) where {U,D,T} = TraceMesh(mesh(a),direction(a).+Ref(b)) -+(a::TraceMesh,b::SVector) = TraceMesh(mesh(a),a.direction+b) -+(a::SVector,b::TraceMesh) = b+a ++(a::TraceMesh{U,D,T},b::Vector{SVector{3,T}}) where {U,D,T} = TraceMesh(mesh(a),a.direction+b) ++(a::Union{SVector,Vector},b::TraceMesh) = b+a CompScienceMeshes.indices(t::TraceMesh,i::Int) = CompScienceMeshes.indices(mesh(t),i) CompScienceMeshes.numvertices(t::TraceMesh) = CompScienceMeshes.numvertices(mesh(t)) CompScienceMeshes.vertextype(t::TraceMesh) = CompScienceMeshes.vertextype(mesh(t)) @@ -112,4 +115,19 @@ CompScienceMeshes.cells(p::TraceMesh) = cells(mesh(p)) CompScienceMeshes.vertices(p::TraceMesh) = vertices(mesh(p)) +# function buffachristiansen(Γ::TraceMesh,γ=mesh(coordtype(Γ),1,3);kwargs...) +# rtspace = buffachristiansen(mesh(Γ),γ;kwargs...) +# geo = geometry(rtspace) +# direction = [Γ.direction[CompScienceMeshes.parent(geo,i)] for i in 1:length(geo)] +# redefine_geometrie(rtspace,TraceMesh(geo,direction)) +# end + +function CompScienceMeshes.barycentric_refinement(m::TraceMesh;kwargs...) + geo = mesh(m) + fine = barycentric_refinement(geo) + direction = [m.direction[CompScienceMeshes.parent(fine,i)] for i in 1:length(fine)] + return TraceMesh(fine,direction) +end +CompScienceMeshes.vertextocellmap(m::TraceMesh) = vertextocellmap(mesh(m)) +Base.getindex(m::TraceMesh,i::Vector{Int}) = mesh(m)[i] \ No newline at end of file diff --git a/src/operator.jl b/src/operator.jl index 0b51d849..50c1408d 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -3,7 +3,7 @@ using .LinearSpace struct LongDelays{T} end struct Threading{T} end -import Base: transpose, +, -, * +import Base: transpose, +, -, *, zero abstract type AbstractOperator end @@ -17,8 +17,8 @@ abstract type Operator <: AbstractOperator end struct ZeroOperator <: AbstractOperator end - - +export ZeroOperator +Base.zero(op::Type{<:AbstractOperator}) = ZeroOperator() mutable struct TransposedOperator <: AbstractOperator op::AbstractOperator end diff --git a/src/solvers/itsolver.jl b/src/solvers/itsolver.jl index 84a63169..9612dc2b 100644 --- a/src/solvers/itsolver.jl +++ b/src/solvers/itsolver.jl @@ -119,6 +119,17 @@ function gmres_ch(eq::DiscreteEquation; maxiter=0, restart=0, tol=0) ax = nestedrange(Y, 1, numfunctions) return PseudoBlockVector(x, (ax,)), ch end +function assemble(eq::DiscreteEquation;kwargs...) + lhs = eq.equation.lhs + rhs = eq.equation.rhs + + X = _spacedict_to_directproductspace(eq.test_space_dict) + Y = _spacedict_to_directproductspace(eq.trial_space_dict) + + b = assemble(rhs, X;kwargs...) + Z = assemble(lhs, X, Y;kwargs...) + return Z,b,X,Y +end function gmres_ch(b,Z,trial_direct_product_space; maxiter=0, restart=0, tol=0) if tol == 0 diff --git a/src/solvers/lusolver.jl b/src/solvers/lusolver.jl index 65d25a85..50069dba 100644 --- a/src/solvers/lusolver.jl +++ b/src/solvers/lusolver.jl @@ -40,3 +40,18 @@ function solve(eq;Zz=false) end +function solve(b,Z,Y;Zz=true) + + + print("Converting system to Matrix...") + M = Matrix(Z) + println("done.") + + print("LU solution of the linear system...") + u = M \ Vector(b) + println("done.") + + ax = nestedrange(Y, 1, numfunctions) + Zz && (return PseudoBlockVector(u, (ax,)), Z) + return PseudoBlockVector(u, (ax,)) +end diff --git a/src/solvers/solver.jl b/src/solvers/solver.jl index 2a482cdd..d2a751ef 100644 --- a/src/solvers/solver.jl +++ b/src/solvers/solver.jl @@ -103,7 +103,6 @@ function discretise(eq, space_mappings::Pair...) DiscreteEquation(eq, trial_space_dict, test_space_dict) end - """ discr(eq, pairs...) diff --git a/src/utils/variational.jl b/src/utils/variational.jl index a27edc64..b69e4c0b 100644 --- a/src/utils/variational.jl +++ b/src/utils/variational.jl @@ -1,5 +1,5 @@ module Variational - +import Base.zero using BlockArrays import BEAST # import Base: start, done, next @@ -140,7 +140,7 @@ mutable struct BilForm trial_space terms end - +Base.copy(b::BilForm) = BilForm(b.test_space,b.trial_space,copy(b.terms)) mutable struct BilTerm test_id trial_id @@ -149,7 +149,11 @@ mutable struct BilTerm coeff kernel end - +Base.copy(b::BilTerm) = BilTerm(b.test_id,b.trial_id,b.test_ops,b.trial_ops,b.coeff,b.kernel) +mutable struct ProdBilTerm + terms + coeff +end mutable struct Equation lhs rhs @@ -162,7 +166,10 @@ Build an equation from a left hand and right hand side """ ==(lhs::BilForm, rhs::LinForm) = Equation(lhs, rhs) - +function ==(lhs::BilForm, rhs::Number) + @assert rhs == Base.zero(rhs) + return Equation(lhs,ZeroLinForm()) +end # """ # hilbert_space(type, g1, g2, ...) @@ -361,11 +368,11 @@ function *(α::Number, a::LinForm) return b end --(a::BilForm) = (-1 * a) --(a::BilForm, b::BilForm) = a + (-b) +#-(a::BilForm) = (-1 * a) +# -(a::BilForm, b::BilForm) = a + (-b) --(a::LinForm) = (-1 * a) --(a::LinForm, b::LinForm) = a + (-b) +# -(a::LinForm) = (-1 * a) +# -(a::LinForm, b::LinForm) = a + (-b) function print(io::IO, v::HilbertVector) @@ -486,4 +493,76 @@ function getindex(op::OffDiagKernel, V::Vector{HilbertVector}, U::Vector{Hilbert return BilForm(first(V).space, first(U).space, terms) end + + + +#### suport to use diagonal matrix multiplications with bilforms +function *(a::Number,b::BilTerm) + out = copy(b) + out.coeff *= a + return out +end +function *(a::Matrix,b::BilForm) + n = length(b.test_space) + m = length(b.trial_space) + @assert (n,m)==size(a) + @assert sum([abs(a[i,j]) for i in 1:n for j in 1:m if i≠j]) == 0.0 + out = [a[term.test_id,term.test_id]*term for term in b.terms] + return BilForm(b.test_space,b.trial_space,out) +end +function *(b::BilForm,a::Matrix) + n = length(b.test_space) + m = length(b.trial_space) + @assert (n,m)==size(a) + @assert sum([abs(a[i,j]) for i in 1:n for j in 1:m if i≠j]) == 0.0 + out = [a[term.trial_id,term.trial_id]*term for term in b.terms] + return BilForm(b.test_space,b.trial_space,out) end +# mutable struct ProdBilTerm +# bilterm1 +# bilterm2 +# betweenspace +# end +# function *(a::BilForm,b::BilForm) +# @assert a.trial_space == b.test_space +# r = [[term.trial_id for term in a.terms];[term.test_id for term in b.terms]...] +# @assert allequal(r) +# return BilForm(a.test_space,b.trial_space,ProdBilTerm(a.terms,b.terms,a.trial_space)) +# end + +struct ZeroBilForm end +struct ZeroLinForm end ++(a::Union{BilForm,ZeroBilForm},b::ZeroBilForm) = a ++(a::ZeroBilForm,b::BilForm) = b +*(a,b::ZeroBilForm) = b +*(a::ZeroBilForm,b) = a +-(a::Union{BilForm,ZeroBilForm}) = (-1)*a +-(a::Union{BilForm,ZeroBilForm},b::Union{BilForm,ZeroBilForm}) = a+ (-1)*b +Base.zero(::Type{BilForm}) = ZeroBilForm() + ++(a::Union{LinForm,ZeroLinForm},b::ZeroLinForm) = a ++(a::ZeroLinForm,b::LinForm) = b +*(a,b::ZeroLinForm) = b +*(a::ZeroLinForm,b) = a +-(a::Union{LinForm,ZeroLinForm}) = (-1)*a +-(a::Union{LinForm,ZeroLinForm},b::Union{LinForm,ZeroLinForm}) = a+ (-1)*b +Base.zero(::Type{LinForm}) = ZeroLinForm() + + ++(a::Equation,b::Equation) = Equation(a.lhs+b.lhs,a.rhs+b.rhs) +*(a::Number,b::Equation) = Equation(a*b.lhs,a*b.rhs) +-(a::Equation,b::Equation) = a + (-1)*b +-(a::Equation) = (-1)*a + +Base.zero(::Type{Equation}) = Equation(ZeroBilForm(),ZeroLinForm()) +struct ZeroEquation end + ++(a::Union{Equation,ZeroEquation},b::ZeroEquation) = a ++(a::ZeroEquation,b::Equation) = b +*(a,b::ZeroEquation) = b +*(a::ZeroEquation,b) = a +-(a::Union{Equation,ZeroEquation}) = (-1)*a +-(a::Union{Equation,ZeroEquation},b::Union{Equation,ZeroEquation}) = a+ (-1)*b +Base.zero(::Type{Equation}) = ZeroEquation() + +end \ No newline at end of file From b843ead505a6c3bae0d3525a5eec463a9df4e3e6 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 21 Feb 2024 11:40:14 +0100 Subject: [PATCH 084/110] inserted kwargs argument in assemble --- src/composedoperator/composedoperator.jl | 16 ++++---- src/dyadicop.jl | 2 +- src/excitation.jl | 18 ++++---- src/integralop.jl | 19 +++++---- src/localop.jl | 28 +++++++------ src/operator.jl | 52 ++++++++++++------------ src/solvers/solver.jl | 24 +++++------ 7 files changed, 85 insertions(+), 74 deletions(-) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 2dbc3e9e..230cb0c2 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -519,7 +519,7 @@ defaultquadstrat(op::Potential,test,trial) = defaultquadstrat(op.operator,test,t # end function assemble!(op::Potential, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; - quadstrat = defaultquadstrat(op, test_functions, trial_functions)) + kwargs...) # checks if surface given in basis is the same as surface given in potential dsurf = surface(op) surf = geometry(trial_functions) @@ -528,7 +528,7 @@ function assemble!(op::Potential, test_functions::Space, trial_functions::Space, trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf,direction(dsurf))) assemble!(op.operator, test_functions, trial_functions, store, threading; - quadstrat = quadstrat) + kwargs...) end # function assemble!(op::Potential{T,Nothing}, test_functions::Space, trial_functions::Space, # store, threading = Threading{:multi}; @@ -542,13 +542,13 @@ end # end function assemble!(op::Potential{T,Nothing}, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; - quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} + kwargs...) where {T} surf = geometry(trial_functions) trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) assemble!(op.operator, test_functions, trial_functions, store, threading; - quadstrat = quadstrat) + kwargs...) end # function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, @@ -570,7 +570,7 @@ end function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; - quadstrat = defaultquadstrat(op, test_functions, trial_functions)) + kwargs...) dsurf = surface(op) surf = geometry(test_functions) @@ -582,11 +582,11 @@ function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Sp test_functions = redefine_geometrie(test_functions,TraceMesh(surf,direction(dsurf))) assemble!(op.operator, test_functions, trial_functions, store, threading; - quadstrat = quadstrat) + kwargs...) end function assemble!(op::TraceOperator{T,Int}, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; - quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} + kwargs...) where {T} surface = geometry(test_functions) @@ -602,5 +602,5 @@ function assemble!(op::TraceOperator{T,Int}, test_functions::Space, trial_functi test_functions = redefine_geometrie(test_functions,surf) assemble!(op.operator, test_functions, trial_functions, store, threading; - quadstrat = quadstrat) + kwargs...) end diff --git a/src/dyadicop.jl b/src/dyadicop.jl index 5306d397..b3eb0d5b 100644 --- a/src/dyadicop.jl +++ b/src/dyadicop.jl @@ -35,7 +35,7 @@ end function assemble!(biop::DyadicOp, tfs::Space, bfs::Space, store, threading::Type{BEAST.Threading{:multi}}; - quadstrat=defaultquadstrat(biop, tfs, bfs)) + kwargs...) u = assemble(biop.f, tfs) v = assemble(biop.g, bfs) diff --git a/src/excitation.jl b/src/excitation.jl index df3ce36b..64718255 100644 --- a/src/excitation.jl +++ b/src/excitation.jl @@ -15,10 +15,10 @@ end *(n::Number,a::LinearCombinationOfFunctionals) = LinearCombinationOfFunctionals(a.coeffs*n,a.ops) scalartype(a::LinearCombinationOfFunctionals{T}) where {T} = promote_type(T,scalartype.(a.ops)...) function assemble(field::LinearCombinationOfFunctionals,tfs; - quadstrat=defaultquadstrat(field, tfs)) + kwargs...) out = [] for (c,func) in zip(field.coeffs,field.ops) - push!(out,c*assemble(func,tfs;quadstrat=quadstrat)) + push!(out,c*assemble(func,tfs;kwargs...)) end return sum(out) end @@ -35,12 +35,12 @@ Assemble the vector of test coefficients corresponding to functional `fn` and test functions `tfs`. """ function assemble(field::Functional, tfs; - quadstrat=defaultquadstrat(field, tfs)) + kwargs...) R = scalartype(tfs) b = zeros(Complex{R}, numfunctions(tfs)) store(v,m) = (b[m] += v) - assemble!(field, tfs, store; quadstrat) + assemble!(field, tfs, store; kwargs...) return b end function assemble(n::Number, tfs) @@ -53,18 +53,19 @@ function assemble(n::Number, tfs) end function assemble!(field::Functional, tfs::DirectProductSpace, store; - quadstrat=defaultquadstrat(field, tfs)) + kwargs...) I = Int[0] for s in tfs.factors push!(I, last(I) + numfunctions(s)) end for (i,s) in enumerate(tfs.factors) store1(v,m) = store(v, m + I[i]) - assemble!(field, s, store1; quadstrat) + assemble!(field, s, store1; kwargs...) end end function assemble!(field::Functional, tfs::Space, store; - quadstrat=defaultquadstrat(field, tfs)) + quadstratfunction = defaultquadstrat, + quadstrat=quadstratfunction(field, tfs)) tels, tad = assemblydata(tfs) @@ -88,7 +89,8 @@ function assemble!(field::Functional, tfs::Space, store; end function assemble!(field::Functional, tfs::subdBasis, store; - quadstrat=defaultquadstrat(field, tfs)) + quadstratfunction = defaultquadstrat, + quadstrat=quadstratfunction(field, tfs)) tels, tad = assemblydata(tfs) diff --git a/src/integralop.jl b/src/integralop.jl index c38323b0..8524bd3f 100644 --- a/src/integralop.jl +++ b/src/integralop.jl @@ -67,7 +67,8 @@ elements(sp::Space) = elements(geometry(sp)) Computes the matrix of operator biop wrt the finite element spaces tfs and bfs """ function assemblechunk!(biop::IntegralOperator, tfs::Space, bfs::Space, store; - quadstrat=defaultquadstrat(biop, tfs, bfs)) + quadstratfunction = defaultquadstrat, + quadstrat=quadstratfunction(biop, tfs, bfs)) # test_elements, tad, tcells = assemblydata(tfs) # bsis_elements, bad, bcells = assemblydata(bfs) @@ -295,16 +296,17 @@ end function assembleblock(operator::AbstractOperator, test_functions, trial_functions; - quadstrat=defaultquadstrat(operator, test_functions, trial_functions)) + kwargs...) Z, store = allocatestorage(operator, test_functions, trial_functions) - assembleblock!(operator, test_functions, trial_functions, store; quadstrat) + assembleblock!(operator, test_functions, trial_functions, store; kwargs...) sdata(Z) end function assembleblock!(biop::IntegralOperator, tfs::Space, bfs::Space, store; - quadstrat=defaultquadstrat(biop, tfs, bfs)) + quadstratfunction = defualtquadstrat, + quadstrat=quadstratfunction(biop, tfs, bfs)) test_elements, tad, trial_elements, bad, quadrature_data, zlocals = assembleblock_primer(biop, tfs, bfs; quadstrat) @@ -320,7 +322,8 @@ end function assembleblock_primer(biop, tfs, bfs; - quadstrat=defaultquadstrat(biop, tfs, bfs)) + quadstratfunction=defaultquadstrat, + quadstrat=quadstratfunction(biop, tfs, bfs)) test_elements, tad = assemblydata(tfs; onlyactives=false) bsis_elements, bad = assemblydata(bfs; onlyactives=false) @@ -544,7 +547,8 @@ end end end end end end end function assemblerow!(biop::IntegralOperator, test_functions::Space, trial_functions::Space, store; - quadstrat=defaultquadstrat(biop, test_functions, trial_functions)) + quadstratfunction = defaultquadstrat, + quadstrat=quadstratfunction(biop, test_functions, trial_functions)) test_elements = elements(geometry(test_functions)) trial_elements, trial_assembly_data = assemblydata(trial_functions) @@ -594,7 +598,8 @@ end end end end end function assemblecol!(biop::IntegralOperator, test_functions::Space, trial_functions::Space, store; - quadstrat=defaultquadstrat(biop, test_functions, trial_functions)) + quadstratfunction = defaultquadstrat, + quadstrat=quadstratfunction(biop, test_functions, trial_functions)) test_elements, test_assembly_data = assemblydata(test_functions) trial_elements = elements(geometry(trial_functions)) diff --git a/src/localop.jl b/src/localop.jl index 0181e071..4293c4a8 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -79,38 +79,39 @@ end function assemble!(biop::LocalOperator, tfs::Space, bfs::Space, store, threading::Type{Threading{:multi}}; - quadstrat=defaultquadstrat(biop, tfs, bfs)) + kwargs...) if geometry(tfs) == geometry(bfs) @warn "Function cannot be used for infinitely thin surfaces!!!" - return assemble_local_matched!(biop, tfs, bfs, store; quadstrat) + return assemble_local_matched!(biop, tfs, bfs, store; kwargs...) end if CompScienceMeshes.refines(geometry(tfs), geometry(bfs)) - return assemble_local_refines!(biop, tfs, bfs, store; quadstrat) + return assemble_local_refines!(biop, tfs, bfs, store; kwargs...) end - return assemble_local_mixed!(biop, tfs, bfs, store; quadstrat) + return assemble_local_mixed!(biop, tfs, bfs, store; kwargs...) end function assemble!(biop::LocalOperator, tfs::Space, bfs::Space, store, threading::Type{Threading{:single}}; - quadstrat=defaultquadstrat(biop, tfs, bfs)) + kwargs...) if geometry(tfs) == geometry(bfs) @warn "Function cannot be used for infinitely thin surfaces!!!" - return assemble_local_matched!(biop, tfs, bfs, store; quadstrat) + return assemble_local_matched!(biop, tfs, bfs, store; kwargs...) end if CompScienceMeshes.refines(geometry(tfs), geometry(bfs)) - return assemble_local_refines!(biop, tfs, bfs, store; quadstrat) + return assemble_local_refines!(biop, tfs, bfs, store; kwargs...) end - return assemble_local_mixed!(biop, tfs, bfs, store; quadstrat) + return assemble_local_mixed!(biop, tfs, bfs, store; kwargs...) end function assemble_local_matched!(biop::LocalOperator, tfs::Space, bfs::Space, store; - quadstrat=defaultquadstrat(biop, tfs, bfs)) + quadstratfunction = defaultquadstrat, + quadstrat=quadstratfunction(biop, tfs, bfs)) tels, tad, ta2g = assemblydata(tfs) bels, bad, ba2g = assemblydata(bfs) @@ -156,7 +157,8 @@ end function assemble_local_refines!(biop::LocalOperator, tfs::Space, bfs::Space, store; - quadstrat=defaultquadstrat(biop, tfs, bfs)) + quadstratfunction = defaultquadstrat, + quadstrat=quadstratfunction(biop, tfs, bfs)) println("Using 'refines' algorithm for local assembly:") @@ -221,7 +223,8 @@ function assemble_local_refines!(biop::LocalOperator, tfs::Space, bfs::Space, st end function assemble_local_matched!(biop::LocalOperator, tfs::subdBasis, bfs::subdBasis, store; - quadstrat=defaultquadstrat(biop, tfs, bfs)) + quadstratfunction = defaultquadstrat, + quadstrat=quadstratfunction(biop, tfs, bfs)) @assert !(typeof(biop) <: ComposedOperator) @@ -283,7 +286,8 @@ end For use when basis and test functions are defined on different meshes """ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T}, store; - quadstrat=defaultquadstrat(biop, tfs, bfs)) where {T} + quadstratfunction = defaultquadstrat, + quadstrat=quadstratfunction(biop, tfs, bfs)) where {T} tol = sqrt(eps(T)) diff --git a/src/operator.jl b/src/operator.jl index 50c1408d..548ad926 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -99,11 +99,11 @@ function assemble(operator::AbstractOperator, test_functions, trial_functions; storage_policy = Val{:bandedstorage}, # long_delays_policy = LongDelays{:compress}, threading = Threading{:multi}, - quadstrat=defaultquadstrat(operator, test_functions, trial_functions)) + kwargs...) Z, store = allocatestorage(operator, test_functions, trial_functions, storage_policy) - assemble!(operator, test_functions, trial_functions, store, threading; quadstrat) + assemble!(operator, test_functions, trial_functions, store, threading; kwargs...) return Z() end @@ -117,11 +117,11 @@ end function assemblerow(operator::AbstractOperator, test_functions, trial_functions, storage_policy = Val{:bandedstorage}, long_delays_policy = LongDelays{:ignore}; - quadstrat=defaultquadstrat(operator, test_functions, trial_functions)) + kwargs...) Z, store = allocatestorage(operator, test_functions, trial_functions, storage_policy, long_delays_policy) - assemblerow!(operator, test_functions, trial_functions, store; quadstrat) + assemblerow!(operator, test_functions, trial_functions, store; kwargs...) Z() end @@ -129,11 +129,11 @@ end function assemblecol(operator::AbstractOperator, test_functions, trial_functions, storage_policy = Val{:bandestorage}, long_delays_policy = LongDelays{:ignore}; - quadstrat=defaultquadstrat(operator, test_functions, trial_functions)) + kwargs...) Z, store = allocatestorage(operator, test_functions, trial_functions, storage_policy, long_delays_policy) - assemblecol!(operator, test_functions, trial_functions, store; quadstrat) + assemblecol!(operator, test_functions, trial_functions, store; kwargs...) Z() end @@ -187,7 +187,7 @@ end function assemble!(operator::Operator, test_functions::Space, trial_functions::Space, store, threading::Type{Threading{:multi}}; - quadstrat=defaultquadstrat(operator, test_functions, trial_functions)) + kwargs...) # @info "Multi-threaded assembly:" @@ -203,18 +203,18 @@ function assemble!(operator::Operator, test_functions::Space, trial_functions::S test_functions_p = subset(test_functions, lo:hi) # store1 = (v,m,n) -> store(v,lo+m-1,n) store1 = _OffsetStore(store, lo-1, 0) - assemblechunk!(operator, test_functions_p, trial_functions, store1, quadstrat=quadstrat) + assemblechunk!(operator, test_functions_p, trial_functions, store1; kwargs...) end end function assemble!(operator::Operator, test_functions::Space, trial_functions::Space, store, threading::Type{Threading{:single}}; - quadstrat=defaultquadstrat(operator, test_functions, trial_functions)) + kwargs...) # @info "Single-threaded assembly" - assemblechunk!(operator, test_functions, trial_functions, store; quadstrat) + assemblechunk!(operator, test_functions, trial_functions, store; kwargs...) end # defaultquadstrat(op::BasisOperatorLeft,tfs,bfs) = defaultquadstrat(op.operator,op.left_function(tfs),bfs) # defaultquadstrat(op::BasisOperatorRight,tfs,bfs) = defaultquadstrat(op.operator,tfs,op.right_function(bfs)) @@ -222,14 +222,14 @@ end function assemble!(op::TransposedOperator, tfs::Space, bfs::Space, store, threading = Threading{:multi}; - quadstrat=defaultquadstrat(op, tfs, bfs)) + kwargs...) store1(v,m,n) = store(v,n,m) - assemble!(op.op, bfs, tfs, store1, threading; quadstrat) + assemble!(op.op, bfs, tfs, store1, threading; kwargs...) end function assemble!(op::ZeroOperator, tfs::Space, bfs::Space, store, threading = Threading{:multi}; - quadstrat=nothing) + kwargs...) end # function assemble!(op::BasisOperatorLeft, tfs::Space, bfs::Space, store,threading = Threading{:multi}; @@ -247,11 +247,11 @@ end function assemble!(op::LinearCombinationOfOperators, tfs::AbstractSpace, bfs::AbstractSpace, store, threading = Threading{:multi}; - quadstrat=defaultquadstrat(op, tfs, bfs)) + kwargs...) - for (a,A,qs) in zip(op.coeffs, op.ops, quadstrat) + for (a,A) in zip(op.coeffs, op.ops) store1(v,m,n) = store(a*v,m,n) - assemble!(A, tfs, bfs, store1, threading; quadstrat=qs) + assemble!(A, tfs, bfs, store1, threading; kwargs...) end end @@ -259,38 +259,38 @@ end # Support for direct product spaces function assemble!(op::AbstractOperator, tfs::DirectProductSpace, bfs::Space, store, threading = Threading{:multi}; - quadstrat=defaultquadstrat(op, tfs[1], bfs)) + kwargs...) I = Int[0] for s in tfs.factors push!(I, last(I) + numfunctions(s)) end for (i,s) in enumerate(tfs.factors) store1(v,m,n) = store(v,m + I[i], n) - assemble!(op, s, bfs, store1, threading; quadstrat) + assemble!(op, s, bfs, store1, threading; kwargs...) end end function assemble!(op::AbstractOperator, tfs::Space, bfs::DirectProductSpace, store, threading=Threading{:multi}; - quadstrat=defaultquadstrat(op, tfs, bfs[1])) + kwargs...) J = Int[0] for s in bfs.factors push!(J, last(J) + numfunctions(s)) end for (j,s) in enumerate(bfs.factors) store1(v,m,n) = store(v,m,n + J[j]) - assemble!(op, tfs, s, store1, threading; quadstrat) + assemble!(op, tfs, s, store1, threading; kwargs...) end end function assemble!(op::AbstractOperator, tfs::DirectProductSpace, bfs::DirectProductSpace, store, threading=Threading{:multi}; - quadstrat=defaultquadstrat(op, tfs[1], bfs[1])) + kwargs...) I = Int[0] for s in tfs.factors push!(I, last(I) + numfunctions(s)) end for (i,s) in enumerate(tfs.factors) store1(v,m,n) = store(v,m + I[i],n) - assemble!(op, s, bfs, store1, threading; quadstrat) + assemble!(op, s, bfs, store1, threading; kwargs...) end end @@ -310,7 +310,7 @@ allocatestorage(op::BlockDiagonalOperator, X, Y, storage_trait, longdelays_trait function assemble!(op::BlockDiagonalOperator, U::DirectProductSpace, V::DirectProductSpace, store, threading=Threading{:multi}; - quadstrat = defaultquadstrat(op, U, V)) + kwargs...) @assert length(U.factors) == length(V.factors) I = Int[0]; for u in U.factors push!(I, last(I) + numfunctions(u)) end @@ -318,7 +318,7 @@ function assemble!(op::BlockDiagonalOperator, U::DirectProductSpace, V::DirectPr for (k,(u,v)) in enumerate(zip(U.factors, V.factors)) store1(v,m,n) = store(v, I[k] + m, J[k] + n) - assemble!(op.op, u, v, store1, threading; quadstrat) + assemble!(op.op, u, v, store1, threading; kwargs...) end end @@ -335,7 +335,7 @@ defaultquadstrat(op::BlockFullOperators, U::DirectProductSpace, V::DirectProduct function assemble!(op::BlockFullOperators, U::DirectProductSpace, V::DirectProductSpace, store, threading; - quadstrat = defaultquadstrat(op, U, V)) + kwargs...) # @assert length(U.factors) == length(V.factors) I = Int[0]; for u in U.factors push!(I, last(I) + numfunctions(u)) end @@ -351,7 +351,7 @@ function assemble!(op::BlockFullOperators, U::DirectProductSpace, V::DirectProdu for (k,u) in enumerate(U.factors) for (l,v) in enumerate(V.factors) store1(x,m,n) = store(x, I[k]+m, J[l]+n) - assemble!(op.op, u, v, store1, threading; quadstrat) + assemble!(op.op, u, v, store1, threading; kwargs...) end end end diff --git a/src/solvers/solver.jl b/src/solvers/solver.jl index d2a751ef..6166b165 100644 --- a/src/solvers/solver.jl +++ b/src/solvers/solver.jl @@ -137,15 +137,15 @@ function _spacedict_to_directproductspace(spacedict) X = DirectProductSpace(xfactors) end -function assemble(lform::LinForm, test_space_dict) +function assemble(lform::LinForm, test_space_dict;kwargs...) X = _spacedict_to_directproductspace(test_space_dict) - return assemble(lform, X) + return assemble(lform, X;kwargs...) end scalartype(lf::LinForm) = scalartype(lf.terms...) scalartype(lt::LinTerm) = scalartype(lt.coeff, lt.functional) -function assemble(lform::LinForm, X::DirectProductSpace) +function assemble(lform::LinForm, X::DirectProductSpace;kwargs...) @assert !isempty(lform.terms) @@ -166,7 +166,7 @@ function assemble(lform::LinForm, X::DirectProductSpace) for op in reverse(t.test_ops) x = op[end](op[1:end-1]..., x) end - b = assemble(t.functional, x) + b = assemble(t.functional, x;kwargs...) B[Block(m),Block(1)] = t.coeff * b end @@ -192,12 +192,12 @@ _righthandside_axes(x, U, N) = (U,) td_assemble(lform::LinForm, X::DirectProductSpace) = assemble(lform, X) function assemble(bilform::BilForm, test_space_dict, trial_space_dict; - materialize=BEAST.assemble) + kwargs...) X = _spacedict_to_directproductspace(test_space_dict) Y = _spacedict_to_directproductspace(trial_space_dict) - return assemble(bilform, X, Y; materialize) + return assemble(bilform, X, Y; kwargs...) end lift(a,I,J,U,V) = LiftedMaps.LiftedMap(a,I,J,U,V) @@ -205,7 +205,7 @@ lift(a::ConvolutionOperators.AbstractConvOp ,I,J,U,V) = ConvolutionOperators.LiftedConvOp(a, U, V, I, J) function assemble(bf::BilForm, X::DirectProductSpace, Y::DirectProductSpace; - materialize=BEAST.assemble) + materialize=BEAST.assemble,kwargs...) @assert !isempty(bf.terms) @@ -228,19 +228,19 @@ function assemble(bf::BilForm, X::DirectProductSpace, Y::DirectProductSpace; end a = term.coeff * term.kernel - z = materialize(a, x, y) + z = materialize(a, x, y;kwargs...) lift(z, Block(term.test_id), Block(term.trial_id), U, V) end end -function assemble(bf::BilForm, X::Space, Y::Space) +function assemble(bf::BilForm, X::Space, Y::Space;kwargs...) @assert length(bf.terms) == 1 - assemble(bf, BEAST.DirectProductSpace([X]), BEAST.DirectProductSpace([Y])) + assemble(bf, BEAST.DirectProductSpace([X]), BEAST.DirectProductSpace([Y]);kwargs...) end -function assemble(bf::BilForm, pairs::Pair...) +function assemble(bf::BilForm, pairs::Pair...;kwargs...) dbf = discretise(bf, pairs...) - assemble(dbf) + assemble(dbf;kwargs...) end # struct BilFormDirectProductSpace # test_space From 6f64680e8df185a9184e3c9dfa78ccbd5a4ec695 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 22 Feb 2024 17:41:34 +0100 Subject: [PATCH 085/110] update vppmchwt example --- examples/vppmchwt.jl | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl index 69e79d32..bd30b736 100644 --- a/examples/vppmchwt.jl +++ b/examples/vppmchwt.jl @@ -62,7 +62,7 @@ end function Zp(κ;rows=[1,2,3,4],cols=[1,2,3,4],trace=true,dual=true,tr=1) # build to test with nxt in dual true G = BEAST.greenhh3d(wavenumber=κ) gradG = BEAST.∇(G) - tr *=-1 + tr *=1 if trace ∇Gx = BEAST.build_potential(gradG×B) Gn = BEAST.build_potential(G*(n*B)) @@ -141,15 +141,15 @@ children(ind,tree) = findall(==(ind),tree) #### define meshes hh = 0.3 -Γ1 = meshcuboid(1.0, 1.0, 1.0, hh) +Γ1 = meshcuboid(1.1, 1.0, 1.1, hh) Γ2 = (@SVector [-1.0,0.0,0.0]) + BEAST.TraceMesh(-Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1)))) -Γ3 = (@SVector [0.0,0.0,-1.0]) + BEAST.TraceMesh(-Mesh([point(x,y,-z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1)))) +Γ3 = (@SVector [0.0,0.0,-1.0]) + BEAST.TraceMesh(-translate(Mesh([point(x,y,-z-1.1) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))),[0.0,0.0,0.0])) Γ = [Γ1,Γ2,Γ3] Tree = [0,0,0] # give index in which material is HOM = [1,2,3] #indices of homogeneous domains (without free space) -HomPars = Dict(0=>(ϵ0,μ0),1=>(ϵ0,μ0*3),2=>(ϵ0*6,μ0*4),3=>(ϵ0*2,μ0*3))#index --> (eps,mu) +HomPars = Dict(0=>(ϵ0,μ0),1=>(ϵ0,μ0*3),2=>(ϵ0*2,μ0*2),3=>(ϵ0*3,μ0))#index --> (eps,mu) κ = Dict(i => ω*sqrt(prod(HomPars[i])) for i in HOM) EFIE = [] #indices of pec domains modeled with efie MFIE = [] #indices of pec domains modeled with mfie @@ -296,6 +296,10 @@ outnew = solve(Zunprec,bunprec,yy;strat=solvestrat,solveargs...) peqs1 = BEAST.Equation[(Q[i]*Zp(κ[i];tr=-1)*(Qp[i]^-1))[t[i],b[i]] + -sum(BEAST.BilForm[(Q[i]*Zp(κ[i];tr=-1))[t[i],b[j]] for j in HOM ∩ children(i,Tree)]) + -sum(BEAST.BilForm[(Q[i]*Zp(κ[i];cols=[3,4],tr=-1))[t[i],b[j]] for j in [EFIE...,CFIE...,MFIE...] ∩ children(i,Tree)]) ==0 for i in HOM] +pdeqs1 = BEAST.Equation[(Q[i]*Zp(κ[i];tr=-1)*(Qp[i]^-1))[t[i],b[i]] ==0 for i in HOM] +pnuleqs1 = BEAST.Equation[(Q[i]*Zp(κ[i];tr=0)*(Qp[i]^-1))[t[i],b[i]] + +-sum(BEAST.BilForm[(Q[i]*Zp(κ[i];tr=0))[t[i],b[j]] for j in HOM ∩ children(i,Tree)]) + +-sum(BEAST.BilForm[(Q[i]*Zp(κ[i];cols=[3,4],tr=0))[t[i],b[j]] for j in [EFIE...,CFIE...,MFIE...] ∩ children(i,Tree)]) ==0 for i in HOM] # deqs1 = BEAST.discretise.(eqs1, Ref.((t .∈ X))..., Ref.((b .∈ X))...) @@ -303,9 +307,15 @@ peqs1 = BEAST.Equation[(Q[i]*Zp(κ[i];tr=-1)*(Qp[i]^-1))[t[i],b[i]] + peqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -sum(BEAST.BilForm[Zp(κ0;cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xin[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end + +pdeqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0)[t[ci],b[ci]] for j in [HOM ∩ [ci]]])+ + -sum(BEAST.BilForm[Zp(κ0;cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ [ci]]) ==-Xin[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end + + peqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0;rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Zp(κ0;rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind[t[ci]] - for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end + -sum(BEAST.BilForm[Zp(κ0;rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end # peqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0;rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ # -sum(BEAST.BilForm[Zp(κ0;rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + # -idN()[t[ci],b[ci]] ==-Xinn[t[ci]] @@ -352,11 +362,15 @@ peqs3cefie = begin BEAST.Equation[α[ci]*(Zp(κ[i];rows=[3,4])*(Qp[i]^-1))[t[ci] #discretise system psymeq = -sum(peqs1)+sum(peqs2cefie)+sum(peqs2efie)+sum(peqs2hom)+sum(peqs3cefie)+sum(peqs3efie)+sum(peqs3hom) - - +pdsymeq = -sum(pdeqs1)+sum(pdeqs2hom) +pnulsymeq = sum(pnuleqs1) Dsymeq = BEAST.discretise(psymeq, (t.∈Y)..., (b.∈Y)...) +# quadstrat +qs(::BEAST.LocalOperator, a, b) = BEAST.SingleNumQStrat(3) +qs(op::BEAST.ComposedOperatorIntegral,testspace,trialspace) = BEAST.DoubleNumSauterQstrat(5,5,5,5,2,2) +qs(op::BEAST.ComposedOperatorLocal,testspace,trialpsace) = BEAST.SingleNumQStrat(3) -Pyy = assemble(Dsymeq.equation.lhs,BEAST.DirectProductSpace(Y),BEAST.DirectProductSpace(Y)) +Pyy = assemble(Dsymeq.equation.lhs,BEAST.DirectProductSpace(Y),BEAST.DirectProductSpace(Y);quadstratfunction=qs) # construct gramm matrix From ca3a9ac739adec84f333085cba691aad9f66dcae Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 23 Feb 2024 18:05:07 +0100 Subject: [PATCH 086/110] added complement error + nearfield calculation TODO test --- examples/vppmchwt.jl | 276 ++++++++++++++++++++++- src/composedoperator/composedoperator.jl | 31 ++- 2 files changed, 300 insertions(+), 7 deletions(-) diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl index bd30b736..ad39d1a3 100644 --- a/examples/vppmchwt.jl +++ b/examples/vppmchwt.jl @@ -115,11 +115,18 @@ function Zp(κ;rows=[1,2,3,4],cols=[1,2,3,4],trace=true,dual=true,tr=1) # build end return BEAST.matrix_to_bilform(int[rows,cols]) end -function excitation(A,curlA,divA;rows=[1,2,3,4]) +function excitation(A,curlA,divA;rows=[1,2,3,4],dual=true) + if dual out = [((n × FunctionExcitation{ComplexF64}(curlA))×n), BEAST.NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(A)), ((n × FunctionExcitation{ComplexF64}(A))×n), FunctionExcitation{ComplexF64}(divA)] + else + out = [((n × FunctionExcitation{ComplexF64}(curlA))), + BEAST.NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(A)), + ((n × FunctionExcitation{ComplexF64}(A))), + FunctionExcitation{ComplexF64}(divA)] + end return BEAST.array_to_linform(out[rows]) end function solve(Z,b,X;strat,kwargs...) @@ -148,18 +155,20 @@ hh = 0.3 Γ = [Γ1,Γ2,Γ3] Tree = [0,0,0] # give index in which material is -HOM = [1,2,3] #indices of homogeneous domains (without free space) -HomPars = Dict(0=>(ϵ0,μ0),1=>(ϵ0,μ0*3),2=>(ϵ0*2,μ0*2),3=>(ϵ0*3,μ0))#index --> (eps,mu) +HOM = [1,2] #indices of homogeneous domains (without free space) +HomPars = Dict(0=>(ϵ0,μ0),1=>(ϵ0,μ0*3),2=>(ϵ0*2,μ0*2))#,3=>(ϵ0*3,μ0))#index --> (eps,mu) κ = Dict(i => ω*sqrt(prod(HomPars[i])) for i in HOM) +κ[0]=κ0 EFIE = [] #indices of pec domains modeled with efie MFIE = [] #indices of pec domains modeled with mfie -CFIE = [] #indices of pec domains modeled with cfie -CFIEPars = Dict()#index --> alpha +CFIE = [3] #indices of pec domains modeled with cfie +α = Dict(3=>0.2)#index --> alpha #### Incident field A(x) = x[1]*[0.0,0.0,1.0]*sqrt(ϵ0*μ0)*exp(-1.0im*κ0*x[3]) curlA(x) = -[0.0,1.0,0.0]*sqrt(ϵ0*μ0)*exp(-1.0im*κ0 *x[3]) divA(x) = -im*κ0 *x[1]*sqrt(ϵ0*μ0)*exp(-1.0im*κ0 *x[3]) +graddivA(x) = -im*κ0 *sqrt(ϵ0*μ0)*exp(-1.0im*κ0 *x[3])*[1.0,0.0,-im*κ0*x[1]] #### spaces Xdi(Γ) = BEAST.DirectProductSpace([raviartthomas(Γ),lagrangec0d1(Γ)]) Xni(Γ) = BEAST.DirectProductSpace([raviartthomas(Γ),lagrangecxd0(Γ)]) @@ -172,11 +181,16 @@ Yi(Γ) = BEAST.DirectProductSpace([BEAST.buffachristiansen(Γ),duallagrangecxd0( Xin = excitation(A,curlA,divA) Xind = excitation(A,curlA,divA;rows = [3,4]) Xinn = excitation(A,curlA,divA; rows = [1,2]) +#### incident field trace non dual +Xin_notdual = excitation(A,curlA,divA;dual=false) +Xind_notdual = excitation(A,curlA,divA;rows = [3,4],dual=false) +Xinn_notdual = excitation(A,curlA,divA; rows = [1,2],dual=false) #@error "check if correct order of traces" ##### identities id() = BEAST.matrix_to_bilform(diagm([-NCross(),Identity(),-NCross(),Identity()])) idN() = BEAST.matrix_to_bilform(diagm([-NCross(),Identity()])) - +idnotdual() = BEAST.matrix_to_bilform(diagm([Identity(),Identity(),Identity(),Identity()])) +idNnotdual() = BEAST.matrix_to_bilform(diagm([Identity(),Identity()])) ##### from here do nothing anymore. N = length(Γ) Q = Dict(i=>diagm([1,1,HomPars[parent(i,Tree)][2]/HomPars[i][2],HomPars[i][1]/HomPars[parent(i,Tree)][1]]) for i in HOM) @@ -392,3 +406,253 @@ solveargs = Dict( :restart => 20000, :tol => real(sqrt(eps()))) outnewprec = solve(Zprec,bprec,yy;strat=solvestrat,solveargs...) + +u = outnewprec[1] + +###### exit dict: mesh, number of iterations, inputdata, cond number both, eigenvalue distribution both cases + + +##### post processing + + +##### nearfield +using BlockArrays +function nearfield_B(u,X,κ,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume + G = BEAST.greenhh3d(wavenumber=κ) + gradG = BEAST.∇(G) + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*BEAST.div(B) + ∇Gxn = gradG×(nb*B) + + + if HOM + @hilbertspace T D R N + B = -Q[1,1]*potential(∇G∇B, points, u[T], X.factors[1])-Q[1,1]*potential(κ^2*Gr, points, u[T], X.factors[1]) + B .+= Q[2,2]*potential(∇Gxn, points, u[D], X.factors[2]) + B .+= -Q[3,3]*potential(∇Gx, points, u[R], X.factors[3]) + + else + @hilbertspace R N + B = -potential(∇Gx, points, u[R], X.factors[1]) + + end + + return sign*B +end + +function nearfield_A(u,X,κ,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume + G = BEAST.greenhh3d(wavenumber=κ) + gradG = BEAST.∇(G) + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*BEAST.div(B) + ∇Gxn = gradG×(nb*B) + + + if HOM + @hilbertspace T D R N + A = -Q[1,1]*potential(∇Gx, points, u[T], X.factors[1]) + A .+= Q[2,2]*potential(Gn, points, u[D], X.factors[2]) + A .+= -Q[3,3]*potential(Gr, points, u[R], X.factors[3]) + A .+= Q[4,4]*potential(∇G, points, u[N], X.factors[4]) + else + @hilbertspace R N + A = -potential(Gr, points, u[R], X.factors[1]) + A .+= potential(∇G, points, u[N], X.factors[2]) + end + + return sign*A +end +function nearfield_phi(u,X,κ,ω,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume + G = BEAST.greenhh3d(wavenumber=κ) + gradG = BEAST.∇(G) + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*BEAST.div(B) + ∇Gxn = gradG×(nb*B) + + + if HOM + @hilbertspace T D R N + A = Q[2,2]*potential(∇Gdotn, points, u[D], X.factors[2]) + A .+= -Q[3,3]*potential(∇Gdot, points, u[R], X.factors[3]) + A .+= -κ^2* Q[4,4]*potential(Gr, points, u[N], X.factors[4]) + else + @hilbertspace R N + A = -potential(∇Gdot, points, u[R], X.factors[1]) + A .+= -κ^2* potential(Gr, points, u[N], X.factors[2]) + end + + return sign*A/κ^2*im*ω +end +function nearfield_E(u,X,κ,ω,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume + G = BEAST.greenhh3d(wavenumber=κ) + gradG = BEAST.∇(G) + graddivG = BEAST.graddiv(G) + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + graddivGdotn = graddivG*(nb*B) + graddivGdot = graddivG*B + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*BEAST.div(B) + ∇Gxn = gradG×(nb*B) + + + if HOM + @hilbertspace T D R N + p = Q[2,2]*potential(graddivGdotn, points, u[D], X.factors[2]) + p .+= -Q[3,3]*potential(graddivGdot, points, u[R], X.factors[3]) + p .+= -κ^2* Q[4,4]*potential(∇G, points, u[N], X.factors[4]) + else + @hilbertspace R N + p = -potential(graddivGdot, points, u[R], X.factors[1]) + p .+= -κ^2* potential(∇G, points, u[N], X.factors[2]) + end + if HOM + @hilbertspace T D R N + A = -Q[1,1]*potential(∇Gx, points, u[T], X.factors[1]) + A .+= Q[2,2]*potential(Gn, points, u[D], X.factors[2]) + A .+= -Q[3,3]*potential(Gr, points, u[R], X.factors[3]) + A .+= Q[4,4]*potential(∇G, points, u[N], X.factors[4]) + else + @hilbertspace R N + A = -potential(Gr, points, u[R], X.factors[1]) + A .+= potential(∇G, points, u[N], X.factors[2]) + end + return -sign*A/κ^2*im*ω-sign*im*ω*A +end +Xs = range(-2.0,2.0,length=150) +Zs = range(-1.5,2.5,length=100) +pts = [point(x,0.5,z) for z in Zs, x in Xs] + +A1 = [nearfield_A(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] +A2 = [nearfield_A(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] +A3 = [nearfield_A(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] +Atot = sum(A1)+sum(A2)+sum(A3)+A.(pts) + +B1 = [nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] +B2 = [nearfield_B(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] +B3 = [nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] +Btot = sum(B1)+sum(B2)+sum(B3)+curlA.(pts) + +H1 = [1/HomPars[parent(i,Tree)][2]*nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] +H2 = [1/HomPars[i][2]*nearfield_B(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] +H3 = [1/HomPars[parent(i,Tree)][2]*nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] +Htot = sum(H1)+sum(H2)+sum(H3)+1/μ0*curlA.(pts) + +E1 = [nearfield_E(u[Block(i)],X[i],κ[parent(i,Tree)],ω,pts) for i in HOM] +E2 = [nearfield_E(u[Block(i)],X[i],κ[i],ω,pts;sign=-1,Q=Q[i]^-1) for i in HOM] +E3 = [nearfield_E(u[Block(i)],X[i],κ[parent(i,Tree)],ω,pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] +Etot = sum(E1)+sum(E2)+sum(E3)-im*ω*A.(pts)-graddivA.(pts)/κ^2*im*ω + +##### complement error, different from aps paper, traces from inside are compared, for the reset same formula as in aps paper, for pec all are treated with mfie, as efie yields zero traces in denominator. + + + + + + +##### define equation +ceqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ0;cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xin_notdual[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end +# ceqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind_notdual[t[ci]] +# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end +ceqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + + ==-Xinn_notdual[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ [MFIE...,EFIE...]]end +# ceqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == +# -α[ci]*Xind_notdual[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end +ceqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Z(κ0;rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + + == -(1-α[ci])*Xinn_notdual[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end + +# deqs2hom = BEAST.discretise(eqs2hom, (t.∈X),(b.∈X)) +# deqs2efie = BEAST.discretise(eqs2efie, (t.∈X),(b.∈X)) +# deqs2mfie = BEAST.discretise(eqs2mfie, (t.∈Y),(b.∈X)) +# deqs2cefie = BEAST.discretise(eqs2cefie, (t.∈X),(b.∈X)) +# deqs2cmfie = BEAST.discretise(eqs2cmfie, (t.∈Y),(b.∈X)) + + +##### define equation +ceqs3hom = begin BEAST.Equation[(Z(κ[i];tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ + -sum(BEAST.BilForm[Z(κ[i];tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ[i];cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 + for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end +# ceqs3efie = begin BEAST.Equation[(Z(κ[i];rows=[3,4],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ +# -sum(BEAST.BilForm[Z(κ[i];rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 +# for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end +ceqs3mfie = begin BEAST.Equation[(Z(κ[i];rows=[1,2],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ + -sum(BEAST.BilForm[Z(κ[i];rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ [MFIE...,EFIE...]]end +# ceqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[3,4],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ +# -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 +# for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end +ceqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Z(κ[i];rows=[1,2],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ + -(1-α[ci])* sum(BEAST.BilForm[Z(κ[i];rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -(1-α[ci])*sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 + for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end + + + +ceq = sum(ceqs2hom)+sum(ceqs3hom) +cmeq = sum(ceqs2cmfie)+sum(ceqs2mfie)+sum(ceqs3cmfie)+sum(ceqs3mfie) + +Dseq = BEAST.discretise(ceq, (t.∈X)..., (b.∈X)...) + +F,bsa,_,_ = assemble(Dseq) + +u_error = F*u-bsa + +#select in u_error en in u + +function select_trace(u,trace_ind) + usub = 0*deepcopy(u) + N = length(blocks(u)) + for i in 1:N + if i ∈ HOM + usub[Block(i)][Block(trace_ind)] += u[Block(i)][Block(trace_ind)] + elseif i∈ [EFIE...,MFIE...,CFIE...] && trace_ind ∈ [3,4] + usub[Block(i)][Block(trace_ind)] += u[Block(i)][Block(trace_ind)] + end + end + return usub +end + +Gsym = assemble(diag(diag(Identity())),BEAST.DirectProductSpace(X),BEAST.DirectProductSpace(X)) +Ginvsym = inv(Matrix(Gsym)) + +nom = sqrt.([Array(select_trace(u_error,i))'*Ginvsym*Array(select_trace(u_error,i)) for i in 1:4]) +denom = sqrt.([Array(select_trace(u,i))'*Matrix(Gsym)*Array(select_trace(u,i)) for i in 1:4]) +error = 1/4*sum(nom./denom) \ No newline at end of file diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 230cb0c2..693df325 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -369,6 +369,9 @@ struct GradGreenHH3D{T} <: Kernel gamma::T end +struct GradDivGreenHH3D{T} <: Kernel + gamma::T +end function (op::GreenHH3D)(x,y,g) gamma = op.gamma @@ -389,6 +392,30 @@ function (op::GreenHH3D)(x::Union{SVector,Vector},y,g) Ref(green) end +function (op::GradDivGreenHH3D)(x,y,g) + gamma = op.gamma + + r = cartesian(x) - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-gamma*R)*(i4pi*iR) + f = -(gamma + iR) * green * iR + df = (3*iR^2-gamma*iR+gamma^2)*green*iR + Ref(df*(r*r')+f*I) + +end +function (op::GradDivGreenHH3D)(x::Union{SVector,Vector},y,g) + gamma = op.gamma + + r = x - cartesian(y) + R = norm(r) + iR = 1/R + green = exp(-gamma*R)*(i4pi*iR) + f = -(gamma + iR) * green * iR + df = (3*iR^2-gamma*iR+gamma^2)*green*iR + Ref(df*(r*r')+f*I) +end + function (op::GradGreenHH3D)(x,y,g) gamma = op.gamma @@ -421,16 +448,18 @@ function (op::GradGreenHH3D)(x::Union{SVector,Vector},y,g) end γ(op::GreenHH3D) = op +γ(op::GradDivGreenHH3D) = op γ(op::GradGreenHH3D) = op + 1/2*TraceDirection() grad(G::GreenHH3D) = GradGreenHH3D(G.gamma) - +graddiv(G::GreenHH3D) = GradDivGreenHH3D(G.gamma) function (::Nabla)(G::Kernel) grad(G) end scalartype(G::GreenHH3D{T}) where {T} = T scalartype(G::GradGreenHH3D{T}) where {T} = T +scalartype(G::GradDivGreenHH3D{T}) where {T} = T struct DoubleIntegralR{T} <: Kernel end From 058ae78b802eea0300f0aa46accfeea8b42997b2 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 8 Mar 2024 11:13:09 +0100 Subject: [PATCH 087/110] added getindex for operators, hilbertvector, vector{hilbertvector} --- src/utils/variational.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/utils/variational.jl b/src/utils/variational.jl index b69e4c0b..e3bf97ba 100644 --- a/src/utils/variational.jl +++ b/src/utils/variational.jl @@ -337,7 +337,23 @@ function getindex(op::Any, V::Vector{HilbertVector}, U::Vector{HilbertVector}) end return BilForm(first(V).space, first(U).space, terms) end +function getindex(op::Any, V::Vector{HilbertVector}, u::Hilbertvector) + terms = Vector{BilTerm}() + for v in V + term = BilTerm(v.idx, u.idx, v.opstack, u.opstack, 1, op) + push!(terms, term) + end + return BilForm(first(V).space, u.space, terms) +end +function getindex(op::Any, v::HilbertVector, U::Vector{HilbertVector}) + terms = Vector{BilTerm}() + for u in U + term = BilTerm(v.idx, u.idx, v.opstack, u.opstack, 1, op) + push!(terms, term) + end + return BilForm(v.space, first(U).space, terms) +end function getindex(A::Matrix, v::HilbertVector, u::HilbertVector) terms = [ BilTerm(v.idx, u.idx, v.opstack, u.opstack, 1, A) ] BilForm(v.space, u.space, terms) From 8bb343a3c6f9d02d504fd3e02bfc2adf143ddfdd Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 11 Mar 2024 13:52:55 +0100 Subject: [PATCH 088/110] update --- examples/vppmchwt.jl | 117 ++++++++++++++++++++++---------- src/bases/lincomb.jl | 2 +- src/bases/local/ndlocal.jl | 24 ++++++- src/multi-trace/interactions.jl | 16 ++--- src/utils/variational.jl | 50 +++++++------- 5 files changed, 142 insertions(+), 67 deletions(-) diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl index ad39d1a3..d4d14952 100644 --- a/examples/vppmchwt.jl +++ b/examples/vppmchwt.jl @@ -3,7 +3,7 @@ using CompScienceMeshes using LinearAlgebra using AbstractTrees using StaticArrays - +using Plots function Z(κ;rows=[1,2,3,4],cols=[1,2,3,4],trace=true,dual=true,tr=1) # build to test with nxt in dual true G = BEAST.greenhh3d(wavenumber=κ) gradG = BEAST.∇(G) @@ -137,31 +137,46 @@ function solve(Z,b,X;strat,kwargs...) end @error "no existing strategy given, use :LU or :GMRES" end +function plot_eigenvalues(M) + eigs = eigen(M).values + display(scatter(real.(eigs),imag.(eigs))) + +end parent(ind,tree) = tree[ind] children(ind,tree) = findall(==(ind),tree) ### physical constants ϵ0 = 8.854e-12 μ0 = 4π*1e-7 -ω = 10.0^8*2*pi +ω = 10.0^8#*2*pi κ0 = ω*sqrt(ϵ0*μ0) +### what to do: +execute = Dict( +:precondition => true, +:plot_E => true, +:plot_H => true, +:plot_A => true, +:extinction_error => true, +:unprec_solve => true +) + #### define meshes hh = 0.3 -Γ1 = meshcuboid(1.1, 1.0, 1.1, hh) -Γ2 = (@SVector [-1.0,0.0,0.0]) + BEAST.TraceMesh(-Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1)))) -Γ3 = (@SVector [0.0,0.0,-1.0]) + BEAST.TraceMesh(-translate(Mesh([point(x,y,-z-1.1) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))),[0.0,0.0,0.0])) - -Γ = [Γ1,Γ2,Γ3] -Tree = [0,0,0] # give index in which material is - -HOM = [1,2] #indices of homogeneous domains (without free space) -HomPars = Dict(0=>(ϵ0,μ0),1=>(ϵ0,μ0*3),2=>(ϵ0*2,μ0*2))#,3=>(ϵ0*3,μ0))#index --> (eps,mu) +# Γ1 = meshcuboid(1.0, 1.0, 1.0, hh) +# Γ2 = (@SVector [-1.0,0.0,0.0]) + BEAST.TraceMesh(-Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1)))) +# Γ3 = (@SVector [0.0,0.0,-1.0]) + BEAST.TraceMesh(-translate(Mesh([point(x,y,-z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))),[0.0,0.0,0.0])) +Γ = [boundary(tetmeshsphere(1.0,0.5))] +#Γ = [Γ1]#,Γ2,Γ3] +Tree = [0]#,0,0] # give index in which material is + +HOM = [1]#,2] #indices of homogeneous domains (without free space) +HomPars = Dict(0=>(ϵ0,μ0),1=>(ϵ0*2,μ0*2),2=>(ϵ0*2,μ0*2))#,3=>(ϵ0*3,μ0))#index --> (eps,mu) κ = Dict(i => ω*sqrt(prod(HomPars[i])) for i in HOM) κ[0]=κ0 EFIE = [] #indices of pec domains modeled with efie MFIE = [] #indices of pec domains modeled with mfie -CFIE = [3] #indices of pec domains modeled with cfie +CFIE = []#3] #indices of pec domains modeled with cfie α = Dict(3=>0.2)#index --> alpha #### Incident field @@ -302,7 +317,7 @@ outnew = solve(Zunprec,bunprec,yy;strat=solvestrat,solveargs...) #preconditioner - +@error "hoi" ##### define equation @@ -400,6 +415,8 @@ Ginvxy = BEAST.GMRESSolver(Gxy';abstol=1e-15, maxiter=1_000, restart=1_000, verb Zprec = Za*I+Ginvxy*Pyy*Ginvyx*Zs*I bprec = ba .+ Ginvxy*Pyy*Ginvyx*bs +MZprec = inv(Matrix(Gxy)')*Matrix(Pyy)*inv(Matrix(Gxy))*Matrix(Zs) + solvestrat = :GMRES solveargs = Dict( :maxiter => 20000, @@ -434,17 +451,17 @@ function nearfield_B(u,X,κ,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#n if HOM @hilbertspace T D R N - B = -Q[1,1]*potential(∇G∇B, points, u[T], X.factors[1])-Q[1,1]*potential(κ^2*Gr, points, u[T], X.factors[1]) - B .+= Q[2,2]*potential(∇Gxn, points, u[D], X.factors[2]) - B .+= -Q[3,3]*potential(∇Gx, points, u[R], X.factors[3]) + Bb = -Q[1,1]*potential(∇G∇B, points, u[T], X.factors[1])-Q[1,1]*κ^2* potential(Gr, points, u[T], X.factors[1]) + Bb .+= Q[2,2]*potential(∇Gxn, points, u[D], X.factors[2]) + Bb .+= -Q[3,3]*potential(∇Gx, points, u[R], X.factors[3]) else @hilbertspace R N - B = -potential(∇Gx, points, u[R], X.factors[1]) + Bb = -potential(∇Gx, points, u[R], X.factors[1]) end - return sign*B + return sign*Bb end function nearfield_A(u,X,κ,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume @@ -543,7 +560,7 @@ function nearfield_E(u,X,κ,ω,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]) A = -potential(Gr, points, u[R], X.factors[1]) A .+= potential(∇G, points, u[N], X.factors[2]) end - return -sign*A/κ^2*im*ω-sign*im*ω*A + return -sign*p/κ^2*im*ω-sign*im*ω*A end Xs = range(-2.0,2.0,length=150) Zs = range(-1.5,2.5,length=100) @@ -552,27 +569,52 @@ pts = [point(x,0.5,z) for z in Zs, x in Xs] A1 = [nearfield_A(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] A2 = [nearfield_A(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] A3 = [nearfield_A(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -Atot = sum(A1)+sum(A2)+sum(A3)+A.(pts) +Atot = sum(A1)+sum(A2)+sum(A3)-A.(pts) B1 = [nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] B2 = [nearfield_B(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] B3 = [nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -Btot = sum(B1)+sum(B2)+sum(B3)+curlA.(pts) +Btot = sum(B1)+sum(B2)+sum(B3)-curlA.(pts) H1 = [1/HomPars[parent(i,Tree)][2]*nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] H2 = [1/HomPars[i][2]*nearfield_B(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] H3 = [1/HomPars[parent(i,Tree)][2]*nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -Htot = sum(H1)+sum(H2)+sum(H3)+1/μ0*curlA.(pts) +Htot = sum(H1)+sum(H2)+sum(H3)-1/μ0*curlA.(pts) E1 = [nearfield_E(u[Block(i)],X[i],κ[parent(i,Tree)],ω,pts) for i in HOM] E2 = [nearfield_E(u[Block(i)],X[i],κ[i],ω,pts;sign=-1,Q=Q[i]^-1) for i in HOM] E3 = [nearfield_E(u[Block(i)],X[i],κ[parent(i,Tree)],ω,pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -Etot = sum(E1)+sum(E2)+sum(E3)-im*ω*A.(pts)-graddivA.(pts)/κ^2*im*ω +Etot = sum(E1)+sum(E2)+sum(E3)-(-im*ω*A.(pts)-graddivA.(pts)/κ0^2*im*ω) ##### complement error, different from aps paper, traces from inside are compared, for the reset same formula as in aps paper, for pec all are treated with mfie, as efie yields zero traces in denominator. - +### to generate plot +using Plots +using LaTeXStrings +using ColorSchemes +p1 = Plots.heatmap(Xs, Zs, (real.(getindex.(Htot,2)))*1000,clim=(-0.01001*1000,0.01*1000),show=true, + +xlabel="z-axis [m]", +ylabel="x-axis [m]", +colorbar_title=" \nHy [mA/m]", +c= :PuBu, +right_margin = 7Plots.mm) +rectangle(w, h, x, y) = Plots.Shape(x .+ [0,w,w,0], y .+ [0,0,h,h]) +# plot!(rectangle(1,1,0,0),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4) +# plot!(rectangle(1,1,-1,0),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4) +# plot!(rectangle(1,1,0,-1),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4,legend=false) +# annotate!(-0.5,0.5,"Ω₃", :black) +# annotate!(0.5,0.5,"Ω₁", :black) +# annotate!(0.5,-0.5,"Ω₂", :black) +display(plot!( + xtickfont=font(11), + ytickfont=font(11), + xguidefontsize=12, +yguidefontsize=13, +colorbar_titlefontsize=13 +)) +#savefig("Hfield.pdf") @@ -584,15 +626,13 @@ ceqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;tr=-1,dual=false)[t[ci] # -sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind_notdual[t[ci]] # for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end ceqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - ==-Xinn_notdual[t[ci]] + -sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xinn_notdual[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ [MFIE...,EFIE...]]end # ceqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ # -α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == # -α[ci]*Xind_notdual[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end ceqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Z(κ0;rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - == -(1-α[ci])*Xinn_notdual[t[ci]] + -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == -(1-α[ci])*Xinn_notdual[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end # deqs2hom = BEAST.discretise(eqs2hom, (t.∈X),(b.∈X)) @@ -629,30 +669,39 @@ ceqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Z(κ[i];rows=[1,2],tr=-1,dual=fals ceq = sum(ceqs2hom)+sum(ceqs3hom) cmeq = sum(ceqs2cmfie)+sum(ceqs2mfie)+sum(ceqs3cmfie)+sum(ceqs3mfie) -Dseq = BEAST.discretise(ceq, (t.∈X)..., (b.∈X)...) +Dseq = BEAST.discretise(ceq+cmeq, (t.∈X)..., (b.∈X)...) F,bsa,_,_ = assemble(Dseq) -u_error = F*u-bsa +using NestedUnitRanges +ax = nestedrange(BEAST.DirectProductSpace(X), 1,numfunctions) +u_error = PseudoBlockVector(F*u-bsa, (ax,)) #select in u_error en in u function select_trace(u,trace_ind) usub = 0*deepcopy(u) N = length(blocks(u)) + println(N) for i in 1:N if i ∈ HOM - usub[Block(i)][Block(trace_ind)] += u[Block(i)][Block(trace_ind)] + + usub2 = deepcopy(usub[Block(i)]) + usub2[Block(trace_ind)] .+= u[Block(i)][Block(trace_ind)] + usub[Block(i)] .+= usub2 elseif i∈ [EFIE...,MFIE...,CFIE...] && trace_ind ∈ [3,4] - usub[Block(i)][Block(trace_ind)] += u[Block(i)][Block(trace_ind)] + println("pec") + usub2 = deepcopy(usub[Block(i)]) + usub2[Block(trace_ind-2)] .+= u[Block(i)][Block(trace_ind-2)] + usub[Block(i)] .+= usub2 end end return usub end -Gsym = assemble(diag(diag(Identity())),BEAST.DirectProductSpace(X),BEAST.DirectProductSpace(X)) +Gsym = assemble(BEAST.diag(BEAST.diag(Identity())),BEAST.DirectProductSpace(X),BEAST.DirectProductSpace(X)) Ginvsym = inv(Matrix(Gsym)) nom = sqrt.([Array(select_trace(u_error,i))'*Ginvsym*Array(select_trace(u_error,i)) for i in 1:4]) denom = sqrt.([Array(select_trace(u,i))'*Matrix(Gsym)*Array(select_trace(u,i)) for i in 1:4]) -error = 1/4*sum(nom./denom) \ No newline at end of file +error = 1/4*sum(nom./denom)* \ No newline at end of file diff --git a/src/bases/lincomb.jl b/src/bases/lincomb.jl index 9b42a7e2..24c1e4b7 100644 --- a/src/bases/lincomb.jl +++ b/src/bases/lincomb.jl @@ -1,4 +1,4 @@ -function Base.:*(A::AbstractArray, s::Space) where {Space} +function Base.:*(A::AbstractArray, s::Space) @assert ndims(A) == 2 @assert size(A,2) == numfunctions(s) diff --git a/src/bases/local/ndlocal.jl b/src/bases/local/ndlocal.jl index ed373a01..15360973 100644 --- a/src/bases/local/ndlocal.jl +++ b/src/bases/local/ndlocal.jl @@ -16,7 +16,7 @@ function (ϕ::NDRefSpace)(nbd) tu = tangents(nbd,1) tv = tangents(nbd,2) - n = normalize(tu×tv) + n = normal(nbd) d = 2/j return SVector(( @@ -67,3 +67,25 @@ function restrict(ϕ::NDRefSpace{T}, dom1, dom2) where T return Q end + +const _vert_perms_nd = [ + (1,2,3), + (2,3,1), + (3,1,2), + (2,1,3), + (1,3,2), + (3,2,1), +] +const _dof_perms_nd = [ + (1,2,3), + (3,1,2), + (2,3,1), + (2,1,3), + (1,3,2), + (3,2,1), +] +function dof_permutation(::Union{NDRefSpace}, vert_permutation) + i = something(findfirst(==(tuple(vert_permutation...)), _vert_perms_nd),0) + @assert i != 0 + return _dof_perms_nd[i] +end \ No newline at end of file diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 95ff1ab6..9bf442cc 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -186,11 +186,11 @@ geometry(o::Object) = geometry(o.type) geometry(o::Union{HOM,FreeSpace,PEC}) = o.mesh geometry(o::Inside) = geometry(o.inside) -function matrix_to_bilform(mat) +function matrix_to_bilform(mat;dims=size(mat),kwargs...) nrows,ncols = size(mat) - tin = BEAST.hilbertspace(:tin,nrows) - bin = BEAST.hilbertspace(:bin,ncols) - terms = [mat[i,j][tin[i],bin[j]] for i in 1:nrows, j in 1:ncols if typeof(mat[i,j]) != ZeroOperator] + tin = BEAST.hilbertspace(:tin,dims[1]) + bin = BEAST.hilbertspace(:bin,dims[2]) + terms = [mat[i,j][tin[i],bin[j]] for i in 1:minimum([nrows,dims[1]]), j in 1:minimum([ncols,dims[2]]) if typeof(mat[i,j]) != ZeroOperator] if length(terms) > 0 return sum(terms) else @@ -198,11 +198,11 @@ function matrix_to_bilform(mat) end end -function array_to_linform(array) +function array_to_linform(array;dim=length(array)) nrows = length(array) - tin = BEAST.hilbertspace(:tin,nrows) - println(sum([array[i][tin[i]] for i in 1:nrows])) - return sum([array[i][tin[i]] for i in 1:nrows]) + tin = BEAST.hilbertspace(:tin,dim) + println(sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])])) + return sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])]) end # function discretise_rhs(w::World, ex::Excitation, strat::Interaction) diff --git a/src/utils/variational.jl b/src/utils/variational.jl index e3bf97ba..5351f0de 100644 --- a/src/utils/variational.jl +++ b/src/utils/variational.jl @@ -2,6 +2,7 @@ module Variational import Base.zero using BlockArrays import BEAST +using StaticArrays # import Base: start, done, next export transposecalls! @@ -337,23 +338,23 @@ function getindex(op::Any, V::Vector{HilbertVector}, U::Vector{HilbertVector}) end return BilForm(first(V).space, first(U).space, terms) end -function getindex(op::Any, V::Vector{HilbertVector}, u::Hilbertvector) - terms = Vector{BilTerm}() - for v in V - term = BilTerm(v.idx, u.idx, v.opstack, u.opstack, 1, op) - push!(terms, term) - end - return BilForm(first(V).space, u.space, terms) -end +# function getindex(op::Any, V::Vector{HilbertVector}, u::Hilbertvector) +# terms = Vector{BilTerm}() +# for v in V +# term = BilTerm(v.idx, u.idx, v.opstack, u.opstack, 1, op) +# push!(terms, term) +# end +# return BilForm(first(V).space, u.space, terms) +# end -function getindex(op::Any, v::HilbertVector, U::Vector{HilbertVector}) - terms = Vector{BilTerm}() - for u in U - term = BilTerm(v.idx, u.idx, v.opstack, u.opstack, 1, op) - push!(terms, term) - end - return BilForm(v.space, first(U).space, terms) -end +# function getindex(op::Any, v::HilbertVector, U::Vector{HilbertVector}) +# terms = Vector{BilTerm}() +# for u in U +# term = BilTerm(v.idx, u.idx, v.opstack, u.opstack, 1, op) +# push!(terms, term) +# end +# return BilForm(v.space, first(U).space, terms) +# end function getindex(A::Matrix, v::HilbertVector, u::HilbertVector) terms = [ BilTerm(v.idx, u.idx, v.opstack, u.opstack, 1, A) ] BilForm(v.space, u.space, terms) @@ -367,7 +368,7 @@ function +(a::BilForm, b::BilForm) BilForm(a.test_space, a.trial_space, [a.terms; b.terms]) end -function+(a::LinForm, b::LinForm) +function +(a::LinForm, b::LinForm) @assert a.test_space == b.test_space LinForm(a.test_space, [a.terms; b.terms]) end @@ -383,7 +384,8 @@ function *(α::Number, a::LinForm) for t in b.terms t.coeff *= α end return b end - +*(a,b::BilTerm) = BilTerm(b.test_id,b.trial_id,b.test_ops,b.trial_ops,b.coeff,a*b.kernel) +*(b::BilTerm,a) = BilTerm(b.test_id,b.trial_id,b.test_ops,b.trial_ops,b.coeff,b.kernel*a) #-(a::BilForm) = (-1 * a) # -(a::BilForm, b::BilForm) = a + (-b) @@ -518,20 +520,22 @@ function *(a::Number,b::BilTerm) out.coeff *= a return out end -function *(a::Matrix,b::BilForm) +function *(a::Union{Matrix,SMatrix},b::BilForm) n = length(b.test_space) m = length(b.trial_space) @assert (n,m)==size(a) - @assert sum([abs(a[i,j]) for i in 1:n for j in 1:m if i≠j]) == 0.0 + @warn "use only with diagonal matrices" +# @assert sum([abs(a[i,j]) for i in 1:n for j in 1:m if i≠j]) == 0.0 +println(typeof(b.terms[1])) out = [a[term.test_id,term.test_id]*term for term in b.terms] return BilForm(b.test_space,b.trial_space,out) end -function *(b::BilForm,a::Matrix) +function *(b::BilForm,a::Union{Matrix,SMatrix}) n = length(b.test_space) m = length(b.trial_space) @assert (n,m)==size(a) - @assert sum([abs(a[i,j]) for i in 1:n for j in 1:m if i≠j]) == 0.0 - out = [a[term.trial_id,term.trial_id]*term for term in b.terms] + # @assert sum([abs(a[i,j]) for i in 1:n for j in 1:m if i≠j]) == 0.0 + out = [term*a[term.trial_id,term.trial_id] for term in b.terms] return BilForm(b.test_space,b.trial_space,out) end # mutable struct ProdBilTerm From 4babce8c9d64ea003a9530bb09e54cb8b1013c99 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 11 Mar 2024 15:00:34 +0100 Subject: [PATCH 089/110] update multi-trace --- src/multi-trace/VectorPotential.jl | 92 +++++++++++++++++++++++------ src/multi-trace/interactions.jl | 34 +++++------ src/multi-trace/interactions_new.jl | 44 ++++++++++++++ 3 files changed, 134 insertions(+), 36 deletions(-) create mode 100644 src/multi-trace/interactions_new.jl diff --git a/src/multi-trace/VectorPotential.jl b/src/multi-trace/VectorPotential.jl index 362b6cb4..30b94193 100644 --- a/src/multi-trace/VectorPotential.jl +++ b/src/multi-trace/VectorPotential.jl @@ -110,6 +110,47 @@ function trialbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: HOM} x4 = BEAST.lagrangecxd0(Γ) return BEAST.DirectProductSpace([x1,x2,x3,x4]) end + + +function testbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: PECEFIE} + Γ = obj.type.mesh + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangecxd0(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end + +function trialbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: PECEFIE} + Γ = obj.type.mesh + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangecxd0(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end +function testbasis(obj::Object{T}, ::PRECVPPMCHWT2) where {T <: PECEFIE} + Γ = obj.type.mesh + x3 = buffachristiansen(Γ) + x4 = BEAST.duallagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end + +function trialbasis(obj::Object{T}, ::PRECVPPMCHWT2) where {T <: PECEFIE} + Γ = obj.type.mesh + x3 = buffachristiansen(Γ) + x4 = BEAST.duallagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end +function testbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: PECMFIE} + Γ = obj.type.mesh + x3 = buffachristiansen(Γ) + x4 = BEAST.duallagrangec0d1(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end + +function trialbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: PECMFIE} + Γ = obj.type.mesh + x3 = raviartthomas(Γ) + x4 = BEAST.lagrangecxd0(Γ) + return BEAST.DirectProductSpace([x3,x4]) +end # function testbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} # Γ = obj.type.mesh # x1 = buffachristiansen(Γ) @@ -219,21 +260,30 @@ function interaction(testobj::Object,trialobj::Object,embobj::Object, a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign,dual=dual,trace=trace) end +# function interaction(testobj::Object,trialobj::Object,embobj::Object, +# testtype::PECCFIE,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + +# testtype.alpha*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[1:2,:]+ +# (1-testtype.alpha)*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] +# end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::PECCFIE,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + testtype::PECEFIE,trialtype,strat::Union{PRECVP,VP,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) - testtype.alpha*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[1:2,:]+ - (1-testtype.alpha)*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] + interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[1:2,:] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::PECEFIE,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + testtype::PECEFIE,trialtype,strat::Union{VPPMCHWT2}; sign=1,dual=true,trace=true) - interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[1:2,:] + interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::PECMFIE,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + testtype::PECMFIE,trialtype,strat::Union{PRECVP,VP,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::PECMFIE,trialtype,strat::Union{VPPMCHWT2}; sign=1,dual=true,trace=true) + interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[1:2,:] +end function interaction(testobj::Object,trialobj::Object,embobj::Object, testtype::ObjectType,trialtype::Inside,strat::Union{PRECVP,VP,VPPMCHWT,VPPMCHWT2}; sign=1,dual=true,trace=true) a = -[1 0 0 0; @@ -251,9 +301,13 @@ function interaction(testobj::Object,trialobj::Object,embobj::Object, interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)*a end function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::PEC,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) + testtype::ObjectType,trialtype::PEC,strat::Union{PRECVP,VP,VPPMCHWT2}; sign=1,dual=true,trace=true) interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)[:,3:4] end +function interaction(testobj::Object,trialobj::Object,embobj::Object, + testtype::ObjectType,trialtype::PEC,strat::Union{PRECVPPMCHWT2}; sign=1,dual=true,trace=true) + interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)[:,1:2] +end function interaction(testobj::Object,trialobj::Object,embobj::Object, testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP,VPPMCHWT,VPPMCHWT2,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace) @@ -517,7 +571,7 @@ function interaction(testobj::Object, trialobj::Object, embobj::Object, elseif dual int = [nt×(nt×(∇G∇B))+k^2*nt×(nt×(Gr)) -nt×(nt×(∇Gxn)) nt×(nt×(∇Gx)) ZeroOperator(); nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); - nt×(nt×(∇Gx)) -nt×(nt×(Gn)) nt×(nt×(Gr)) nt×(nt×(∇G)); + nt×(nt×(∇Gx)) -nt×(nt×(Gn)) nt×(nt×(Gr)) -nt×(nt×(∇G)); ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr)] return int elseif trace @@ -618,13 +672,13 @@ function identity(objtype::ObjectType,strat::PRECVP) ZeroOperator() ZeroOperator() NCross() ZeroOperator(); ZeroOperator() ZeroOperator() ZeroOperator() Identity()] end -function identity(objtype::PECCFIE,strat::Union{PRECVP,VP}) - (1-objtype.alpha)*identity(objtype.inside,strat)[3:4,3:4] -end -function identity(objtype::PECMFIE,strat::Union{PRECVP,VP}) +# function identity(objtype::PECCFIE,strat::Union{PRECVP,VP}) +# (1-objtype.alpha)*identity(objtype.inside,strat)[3:4,3:4] +# end +function identity(objtype::PECMFIE,strat::Union{PRECVP,VP,VPPMCHWT2,PRECVPPMCHWT2}) identity(objtype.inside,strat)[3:4,3:4] end -function identity(objtype::PECEFIE,strat::Union{PRECVP,VP}) +function identity(objtype::PECEFIE,strat::Union{PRECVP,VP,VPPMCHWT2,PRECVPPMCHWT2}) [ZeroOperator() ZeroOperator(); ZeroOperator() ZeroOperator()] end @@ -745,16 +799,16 @@ function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation return a^-1*excitation(testobj,emb,objtype.inside,ex,strat) end -function excitation(testobj::Object,emb::Object,objtype::PECCFIE,ex::VPExcitation,strat::VP) +# function excitation(testobj::Object,emb::Object,objtype::PECCFIE,ex::VPExcitation,strat::VP) - objtype.alpha*excitation(testobj,emb,objtype.inside,ex,strat)[1:2]+ - (1-objtype.alpha)*excitation(testobj,emb,objtype.inside,ex,strat)[3:4] -end -function excitation(testobj::Object,emb::Object,objtype::PECEFIE,ex::VPExcitation,strat::VP) +# objtype.alpha*excitation(testobj,emb,objtype.inside,ex,strat)[1:2]+ +# (1-objtype.alpha)*excitation(testobj,emb,objtype.inside,ex,strat)[3:4] +# end +function excitation(testobj::Object,emb::Object,objtype::PECEFIE,ex::VPExcitation,strat::Union{VP,VPPMCHWT2}) excitation(testobj,emb,objtype.inside,ex,strat)[1:2] end -function excitation(testobj::Object,emb::Object,objtype::PECMFIE,ex::VPExcitation,strat::VP) +function excitation(testobj::Object,emb::Object,objtype::PECMFIE,ex::VPExcitation,strat::Union{VP,VPPMCHWT2}) excitation(testobj,emb,objtype.inside,ex,strat)[3:4] end diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl index 9bf442cc..b092e1d6 100644 --- a/src/multi-trace/interactions.jl +++ b/src/multi-trace/interactions.jl @@ -186,24 +186,24 @@ geometry(o::Object) = geometry(o.type) geometry(o::Union{HOM,FreeSpace,PEC}) = o.mesh geometry(o::Inside) = geometry(o.inside) -function matrix_to_bilform(mat;dims=size(mat),kwargs...) - nrows,ncols = size(mat) - tin = BEAST.hilbertspace(:tin,dims[1]) - bin = BEAST.hilbertspace(:bin,dims[2]) - terms = [mat[i,j][tin[i],bin[j]] for i in 1:minimum([nrows,dims[1]]), j in 1:minimum([ncols,dims[2]]) if typeof(mat[i,j]) != ZeroOperator] - if length(terms) > 0 - return sum(terms) - else - return ZeroOperator()[tin[1],bin[1]] - end -end +# function matrix_to_bilform(mat;dims=size(mat),kwargs...) +# nrows,ncols = size(mat) +# tin = BEAST.hilbertspace(:tin,dims[1]) +# bin = BEAST.hilbertspace(:bin,dims[2]) +# terms = [mat[i,j][tin[i],bin[j]] for i in 1:minimum([nrows,dims[1]]), j in 1:minimum([ncols,dims[2]]) if typeof(mat[i,j]) != ZeroOperator] +# if length(terms) > 0 +# return sum(terms) +# else +# return ZeroOperator()[tin[1],bin[1]] +# end +# end -function array_to_linform(array;dim=length(array)) - nrows = length(array) - tin = BEAST.hilbertspace(:tin,dim) - println(sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])])) - return sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])]) -end +# function array_to_linform(array;dim=length(array)) +# nrows = length(array) +# tin = BEAST.hilbertspace(:tin,dim) +# println(sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])])) +# return sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])]) +# end # function discretise_rhs(w::World, ex::Excitation, strat::Interaction) # out = [] diff --git a/src/multi-trace/interactions_new.jl b/src/multi-trace/interactions_new.jl new file mode 100644 index 00000000..86204570 --- /dev/null +++ b/src/multi-trace/interactions_new.jl @@ -0,0 +1,44 @@ +import Base:*, +, - + +mutable struct DiscreteEq + lhs + rhs + trialspace +end + +function +(a::VGL,b::VGL) + @assert a.trialspace == b.trialspace + return VGL(a.lhs+b.lhs,a.rhs+b.rhs,a.trialspace) +end + +*(a::Union{LinearMap,Number},b::VGL) = VGL(a*b.lhs,a*b.rhs,b.trialspace) +-(a::VGL,b::VGL) = a + (-1)*b + +function generate_discrete_equations(w::World,strat;kwargs...) + # create hilbertspaces + + +end + +### to define for your specific problem +function hilbertspace(obj,strat) + return true +end + +function getequations(strat,dict)# builds the equations in vp case there are 2 homogeneous equations and 2 pec cfie equations + + return [] +end +##### vanaf hier voor vp + +function getequations(strat::VPPMCHWT,d::Dict) + homind = d[HOM()] + mfie = d[MFIE()] + efie = d[EFIE()] + cfie = d[CFIE()] + freespace = d[FREESPACE()] + eq1 = [] +end +function testspace(obj,strat) end +function trialspace(obj,strat) end +function getequations(strat::VP,dict) end \ No newline at end of file From e88216df8407f0a87a90e151759147edfc51cc31 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 11 Mar 2024 15:01:14 +0100 Subject: [PATCH 090/110] correcting n cross rt space and n cross nd space --- src/bases/ndspace.jl | 8 ++++++-- src/bases/rtspace.jl | 6 +----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/bases/ndspace.jl b/src/bases/ndspace.jl index ef9f740e..4d7a0ff9 100644 --- a/src/bases/ndspace.jl +++ b/src/bases/ndspace.jl @@ -42,8 +42,12 @@ function nedelec(surface, edges=skeleton(surface,1)) end function LinearAlgebra.cross(::NormalVector, s::NDBasis) - # @assert CompScienceMeshes.isoriented(s.geo) - RTBasis(s.geo, s.fns, s.pos) + @assert CompScienceMeshes.isoriented(s.geo) + fns = similar(s.fns) + for (i,fn) in pairs(s.fns) + fns[i] = [Shape(sh.cellid, sh.refid, -sh.coeff) for sh in fn] + end + RTBasis(s.geo, fns, s.pos) end diff --git a/src/bases/rtspace.jl b/src/bases/rtspace.jl index 991cecef..499d714b 100644 --- a/src/bases/rtspace.jl +++ b/src/bases/rtspace.jl @@ -263,9 +263,5 @@ ntrace(X::RTBasis, geo, fns) = LagrangeBasis{0,-1,1}(geo, fns, deepcopy(position function LinearAlgebra.cross(::NormalVector, s::RTBasis) @assert CompScienceMeshes.isoriented(s.geo) - fns = similar(s.fns) - for (i,fn) in pairs(s.fns) - fns[i] = [Shape(sh.cellid, sh.refid, -sh.coeff) for sh in fn] - end - NDBasis(s.geo, fns, s.pos) + NDBasis(s.geo, s.fns, s.pos) end From 762deae8d8a8f97cc97a22254899350fa813ef3d Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 11 Mar 2024 15:01:37 +0100 Subject: [PATCH 091/110] cleanup composed operator --- src/composedoperator/composedoperator.jl | 173 +++++++++++++++-------- 1 file changed, 113 insertions(+), 60 deletions(-) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 693df325..19ce74db 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -2,9 +2,6 @@ import Base: *, div import LinearAlgebra: ×, ⋅ -#TODO add ref of cross etc to eliminate brackets in notation. - -#const i4pi = 1 / (4pi) abstract type ComposedOperatorLocal <: LocalOperator end abstract type ComposedOperatorIntegral <: IntegralOperator end abstract type Kernel <: ComposedOperatorIntegral end @@ -34,6 +31,8 @@ struct Potential{T,M} <: AbstractOperator end Potential(a) = Potential(a,nothing) surface(p::Potential) = p.surface + + function Potential(linop::LinearCombinationOfOperators,surface::TraceMesh) out = ZeroOperator() for (op,coeff) in zip(linop.ops,linop.coeffs) @@ -92,6 +91,8 @@ struct CrossIntegral{U,V} <: ComposedOperatorIntegral rhs::V end +# ComposedOperations = Union{} +# ComposedValues = Union{} function TimesLocal(lhs::LinearCombinationOfOperators,rhs::Union{Union{ComposedOperator,NormalVector},LinearCombinationOfOperators}) out = ZeroOperator() for (op,coeff) in zip(lhs.ops,lhs.coeffs) @@ -228,16 +229,7 @@ end # return true # end -function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt × (γ(op.operator) × nt) - direction = [] - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,SVector{length(direction),typeof(direction[1])}(direction))) -end + function γₜ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = nt × (γ(op.operator) × nt) @@ -259,21 +251,9 @@ function τ(op::Potential,sign::Int)# sign + if according to normal on surface, return TraceOperator(Potential(newop,op.surface),sign) end -function γ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = nt × (γ(op.operator) × nt) - direction = [] - for i in 1:numcells(surface) - c = chart(surface,i) - push!(direction,sign*normal(c)/3) - end - return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) -end - - -function γₛ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt × γ(op.operator) # direction = [] # for i in 1:numcells(surface) # c = chart(surface,i) @@ -283,7 +263,20 @@ function γₛ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# direction = sign/3*normal.(charts) return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) end -function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise + +# function γ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = nt × (γ(op.operator) × nt) +# direction = [] +# for i in 1:numcells(surface) +# c = chart(surface,i) +# push!(direction,sign*normal(c)/3) +# end +# return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) +# end + + +function γₛ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator newop = nt × γ(op.operator) # direction = [] @@ -293,8 +286,20 @@ function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according # end charts = chart.(Ref(surface),1:numcells(surface)) direction = sign/3*normal.(charts) - return TraceOperator(Potential(newop,op.surface),direction+surface) + return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) end +# function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = nt × γ(op.operator) +# # direction = [] +# # for i in 1:numcells(surface) +# # c = chart(surface,i) +# # push!(direction,sign*normal(c)/3) +# # end +# charts = chart.(Ref(surface),1:numcells(surface)) +# direction = sign/3*normal.(charts) +# return TraceOperator(Potential(newop,op.surface),direction+surface) +# end function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator @@ -303,13 +308,13 @@ function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# direction = sign/3*normal.(charts) return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) end - function γₜ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise - # check_if_coincide(op.surface,surface) || return op.operator - newop = (nt × γ(op.operator)) × nt - charts = chart.(Ref(surface),1:numcells(surface)) - direction = sign/3*normal.(charts) - return TraceOperator(Potential(newop,op.surface),direction+surface) - end + # function γₜ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise + # # check_if_coincide(op.surface,surface) || return op.operator + # newop = (nt × γ(op.operator)) × nt + # charts = chart.(Ref(surface),1:numcells(surface)) + # direction = sign/3*normal.(charts) + # return TraceOperator(Potential(newop,op.surface),direction+surface) + # end function γₙ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator @@ -318,13 +323,13 @@ function γₙ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# direction = sign/3*normal.(charts) return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) end -function γₙ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt ⋅ γ(op.operator) - charts = chart.(Ref(surface),1:numcells(surface)) - direction = sign/3*normal.(charts) - return TraceOperator(Potential(newop,op.surface),direction+surface) -end +# function γₙ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = nt ⋅ γ(op.operator) +# charts = chart.(Ref(surface),1:numcells(surface)) +# direction = sign/3*normal.(charts) +# return TraceOperator(Potential(newop,op.surface),direction+surface) +# end function τ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # check_if_coincide(op.surface,surface) || return op.operator @@ -333,16 +338,16 @@ function τ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# si direction = sign/3*normal.(charts) return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) end -function τ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = γ(op.operator) - charts = chart.(Ref(surface),1:numcells(surface)) - direction = sign/3*normal.(charts) - return TraceOperator(Potential(newop,op.surface),direction+surface) -end +# function τ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = γ(op.operator) +# charts = chart.(Ref(surface),1:numcells(surface)) +# direction = sign/3*normal.(charts) +# return TraceOperator(Potential(newop,op.surface),direction+surface) +# end export γₛ, γₜ, γₙ, γ, τ -#### Define new greens functions below +#### Define kernel functions below function greenhh3d(; gamma=nothing, @@ -415,7 +420,9 @@ function (op::GradDivGreenHH3D)(x::Union{SVector,Vector},y,g) df = (3*iR^2-gamma*iR+gamma^2)*green*iR Ref(df*(r*r')+f*I) end - +# gamma(op::ComposedOperations) = gamma(op.rhs)+gamma(op.lhs) +# gamma(op::ComposedValues) = 0 +# gamma(op::Union{GreenHH3D,GradGreenHH3D,GradDivGreenHH3D}) = op.gamma function (op::GradGreenHH3D)(x,y,g) gamma = op.gamma @@ -424,12 +431,12 @@ function (op::GradGreenHH3D)(x,y,g) iR = 1/R green = exp(-gamma*R)*(iR*i4pi) gradgreen = -(gamma + iR) * green * (iR * r) - tt = Ref(gradgreen) + # tt = Ref(gradgreen) - if maximum(abs.(gradgreen)) === NaN - display(R) - end - return tt + # if maximum(abs.(gradgreen)) === NaN + # display(R) + # end + return Ref(gradgreen) end function (op::GradGreenHH3D)(x::Union{SVector,Vector},y,g) gamma = op.gamma @@ -441,9 +448,9 @@ function (op::GradGreenHH3D)(x::Union{SVector,Vector},y,g) gradgreen = -(gamma + iR) * green * (iR * r) tt = Ref(gradgreen) - if maximum(abs.(gradgreen)) === NaN - display(R) - end + # if maximum(abs.(gradgreen)) === NaN + # display(R) + # end return tt end @@ -472,6 +479,9 @@ scalartype(G::DoubleIntegralR{T}) where {T} = T γ(op::DoubleIntegralR) = op + + +######################################### integrand evaluation function (op::Union{TimesIntegral,TimesLocal})(x,y,g) op.lhs(x,y,g).*op.rhs(x,y,g) end @@ -489,7 +499,6 @@ function (op::TestNormal)(x,y,g) Ref(normal(x)) end function (op::TraceDirection)(x,y,g) - #println(direction(x)-direction(y)) Ref(approx_sign(dot(normal(x),(direction(y)-direction(x))))*normal(x)) end function (op::BasisFunction)(x,y,g) @@ -515,6 +524,50 @@ function integrand(op::ComposedOperator,kernel, y, f, x) r = op(y,x,f) return r end + +# function ex(op::Type{TimesIntegral{U,V}}) where{U,V} +# lhs = ex(U) +# rhs = ex(V) +# return :($lhs.*$rhs) +# end +# function ex(op::Type{TimesLocal{U,V}}) where{U,V} +# lhs = ex(U) +# rhs = ex(V) +# return :($lhs.*$rhs) +# end +# function ex(op::Type{CrossIntegral{U,V}}) where{U,V} +# lhs = ex(U) +# rhs = ex(V) +# return :(cross.($lhs,$rhs)) +# end +# function ex(op::Type{CrossLocal{U,V}}) where{U,V} +# lhs = ex(U) +# rhs = ex(V) +# return :(cross.($lhs,$rhs)) +# end +# function ex(op::Type{DotIntegral{U,V}}) where{U,V} +# lhs = ex(U) +# rhs = ex(V) +# return :(transpose.($lhs).*$rhs) +# end +# function ex(op::Type{DotLocal{U,V}}) where{U,V} +# lhs = ex(U) +# rhs = ex(V) +# return :(transpose.($lhs).*$rhs) +# end +# ex(op::Type{TestNormal}) = :(Ref(normal(x))) +# ex(op::Type{TrialNormal}) = :(Ref(normal(y))) +# ex(op::Type{TraceDirection}) = :(Ref(approx_sign(dot(normal(x),(direction(y)-direction(x))))*normal(x))) +# ex(op::Type{BasisFunction}) = :(getvalue(g)) +# ex(op::Type{DivBasisFunction}) = :(getdivergence(g)) + + +# @generated function integrand(igd::ComposedOperator,kernel,x,y,f,g) +# exp = ex(igd) +# out = quote _krondot(getvalue(f),$exp) end +# return out +# end + kernelvals(op::ComposedOperatorIntegral, y,x) = nothing quaddata(op::ComposedOperatorIntegral,rs,els,qs::SingleNumQStrat) = quadpoints(rs,els,(qs.quad_rule,)) quadrule(op::ComposedOperatorIntegral,refspace,p,y,q,el,qdata,qs::SingleNumQStrat) = qdata[1,q] From 2e7cbdac2cac0eec62eb202bf00aedd5bd084f85 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 11 Mar 2024 15:02:02 +0100 Subject: [PATCH 092/110] add documentation trace simplex and trace meshpoint --- src/composedoperator/tracesimplex.jl | 42 +++++++++++++++++----------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index 3206a491..c6b8f8a8 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -1,5 +1,11 @@ import Base.sign import Base.getindex + + +""" +TraceSimplex(simplex,direction::SVector) + simplex plus infinitesimal direction d, for each point p on the simplex, the trace is taken in the p-d direction +""" struct TraceSimplex{T,U} simp::T direction::SVector{3,U} @@ -7,6 +13,10 @@ end TraceSimplex(t::TraceSimplex,d::SVector{3,U}) where {U} = TraceSimplex(simplex(t),direction(t)+d) simplex(t::TraceSimplex) = t.simp direction(t::TraceSimplex) = t.direction +""" +TraceMeshPointNM(neighborhood,direction::SVector) + neighborhood p plus infinitesimal direction d, the trace is taken in the p-d direction +""" struct TraceMeshPointNM{T,U} neighborhood::T direction::SVector{3,U} @@ -67,10 +77,10 @@ CompScienceMeshes.barycentric(a::TraceMeshPointNM) = barycentric(a.neighborhood) -struct OrientedMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} - mesh::CompScienceMeshes.AbstractMesh{U,D1,T} - normalmesh::CompScienceMeshes.AbstractMesh{U,D1,T} -end +# struct OrientedMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} +# mesh::CompScienceMeshes.AbstractMesh{U,D1,T} +# normalmesh::CompScienceMeshes.AbstractMesh{U,D1,T} +# end struct TraceMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} mesh::CompScienceMeshes.AbstractMesh{U,D1,T} direction::Vector{SVector{3,T}} @@ -85,20 +95,20 @@ CompScienceMeshes.numvertices(t::TraceMesh) = CompScienceMeshes.numvertices(mesh CompScienceMeshes.vertextype(t::TraceMesh) = CompScienceMeshes.vertextype(mesh(t)) CompScienceMeshes.universedimension(t::TraceMesh) = CompScienceMeshes.universedimension(mesh(t)) -mesh(p::OrientedMesh) = p.mesh +# mesh(p::OrientedMesh) = p.mesh mesh(p::TraceMesh) = p.mesh -CompScienceMeshes.normal(p::OrientedMesh) = p.normalmesh +# CompScienceMeshes.normal(p::OrientedMesh) = p.normalmesh direction(p::TraceMesh) = p.direction -function CompScienceMeshes.chart(p::OrientedMesh,i) - c = chart(mesh(p),i) - n1 = normal(c) - n2 = normal(chart(normal(p),i)) - d = dot(n1,n2) - @assert abs(d) ≈ 1.0 - sign(d) == 1 && return c - return mirror(c) -end +# function CompScienceMeshes.chart(p::OrientedMesh,i) +# c = chart(mesh(p),i) +# n1 = normal(c) +# n2 = normal(chart(normal(p),i)) +# d = dot(n1,n2) +# @assert abs(d) ≈ 1.0 +# sign(d) == 1 && return c +# return mirror(c) +# end function CompScienceMeshes.chart(p::TraceMesh,i) c = chart(mesh(p),i) d = direction(p)[i] @@ -110,7 +120,7 @@ function same_geometry(m1,m2) end _ispermutation(a,b) = sort(a)==sort(b) -CompScienceMeshes.cells(p::OrientedMesh) = cells(mesh(p)) +# CompScienceMeshes.cells(p::OrientedMesh) = cells(mesh(p)) CompScienceMeshes.cells(p::TraceMesh) = cells(mesh(p)) CompScienceMeshes.vertices(p::TraceMesh) = vertices(mesh(p)) From 2596a814702e36a4314736f591223229e7036722 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 11 Mar 2024 16:22:10 +0100 Subject: [PATCH 093/110] matrix to bilform --- src/operator.jl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/operator.jl b/src/operator.jl index 548ad926..d12bd4b8 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -371,3 +371,24 @@ Base.zero(op::AbstractOperator) = ZeroOperator() -(a::ZeroOperator,b::AbstractOperator) = -b *(a::Number,b::ZeroOperator) = b +function matrix_to_bilform(mat;dims=size(mat),kwargs...) + nrows,ncols = size(mat) + tin = BEAST.hilbertspace(:tin,dims[1]) + bin = BEAST.hilbertspace(:bin,dims[2]) + terms = [mat[i,j][tin[i],bin[j]] for i in 1:minimum([nrows,dims[1]]), j in 1:minimum([ncols,dims[2]]) if typeof(mat[i,j]) != ZeroOperator] + if length(terms) > 0 + return sum(terms) + else + return ZeroOperator()[tin[1],bin[1]] + end +end + +function array_to_linform(array;dim=length(array)) + nrows = length(array) + tin = BEAST.hilbertspace(:tin,dim) + println(sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])])) + return sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])]) +end + +export matrix_to_bilform +export array_to_linform \ No newline at end of file From d642dc260a68becd7d3dad01a2d4bb23f90a57a0 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 11 Mar 2024 16:33:58 +0100 Subject: [PATCH 094/110] simplified trace and potential operator --- src/composedoperator/composedoperator.jl | 337 +++++++++++++---------- src/composedoperator/tracesimplex.jl | 1 + 2 files changed, 191 insertions(+), 147 deletions(-) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 19ce74db..c842f78f 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -25,41 +25,41 @@ const nt = TestNormal() const nb = TrialNormal() export nt export nb -struct Potential{T,M} <: AbstractOperator +struct Potential{T} <: AbstractOperator operator::T - surface::M + # surface::M end -Potential(a) = Potential(a,nothing) -surface(p::Potential) = p.surface +#Potential(a) = Potential(a,nothing) +#surface(p::Potential) = p.surface -function Potential(linop::LinearCombinationOfOperators,surface::TraceMesh) +function Potential(linop::LinearCombinationOfOperators)#,surface::TraceMesh) out = ZeroOperator() for (op,coeff) in zip(linop.ops,linop.coeffs) - out += coeff*Potential(op,surface) + out += coeff*Potential(op)#,surface) end return out end -struct TraceOperator{T,M} <: AbstractOperator +struct TraceOperator{T} <: AbstractOperator operator::T - surface::M + direction::Int end -function TraceOperator(linop::LinearCombinationOfOperators,surf::TraceMesh) +function TraceOperator(linop::LinearCombinationOfOperators,direction::Int) out = ZeroOperator() for (op,coeff) in zip(linop.ops,linop.coeffs) - out += coeff*TraceOperator(op,surf) + out += coeff*TraceOperator(op,direction) end return out end -function TraceOperator(linop::LinearCombinationOfOperators) - out = ZeroOperator() - for (op,coeff) in zip(linop.ops,linop.coeffs) - out += coeff*TraceOperator(op) - end - return out -end -surface(p::TraceOperator) = p.surface +# function TraceOperator(linop::LinearCombinationOfOperators) +# out = ZeroOperator() +# for (op,coeff) in zip(linop.ops,linop.coeffs) +# out += coeff*TraceOperator(op) +# end +# return out +# end +direction(p::TraceOperator) = p.direction struct TimesLocal{U,V} <: ComposedOperatorLocal lhs::U @@ -204,20 +204,31 @@ replace_normal_by_trialnormal(op::NormalVector) = TrialNormal() +# function build_potential(op::ComposedOperator,surface::CompScienceMeshes.AbstractMesh) +# newop = replace_normal_by_trialnormal(op) +# Potential(newop,TraceMesh(surface)) +# end +# function build_potential(op::ComposedOperator,surface::TraceMesh) +# newop = replace_normal_by_trialnormal(op) +# Potential(newop,surface) +# end +# function build_potential(op::ComposedOperator) +# newop = replace_normal_by_trialnormal(op) +# Potential(newop,nothing) +# end function build_potential(op::ComposedOperator,surface::CompScienceMeshes.AbstractMesh) newop = replace_normal_by_trialnormal(op) - Potential(newop,TraceMesh(surface)) + Potential(newop) end function build_potential(op::ComposedOperator,surface::TraceMesh) newop = replace_normal_by_trialnormal(op) - Potential(newop,surface) + Potential(newop) end function build_potential(op::ComposedOperator) newop = replace_normal_by_trialnormal(op) - Potential(newop,nothing) + Potential(newop) end - function γ(op::Operations) return get_constructor(op)(γ(op.lhs),γ(op.rhs)) end @@ -230,65 +241,72 @@ end # end +# function γₜ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = nt × (γ(op.operator) × nt) +# return TraceOperator(Potential(newop,op.surface),sign) +# end +# function γₛ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = nt × γ(op.operator) +# return TraceOperator(Potential(newop,op.surface),sign) +# end +# function γₙ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = nt ⋅ γ(op.operator) +# return TraceOperator(Potential(newop,op.surface),sign) +# end +# function τ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = γ(op.operator) +# return TraceOperator(Potential(newop,op.surface),sign) +# end function γₜ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt × (γ(op.operator) × nt) - return TraceOperator(Potential(newop,op.surface),sign) -end -function γₛ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt × γ(op.operator) - return TraceOperator(Potential(newop,op.surface),sign) -end -function γₙ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt ⋅ γ(op.operator) - return TraceOperator(Potential(newop,op.surface),sign) -end -function τ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = γ(op.operator) - return TraceOperator(Potential(newop,op.surface),sign) -end - -function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt × (γ(op.operator) × nt) - # direction = [] - # for i in 1:numcells(surface) - # c = chart(surface,i) - # push!(direction,sign*normal(c)/3) - # end - charts = chart.(Ref(surface),1:numcells(surface)) - direction = sign/3*normal.(charts) - return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) -end - -# function γ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise + # check_if_coincide(op.surface,surface) || return op.operator + newop = nt × (γ(op.operator) × nt) + return TraceOperator(Potential(newop),sign) + end + function γₛ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise + # check_if_coincide(op.surface,surface) || return op.operator + newop = nt × γ(op.operator) + return TraceOperator(Potential(newop),sign) + end + function γₙ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise + # check_if_coincide(op.surface,surface) || return op.operator + newop = nt ⋅ γ(op.operator) + return TraceOperator(Potential(newop),sign) + end + function τ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise + # check_if_coincide(op.surface,surface) || return op.operator + newop = γ(op.operator) + return TraceOperator(Potential(newop),sign) + end +# function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # # check_if_coincide(op.surface,surface) || return op.operator # newop = nt × (γ(op.operator) × nt) -# direction = [] -# for i in 1:numcells(surface) -# c = chart(surface,i) -# push!(direction,sign*normal(c)/3) -# end -# return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) +# # direction = [] +# # for i in 1:numcells(surface) +# # c = chart(surface,i) +# # push!(direction,sign*normal(c)/3) +# # end +# charts = chart.(Ref(surface),1:numcells(surface)) +# direction = sign/3*normal.(charts) +# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) # end +# # function γ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # # check_if_coincide(op.surface,surface) || return op.operator +# # newop = nt × (γ(op.operator) × nt) +# # direction = [] +# # for i in 1:numcells(surface) +# # c = chart(surface,i) +# # push!(direction,sign*normal(c)/3) +# # end +# # return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) +# # end -function γₛ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt × γ(op.operator) - # direction = [] - # for i in 1:numcells(surface) - # c = chart(surface,i) - # push!(direction,sign*normal(c)/3) - # end - charts = chart.(Ref(surface),1:numcells(surface)) - direction = sign/3*normal.(charts) - return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) -end -# function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise + +# function γₛ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # # check_if_coincide(op.surface,surface) || return op.operator # newop = nt × γ(op.operator) # # direction = [] @@ -298,53 +316,65 @@ end # # end # charts = chart.(Ref(surface),1:numcells(surface)) # direction = sign/3*normal.(charts) -# return TraceOperator(Potential(newop,op.surface),direction+surface) +# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) # end +# # function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # # check_if_coincide(op.surface,surface) || return op.operator +# # newop = nt × γ(op.operator) +# # # direction = [] +# # # for i in 1:numcells(surface) +# # # c = chart(surface,i) +# # # push!(direction,sign*normal(c)/3) +# # # end +# # charts = chart.(Ref(surface),1:numcells(surface)) +# # direction = sign/3*normal.(charts) +# # return TraceOperator(Potential(newop,op.surface),direction+surface) +# # end + +# function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # check_if_coincide(op.surface,surface) || return op.operator +# newop = (nt × γ(op.operator)) × nt +# charts = chart.(Ref(surface),1:numcells(surface)) +# direction = sign/3*normal.(charts) +# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) +# end +# # function γₜ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # # check_if_coincide(op.surface,surface) || return op.operator +# # newop = (nt × γ(op.operator)) × nt +# # charts = chart.(Ref(surface),1:numcells(surface)) +# # direction = sign/3*normal.(charts) +# # return TraceOperator(Potential(newop,op.surface),direction+surface) +# # end -function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise - # check_if_coincide(op.surface,surface) || return op.operator - newop = (nt × γ(op.operator)) × nt - charts = chart.(Ref(surface),1:numcells(surface)) - direction = sign/3*normal.(charts) - return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) - end - # function γₜ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise - # # check_if_coincide(op.surface,surface) || return op.operator - # newop = (nt × γ(op.operator)) × nt - # charts = chart.(Ref(surface),1:numcells(surface)) - # direction = sign/3*normal.(charts) - # return TraceOperator(Potential(newop,op.surface),direction+surface) - # end - -function γₙ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = nt ⋅ γ(op.operator) - charts = chart.(Ref(surface),1:numcells(surface)) - direction = sign/3*normal.(charts) - return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) -end -# function γₙ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# function γₙ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # # check_if_coincide(op.surface,surface) || return op.operator # newop = nt ⋅ γ(op.operator) # charts = chart.(Ref(surface),1:numcells(surface)) # direction = sign/3*normal.(charts) -# return TraceOperator(Potential(newop,op.surface),direction+surface) +# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) # end - -function τ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# check_if_coincide(op.surface,surface) || return op.operator - newop = γ(op.operator) - charts = chart.(Ref(surface),1:numcells(surface)) - direction = sign/3*normal.(charts) - return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) -end -# function τ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # function γₙ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # # check_if_coincide(op.surface,surface) || return op.operator +# # newop = nt ⋅ γ(op.operator) +# # charts = chart.(Ref(surface),1:numcells(surface)) +# # direction = sign/3*normal.(charts) +# # return TraceOperator(Potential(newop,op.surface),direction+surface) +# # end + +# function τ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise # # check_if_coincide(op.surface,surface) || return op.operator # newop = γ(op.operator) # charts = chart.(Ref(surface),1:numcells(surface)) # direction = sign/3*normal.(charts) -# return TraceOperator(Potential(newop,op.surface),direction+surface) +# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) # end +# # function τ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise +# # # check_if_coincide(op.surface,surface) || return op.operator +# # newop = γ(op.operator) +# # charts = chart.(Ref(surface),1:numcells(surface)) +# # direction = sign/3*normal.(charts) +# # return TraceOperator(Potential(newop,op.surface),direction+surface) +# # end export γₛ, γₜ, γₙ, γ, τ #### Define kernel functions below @@ -603,11 +633,11 @@ function assemble!(op::Potential, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; kwargs...) # checks if surface given in basis is the same as surface given in potential - dsurf = surface(op) - surf = geometry(trial_functions) - @assert same_geometry(dsurf,surf) - nsurf = mesh(dsurf) - trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf,direction(dsurf))) + # dsurf = surface(op) + # surf = geometry(trial_functions) + # @assert same_geometry(dsurf,surf) + # nsurf = mesh(dsurf) + trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) assemble!(op.operator, test_functions, trial_functions, store, threading; kwargs...) @@ -622,16 +652,16 @@ end # assemble!(op.operator, test_functions, trial_functions, store, threading; # quadstrat = quadstrat) # end -function assemble!(op::Potential{T,Nothing}, test_functions::Space, trial_functions::Space, - store, threading = Threading{:multi}; - kwargs...) where {T} +# function assemble!(op::Potential{T,Nothing}, test_functions::Space, trial_functions::Space, +# store, threading = Threading{:multi}; +# kwargs...) where {T} - surf = geometry(trial_functions) - trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) +# surf = geometry(trial_functions) +# trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) - assemble!(op.operator, test_functions, trial_functions, store, threading; - kwargs...) -end +# assemble!(op.operator, test_functions, trial_functions, store, threading; +# kwargs...) +# end # function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, # store, threading = Threading{:multi}; @@ -650,37 +680,50 @@ end # quadstrat = quadstrat) # end -function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, - store, threading = Threading{:multi}; - kwargs...) +# function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, +# store, threading = Threading{:multi}; +# kwargs...) - dsurf = surface(op) - surf = geometry(test_functions) - println(typeof(surf)) - println(typeof(mesh(dsurf))) - @assert same_geometry(dsurf,surf) - nsurf = mesh(dsurf) +# dsurf = surface(op) +# surf = geometry(test_functions) +# println(typeof(surf)) +# println(typeof(mesh(dsurf))) +# @assert same_geometry(dsurf,surf) +# nsurf = mesh(dsurf) - test_functions = redefine_geometrie(test_functions,TraceMesh(surf,direction(dsurf))) +# test_functions = redefine_geometrie(test_functions,TraceMesh(surf,direction(dsurf))) - assemble!(op.operator, test_functions, trial_functions, store, threading; - kwargs...) -end -function assemble!(op::TraceOperator{T,Int}, test_functions::Space, trial_functions::Space, - store, threading = Threading{:multi}; - kwargs...) where {T} +# assemble!(op.operator, test_functions, trial_functions, store, threading; +# kwargs...) +# end +# function assemble!(op::TraceOperator{T,Int}, test_functions::Space, trial_functions::Space, +# store, threading = Threading{:multi}; +# kwargs...) where {T} - surface = geometry(test_functions) +# surface = geometry(test_functions) - sign = op.surface - direction = [sign*normal(c)/3 for c in chart.(Ref(surface),1:numcells(surface))] +# sign = op.surface +# direction = [sign*normal(c)/3 for c in chart.(Ref(surface),1:numcells(surface))] - if typeof(surface) <: TraceMesh - surf = surface + direction - else - surf = TraceMesh(surface,direction) - end +# if typeof(surface) <: TraceMesh +# surf = surface + direction +# else +# surf = TraceMesh(surface,direction) +# end + +# test_functions = redefine_geometrie(test_functions,surf) +# assemble!(op.operator, test_functions, trial_functions, store, threading; +# kwargs...) +# end +function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, + store, threading = Threading{:multi}; + kwargs...) + + surface = geometry(test_functions) + sign = direction(op) + direction = [sign*normal(c)/3 for c in chart.(Ref(surface),1:numcells(surface))] + surf = TraceMesh(surface,direction) test_functions = redefine_geometrie(test_functions,surf) assemble!(op.operator, test_functions, trial_functions, store, threading; diff --git a/src/composedoperator/tracesimplex.jl b/src/composedoperator/tracesimplex.jl index c6b8f8a8..b2f7ceaf 100644 --- a/src/composedoperator/tracesimplex.jl +++ b/src/composedoperator/tracesimplex.jl @@ -85,6 +85,7 @@ struct TraceMesh{U,D1,T} <: CompScienceMeshes.AbstractMesh{U,D1,T} mesh::CompScienceMeshes.AbstractMesh{U,D1,T} direction::Vector{SVector{3,T}} end + TraceMesh(a::TraceMesh,b::Vector{SVector{3,T}}) where {T} = a+b TraceMesh(a::CompScienceMeshes.AbstractMesh{U,D,T}) where {U,D,T} = TraceMesh(a,zeros(SVector{3,T},(numcells(a)))) +(a::TraceMesh{U,D,T},b::SVector{3,T}) where {U,D,T} = TraceMesh(mesh(a),direction(a).+Ref(b)) From 460b352a3a06fcb3922b966f8cfe3f64be160397 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Mon, 11 Mar 2024 16:47:02 +0100 Subject: [PATCH 095/110] update --- src/bases/basis.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bases/basis.jl b/src/bases/basis.jl index d8578ad2..d47bb00c 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -88,7 +88,7 @@ function Base.:+(x::AbstractSpace...) T = scalartype(x...) return DirectProductSpace{T, AbstractSpace}([x...]) end -cross(a::Nothing,b::AbstractSpace) = b +#cross(a::Nothing,b::AbstractSpace) = b cross(a::Space{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}(Space{T}[a,b]) cross(a::DirectProductSpace{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b]) #cross(a::DirectProductSpace{T}, b::DirectProductSpace{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b.factors]) From 3ab7da4f350e67caa23d368d9eb9403a6d78babf Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Mar 2024 12:25:22 +0100 Subject: [PATCH 096/110] update master to merge with beast --- .gitignore | 1 + examples/vppmchwt.jl | 968 ++++++++++------------- src/BEAST.jl | 9 +- src/bases/basis.jl | 4 +- src/bases/bcspace.jl | 1 + src/bases/local/laglocal.jl | 61 +- src/bases/local/ncrossbdmlocal.jl | 3 +- src/bases/local/ndlocal.jl | 3 +- src/bases/local/rtlocal.jl | 4 +- src/composedoperator/composedoperator.jl | 8 +- src/integralop.jl | 6 +- src/localop.jl | 33 +- src/quadrature/quadstrats.jl | 5 +- src/quadrature/sauterschwabints.jl | 56 +- src/solvers/lusolver.jl | 6 +- src/solvers/solver.jl | 43 +- src/utils/geometrie.jl | 30 - test/runtests.jl | 4 +- test/test_basis.jl | 4 +- test/test_composed_operator.jl | 33 +- test/test_dipole.jl | 2 +- test/test_embedding.jl | 2 +- test/test_momintegrals_overlap.jl | 25 - test/test_ndspace.jl | 4 +- 24 files changed, 565 insertions(+), 750 deletions(-) delete mode 100644 src/utils/geometrie.jl delete mode 100644 test/test_momintegrals_overlap.jl diff --git a/.gitignore b/.gitignore index a023f4f4..7c294c59 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ programs/ results/ src/todo.txt +dev_test/ \ No newline at end of file diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl index d4d14952..cc3eddd0 100644 --- a/examples/vppmchwt.jl +++ b/examples/vppmchwt.jl @@ -4,7 +4,7 @@ using LinearAlgebra using AbstractTrees using StaticArrays using Plots -function Z(κ;rows=[1,2,3,4],cols=[1,2,3,4],trace=true,dual=true,tr=1) # build to test with nxt in dual true +function T1(κ;trace=true,tr=1,kwargs...) G = BEAST.greenhh3d(wavenumber=κ) gradG = BEAST.∇(G) if trace @@ -31,38 +31,56 @@ function Z(κ;rows=[1,2,3,4],cols=[1,2,3,4],trace=true,dual=true,tr=1) # build t ∇Gxn = gradG×(nb*B) end - - if dual && trace - int = -[γₜ(∇G∇B,tr)+κ^2*γₜ(Gr,tr) -γₜ(∇Gxn,tr) γₜ(∇Gx,tr) ZeroOperator(); - γₙ(∇Gx,tr) -γₙ(Gn,tr) γₙ(Gr,tr) -γₙ(∇G,tr); - γₜ(∇Gx,tr) -γₜ(Gn,tr) γₜ(Gr,tr) -γₜ(∇G,tr); - ZeroOperator() -τ(∇Gdotn,tr) τ(∇Gdot,tr) κ^2*τ(Gr,tr)] - - elseif dual - int = -[-nt×(nt×(∇G∇B))-κ^2*nt×(nt×(Gr)) nt×(nt×(∇Gxn)) -nt×(nt×(∇Gx)) ZeroOperator(); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); - -nt×(nt×(∇Gx)) nt×(nt×(Gn)) -nt×(nt×(Gr)) nt×(nt×(∇G)); - ZeroOperator() -(∇Gdotn) (∇Gdot) κ^2*(Gr)] + if trace + int = -[γₛ(∇Gx,tr) -γₛ(Gn,tr) ; + ZeroOperator() -τ(∇Gdotn,tr) ] - elseif trace - int = -[γₛ(∇G∇B,tr)+κ^2*γₛ(Gr,tr) -γₛ(∇Gxn,tr) γₛ(∇Gx,tr) ZeroOperator(); - γₙ(∇Gx,tr) -γₙ(Gn,tr) γₙ(Gr,tr) -γₙ(∇G,tr); - γₛ(∇Gx,tr) -γₛ(Gn,tr) γₛ(Gr,tr) -γₛ(∇G,tr); - ZeroOperator() -τ(∇Gdotn,tr) τ(∇Gdot,tr) κ^2*τ(Gr,tr)] + else + int = -[nt×(∇Gx) -nt×(Gn) ; + ZeroOperator() -(∇Gdotn) ] + end + return BEAST.matrix_to_bilform(int) +end +function T2(κ;trace=true,tr=1,kwargs...) + G = BEAST.greenhh3d(wavenumber=κ) + gradG = BEAST.∇(G) + if trace + ∇Gx = BEAST.build_potential(gradG×B) + Gn = BEAST.build_potential(G*(n*B)) + #Gnx = BEAST.build_potential(G*(n × B)) + ∇G = BEAST.build_potential(gradG*B) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B)) + ∇Gdot = BEAST.build_potential(B ⋅ gradG) + Gr = BEAST.build_potential(G*B) + ∇G∇B = BEAST.build_potential(gradG*BEAST.div(B)) + ∇Gxn = BEAST.build_potential(gradG×(n*B)) else - int = -[nt×(∇G∇B)+κ^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); - nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); - ZeroOperator() -(∇Gdotn) (∇Gdot) κ^2*(Gr)] + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + + Gr = G*B + ∇G∇B = gradG*BEAST.div(B) + ∇Gxn = gradG×(nb*B) + end + + if trace + int = -[γₛ(∇Gx,tr) ZeroOperator(); + γₙ(Gr,tr) -γₙ(∇G,tr)] + else + int = -[nt×(∇Gx) ZeroOperator(); + nt ⋅(Gr) -nt ⋅(∇G)] end - return BEAST.matrix_to_bilform(int[rows,cols]) + return BEAST.matrix_to_bilform(int) end -function Zp(κ;rows=[1,2,3,4],cols=[1,2,3,4],trace=true,dual=true,tr=1) # build to test with nxt in dual true +function A(κ;trace=true,tr=1,kwargs...) G = BEAST.greenhh3d(wavenumber=κ) gradG = BEAST.∇(G) - tr *=1 if trace ∇Gx = BEAST.build_potential(gradG×B) Gn = BEAST.build_potential(G*(n*B)) @@ -87,47 +105,68 @@ function Zp(κ;rows=[1,2,3,4],cols=[1,2,3,4],trace=true,dual=true,tr=1) # build ∇Gxn = gradG×(nb*B) end - - if dual && trace - int = -[γₜ(∇G∇B,tr)+κ^2*γₜ(Gr,tr) -γₜ(∇Gxn,tr) γₜ(∇Gx,tr) ZeroOperator(); - γₙ(∇Gx,tr) -γₙ(Gn,tr) γₙ(Gr,tr) -γₙ(∇G,tr); - γₜ(∇Gx,tr) -γₜ(Gn,tr) γₜ(Gr,tr) -γₜ(∇G,tr); - ZeroOperator() -τ(∇Gdotn,tr) τ(∇Gdot,tr) κ^2*τ(Gr,tr)][[3,4,1,2],[3,4,1,2]] - - elseif dual - int = -[-nt×(nt×(∇G∇B))-κ^2*nt×(nt×(Gr)) nt×(nt×(∇Gxn)) -nt×(nt×(∇Gx)) ZeroOperator(); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); - -nt×(nt×(∇Gx)) nt×(nt×(Gn)) -nt×(nt×(Gr)) nt×(nt×(∇G)); - ZeroOperator() -(∇Gdotn) (∇Gdot) κ^2*(Gr)] + if trace + int = -[γₛ(Gr,tr) -γₛ(∇G,tr); + τ(∇Gdot,tr) κ^2*τ(Gr,tr)] - elseif trace - int = -[γₛ(∇G∇B,tr)+κ^2*γₛ(Gr,tr) -γₛ(∇Gxn,tr) γₛ(∇Gx,tr) ZeroOperator(); - γₙ(∇Gx,tr) -γₙ(Gn,tr) γₙ(Gr,tr) -γₙ(∇G,tr); - γₛ(∇Gx,tr) -γₛ(Gn,tr) γₛ(Gr,tr) -γₛ(∇G,tr); - ZeroOperator() -τ(∇Gdotn,tr) τ(∇Gdot,tr) κ^2*τ(Gr,tr)][[3,4,1,2],[3,4,1,2]] + else + int = -[nt×(Gr) -nt×(∇G); + (∇Gdot) κ^2*(Gr)] + end + return BEAST.matrix_to_bilform(int) +end + +function Bb(κ;trace=true,tr=1,kwargs...) + G = BEAST.greenhh3d(wavenumber=κ) + gradG = BEAST.∇(G) + if trace + ∇Gx = BEAST.build_potential(gradG×B) + Gn = BEAST.build_potential(G*(n*B)) + #Gnx = BEAST.build_potential(G*(n × B)) + ∇G = BEAST.build_potential(gradG*B) + ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B)) + ∇Gdot = BEAST.build_potential(B ⋅ gradG) + Gr = BEAST.build_potential(G*B) + ∇G∇B = BEAST.build_potential(gradG*BEAST.div(B)) + ∇Gxn = BEAST.build_potential(gradG×(n*B)) else - int = -[nt×(∇G∇B)+κ^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); - nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); - ZeroOperator() -(∇Gdotn) (∇Gdot) κ^2*(Gr)][[3,4,1,2],[3,4,1,2]] + ∇Gx = gradG×B + Gn = G*(nb*B) + #Gnx = G*(n × B) + ∇G = gradG*B + ∇Gdotn = nb ⋅ (gradG*B) + ∇Gdot = B ⋅ gradG + Gr = G*B + ∇G∇B = gradG*BEAST.div(B) + ∇Gxn = gradG×(nb*B) + end - return BEAST.matrix_to_bilform(int[rows,cols]) -end -function excitation(A,curlA,divA;rows=[1,2,3,4],dual=true) - if dual - out = [((n × FunctionExcitation{ComplexF64}(curlA))×n), - BEAST.NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(A)), - ((n × FunctionExcitation{ComplexF64}(A))×n), - FunctionExcitation{ComplexF64}(divA)] + if trace + int = -[γₛ(∇G∇B,tr)+κ^2*γₛ(Gr,tr) -γₛ(∇Gxn,tr); + γₙ(∇Gx,tr) -γₙ(Gn,tr)] + else - out = [((n × FunctionExcitation{ComplexF64}(curlA))), - BEAST.NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(A)), - ((n × FunctionExcitation{ComplexF64}(A))), - FunctionExcitation{ComplexF64}(divA)] + int = -[nt×(∇G∇B)+κ^2*nt×(Gr) -nt×(∇Gxn) ; + nt ⋅(∇Gx) -nt ⋅(Gn)] end - return BEAST.array_to_linform(out[rows]) + return BEAST.matrix_to_bilform(int) +end + +Z(κ;rows = [1,2],cols = [1,2],kwargs...) = BEAST.matrix_to_bilform([Bb(κ;kwargs...) T2(κ;kwargs...);T1(κ;kwargs...) A(κ;kwargs...)][rows,cols];kwargs...) +Zp(κ;rows = [1,2],cols = [1,2],kwargs...) = BEAST.matrix_to_bilform([A(κ;kwargs...) T1(κ;kwargs...);T2(κ;kwargs...) Bb(κ;kwargs...)][rows,cols];kwargs...) + + +function excitation_dirichlet(A,curlA,divA) + out = [((n × FunctionExcitation{ComplexF64}(A))), + FunctionExcitation{ComplexF64}(divA)] + return BEAST.array_to_linform(out) +end +function excitation_neumann(A,curlA,divA) + out = [((n × FunctionExcitation{ComplexF64}(curlA))), + BEAST.NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(A))] + return BEAST.array_to_linform(out) end function solve(Z,b,X;strat,kwargs...) if strat ==:LU @@ -137,46 +176,42 @@ function solve(Z,b,X;strat,kwargs...) end @error "no existing strategy given, use :LU or :GMRES" end + + +parent(ind,tree) = tree[ind] +children(ind,tree) = findall(==(ind),tree) + + function plot_eigenvalues(M) eigs = eigen(M).values display(scatter(real.(eigs),imag.(eigs))) end -parent(ind,tree) = tree[ind] -children(ind,tree) = findall(==(ind),tree) + ### physical constants ϵ0 = 8.854e-12 μ0 = 4π*1e-7 ω = 10.0^8#*2*pi κ0 = ω*sqrt(ϵ0*μ0) -### what to do: -execute = Dict( -:precondition => true, -:plot_E => true, -:plot_H => true, -:plot_A => true, -:extinction_error => true, -:unprec_solve => true -) #### define meshes hh = 0.3 -# Γ1 = meshcuboid(1.0, 1.0, 1.0, hh) -# Γ2 = (@SVector [-1.0,0.0,0.0]) + BEAST.TraceMesh(-Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1)))) -# Γ3 = (@SVector [0.0,0.0,-1.0]) + BEAST.TraceMesh(-translate(Mesh([point(x,y,-z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))),[0.0,0.0,0.0])) -Γ = [boundary(tetmeshsphere(1.0,0.5))] -#Γ = [Γ1]#,Γ2,Γ3] -Tree = [0]#,0,0] # give index in which material is - -HOM = [1]#,2] #indices of homogeneous domains (without free space) -HomPars = Dict(0=>(ϵ0,μ0),1=>(ϵ0*2,μ0*2),2=>(ϵ0*2,μ0*2))#,3=>(ϵ0*3,μ0))#index --> (eps,mu) +Γ1 = meshcuboid(1.0, 1.0, 1.0, hh) +Γ2 = (@SVector [-1.0,0.0,0.0]) + BEAST.TraceMesh(-Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1)))) +Γ3 = (@SVector [0.0,0.0,-1.0]) + BEAST.TraceMesh(-translate(Mesh([point(x,y,-z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))),[0.0,0.0,0.0])) + +Γ = [Γ1,Γ2,Γ3] +Tree = [0,0,0] # give index in which volume material is + +HOM = [1,2] #indices of homogeneous domains (without free space) +HomPars = Dict(0=>(ϵ0,μ0),1=>(ϵ0*2,μ0*2),2=>(ϵ0*2,μ0*2))# κ = Dict(i => ω*sqrt(prod(HomPars[i])) for i in HOM) κ[0]=κ0 EFIE = [] #indices of pec domains modeled with efie MFIE = [] #indices of pec domains modeled with mfie -CFIE = []#3] #indices of pec domains modeled with cfie +CFIE = [3] #indices of pec domains modeled with cfie α = Dict(3=>0.2)#index --> alpha #### Incident field @@ -185,103 +220,89 @@ curlA(x) = -[0.0,1.0,0.0]*sqrt(ϵ0*μ0)*exp(-1.0im*κ0 *x[3]) divA(x) = -im*κ0 *x[1]*sqrt(ϵ0*μ0)*exp(-1.0im*κ0 *x[3]) graddivA(x) = -im*κ0 *sqrt(ϵ0*μ0)*exp(-1.0im*κ0 *x[3])*[1.0,0.0,-im*κ0*x[1]] #### spaces -Xdi(Γ) = BEAST.DirectProductSpace([raviartthomas(Γ),lagrangec0d1(Γ)]) -Xni(Γ) = BEAST.DirectProductSpace([raviartthomas(Γ),lagrangecxd0(Γ)]) -Ydi(Γ) = BEAST.DirectProductSpace([BEAST.buffachristiansen(Γ),duallagrangec0d1(Γ)]) -Yni(Γ) = BEAST.DirectProductSpace([BEAST.buffachristiansen(Γ),duallagrangecxd0(Γ)]) -Xi(Γ) = BEAST.DirectProductSpace([raviartthomas(Γ),lagrangec0d1(Γ),raviartthomas(Γ),lagrangecxd0(Γ)]) -Yi(Γ) = BEAST.DirectProductSpace([BEAST.buffachristiansen(Γ),duallagrangecxd0(Γ),BEAST.buffachristiansen(Γ),duallagrangec0d1(Γ)])# this one maybe omgedraaid - -#### incident field trace -Xin = excitation(A,curlA,divA) -Xind = excitation(A,curlA,divA;rows = [3,4]) -Xinn = excitation(A,curlA,divA; rows = [1,2]) -#### incident field trace non dual -Xin_notdual = excitation(A,curlA,divA;dual=false) -Xind_notdual = excitation(A,curlA,divA;rows = [3,4],dual=false) -Xinn_notdual = excitation(A,curlA,divA; rows = [1,2],dual=false) -#@error "check if correct order of traces" -##### identities -id() = BEAST.matrix_to_bilform(diagm([-NCross(),Identity(),-NCross(),Identity()])) -idN() = BEAST.matrix_to_bilform(diagm([-NCross(),Identity()])) -idnotdual() = BEAST.matrix_to_bilform(diagm([Identity(),Identity(),Identity(),Identity()])) -idNnotdual() = BEAST.matrix_to_bilform(diagm([Identity(),Identity()])) -##### from here do nothing anymore. +Xdb = Γ -> BEAST.DirectProductSpace([raviartthomas(Γ),lagrangec0d1(Γ)]) +Xnb = Γ -> BEAST.DirectProductSpace([raviartthomas(Γ),lagrangecxd0(Γ)]) +Ydb = Γ -> BEAST.DirectProductSpace([BEAST.buffachristiansen(Γ),duallagrangec0d1(Γ)]) +Ynb = Γ -> BEAST.DirectProductSpace([BEAST.buffachristiansen(Γ),duallagrangecxd0(Γ)]) + +Xdt = Γ -> BEAST.DirectProductSpace([n×raviartthomas(Γ),lagrangecxd0(Γ)]) +Xnt = Γ -> BEAST.DirectProductSpace([n×(n×(n×raviartthomas(Γ))),lagrangec0d1(Γ)]) +Ydt = Γ -> BEAST.DirectProductSpace([n×BEAST.buffachristiansen(Γ),duallagrangecxd0(Γ)]) +Ynt = Γ -> BEAST.DirectProductSpace([n×(n×(n×BEAST.buffachristiansen(Γ))),duallagrangec0d1(Γ)]) + +Xinn = BEAST.array_to_linform([excitation_neumann(A,curlA,divA)]) +Xind = BEAST.array_to_linform([excitation_dirichlet(A,curlA,divA)]) +Xin = BEAST.array_to_linform([excitation_neumann(A,curlA,divA),excitation_dirichlet(A,curlA,divA)]) + +idnd = BEAST.matrix_to_bilform(diagm([Identity(),Identity()])) +@hilbertspace t1 t2 +@hilbertspace b1 b2 +id = idnd[t1,b1]+idnd[t2,b2] + N = length(Γ) -Q = Dict(i=>diagm([1,1,HomPars[parent(i,Tree)][2]/HomPars[i][2],HomPars[i][1]/HomPars[parent(i,Tree)][1]]) for i in HOM) -Qp = Dict(i=>diagm([HomPars[parent(i,Tree)][2]/HomPars[i][2],HomPars[i][1]/HomPars[parent(i,Tree)][1],1,1]) for i in HOM) +Q = Dict(i=>diagm([diagm(@SVector [1.0,1.0]),diagm(SVector{2,Float64}([HomPars[parent(i,Tree)][2]/HomPars[i][2],HomPars[i][1]/HomPars[parent(i,Tree)][1]]))]) for i in HOM) +Qp = Dict(i=>diagm([diagm(SVector{2,Float64}([HomPars[parent(i,Tree)][2]/HomPars[i][2],HomPars[i][1]/HomPars[parent(i,Tree)][1]])),diagm(@SVector [1.0,1.0])]) for i in HOM) +Qinv = Dict(i=>diagm([diagm(@SVector [1.0,1.0]),diagm(SVector{2,Float64}(1.0./[HomPars[parent(i,Tree)][2]/HomPars[i][2],HomPars[i][1]/HomPars[parent(i,Tree)][1]]))]) for i in HOM) +Qpinv = Dict(i=>diagm([diagm(SVector{2,Float64}(1.0./[HomPars[parent(i,Tree)][2]/HomPars[i][2],HomPars[i][1]/HomPars[parent(i,Tree)][1]])),diagm(@SVector [1.0,1.0])]) for i in HOM) t = BEAST.hilbertspace(:t, length(Γ)) b = BEAST.hilbertspace(:b, length(Γ)) ##### define space perm = sortperm([HOM...,EFIE...,CFIE...,MFIE...]) -X = [BEAST.DirectProductSpace[Xi(Γ[i]) for i in HOM];BEAST.DirectProductSpace[Xdi(Γ[i]) for i in [EFIE...,CFIE...,MFIE...]]][perm] -Y = [BEAST.DirectProductSpace[Yi(Γ[i]) for i in HOM];BEAST.DirectProductSpace[Yni(Γ[i]) for i in [EFIE...,CFIE...,MFIE...]]][perm] +Xt = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Xnt(Γ[i]),Xdt(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Xdt(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] +Yt = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ydt(Γ[i]),Ynt(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ydt(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] +Xb = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Xdb(Γ[i]),Xnb(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Xnb(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] +Yb = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ynb(Γ[i]),Ydb(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ynb(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] +Xtmfie = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Xnt(Γ[i]),Xdt(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ynt(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] ##### define equation -eqs1 = BEAST.Equation[(Qp[i]*Z(κ[i];tr=-1)*(Q[i]^-1))[t[i],b[i]] + +eqs1 = BEAST.Equation[(Qp[i]*Z(κ[i];tr=-1)*(Qinv[i]))[t[i],b[i]] + -sum(BEAST.BilForm[(Qp[i]*Z(κ[i];tr=-1))[t[i],b[j]] for j in HOM ∩ children(i,Tree)]) + - -sum(BEAST.BilForm[(Qp[i]*Z(κ[i];cols=[3,4],tr=-1))[t[i],b[j]] for j in [EFIE...,CFIE...,MFIE...] ∩ children(i,Tree)]) ==0 for i in HOM] + -sum(BEAST.BilForm[(Qp[i]*Z(κ[i];cols=[2],tr=-1))[t[i],b[j]] for j in [EFIE...,CFIE...,MFIE...] ∩ children(i,Tree)]) ==0 for i in HOM] -# deqs1 = BEAST.discretise.(eqs1, Ref.((t .∈ X))..., Ref.((b .∈ X))...) - -##### define equation eqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ0;cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xin[t[ci]] - for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end -eqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind[t[ci]] + -sum(BEAST.BilForm[Z(κ0;cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xin[t[ci]] + for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end +eqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ0;rows=[2],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end -eqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -idN()[t[ci],b[ci]] ==-Xinn[t[ci]] +eqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ0;rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + + -idnd[t[ci],b[ci]] ==-Xinn[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end -eqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == +eqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[2],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == -α[ci]*Xind[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -eqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Z(κ0;rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -(1-α[ci])*idN()[t[ci],b[ci]] == -(1-α[ci])*Xinn[t[ci]] +eqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Z(κ0;rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + + -(1-α[ci])*idnd()[t[ci],b[ci]] == -(1-α[ci])*Xinn[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -# deqs2hom = BEAST.discretise(eqs2hom, (t.∈X),(b.∈X)) -# deqs2efie = BEAST.discretise(eqs2efie, (t.∈X),(b.∈X)) -# deqs2mfie = BEAST.discretise(eqs2mfie, (t.∈Y),(b.∈X)) -# deqs2cefie = BEAST.discretise(eqs2cefie, (t.∈X),(b.∈X)) -# deqs2cmfie = BEAST.discretise(eqs2cmfie, (t.∈Y),(b.∈X)) - -##### define equation -eqs3hom = begin BEAST.Equation[(Z(κ[i])*(Q[i]^-1))[t[ci],b[i]]+ +eqs3hom = begin BEAST.Equation[(Z(κ[i])*(Qinv[i]))[t[ci],b[i]]+ -sum(BEAST.BilForm[Z(κ[i])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ[i];cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 - for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end -eqs3efie = begin BEAST.Equation[(Z(κ[i];rows=[3,4])*(Q[i]^-1))[t[ci],b[i]]+ - -sum(BEAST.BilForm[Z(κ[i];rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 + -sum(BEAST.BilForm[Z(κ[i];cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 + for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end +eqs3efie = begin BEAST.Equation[(Z(κ[i];rows=[2])*(Qinv[i]))[t[ci],b[i]]+ + -sum(BEAST.BilForm[Z(κ[i];rows=[2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ[i];rows=[2],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end -eqs3mfie = begin BEAST.Equation[(Z(κ[i];rows=[1,2])*(Q[i]^-1))[t[ci],b[i]]+ - -sum(BEAST.BilForm[Z(κ[i];rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -idN()[t[ci],b[ci]] ==0 +eqs3mfie = begin BEAST.Equation[(Z(κ[i];rows=[1])*(Qinv[i]))[t[ci],b[i]]+ + -sum(BEAST.BilForm[Z(κ[i];rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -sum(BEAST.BilForm[Z(κ[i];rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + + -idnd()[t[ci],b[ci]] ==0 for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end -eqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[3,4])*(Q[i]^-1))[t[ci],b[i]]+ - -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 +eqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[2])*(Qinv[i]))[t[ci],b[i]]+ + -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[2],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -eqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Z(κ[i];rows=[1,2])*(Q[i]^-1))[t[ci],b[i]]+ - -(1-α[ci])* sum(BEAST.BilForm[Z(κ[i];rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -(1-α[ci])*sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -(1-α[ci])*idN()[t[ci],b[ci]] == 0 +eqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Z(κ[i];rows=[1])*(Qinv[i]))[t[ci],b[i]]+ + -(1-α[ci])* sum(BEAST.BilForm[Z(κ[i];rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ + -(1-α[ci])*sum(BEAST.BilForm[Z(κ[i];rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + + -(1-α[ci])*idnd()[t[ci],b[ci]] == 0 for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -# deqs3hom = BEAST.discretise.(eqs3hom, Ref.((t.∈X))...,Ref.((b.∈X))...) -# deqs3efie = BEAST.discretise.(eqs3efie, (t.∈X),(b.∈X)) -# deqs3mfie = BEAST.discretise.(eqs3mfie, (t.∈Y),(b.∈X)) -# deqs3cefie = BEAST.discretise.(eqs3cefie, (t.∈X),(b.∈X)) -# deqs3cmfie = BEAST.discretise.(eqs3cmfie, (t.∈Y),(b.∈X)) - ## sum the equations in the two parts in a pmchwt fassion, symeq = -sum(eqs1)+sum(eqs2cefie)+sum(eqs2efie)+sum(eqs2hom)+sum(eqs3cefie)+sum(eqs3efie)+sum(eqs3hom) @@ -291,417 +312,302 @@ symfilled = typeof(symeq) <: BEAST.Equation asymfilled = typeof(asymeq) <: BEAST.Equation -symfilled && (Dsymeq = BEAST.discretise(symeq, (t.∈X)..., (b.∈X)...)) -asymfilled && (Dasymeq = BEAST.discretise(asymeq, (t.∈Y)..., (b.∈X)...)) +symfilled && (Dsymeq = BEAST.discretise(symeq, (t.∈Xt)..., (b.∈Xb)...)) +asymfilled && (Dasymeq = BEAST.discretise(asymeq, (t.∈Xtmfie)..., (b.∈Xb)...)) #assemble system -Zs,Za,bs,ba = 0,0,0,0 -asymfilled && ((Za,ba,xx,yy) = assemble(Dasymeq)) -symfilled && ((Zs,bs,xx,yy) = assemble(Dsymeq)) - -#unprec system - -Zunprec = Za*I+Zs*I -bunprec = ba .+ bs - -solvestrat = :GMRES -solveargs = Dict( - :maxiter => 20000, - :restart => 20000, - :tol => real(sqrt(eps()))) -outnew = solve(Zunprec,bunprec,yy;strat=solvestrat,solveargs...) - - -#generate_plot_field - - - -#preconditioner -@error "hoi" -##### define equation - -peqs1 = BEAST.Equation[(Q[i]*Zp(κ[i];tr=-1)*(Qp[i]^-1))[t[i],b[i]] + - -sum(BEAST.BilForm[(Q[i]*Zp(κ[i];tr=-1))[t[i],b[j]] for j in HOM ∩ children(i,Tree)]) + - -sum(BEAST.BilForm[(Q[i]*Zp(κ[i];cols=[3,4],tr=-1))[t[i],b[j]] for j in [EFIE...,CFIE...,MFIE...] ∩ children(i,Tree)]) ==0 for i in HOM] -pdeqs1 = BEAST.Equation[(Q[i]*Zp(κ[i];tr=-1)*(Qp[i]^-1))[t[i],b[i]] ==0 for i in HOM] -pnuleqs1 = BEAST.Equation[(Q[i]*Zp(κ[i];tr=0)*(Qp[i]^-1))[t[i],b[i]] + --sum(BEAST.BilForm[(Q[i]*Zp(κ[i];tr=0))[t[i],b[j]] for j in HOM ∩ children(i,Tree)]) + --sum(BEAST.BilForm[(Q[i]*Zp(κ[i];cols=[3,4],tr=0))[t[i],b[j]] for j in [EFIE...,CFIE...,MFIE...] ∩ children(i,Tree)]) ==0 for i in HOM] - -# deqs1 = BEAST.discretise.(eqs1, Ref.((t .∈ X))..., Ref.((b .∈ X))...) - -##### define equation -peqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Zp(κ0;cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xin[t[ci]] - for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end - -pdeqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0)[t[ci],b[ci]] for j in [HOM ∩ [ci]]])+ - -sum(BEAST.BilForm[Zp(κ0;cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ [ci]]) ==-Xin[t[ci]] - for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end - - -peqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0;rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Zp(κ0;rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind[t[ci]] - for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end -# peqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Zp(κ0;rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -sum(BEAST.BilForm[Zp(κ0;rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + -# -idN()[t[ci],b[ci]] ==-Xinn[t[ci]] -# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end -peqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Zp(κ0;rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -α[ci]*sum(BEAST.BilForm[Zp(κ0;rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == - -α[ci]*Xind[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -# peqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Zp(κ0;rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -(1-α[ci])*sum(BEAST.BilForm[Zp(κ0;rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + -# -(1-α[ci])*idN()[t[ci],b[ci]] == -(1-α[ci])*Xinn[t[ci]] -# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end +qs(::BEAST.LocalOperator, a, b) = BEAST.SingleNumQStrat(qsZ[1]) +qs(op::BEAST.ComposedOperatorLocal,testspace,trialpsace) = BEAST.SingleNumQStrat(qsZ[2]) +qs(op::BEAST.ComposedOperatorIntegral,testspace,trialspace) = BEAST.DoubleNumSauterQstrat(qsZ[3:end]...) +qs(fn::BEAST.Functional, basis) = BEAST.SingleNumQStrat(8) +asymfilled && ((Za,ba,xx,yy) = assemble(Dasymeq;quadstratfunction = qs)) +symfilled && ((Zs,bs,xx,yy) = assemble(Dsymeq;quadstratfunction = qs)) -# deqs2hom = BEAST.discretise(eqs2hom, (t.∈X),(b.∈X)) -# deqs2efie = BEAST.discretise(eqs2efie, (t.∈X),(b.∈X)) -# deqs2mfie = BEAST.discretise(eqs2mfie, (t.∈Y),(b.∈X)) -# deqs2cefie = BEAST.discretise(eqs2cefie, (t.∈X),(b.∈X)) -# deqs2cmfie = BEAST.discretise(eqs2cmfie, (t.∈Y),(b.∈X)) - - -##### define equation -peqs3hom = begin BEAST.Equation[(Zp(κ[i])*(Qp[i]^-1))[t[ci],b[i]]+ - -sum(BEAST.BilForm[Zp(κ[i])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Zp(κ[i];cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 - for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end -peqs3efie = begin BEAST.Equation[(Zp(κ[i];rows=[3,4])*(Qp[i]^-1))[t[ci],b[i]]+ - -sum(BEAST.BilForm[Zp(κ[i];rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Zp(κ[i];rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 - for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end -# peqs3mfie = begin BEAST.Equation[(Zp(κ[i];rows=[1,2])*(Q[i]^-1))[t[ci],b[i]]+ -# -sum(BEAST.BilForm[Zp(κ[i];rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -sum(BEAST.BilForm[Zp(κ[i];rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + -# -idN()[t[ci],b[ci]] ==0 -# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end -peqs3cefie = begin BEAST.Equation[α[ci]*(Zp(κ[i];rows=[3,4])*(Qp[i]^-1))[t[ci],b[i]]+ - -α[ci]*sum(BEAST.BilForm[Zp(κ[i];rows=[3,4])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -α[ci]*sum(BEAST.BilForm[Zp(κ[i];rows=[3,4],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 - for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -# peqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Zp(κ[i];rows=[1,2])*(Q[i]^-1))[t[ci],b[i]]+ -# -(1-α[ci])* sum(BEAST.BilForm[Zp(κ[i];rows=[1,2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -(1-α[ci])*sum(BEAST.BilForm[Zp(κ[i];rows=[1,2],cols=[3,4])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + -# -(1-α[ci])*idN()[t[ci],b[ci]] == 0 -# for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end - - -#discretise system -psymeq = -sum(peqs1)+sum(peqs2cefie)+sum(peqs2efie)+sum(peqs2hom)+sum(peqs3cefie)+sum(peqs3efie)+sum(peqs3hom) -pdsymeq = -sum(pdeqs1)+sum(pdeqs2hom) -pnulsymeq = sum(pnuleqs1) -Dsymeq = BEAST.discretise(psymeq, (t.∈Y)..., (b.∈Y)...) -# quadstrat -qs(::BEAST.LocalOperator, a, b) = BEAST.SingleNumQStrat(3) -qs(op::BEAST.ComposedOperatorIntegral,testspace,trialspace) = BEAST.DoubleNumSauterQstrat(5,5,5,5,2,2) -qs(op::BEAST.ComposedOperatorLocal,testspace,trialpsace) = BEAST.SingleNumQStrat(3) - -Pyy = assemble(Dsymeq.equation.lhs,BEAST.DirectProductSpace(Y),BEAST.DirectProductSpace(Y);quadstratfunction=qs) - - -# construct gramm matrix -idtest() = BEAST.matrix_to_bilform(diagm([-NCross(),Identity(),-NCross(),Identity()])) - -idNtest() = BEAST.matrix_to_bilform(diagm([-NCross(),Identity()])) - -gramm = sum([idtest()[t[i],b[i]] for i in HOM])+sum([idNtest()[t[i],b[i]] for i in [EFIE...,CFIE...,MFIE...]]) -Gxy = assemble(gramm,BEAST.DirectProductSpace(X),BEAST.DirectProductSpace(Y)) -Ginvyx = BEAST.GMRESSolver(Gxy;abstol=1e-15, maxiter=1_000, restart=1_000, verbose=false) -Ginvxy = BEAST.GMRESSolver(Gxy';abstol=1e-15, maxiter=1_000, restart=1_000, verbose=false) - -Zprec = Za*I+Ginvxy*Pyy*Ginvyx*Zs*I -bprec = ba .+ Ginvxy*Pyy*Ginvyx*bs - -MZprec = inv(Matrix(Gxy)')*Matrix(Pyy)*inv(Matrix(Gxy))*Matrix(Zs) - -solvestrat = :GMRES -solveargs = Dict( - :maxiter => 20000, - :restart => 20000, - :tol => real(sqrt(eps()))) -outnewprec = solve(Zprec,bprec,yy;strat=solvestrat,solveargs...) +Zunprec = Za*I+Zs*I +#unprec system -u = outnewprec[1] -###### exit dict: mesh, number of iterations, inputdata, cond number both, eigenvalue distribution both cases +bunprec = ba .+ bs +uz = solve(Zunprec,bunprec,BEAST.DirectProductSpace(Xb);strat=solvestrat,tol=abstol_Z, maxiter=maxiter_Z, restart=restart_Z) +save_uZ && (out[:uZ] = uz[1]) +save_uZ && (out[:basis] = Xb) +save_itterZ && (out[:itter_Z] = uz[2]) -##### post processing -##### nearfield -using BlockArrays -function nearfield_B(u,X,κ,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume - G = BEAST.greenhh3d(wavenumber=κ) - gradG = BEAST.∇(G) - ∇Gx = gradG×B - Gn = G*(nb*B) - #Gnx = G*(n × B) - ∇G = gradG*B - ∇Gdotn = nb ⋅ (gradG*B) - ∇Gdot = B ⋅ gradG +# ##### nearfield +# using BlockArrays +# function nearfield_B(u,X,κ,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume +# G = BEAST.greenhh3d(wavenumber=κ) +# gradG = BEAST.∇(G) +# ∇Gx = gradG×B +# Gn = G*(nb*B) +# #Gnx = G*(n × B) +# ∇G = gradG*B +# ∇Gdotn = nb ⋅ (gradG*B) +# ∇Gdot = B ⋅ gradG - Gr = G*B - ∇G∇B = gradG*BEAST.div(B) - ∇Gxn = gradG×(nb*B) +# Gr = G*B +# ∇G∇B = gradG*BEAST.div(B) +# ∇Gxn = gradG×(nb*B) - if HOM - @hilbertspace T D R N - Bb = -Q[1,1]*potential(∇G∇B, points, u[T], X.factors[1])-Q[1,1]*κ^2* potential(Gr, points, u[T], X.factors[1]) - Bb .+= Q[2,2]*potential(∇Gxn, points, u[D], X.factors[2]) - Bb .+= -Q[3,3]*potential(∇Gx, points, u[R], X.factors[3]) +# if HOM +# @hilbertspace T D R N +# Bb = -Q[1,1]*potential(∇G∇B, points, u[T], X.factors[1])-Q[1,1]*κ^2* potential(Gr, points, u[T], X.factors[1]) +# Bb .+= Q[2,2]*potential(∇Gxn, points, u[D], X.factors[2]) +# Bb .+= -Q[3,3]*potential(∇Gx, points, u[R], X.factors[3]) - else - @hilbertspace R N - Bb = -potential(∇Gx, points, u[R], X.factors[1]) +# else +# @hilbertspace R N +# Bb = -potential(∇Gx, points, u[R], X.factors[1]) - end - - return sign*Bb -end - -function nearfield_A(u,X,κ,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume - G = BEAST.greenhh3d(wavenumber=κ) - gradG = BEAST.∇(G) - ∇Gx = gradG×B - Gn = G*(nb*B) - #Gnx = G*(n × B) - ∇G = gradG*B - ∇Gdotn = nb ⋅ (gradG*B) - ∇Gdot = B ⋅ gradG +# end + +# return sign*Bb +# end + +# function nearfield_A(u,X,κ,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume +# G = BEAST.greenhh3d(wavenumber=κ) +# gradG = BEAST.∇(G) +# ∇Gx = gradG×B +# Gn = G*(nb*B) +# #Gnx = G*(n × B) +# ∇G = gradG*B +# ∇Gdotn = nb ⋅ (gradG*B) +# ∇Gdot = B ⋅ gradG - Gr = G*B - ∇G∇B = gradG*BEAST.div(B) - ∇Gxn = gradG×(nb*B) +# Gr = G*B +# ∇G∇B = gradG*BEAST.div(B) +# ∇Gxn = gradG×(nb*B) - if HOM - @hilbertspace T D R N - A = -Q[1,1]*potential(∇Gx, points, u[T], X.factors[1]) - A .+= Q[2,2]*potential(Gn, points, u[D], X.factors[2]) - A .+= -Q[3,3]*potential(Gr, points, u[R], X.factors[3]) - A .+= Q[4,4]*potential(∇G, points, u[N], X.factors[4]) - else - @hilbertspace R N - A = -potential(Gr, points, u[R], X.factors[1]) - A .+= potential(∇G, points, u[N], X.factors[2]) - end - - return sign*A -end -function nearfield_phi(u,X,κ,ω,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume - G = BEAST.greenhh3d(wavenumber=κ) - gradG = BEAST.∇(G) - ∇Gx = gradG×B - Gn = G*(nb*B) - #Gnx = G*(n × B) - ∇G = gradG*B - ∇Gdotn = nb ⋅ (gradG*B) - ∇Gdot = B ⋅ gradG +# if HOM +# @hilbertspace T D R N +# A = -Q[1,1]*potential(∇Gx, points, u[T], X.factors[1]) +# A .+= Q[2,2]*potential(Gn, points, u[D], X.factors[2]) +# A .+= -Q[3,3]*potential(Gr, points, u[R], X.factors[3]) +# A .+= Q[4,4]*potential(∇G, points, u[N], X.factors[4]) +# else +# @hilbertspace R N +# A = -potential(Gr, points, u[R], X.factors[1]) +# A .+= potential(∇G, points, u[N], X.factors[2]) +# end + +# return sign*A +# end +# function nearfield_phi(u,X,κ,ω,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume +# G = BEAST.greenhh3d(wavenumber=κ) +# gradG = BEAST.∇(G) +# ∇Gx = gradG×B +# Gn = G*(nb*B) +# #Gnx = G*(n × B) +# ∇G = gradG*B +# ∇Gdotn = nb ⋅ (gradG*B) +# ∇Gdot = B ⋅ gradG - Gr = G*B - ∇G∇B = gradG*BEAST.div(B) - ∇Gxn = gradG×(nb*B) +# Gr = G*B +# ∇G∇B = gradG*BEAST.div(B) +# ∇Gxn = gradG×(nb*B) - if HOM - @hilbertspace T D R N - A = Q[2,2]*potential(∇Gdotn, points, u[D], X.factors[2]) - A .+= -Q[3,3]*potential(∇Gdot, points, u[R], X.factors[3]) - A .+= -κ^2* Q[4,4]*potential(Gr, points, u[N], X.factors[4]) - else - @hilbertspace R N - A = -potential(∇Gdot, points, u[R], X.factors[1]) - A .+= -κ^2* potential(Gr, points, u[N], X.factors[2]) - end - - return sign*A/κ^2*im*ω -end -function nearfield_E(u,X,κ,ω,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume - G = BEAST.greenhh3d(wavenumber=κ) - gradG = BEAST.∇(G) - graddivG = BEAST.graddiv(G) - ∇Gx = gradG×B - Gn = G*(nb*B) - #Gnx = G*(n × B) - ∇G = gradG*B - ∇Gdotn = nb ⋅ (gradG*B) - graddivGdotn = graddivG*(nb*B) - graddivGdot = graddivG*B - ∇Gdot = B ⋅ gradG +# if HOM +# @hilbertspace T D R N +# A = Q[2,2]*potential(∇Gdotn, points, u[D], X.factors[2]) +# A .+= -Q[3,3]*potential(∇Gdot, points, u[R], X.factors[3]) +# A .+= -κ^2* Q[4,4]*potential(Gr, points, u[N], X.factors[4]) +# else +# @hilbertspace R N +# A = -potential(∇Gdot, points, u[R], X.factors[1]) +# A .+= -κ^2* potential(Gr, points, u[N], X.factors[2]) +# end + +# return sign*A/κ^2*im*ω +# end +# function nearfield_E(u,X,κ,ω,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume +# G = BEAST.greenhh3d(wavenumber=κ) +# gradG = BEAST.∇(G) +# graddivG = BEAST.graddiv(G) +# ∇Gx = gradG×B +# Gn = G*(nb*B) +# #Gnx = G*(n × B) +# ∇G = gradG*B +# ∇Gdotn = nb ⋅ (gradG*B) +# graddivGdotn = graddivG*(nb*B) +# graddivGdot = graddivG*B +# ∇Gdot = B ⋅ gradG - Gr = G*B - ∇G∇B = gradG*BEAST.div(B) - ∇Gxn = gradG×(nb*B) +# Gr = G*B +# ∇G∇B = gradG*BEAST.div(B) +# ∇Gxn = gradG×(nb*B) - if HOM - @hilbertspace T D R N - p = Q[2,2]*potential(graddivGdotn, points, u[D], X.factors[2]) - p .+= -Q[3,3]*potential(graddivGdot, points, u[R], X.factors[3]) - p .+= -κ^2* Q[4,4]*potential(∇G, points, u[N], X.factors[4]) - else - @hilbertspace R N - p = -potential(graddivGdot, points, u[R], X.factors[1]) - p .+= -κ^2* potential(∇G, points, u[N], X.factors[2]) - end - if HOM - @hilbertspace T D R N - A = -Q[1,1]*potential(∇Gx, points, u[T], X.factors[1]) - A .+= Q[2,2]*potential(Gn, points, u[D], X.factors[2]) - A .+= -Q[3,3]*potential(Gr, points, u[R], X.factors[3]) - A .+= Q[4,4]*potential(∇G, points, u[N], X.factors[4]) - else - @hilbertspace R N - A = -potential(Gr, points, u[R], X.factors[1]) - A .+= potential(∇G, points, u[N], X.factors[2]) - end - return -sign*p/κ^2*im*ω-sign*im*ω*A -end -Xs = range(-2.0,2.0,length=150) -Zs = range(-1.5,2.5,length=100) -pts = [point(x,0.5,z) for z in Zs, x in Xs] - -A1 = [nearfield_A(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] -A2 = [nearfield_A(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] -A3 = [nearfield_A(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -Atot = sum(A1)+sum(A2)+sum(A3)-A.(pts) - -B1 = [nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] -B2 = [nearfield_B(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] -B3 = [nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -Btot = sum(B1)+sum(B2)+sum(B3)-curlA.(pts) - -H1 = [1/HomPars[parent(i,Tree)][2]*nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] -H2 = [1/HomPars[i][2]*nearfield_B(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] -H3 = [1/HomPars[parent(i,Tree)][2]*nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -Htot = sum(H1)+sum(H2)+sum(H3)-1/μ0*curlA.(pts) - -E1 = [nearfield_E(u[Block(i)],X[i],κ[parent(i,Tree)],ω,pts) for i in HOM] -E2 = [nearfield_E(u[Block(i)],X[i],κ[i],ω,pts;sign=-1,Q=Q[i]^-1) for i in HOM] -E3 = [nearfield_E(u[Block(i)],X[i],κ[parent(i,Tree)],ω,pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -Etot = sum(E1)+sum(E2)+sum(E3)-(-im*ω*A.(pts)-graddivA.(pts)/κ0^2*im*ω) - -##### complement error, different from aps paper, traces from inside are compared, for the reset same formula as in aps paper, for pec all are treated with mfie, as efie yields zero traces in denominator. - - -### to generate plot -using Plots -using LaTeXStrings -using ColorSchemes -p1 = Plots.heatmap(Xs, Zs, (real.(getindex.(Htot,2)))*1000,clim=(-0.01001*1000,0.01*1000),show=true, - -xlabel="z-axis [m]", -ylabel="x-axis [m]", -colorbar_title=" \nHy [mA/m]", -c= :PuBu, -right_margin = 7Plots.mm) -rectangle(w, h, x, y) = Plots.Shape(x .+ [0,w,w,0], y .+ [0,0,h,h]) -# plot!(rectangle(1,1,0,0),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4) -# plot!(rectangle(1,1,-1,0),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4) -# plot!(rectangle(1,1,0,-1),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4,legend=false) -# annotate!(-0.5,0.5,"Ω₃", :black) -# annotate!(0.5,0.5,"Ω₁", :black) -# annotate!(0.5,-0.5,"Ω₂", :black) -display(plot!( - xtickfont=font(11), - ytickfont=font(11), - xguidefontsize=12, -yguidefontsize=13, -colorbar_titlefontsize=13 -)) -#savefig("Hfield.pdf") - - - -##### define equation -ceqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ0;cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xin_notdual[t[ci]] - for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end -# ceqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind_notdual[t[ci]] -# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end -ceqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xinn_notdual[t[ci]] - for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ [MFIE...,EFIE...]]end -# ceqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == -# -α[ci]*Xind_notdual[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -ceqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Z(κ0;rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == -(1-α[ci])*Xinn_notdual[t[ci]] - for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end - -# deqs2hom = BEAST.discretise(eqs2hom, (t.∈X),(b.∈X)) -# deqs2efie = BEAST.discretise(eqs2efie, (t.∈X),(b.∈X)) -# deqs2mfie = BEAST.discretise(eqs2mfie, (t.∈Y),(b.∈X)) -# deqs2cefie = BEAST.discretise(eqs2cefie, (t.∈X),(b.∈X)) -# deqs2cmfie = BEAST.discretise(eqs2cmfie, (t.∈Y),(b.∈X)) - +# if HOM +# @hilbertspace T D R N +# p = Q[2,2]*potential(graddivGdotn, points, u[D], X.factors[2]) +# p .+= -Q[3,3]*potential(graddivGdot, points, u[R], X.factors[3]) +# p .+= -κ^2* Q[4,4]*potential(∇G, points, u[N], X.factors[4]) +# else +# @hilbertspace R N +# p = -potential(graddivGdot, points, u[R], X.factors[1]) +# p .+= -κ^2* potential(∇G, points, u[N], X.factors[2]) +# end +# if HOM +# @hilbertspace T D R N +# A = -Q[1,1]*potential(∇Gx, points, u[T], X.factors[1]) +# A .+= Q[2,2]*potential(Gn, points, u[D], X.factors[2]) +# A .+= -Q[3,3]*potential(Gr, points, u[R], X.factors[3]) +# A .+= Q[4,4]*potential(∇G, points, u[N], X.factors[4]) +# else +# @hilbertspace R N +# A = -potential(Gr, points, u[R], X.factors[1]) +# A .+= potential(∇G, points, u[N], X.factors[2]) +# end +# return -sign*p/κ^2*im*ω-sign*im*ω*A +# end +# Xs = range(-2.0,2.0,length=150) +# Zs = range(-1.5,2.5,length=100) +# pts = [point(x,0.5,z) for z in Zs, x in Xs] + +# A1 = [nearfield_A(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] +# A2 = [nearfield_A(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] +# A3 = [nearfield_A(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] +# Atot = sum(A1)+sum(A2)+sum(A3)-A.(pts) + +# B1 = [nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] +# B2 = [nearfield_B(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] +# B3 = [nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] +# Btot = sum(B1)+sum(B2)+sum(B3)-curlA.(pts) + +# H1 = [1/HomPars[parent(i,Tree)][2]*nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] +# H2 = [1/HomPars[i][2]*nearfield_B(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] +# H3 = [1/HomPars[parent(i,Tree)][2]*nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] +# Htot = sum(H1)+sum(H2)+sum(H3)-1/μ0*curlA.(pts) + +# E1 = [nearfield_E(u[Block(i)],X[i],κ[parent(i,Tree)],ω,pts) for i in HOM] +# E2 = [nearfield_E(u[Block(i)],X[i],κ[i],ω,pts;sign=-1,Q=Q[i]^-1) for i in HOM] +# E3 = [nearfield_E(u[Block(i)],X[i],κ[parent(i,Tree)],ω,pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] +# Etot = sum(E1)+sum(E2)+sum(E3)-(-im*ω*A.(pts)-graddivA.(pts)/κ0^2*im*ω) + +# ##### complement error, different from aps paper, traces from inside are compared, for the reset same formula as in aps paper, for pec all are treated with mfie, as efie yields zero traces in denominator. + + +# ### to generate plot +# using Plots +# using LaTeXStrings +# using ColorSchemes +# p1 = Plots.heatmap(Xs, Zs, (real.(getindex.(Htot,2)))*1000,clim=(-0.01001*1000,0.01*1000),show=true, + +# xlabel="z-axis [m]", +# ylabel="x-axis [m]", +# colorbar_title=" \nHy [mA/m]", +# c= :PuBu, +# right_margin = 7Plots.mm) +# rectangle(w, h, x, y) = Plots.Shape(x .+ [0,w,w,0], y .+ [0,0,h,h]) +# # plot!(rectangle(1,1,0,0),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4) +# # plot!(rectangle(1,1,-1,0),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4) +# # plot!(rectangle(1,1,0,-1),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4,legend=false) +# # annotate!(-0.5,0.5,"Ω₃", :black) +# # annotate!(0.5,0.5,"Ω₁", :black) +# # annotate!(0.5,-0.5,"Ω₂", :black) +# display(plot!( +# xtickfont=font(11), +# ytickfont=font(11), +# xguidefontsize=12, +# yguidefontsize=13, +# colorbar_titlefontsize=13 +# )) +# #savefig("Hfield.pdf") + + + +# ##### define equation +# ceqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -sum(BEAST.BilForm[Z(κ0;cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xin_notdual[t[ci]] +# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end +# # ceqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# # -sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind_notdual[t[ci]] +# # for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end +# ceqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xinn_notdual[t[ci]] +# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ [MFIE...,EFIE...]]end +# # ceqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# # -α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == +# # -α[ci]*Xind_notdual[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end +# ceqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Z(κ0;rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == -(1-α[ci])*Xinn_notdual[t[ci]] +# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -##### define equation -ceqs3hom = begin BEAST.Equation[(Z(κ[i];tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ - -sum(BEAST.BilForm[Z(κ[i];tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ[i];cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 - for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end -# ceqs3efie = begin BEAST.Equation[(Z(κ[i];rows=[3,4],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ -# -sum(BEAST.BilForm[Z(κ[i];rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 -# for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end -ceqs3mfie = begin BEAST.Equation[(Z(κ[i];rows=[1,2],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ - -sum(BEAST.BilForm[Z(κ[i];rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 - for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ [MFIE...,EFIE...]]end -# ceqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[3,4],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ -# -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 +# # deqs2hom = BEAST.discretise(eqs2hom, (t.∈X),(b.∈X)) +# # deqs2efie = BEAST.discretise(eqs2efie, (t.∈X),(b.∈X)) +# # deqs2mfie = BEAST.discretise(eqs2mfie, (t.∈Y),(b.∈X)) +# # deqs2cefie = BEAST.discretise(eqs2cefie, (t.∈X),(b.∈X)) +# # deqs2cmfie = BEAST.discretise(eqs2cmfie, (t.∈Y),(b.∈X)) + + +# ##### define equation +# ceqs3hom = begin BEAST.Equation[(Z(κ[i];tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ +# -sum(BEAST.BilForm[Z(κ[i];tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -sum(BEAST.BilForm[Z(κ[i];cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 +# for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end +# # ceqs3efie = begin BEAST.Equation[(Z(κ[i];rows=[3,4],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ +# # -sum(BEAST.BilForm[Z(κ[i];rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# # -sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 +# # for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end +# ceqs3mfie = begin BEAST.Equation[(Z(κ[i];rows=[1,2],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ +# -sum(BEAST.BilForm[Z(κ[i];rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 +# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ [MFIE...,EFIE...]]end +# # ceqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[3,4],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ +# # -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# # -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 +# # for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end +# ceqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Z(κ[i];rows=[1,2],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ +# -(1-α[ci])* sum(BEAST.BilForm[Z(κ[i];rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ +# -(1-α[ci])*sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 # for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -ceqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Z(κ[i];rows=[1,2],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ - -(1-α[ci])* sum(BEAST.BilForm[Z(κ[i];rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ - -(1-α[ci])*sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 - for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -ceq = sum(ceqs2hom)+sum(ceqs3hom) -cmeq = sum(ceqs2cmfie)+sum(ceqs2mfie)+sum(ceqs3cmfie)+sum(ceqs3mfie) +# ceq = sum(ceqs2hom)+sum(ceqs3hom) +# cmeq = sum(ceqs2cmfie)+sum(ceqs2mfie)+sum(ceqs3cmfie)+sum(ceqs3mfie) -Dseq = BEAST.discretise(ceq+cmeq, (t.∈X)..., (b.∈X)...) +# Dseq = BEAST.discretise(ceq+cmeq, (t.∈X)..., (b.∈X)...) -F,bsa,_,_ = assemble(Dseq) +# F,bsa,_,_ = assemble(Dseq) -using NestedUnitRanges +# using NestedUnitRanges -ax = nestedrange(BEAST.DirectProductSpace(X), 1,numfunctions) -u_error = PseudoBlockVector(F*u-bsa, (ax,)) -#select in u_error en in u +# ax = nestedrange(BEAST.DirectProductSpace(X), 1,numfunctions) +# u_error = PseudoBlockVector(F*u-bsa, (ax,)) +# #select in u_error en in u -function select_trace(u,trace_ind) - usub = 0*deepcopy(u) - N = length(blocks(u)) - println(N) - for i in 1:N - if i ∈ HOM +# function select_trace(u,trace_ind) +# usub = 0*deepcopy(u) +# N = length(blocks(u)) +# println(N) +# for i in 1:N +# if i ∈ HOM - usub2 = deepcopy(usub[Block(i)]) - usub2[Block(trace_ind)] .+= u[Block(i)][Block(trace_ind)] - usub[Block(i)] .+= usub2 - elseif i∈ [EFIE...,MFIE...,CFIE...] && trace_ind ∈ [3,4] - println("pec") - usub2 = deepcopy(usub[Block(i)]) - usub2[Block(trace_ind-2)] .+= u[Block(i)][Block(trace_ind-2)] - usub[Block(i)] .+= usub2 - end - end - return usub -end - -Gsym = assemble(BEAST.diag(BEAST.diag(Identity())),BEAST.DirectProductSpace(X),BEAST.DirectProductSpace(X)) -Ginvsym = inv(Matrix(Gsym)) - -nom = sqrt.([Array(select_trace(u_error,i))'*Ginvsym*Array(select_trace(u_error,i)) for i in 1:4]) -denom = sqrt.([Array(select_trace(u,i))'*Matrix(Gsym)*Array(select_trace(u,i)) for i in 1:4]) -error = 1/4*sum(nom./denom)* \ No newline at end of file +# usub2 = deepcopy(usub[Block(i)]) +# usub2[Block(trace_ind)] .+= u[Block(i)][Block(trace_ind)] +# usub[Block(i)] .+= usub2 +# elseif i∈ [EFIE...,MFIE...,CFIE...] && trace_ind ∈ [3,4] +# println("pec") +# usub2 = deepcopy(usub[Block(i)]) +# usub2[Block(trace_ind-2)] .+= u[Block(i)][Block(trace_ind-2)] +# usub[Block(i)] .+= usub2 +# end +# end +# return usub +# end + +# Gsym = assemble(BEAST.diag(BEAST.diag(Identity())),BEAST.DirectProductSpace(X),BEAST.DirectProductSpace(X)) +# Ginvsym = inv(Matrix(Gsym)) + +# nom = sqrt.([Array(select_trace(u_error,i))'*Ginvsym*Array(select_trace(u_error,i)) for i in 1:4]) +# denom = sqrt.([Array(select_trace(u,i))'*Matrix(Gsym)*Array(select_trace(u,i)) for i in 1:4]) +# error = 1/4*sum(nom./denom)* \ No newline at end of file diff --git a/src/BEAST.jl b/src/BEAST.jl index b3a2d8fe..3b87d68c 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -142,7 +142,6 @@ include("utils/combinatorics.jl") include("utils/linearspace.jl") include("utils/zeromap.jl") include("utils/rank1map.jl") -include("utils/geometrie.jl") include("bases/basis.jl") include("bases/lincomb.jl") @@ -265,11 +264,11 @@ include("utils/plotlyglue.jl") include("composedoperator/tracesimplex.jl") include("composedoperator/composedoperator.jl") -include("composedoperator/postprocessing.jl") +# include("composedoperator/postprocessing.jl") -include("multi-trace/interactions.jl") -include("multi-trace/postprocessing.jl") -include("multi-trace/VectorPotential.jl") +# include("multi-trace/interactions.jl") +# include("multi-trace/postprocessing.jl") +# include("multi-trace/VectorPotential.jl") # include("multi-trace/multi-trace-old/interactions.jl") diff --git a/src/bases/basis.jl b/src/bases/basis.jl index d47bb00c..ba5ede60 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -2,8 +2,8 @@ abstract type RefSpace{T,D} end abstract type AbstractSpace end abstract type Space{T} <: AbstractSpace end -struct EmptySpace{Nothing} <: Space{Nothing} end -numfunctions(::EmptySpace) = 0 +# struct EmptySpace{Nothing} <: Space{Nothing} end +# numfunctions(::EmptySpace) = 0 Base.length(s::AbstractSpace) = numfunctions(s) diff --git a/src/bases/bcspace.jl b/src/bases/bcspace.jl index bd1b9dfe..fdd07481 100644 --- a/src/bases/bcspace.jl +++ b/src/bases/bcspace.jl @@ -187,6 +187,7 @@ function buffachristiansen(Γ, γ=mesh(coordtype(Γ),1,3); ibscaled=false, sort= return RTBasis(fine, bcs, pos) end + """ buildhalfbc(fine, supp::Array{SVector{3,Int},1}, v, p) """ diff --git a/src/bases/local/laglocal.jl b/src/bases/local/laglocal.jl index 33cfc002..9a019379 100644 --- a/src/bases/local/laglocal.jl +++ b/src/bases/local/laglocal.jl @@ -30,10 +30,9 @@ function (f::LagrangeRefSpace{T,1,3})(t) where T # (value=u,), # (value=v,), # (value=w,)) - tu = tangents(t,1) - tv = tangents(t,2) - j = jacobian(t)*sign(dot(normal(t),tu×tv)) - p = chart(t) + + j = jacobian(t) + p = t.patch σ = sign(dot(normal(t), cross(p[1]-p[3],p[2]-p[3]))) SVector( (value=u, curl=σ*(p[3]-p[2])/j), @@ -59,19 +58,6 @@ Compute the values of the shape functions together with their curl. # (value=w, curl=σ*(p[2]-p[1])/j) # ) # end -function (f::LagrangeRefSpace{T,1,3})(t, ::Type{Val{:withcurl}}) where T - # Evaluete linear Lagrange elements on a triange, together with their curl - tu = tangents(t,1) - tv = tangents(t,2) - j = jacobian(t)*sign(dot(normal(t),tu×tv)) - u,v,w, = barycentric(t) - p = t.patch - SVector( - (value=u, curl=(p[3]-p[2])/j), - (value=v, curl=(p[1]-p[3])/j), - (value=w, curl=(p[2]-p[1])/j) - ) -end # Evaluate constant Lagrange elements on a triangle, with their curls @@ -94,8 +80,8 @@ function gradient(ref::LagrangeRefSpace{T,1,4}, sh, tet) where {T} # opp_face = simplex(other_verts...) opp_face = faces(tet)[sh.refid] ctr_opp_face = center(opp_face) - # n = normal(ctr_opp_face) - n = normalize(tangents(ctr_opp_face,1)×tangents(ctr_opp_face,2)) + n = normal(ctr_opp_face) + # n = normalize(tangents(ctr_opp_face,1)×tangents(ctr_opp_face,2)) h = -dot(this_vert - cartesian(ctr_opp_face), n) @assert h > 0 gradval = -(1/h)*n @@ -186,10 +172,7 @@ end ## Quadratic Lagrange element on a triangle function (f::LagrangeRefSpace{T,2,3})(t) where T - u,v,w, = barycentric(t) - tu = tangents(t,1) - tv = tangents(t,2) - j = jacobian(t)*sign(dot(normal(t),tu×tv)) + j = jacobian(t) p = t.patch #curl=(p[3]-p[2])/j), @@ -207,22 +190,22 @@ function (f::LagrangeRefSpace{T,2,3})(t) where T ) end -function (f::LagrangeRefSpace{T,2,3})(t, ::Type{Val{:withcurl}}) where T - # Evaluete quadratic Lagrange elements on a triange, together with their curl - tu = tangents(t,1) - tv = tangents(t,2) - j = jacobian(t)*sign(dot(normal(t),tu×tv)) - u,v,w, = barycentric(t) - p = t.patch - SVector( - (value=u*(2*u-1), curl=(p[3]-p[2])*(4u-1)/j), - (value=v*(2*v-1), curl=(p[1]-p[3])*(4v-1)/j), - (value=w*(2*w-1), curl=(p[2]-p[1])*(4w-1)/j), - (value=4*v*w, curl=4*(w*(p[1]-p[3])+v*(p[2]-p[1]))/j), - (value=4*w*u, curl=4*(w*(p[3]-p[2])+u*(p[2]-p[1]))/j), - (value=4*u*v, curl=4*(u*(p[1]-p[3])+v*(p[3]-p[2]))/j), - ) -end +# function (f::LagrangeRefSpace{T,2,3})(t, ::Type{Val{:withcurl}}) where T +# # Evaluete quadratic Lagrange elements on a triange, together with their curl +# tu = tangents(t,1) +# tv = tangents(t,2) +# j = jacobian(t)*sign(dot(normal(t),tu×tv)) +# u,v,w, = barycentric(t) +# p = t.patch +# SVector( +# (value=u*(2*u-1), curl=(p[3]-p[2])*(4u-1)/j), +# (value=v*(2*v-1), curl=(p[1]-p[3])*(4v-1)/j), +# (value=w*(2*w-1), curl=(p[2]-p[1])*(4w-1)/j), +# (value=4*v*w, curl=4*(w*(p[1]-p[3])+v*(p[2]-p[1]))/j), +# (value=4*w*u, curl=4*(w*(p[3]-p[2])+u*(p[2]-p[1]))/j), +# (value=4*u*v, curl=4*(u*(p[1]-p[3])+v*(p[3]-p[2]))/j), +# ) +# end function curl(ref::LagrangeRefSpace{T,2,3} where {T}, sh, el) #curl of lagc0d2 as combination of bdm functions diff --git a/src/bases/local/ncrossbdmlocal.jl b/src/bases/local/ncrossbdmlocal.jl index 275b433f..ebeb3bfe 100644 --- a/src/bases/local/ncrossbdmlocal.jl +++ b/src/bases/local/ncrossbdmlocal.jl @@ -3,10 +3,9 @@ struct NCrossBDMRefSpace{T} <: RefSpace{T,6} end function (f::NCrossBDMRefSpace{T})(p) where T u,v = parametric(p) - # n = normal(p) + n = normal(p) tu = tangents(p,1) tv = tangents(p,2) - n = normalize(tu×tv) j = jacobian(p) d = 1/j diff --git a/src/bases/local/ndlocal.jl b/src/bases/local/ndlocal.jl index 15360973..b39a5dfe 100644 --- a/src/bases/local/ndlocal.jl +++ b/src/bases/local/ndlocal.jl @@ -11,12 +11,11 @@ mutable struct NDRefSpace{T} <: RefSpace{T,3} end function (ϕ::NDRefSpace)(nbd) u, v = parametric(nbd) - #n = normal(nbd) + n = normal(nbd) j = jacobian(nbd) tu = tangents(nbd,1) tv = tangents(nbd,2) - n = normal(nbd) d = 2/j return SVector(( diff --git a/src/bases/local/rtlocal.jl b/src/bases/local/rtlocal.jl index bad1458f..53b8433b 100644 --- a/src/bases/local/rtlocal.jl +++ b/src/bases/local/rtlocal.jl @@ -64,8 +64,8 @@ function restrict(ϕ::RTRefSpace{T}, dom1, dom2) where T # find the outer binormal there t = b - a l = norm(t) - # n = dom2.normals[1] - n = normalize(tangents(dom2,1)×tangents(dom2,2)) + n = normal(dom2) + #n = normalize(tangents(dom2,1)×tangents(dom2,2)) m = cross(t, n) / l u = carttobary(dom1, c) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index c842f78f..bcfe7baf 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -597,7 +597,7 @@ end # out = quote _krondot(getvalue(f),$exp) end # return out # end - +kernelvals(op::ComposedOperatorLocal,x) = nothing kernelvals(op::ComposedOperatorIntegral, y,x) = nothing quaddata(op::ComposedOperatorIntegral,rs,els,qs::SingleNumQStrat) = quadpoints(rs,els,(qs.quad_rule,)) quadrule(op::ComposedOperatorIntegral,refspace,p,y,q,el,qdata,qs::SingleNumQStrat) = qdata[1,q] @@ -634,7 +634,7 @@ function assemble!(op::Potential, test_functions::Space, trial_functions::Space, kwargs...) # checks if surface given in basis is the same as surface given in potential # dsurf = surface(op) - # surf = geometry(trial_functions) + surf = geometry(trial_functions) # @assert same_geometry(dsurf,surf) # nsurf = mesh(dsurf) trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) @@ -722,8 +722,8 @@ function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Sp surface = geometry(test_functions) sign = direction(op) - direction = [sign*normal(c)/3 for c in chart.(Ref(surface),1:numcells(surface))] - surf = TraceMesh(surface,direction) + dir = [sign*normal(c)/3 for c in chart.(Ref(surface),1:numcells(surface))] + surf = TraceMesh(surface,dir) test_functions = redefine_geometrie(test_functions,surf) assemble!(op.operator, test_functions, trial_functions, store, threading; diff --git a/src/integralop.jl b/src/integralop.jl index 8524bd3f..14eef015 100644 --- a/src/integralop.jl +++ b/src/integralop.jl @@ -112,7 +112,7 @@ function assemblechunk_body!(biop, trial_shapes, trial_elements, trial_assembly_data, qd, zlocal, store; quadstrat) myid = Threads.threadid() - myid == 1 && print(string(typeof(biop))*" dots out of 10: ") + myid == 1 && print(" dots out of 10: ") todo, done, pctg = length(test_elements), 0, 0 for (p,tcell) in enumerate(test_elements) for (q,bcell) in enumerate(trial_elements) @@ -186,7 +186,7 @@ function assemblechunk_body_test_refines_trial!(biop, trial_shapes = refspace(trial_functions) myid = Threads.threadid() - myid == 1 && print(string(typeof(biop))*" dots out of 10: ") + myid == 1 && print(" dots out of 10: ") todo, done, pctg = length(test_charts), 0, 0 for (p,(tcell,tchart)) in enumerate(zip(test_cells, test_charts)) for (q,(bcell,bchart)) in enumerate(zip(trial_cells, trial_charts)) @@ -227,7 +227,7 @@ function assemblechunk_body_trial_refines_test!(biop, trial_shapes = refspace(trial_functions) myid = Threads.threadid() - myid == 1 && print(string(typeof(biop))*" dots out of 10: ") + myid == 1 && print(" dots out of 10: ") todo, done, pctg = length(test_charts), 0, 0 for (p,(tcell,tchart)) in enumerate(zip(test_cells, test_charts)) for (q,(bcell,bchart)) in enumerate(zip(trial_cells, trial_charts)) diff --git a/src/localop.jl b/src/localop.jl index 4293c4a8..8d1cd916 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -81,12 +81,11 @@ function assemble!(biop::LocalOperator, tfs::Space, bfs::Space, store, threading::Type{Threading{:multi}}; kwargs...) - if geometry(tfs) == geometry(bfs) - @warn "Function cannot be used for infinitely thin surfaces!!!" + if geometry(tfs) == geometry(bfs) && !(typeof(biop) <: ComposedOperatorLocal) return assemble_local_matched!(biop, tfs, bfs, store; kwargs...) end - if CompScienceMeshes.refines(geometry(tfs), geometry(bfs)) + if CompScienceMeshes.refines(geometry(tfs), geometry(bfs)) && !(typeof(biop) <: ComposedOperatorLocal) return assemble_local_refines!(biop, tfs, bfs, store; kwargs...) end @@ -97,12 +96,11 @@ function assemble!(biop::LocalOperator, tfs::Space, bfs::Space, store, threading::Type{Threading{:single}}; kwargs...) - if geometry(tfs) == geometry(bfs) - @warn "Function cannot be used for infinitely thin surfaces!!!" + if geometry(tfs) == geometry(bfs) && !(typeof(biop) <: ComposedOperatorLocal) return assemble_local_matched!(biop, tfs, bfs, store; kwargs...) end - if CompScienceMeshes.refines(geometry(tfs), geometry(bfs)) + if CompScienceMeshes.refines(geometry(tfs), geometry(bfs)) && !(typeof(biop) <: ComposedOperatorLocal) return assemble_local_refines!(biop, tfs, bfs, store; kwargs...) end @@ -125,10 +123,10 @@ function assemble_local_matched!(biop::LocalOperator, tfs::Space, bfs::Space, st qd = quaddata(biop, trefs, brefs, tels, bels, quadstrat) verbose = length(tels) > 10_000 - verbose && print(string(typeof(biop))*" dots out of 20: ") + verbose && print(" dots out of 20: ") todo, done, pctg = length(tels), 0, 0 - # locmat = zeros(scalartype(biop, trefs, brefs), numfunctions(trefs), numfunctions(brefs)) + locmat = zeros(scalartype(biop, trefs, brefs), numfunctions(trefs), numfunctions(brefs)) for (p,tcell) in enumerate(tels) P = ta2g[p] @@ -140,12 +138,11 @@ function assemble_local_matched!(biop::LocalOperator, tfs::Space, bfs::Space, st qr = quadrule(biop, trefs, brefs, tcell, bcell,qd, quadstrat) - # fill!(locmat, 0) - locmat = cellinteractions(biop, trefs, brefs, tcell, bcell, qr) + fill!(locmat, 0) + cellinteractions_matched!(locmat,biop, trefs, brefs, tcell, bcell, qr) for i in 1 : size(locmat, 1), j in 1 : size(locmat, 2) for (m,a) in tad[p,i], (n,b) in bad[q,j] - store(a * locmat[i,j] * b, m, n) end end @@ -177,7 +174,7 @@ function assemble_local_refines!(biop::LocalOperator, tfs::Space, bfs::Space, st qd = quaddata(biop, trefs, brefs, tels, bels, quadstrat) - print(string(typeof(biop))*" dots out of 10: ") + print(" dots out of 10: ") todo, done, pctg = length(tels), 0, 0 for (p,tcell) in enumerate(tels) @@ -246,7 +243,7 @@ function assemble_local_matched!(biop::LocalOperator, tfs::subdBasis, bfs::subdB store(a * locmat[i,j] * b, m, n) end end end end function same_cell(a,b) -sort(verticeslist(a)) ≈ sort(verticeslist(b)) + sort(verticeslist(a)) ≈ sort(verticeslist(b)) end function elementstree(elements) @@ -302,7 +299,7 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} # store the bcells in an octree tree = elementstree(bels) - print(string(typeof(biop))*" dots out of 10: ") + print(" dots out of 10: ") todo, done, pctg = length(tels), 0, 0 for (p,tcell) in enumerate(tels) @@ -391,7 +388,7 @@ function cellinteractions_matched!(zlocal, biop, trefs, brefs, cellt,cellb, qr) j = w * jacobian(tp) kernel = kernelvals(biop, tp) - zlocal += j * integrand(biop, kernel, tp, bp, tvals, bvals) + zlocal .+= j * integrand(biop, kernel, tp, bp, tvals, bvals) end return zlocal end @@ -446,10 +443,8 @@ function cellinteractions(biop, trefs::U, brefs::V, cellt,cellb,qr) where {U<:Re return zlocal end -function getvalue(list::Matrix{T}) where {T} - display(list) - return SVector{length(list),T}([i for i in list]) -end +getvalue(list::Matrix{T}) where {T} = SVector{length(list),T}([i for i in list]) + # function cellinteractions(biop, trefs::U, brefs::V, cell,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} # num_tshs = length(qr[1][3]) diff --git a/src/quadrature/quadstrats.jl b/src/quadrature/quadstrats.jl index fc809414..3c801ce5 100644 --- a/src/quadrature/quadstrats.jl +++ b/src/quadrature/quadstrats.jl @@ -39,10 +39,7 @@ struct OuterNumInnerAnalyticQStrat{R} end -function defaultquadstrat(op, tfs, bfs) - @warn "made use of general defaultquadstrat routine which cals defaultquadstrat on refspaces "*string(typeof(op)) - defaultquadstrat(op, refspace(tfs), refspace(bfs)) -end +defaultquadstrat(op, tfs, bfs) = defaultquadstrat(op, refspace(tfs), refspace(bfs)) macro defaultquadstrat(dop, body) @assert dop.head == :tuple @assert length(dop.args) == 3 diff --git a/src/quadrature/sauterschwabints.jl b/src/quadrature/sauterschwabints.jl index 4a165aa0..79d2b892 100644 --- a/src/quadrature/sauterschwabints.jl +++ b/src/quadrature/sauterschwabints.jl @@ -205,32 +205,32 @@ function momintegrals_trial_refines_test!(out, op, end end -function momintegrals_overlap!(biop, - test_shapes, trial_shapes, - tcell, bcell, - out, quadstrat) - tcells, bcells = CompScienceMeshes.complementary_mesh(tcell,bcell) +# function momintegrals_overlap!(biop, +# test_shapes, trial_shapes, +# tcell, bcell, +# out, quadstrat) +# tcells, bcells = CompScienceMeshes.complementary_mesh(tcell,bcell) - qd = quaddata(biop,test_shapes,trial_shapes,tcells,bcells,quadstrat) - - Nt = numfunctions(test_shapes) - Nb = numfunctions(trial_shapes) - - - for (p,tsubcell) in enumerate(tcells) - for (q,bsubcell) in enumerate(bcells) - zlocal = zero(out) - qrule = quadrule(biop, test_shapes, trial_shapes, p, tsubcell, q, bsubcell, qd, quadstrat) - momintegrals!(biop, test_shapes, trial_shapes, tsubcell, bsubcell, zlocal, qrule) - Qt = restrict(test_shapes,tcell,tsubcell) - Qb = restrict(trial_shapes,bcell,bsubcell) - for j in 1:Nb - for i in 1:Nt - for m in 1:Nb - for n in 1:Nt - out[i,j] += Qt[i,n] * zlocal[n,m] * Qb[j,m] - end end end end - end - end - -end \ No newline at end of file +# qd = quaddata(biop,test_shapes,trial_shapes,tcells,bcells,quadstrat) + +# Nt = numfunctions(test_shapes) +# Nb = numfunctions(trial_shapes) + + +# for (p,tsubcell) in enumerate(tcells) +# for (q,bsubcell) in enumerate(bcells) +# zlocal = zero(out) +# qrule = quadrule(biop, test_shapes, trial_shapes, p, tsubcell, q, bsubcell, qd, quadstrat) +# momintegrals!(biop, test_shapes, trial_shapes, tsubcell, bsubcell, zlocal, qrule) +# Qt = restrict(test_shapes,tcell,tsubcell) +# Qb = restrict(trial_shapes,bcell,bsubcell) +# for j in 1:Nb +# for i in 1:Nt +# for m in 1:Nb +# for n in 1:Nt +# out[i,j] += Qt[i,n] * zlocal[n,m] * Qb[j,m] +# end end end end +# end +# end + +# end \ No newline at end of file diff --git a/src/solvers/lusolver.jl b/src/solvers/lusolver.jl index 50069dba..cca69f6b 100644 --- a/src/solvers/lusolver.jl +++ b/src/solvers/lusolver.jl @@ -6,7 +6,7 @@ lusolve(eq) = solve(eq) Solves a variational equation by simply creating the full system matrix and calling a traditional lu decomposition. """ -function solve(eq;Zz=false) +function solve(eq) time_domain = isa(first(eq.trial_space_dict).second, BEAST.SpaceTimeBasis) time_domain |= isa(first(eq.trial_space_dict).second, BEAST.StagedTimeStep) @@ -35,12 +35,11 @@ function solve(eq;Zz=false) println("done.") ax = nestedrange(Y, 1, numfunctions) - Zz && (return PseudoBlockVector(u, (ax,)), Z) return PseudoBlockVector(u, (ax,)) end -function solve(b,Z,Y;Zz=true) +function solve(b,Z,Y) print("Converting system to Matrix...") @@ -52,6 +51,5 @@ function solve(b,Z,Y;Zz=true) println("done.") ax = nestedrange(Y, 1, numfunctions) - Zz && (return PseudoBlockVector(u, (ax,)), Z) return PseudoBlockVector(u, (ax,)) end diff --git a/src/solvers/solver.jl b/src/solvers/solver.jl index 6166b165..e2f1f7b3 100644 --- a/src/solvers/solver.jl +++ b/src/solvers/solver.jl @@ -103,6 +103,7 @@ function discretise(eq, space_mappings::Pair...) DiscreteEquation(eq, trial_space_dict, test_space_dict) end + """ discr(eq, pairs...) @@ -248,25 +249,25 @@ end # terms # end -function LinearAlgebra.dot(test::DirectProductSpace,op::Matrix{AbstractOperator},trial::DirectProductSpace) - test_length = length(test.factors) - trial_length = length(trial.factors) - @assert size(op)==(test_length,trial_length) - terms = Vector{BilTerm}() - test_space_dict = Dict() - trial_space_dict = Dict() - for (i,space) in enumerate(test.factors) - test_space_dict[i]=space - end - for (i,space) in enumerate(trial.factors) - trial_space_dict[i]=space - end - - for i in 1:test_length - for j in 1:trial_length - push!(terms,BilTerm(i,j,[],[],1.0,op[i,j])) - end - end - BilForm([],[],terms) -end +# function LinearAlgebra.dot(test::DirectProductSpace,op::Matrix{AbstractOperator},trial::DirectProductSpace) +# test_length = length(test.factors) +# trial_length = length(trial.factors) +# @assert size(op)==(test_length,trial_length) +# terms = Vector{BilTerm}() +# test_space_dict = Dict() +# trial_space_dict = Dict() +# for (i,space) in enumerate(test.factors) +# test_space_dict[i]=space +# end +# for (i,space) in enumerate(trial.factors) +# trial_space_dict[i]=space +# end + +# for i in 1:test_length +# for j in 1:trial_length +# push!(terms,BilTerm(i,j,[],[],1.0,op[i,j])) +# end +# end +# BilForm([],[],terms) +# end diff --git a/src/utils/geometrie.jl b/src/utils/geometrie.jl deleted file mode 100644 index 47c4e891..00000000 --- a/src/utils/geometrie.jl +++ /dev/null @@ -1,30 +0,0 @@ -# import Base.- -# struct MinusMeshPointNM{T} -# meshpoint::T -# end -# # struct MinusSimplex{T} -# # simplex::T -# # end - -# normal(a::MinusMeshPointNM) = -normal(a.meshpoint) -# # normal(a::MinusSimplex) = -normal(a.MinusSimplex) - -# function map(b::Union{CompScienceMeshes.MeshPointNM,MinusMeshPointNM},sign::Int) -# sign==-1 && (return -b) -# sign == 1 && (return b) -# @error "sign was not 1 or -1" -# end - -# -(b::CompScienceMeshes.MeshPointNM) = MinusMeshPointNM(b) -# -(b::MinusMeshPointNM) = b.meshpoint -# # -(b::Simplex) = MinusSimple(b) -# # -(b::MinusSimplex) = b.simplex - -# Base.length(m::MinusMeshPointNM) = length(m.meshpoint) -# Base.getindex(p::MinusMeshPointNM, i::Int) = p.meshpoint[i] -# CompScienceMeshes.cartesian(m::MinusMeshPointNM) = cartesian(m.meshpoint) -# CompScienceMeshes.parametric(m::MinusMeshPointNM) = parametric(m.meshpoint) -# CompScienceMeshes.chart(m::MinusMeshPointNM) = chart(m.meshpoint) -# CompScienceMeshes.barycentric(mp::MinusMeshPointNM) = barycentric(mp.meshpoint) -# CompScienceMeshes.jacobian(mp::MinusMeshPointNM) = jacobian(mp.meshpoint) -# CompScienceMeshes.tangents(mp::MinusMeshPointNM,i) = tangents(mp.meshpoint,i) diff --git a/test/runtests.jl b/test/runtests.jl index 28fd13a3..f393b52a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -74,8 +74,8 @@ include("test_td_tensoroperator.jl") include("test_variational.jl") include("test_composed_operator.jl") -include("test_momintegrals_overlap.jl") -inlcude("test_multi-trace_VP.jl") +#include("test_momintegrals_overlap.jl") +#inlcude("test_multi-trace_VP.jl") try Pkg.installed("BogaertInts10") diff --git a/test/test_basis.jl b/test/test_basis.jl index 7f2f4d7b..644f9a2c 100644 --- a/test/test_basis.jl +++ b/test/test_basis.jl @@ -22,7 +22,7 @@ for T in [Float32, Float64] @test size(N) == (numfunctions(X), numfunctions(X)) @test size(I) == (numfunctions(X), numfunctions(X)) - + println(X) @test rank(I) == numfunctions(X) @time e = assemble(PlaneWaveNeumann(κ, point(0.0, 1.0)), X) @@ -235,7 +235,7 @@ for i in eachindex(crl.fns) nxgradi = sort(nxgrad.fns[i], by=sh->(sh.cellid, sh.refid)) for j in eachindex(crl.fns[i]) # @test crl.fns[i][j] == nxgrad.fns[i][j] - @test crli[j].coeff == -nxgradi[j].coeff + @test crli[j].coeff == nxgradi[j].coeff end end diff --git a/test/test_composed_operator.jl b/test/test_composed_operator.jl index 78a42b92..4cb53257 100644 --- a/test/test_composed_operator.jl +++ b/test/test_composed_operator.jl @@ -17,14 +17,11 @@ TM = KM +1/2*CM G = BEAST.greenhh3d(wavenumber=k) -KC = BEAST.build_potential(∇(G)×BasisFunction(),m) -KCT1 = BEAST.γ(KC,m,1) +KC = BEAST.build_potential(∇(G)×BasisFunction()) +KCT1 = BEAST.γₜ(KC,-1) TCM1 = assemble(KCT1,r,r) -KCT2 = BEAST.γ(KC,-m,-1) -TCM2 = assemble(KCT2,r,r) -@test TM ≈ TCM1 atol=eps() -@test TM ≈ TCM2 atol=eps() +@test TM ≈ TCM1 atol=sqrt(eps()) #limit from outside TM = KM -1/2*CM @@ -32,13 +29,11 @@ TM = KM -1/2*CM G = BEAST.greenhh3d(wavenumber=k) KC = BEAST.build_potential(∇(G)×BasisFunction(),m) -KCT1 = BEAST.γ(KC,m,-1) +KCT1 = BEAST.γₜ(KC,1) TCM1 = assemble(KCT1,r,r) -KCT2 = BEAST.γ(KC,-m,1) -TCM2 = assemble(KCT2,r,r) -@test TM ≈ TCM1 atol=eps() -@test TM ≈ TCM2 atol=eps() + +@test TM ≈ TCM1 atol=sqrt(eps()) ## same for non matching meshes @@ -60,13 +55,11 @@ TM = KM +1/2*CM G = BEAST.greenhh3d(wavenumber=k) KC = BEAST.build_potential(∇(G)×BasisFunction(),m2) -KCT1 = BEAST.γ(KC,m1,1) +KCT1 = BEAST.γₜ(KC,-1) TCM1 = assemble(KCT1,r1,r2) -KCT2 = BEAST.γ(KC,-m1,-1) -TCM2 = assemble(KCT2,r1,r2) -@test TM ≈ TCM1 atol=eps() -@test TM ≈ TCM2 atol=eps() + +@test TM ≈ TCM1 atol=sqrt(eps()) #limit from outside TM = KM -1/2*CM @@ -74,11 +67,9 @@ TM = KM -1/2*CM G = BEAST.greenhh3d(wavenumber=k) KC = BEAST.build_potential(∇(G)×BasisFunction(),m2) -KCT1 = BEAST.γ(KC,m1,-1) +KCT1 = BEAST.γₜ(KC,1) TCM1 = assemble(KCT1,r1,r2) -KCT2 = BEAST.γ(KC,-m1,1) -TCM2 = assemble(KCT2,r1,r2) -@test TM ≈ TCM1 atol=eps() -@test TM ≈ TCM2 atol=eps() + +@test TM ≈ TCM1 atol=sqrt(eps()) diff --git a/test/test_dipole.jl b/test/test_dipole.jl index f11e277f..e0243529 100644 --- a/test/test_dipole.jl +++ b/test/test_dipole.jl @@ -57,7 +57,7 @@ for U in [Float32,Float64] nf_H_EFIE = potential(BEAST.MWDoubleLayerField3D(𝓚), pts, j_EFIE, X) ff_E_EFIE = potential(MWFarField3D(𝓣), pts, j_EFIE, X) ff_H_EFIE = potential(BEAST.MWDoubleLayerFarField3D(𝓚), pts, j_EFIE, X) - ff_H_EFIE_rotated = potential(n × BEAST.MWDoubleLayerFarField3D(𝓚), pts, -j_EFIE, n × X) + ff_H_EFIE_rotated = potential(n × BEAST.MWDoubleLayerFarField3D(𝓚), pts, j_EFIE, n × X) ff_H_EFIE_doublerotated = potential(n × BEAST.MWDoubleLayerRotatedFarField3D(n × 𝓚), pts, -j_EFIE, X) diff --git a/test/test_embedding.jl b/test/test_embedding.jl index 5d0c2289..08866e4f 100644 --- a/test/test_embedding.jl +++ b/test/test_embedding.jl @@ -37,5 +37,5 @@ nd = BEAST.nedelec(G,E) nd1 = BEAST.nedelec(G1,E1) @test numfunctions(nd1) == numcells(E1) Z_direct = assemble(BEAST.Identity(), nd1, nd) -Z_expand = assemble(BEAST.Identity(), nd1, nd1) * A1 +Z_expand = -assemble(BEAST.Identity(), nd1, nd1) * A1 #minus sign because nd and nd1 are defined on opposite oriented meshes @test norm(Z_direct - Z_expand, Inf) ≤ √(eps(1.0)) diff --git a/test/test_momintegrals_overlap.jl b/test/test_momintegrals_overlap.jl deleted file mode 100644 index 4758133a..00000000 --- a/test/test_momintegrals_overlap.jl +++ /dev/null @@ -1,25 +0,0 @@ -using BEAST -using CompScienceMeshes -using StaticArrays -using Test - -tcell = simplex((@SVector [1.0,0.0,0.0]), (@SVector [0.0,1.0,0.0]),(@SVector [0.0,0.0,0.0])) -bcell = simplex((@SVector [0.0,0.8,0.0]),(@SVector [1.0,1.0,0.0]),(@SVector [0.9,0.0,0.0])) - -bshapes = BEAST.RTRefSpace{Float64}() -tshapes = BEAST.LagrangeRefSpace{Float64,1,3,3}() - -biop = BEAST.DotLocal(nt,(BEAST.DoubleIntegralR{Float64}()×B)) - -quadstrat = BEAST.DoubleNumSauterQstrat(6,7,6,6,6,6) - -qd = quaddata(biop, tshapes, bshapes, [tcell], [bcell], quadstrat) -zlocal1 = zeros(Float64, 6, 6) -zlocal2 = zeros(Float64, 6, 6) -##without subdevision -qrule = quadrule(biop, tshapes, bshapes, 1, tcell, 1, bcell, qd, quadstrat) -BEAST.momintegrals!(biop, tshapes, bshapes, tcell, bcell, zlocal1, qrule) - -##with subdevision -BEAST.momintegrals_overlap!(biop, tshapes, bshapes, tcell, bcell, zlocal2, quadstrat) -@test zlocal1 ≈ zlocal2 \ No newline at end of file diff --git a/test/test_ndspace.jl b/test/test_ndspace.jl index 4a326c42..d9613761 100644 --- a/test/test_ndspace.jl +++ b/test/test_ndspace.jl @@ -38,6 +38,6 @@ for T in [Float32, Float64] @test v1 ≈ v2 ≈ -1/√2 ≈ -1/volume(charts[3]) curlND = curl(ND) - @test curlND.fns[3][1].coeff ≈ +2 - @test curlND.fns[3][2].coeff ≈ -2 + @test curlND.fns[3][1].coeff ≈ -2 + @test curlND.fns[3][2].coeff ≈ +2 end From 907e204135b472726528ce2bda1af0780a71b6a7 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Mar 2024 12:28:56 +0100 Subject: [PATCH 097/110] remove files --- src/composedoperator/excitation.jl | 0 src/composedoperator/postprocessing.jl | 36 - src/multi-trace/PMCHWT.jl | 0 src/multi-trace/VectorPotential.jl | 875 ------------------ src/multi-trace/efie.jl | 0 src/multi-trace/interactions.jl | 415 --------- src/multi-trace/interactions_new.jl | 44 - src/multi-trace/mfie.jl | 0 .../multi-trace-old/configuration.jl | 272 ------ .../design of the multi-trace approach.txt | 11 - .../multi-trace-old/interactions.jl | 238 ----- .../multi-trace-old/postprocessing.jl | 118 --- src/multi-trace/postprocessing.jl | 93 -- src/multi-trace/test_multi-trace_VP.jl | 121 --- 14 files changed, 2223 deletions(-) delete mode 100644 src/composedoperator/excitation.jl delete mode 100644 src/composedoperator/postprocessing.jl delete mode 100644 src/multi-trace/PMCHWT.jl delete mode 100644 src/multi-trace/VectorPotential.jl delete mode 100644 src/multi-trace/efie.jl delete mode 100644 src/multi-trace/interactions.jl delete mode 100644 src/multi-trace/interactions_new.jl delete mode 100644 src/multi-trace/mfie.jl delete mode 100644 src/multi-trace/multi-trace-old/configuration.jl delete mode 100644 src/multi-trace/multi-trace-old/design of the multi-trace approach.txt delete mode 100644 src/multi-trace/multi-trace-old/interactions.jl delete mode 100644 src/multi-trace/multi-trace-old/postprocessing.jl delete mode 100644 src/multi-trace/postprocessing.jl delete mode 100644 src/multi-trace/test_multi-trace_VP.jl diff --git a/src/composedoperator/excitation.jl b/src/composedoperator/excitation.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/composedoperator/postprocessing.jl b/src/composedoperator/postprocessing.jl deleted file mode 100644 index effd6722..00000000 --- a/src/composedoperator/postprocessing.jl +++ /dev/null @@ -1,36 +0,0 @@ -struct FunctionExcitation{T} <: Functional - f -end -export FunctionExcitation -kernelvals(op::ComposedOperator,a) = nothing - - - -function (func::FunctionExcitation)(x) - return func.f(x) -end -function (func::FunctionExcitation)(x::Union{CompScienceMeshes.MeshPointNM,BEAST.TraceMeshPointNM}) - return func.f(cartesian(x)) -end -scalartype(ff::FunctionExcitation{T}) where {T} = T -cross(::NormalVector, p::FunctionExcitation) = CrossTraceMW(p) -integrand(::FunctionExcitation,tval,fval) = tval[1]*fval -export FunctionExcitation - - -function farfieldlocal!(zlocal,op::ComposedOperatorIntegral,refspace,y,el,qr) - - for q in qr - x = q.point - F = q.value - dx = q.weight - - krn = kernelvals(op, y, x) - int = integrand(op,krn,y,F,x) * dx - for (i,j) in enumerate(int) - zlocal[i] += j - end - - end - -end \ No newline at end of file diff --git a/src/multi-trace/PMCHWT.jl b/src/multi-trace/PMCHWT.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/multi-trace/VectorPotential.jl b/src/multi-trace/VectorPotential.jl deleted file mode 100644 index 30b94193..00000000 --- a/src/multi-trace/VectorPotential.jl +++ /dev/null @@ -1,875 +0,0 @@ -# TODO -# Make it possible to measure the complement error -# Cleanup the code, different file for post processing -# other branch Make connection with single-layer operator in different file called: connections with maxwell3D -# later Make PMCHWT, EFIE, MFIE description in the same way -# Include PEC -# Write test files -# Niet plat ding in sheets steken, halve sfeer. --> werkt (hier valt verschil efie-cfie mss nog te halen) -struct PRECVP <: Interaction - trace::Int -end -struct PRECVPPMCHWT2 <: Interaction - trace::Int - rows - cols -end -struct VPPMCHWT <: Interaction - trace::Int -end -VPPMCHWT() = VPPMCHWT(1) -struct VPPMCHWT2 <: Interaction - trace::Int -end -PRECVPPMCHWT2() = PRECVPPMCHWT2(1,[1,2,3,4],[1,2,3,4]) -VPPMCHWT2() = VPPMCHWT2(1) -PRECVP() = PRECVP(1) - -function testbasis(obj::Object{T}, ::VP) where {T <: HOM} - Γ = obj.type.mesh - x1 = raviartthomas(Γ) - x2 = BEAST.lagrangecxd0(Γ) - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangec0d1(Γ) - return BEAST.DirectProductSpace([x1,x2,x3,x4]) -end - -function trialbasis(obj::Object{T}, ::VP) where {T <: HOM} - Γ = obj.type.mesh - x1 = raviartthomas(Γ) - x2 = BEAST.lagrangec0d1(Γ) - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangecxd0(Γ) - return BEAST.DirectProductSpace([x1,x2,x3,x4]) -end -function testbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} - Γ = obj.type.mesh - x1 = buffachristiansen(Γ) - x2 = BEAST.duallagrangecxd0(Γ) - x3 = buffachristiansen(Γ) - x4 = BEAST.duallagrangec0d1(Γ) - return BEAST.DirectProductSpace([x1,x2,x3,x4]) -end - -function trialbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} - Γ = obj.type.mesh - x1 = buffachristiansen(Γ) - x2 = BEAST.duallagrangec0d1(Γ) - x3 = buffachristiansen(Γ) - x4 = BEAST.duallagrangecxd0(Γ) - return BEAST.DirectProductSpace([x1,x2,x3,x4]) -end -function testbasis(obj::Object{T}, ::PRECVPPMCHWT2) where {T <: HOM} - Γ = obj.type.mesh - x1 = buffachristiansen(Γ) - x2 = BEAST.duallagrangec0d1(Γ) - x3 = buffachristiansen(Γ) - x4 = BEAST.duallagrangecxd0(Γ) - return BEAST.DirectProductSpace([x1,x2,x3,x4]) -end - -function trialbasis(obj::Object{T}, ::PRECVPPMCHWT2) where {T <: HOM} - Γ = obj.type.mesh - x1 = buffachristiansen(Γ) - x2 = BEAST.duallagrangec0d1(Γ) - x3 = buffachristiansen(Γ) - x4 = BEAST.duallagrangecxd0(Γ) - return BEAST.DirectProductSpace([x1,x2,x3,x4]) -end -function testbasis(obj::Object{T}, ::VPPMCHWT) where {T <: HOM} - Γ = obj.type.mesh - x1 = raviartthomas(Γ) - x2 = BEAST.lagrangec0d1(Γ) - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangecxd0(Γ) - return BEAST.DirectProductSpace([x1,x2,x3,x4]) -end - -function trialbasis(obj::Object{T}, ::VPPMCHWT) where {T <: HOM} - Γ = obj.type.mesh - x1 = raviartthomas(Γ) - x2 = BEAST.lagrangec0d1(Γ) - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangecxd0(Γ) - return BEAST.DirectProductSpace([x1,x2,x3,x4]) -end -function testbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: HOM} - Γ = obj.type.mesh - x1 = raviartthomas(Γ) - x2 = BEAST.lagrangec0d1(Γ) - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangecxd0(Γ) - return BEAST.DirectProductSpace([x1,x2,x3,x4]) -end - -function trialbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: HOM} - Γ = obj.type.mesh - x1 = raviartthomas(Γ) - x2 = BEAST.lagrangec0d1(Γ) - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangecxd0(Γ) - return BEAST.DirectProductSpace([x1,x2,x3,x4]) -end - - -function testbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: PECEFIE} - Γ = obj.type.mesh - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangecxd0(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end - -function trialbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: PECEFIE} - Γ = obj.type.mesh - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangecxd0(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end -function testbasis(obj::Object{T}, ::PRECVPPMCHWT2) where {T <: PECEFIE} - Γ = obj.type.mesh - x3 = buffachristiansen(Γ) - x4 = BEAST.duallagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end - -function trialbasis(obj::Object{T}, ::PRECVPPMCHWT2) where {T <: PECEFIE} - Γ = obj.type.mesh - x3 = buffachristiansen(Γ) - x4 = BEAST.duallagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end -function testbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: PECMFIE} - Γ = obj.type.mesh - x3 = buffachristiansen(Γ) - x4 = BEAST.duallagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end - -function trialbasis(obj::Object{T}, ::VPPMCHWT2) where {T <: PECMFIE} - Γ = obj.type.mesh - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangecxd0(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end -# function testbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} -# Γ = obj.type.mesh -# x1 = buffachristiansen(Γ) -# x2 = BEAST.lagrangec0d1(Γ) -# x3 = buffachristiansen(Γ) -# x4 = BEAST.lagrangec0d1(Γ) -# return BEAST.DirectProductSpace([x1,x2,x3,x4]) -# end - -# function trialbasis(obj::Object{T}, ::PRECVP) where {T <: HOM} -# Γ = obj.type.mesh -# x1 = buffachristiansen(Γ) -# x2 = BEAST.lagrangec0d1(Γ) -# x3 = buffachristiansen(Γ) -# x4 = BEAST.lagrangec0d1(Γ) -# return BEAST.DirectProductSpace([x1,x2,x3,x4]) -# end - -function testbasis(obj::Object{T}, ::VP) where {T <: PECEFIE} - Γ = obj.type.mesh - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end - -function trialbasis(obj::Object{T}, ::VP) where {T <: PECEFIE} - Γ = obj.type.mesh - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end -function testbasis(obj::Object{T}, ::VP) where {T <: PECMFIE} - Γ = obj.type.mesh - x3 = buffachristiansen(Γ) - x4 = BEAST.lagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end - -function trialbasis(obj::Object{T}, ::VP) where {T <: PECMFIE} - Γ = obj.type.mesh - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end - -function testbasis(obj::Object{T}, ::PRECVP) where {T <: PECEFIE} - Γ = obj.type.mesh - x3 = buffachristiansen(Γ) - x4 = BEAST.lagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end - -function trialbasis(obj::Object{T}, ::PRECVP) where {T <: PECEFIE} - Γ = obj.type.mesh - x3 = buffachristiansen(Γ) - x4 = BEAST.lagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end - -function testbasis(obj::Object{T}, ::PRECVP) where {T <: PECMFIE} - Γ = obj.type.mesh - x3 = buffachristiansen(Γ) - x4 = BEAST.lagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end - -function trialbasis(obj::Object{T}, ::PRECVP) where {T <: PECMFIE} - Γ = obj.type.mesh - x3 = raviartthomas(Γ) - x4 = BEAST.lagrangec0d1(Γ) - return BEAST.DirectProductSpace([x3,x4]) -end - -# function interaction(testobj::Union{Object,Inside}, -# trialobj::Inside{Object{<:Union{FreeSpace,HOM}}}, embobj::Object, strat::VP) - -# a = -[1 0 0 0; -# 0 1 0 0; -# 0 0 mu(trialobj)/mu(parent(trialobj)) 0; -# 0 0 0 epsilon(parent(trialobj.object))/epsilon(trialobj)] -# return interaction(testobj,trialobj.object,embobj,strat)*a -# end - - -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::Inside,trialtype,strat::Union{PRECVP,VP,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) - a = [1 0 0 0; - 0 1 0 0; - 0 0 mu(testobj)/mu(parent(testobj)) 0; - 0 0 0 epsilon(parent(testobj))/epsilon(testobj)] - a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign,dual=dual,trace=trace) -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::Inside,trialtype,strat::Union{VPPMCHWT}; sign=1,dual=true,trace=true) - a = [1 0 0 0; - 0 epsilon(parent(testobj))/epsilon(testobj) 0 0; - 0 0 mu(testobj)/mu(parent(testobj)) 0; - 0 0 0 1] - a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign,dual=dual,trace=trace) -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::Inside,trialtype,strat::Union{VPPMCHWT2}; sign=1,dual=true,trace=true) - a = [mu(testobj)/mu(parent(testobj)) 0 0 0; - 0 epsilon(parent(testobj))/epsilon(testobj) 0 0; - 0 0 1 0; - 0 0 0 1] - a^-1 * interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=-sign,dual=dual,trace=trace) -end - -# function interaction(testobj::Object,trialobj::Object,embobj::Object, -# testtype::PECCFIE,trialtype,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) - -# testtype.alpha*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign)[1:2,:]+ -# (1-testtype.alpha)*interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] -# end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::PECEFIE,trialtype,strat::Union{PRECVP,VP,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) - - interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[1:2,:] -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::PECEFIE,trialtype,strat::Union{VPPMCHWT2}; sign=1,dual=true,trace=true) - - interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::PECMFIE,trialtype,strat::Union{PRECVP,VP,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) - interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[3:4,:] -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::PECMFIE,trialtype,strat::Union{VPPMCHWT2}; sign=1,dual=true,trace=true) - interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace)[1:2,:] -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::Inside,strat::Union{PRECVP,VP,VPPMCHWT,VPPMCHWT2}; sign=1,dual=true,trace=true) - a = -[1 0 0 0; - 0 1 0 0; - 0 0 mu(trialobj)/mu(parent(trialobj)) 0; - 0 0 0 epsilon(parent(trialobj))/epsilon(trialobj)] - interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)*a -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::Inside,strat::Union{PRECVPPMCHWT2}; sign=1,dual=true,trace=true) - a = -[mu(trialobj)/mu(parent(trialobj)) 0 0 0; - 0 epsilon(parent(trialobj))/epsilon(trialobj) 0 0; - 0 0 1 0; - 0 0 0 1] - interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)*a -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::PEC,strat::Union{PRECVP,VP,VPPMCHWT2}; sign=1,dual=true,trace=true) - interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)[:,3:4] -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::PEC,strat::Union{PRECVPPMCHWT2}; sign=1,dual=true,trace=true) - interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace)[:,1:2] -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::ObjectType,trialtype::HOM,strat::Union{PRECVP,VP,VPPMCHWT,VPPMCHWT2,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) - interaction(testobj,trialobj,embobj,testtype,trialtype.inside,strat;sign=sign,dual=dual,trace=trace) -end -function interaction(testobj::Object,trialobj::Object,embobj::Object, - testtype::HOM,trialtype,strat::Union{PRECVP,VP,VPPMCHWT,VPPMCHWT2,PRECVPPMCHWT2}; sign=1,dual=true,trace=true) - interaction(testobj,trialobj,embobj,testtype.inside,trialtype,strat;sign=sign,dual=dual,trace=trace) -end -function interaction(testobj::Object, trialobj::Object, embobj::Object, - testtype::ObjectType,trialtype::ObjectType,strat::Union{PRECVP,VP}; sign=1,dual=true,trace=true) - tr = sign*strat.trace - k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - - bs = geometry(trialobj) - ts = geometry(testobj) - if trace - ∇Gx = BEAST.build_potential(gradG×B,bs) - Gn = BEAST.build_potential(G*(n*B),bs) - #Gnx = BEAST.build_potential(G*(n × B),bs) - ∇G = BEAST.build_potential(gradG*B,bs) - ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) - ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) - - Gr = BEAST.build_potential(G*B,bs) - ∇G∇B = BEAST.build_potential(gradG*div(B),bs) - ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) - else - ∇Gx = gradG×B - Gn = G*(nb*B) - #Gnx = G*(n × B) - ∇G = gradG*B - ∇Gdotn = nb ⋅ (gradG*B) - ∇Gdot = B ⋅ gradG - - Gr = G*B - ∇G∇B = gradG*div(B) - ∇Gxn = gradG×(nb*B) - - end - #gebruik gamma^c --> sign = + - # #without extra ncross - # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); - # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); - # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); - # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] - # #with extra ncross - if dual && trace - int = [-γₜ(∇Gx,ts,tr) γₜ(Gn,ts,tr) -γₜ(Gr,ts,tr) γₜ(∇G,ts,tr); - ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr); - -γₜ(∇G∇B,ts,tr)-k^2*γₜ(Gr,ts,tr) γₜ(∇Gxn,ts,tr) -γₜ(∇Gx,ts,tr) ZeroOperator(); - γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr)] - return int - elseif dual - int = [nt×(nt×(∇Gx)) -nt×(nt×(Gn)) nt×(nt×(Gr)) nt×(nt×(∇G)); - ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr); - nt×(nt×(∇G∇B))+k^2*nt×(nt×(Gr)) -nt×(nt×(∇Gxn)) nt×(nt×(∇Gx)) ZeroOperator(); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G)] - return int - elseif trace - int = [γₛ(∇Gx,ts,tr) -γₛ(Gn,ts,tr) γₛ(Gr,ts,tr) -γₛ(∇G,ts,tr); - ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr); - γₛ(∇G∇B,ts,tr)+k^2*γₛ(Gr,ts,tr) -γₛ(∇Gxn,ts,tr) γₛ(∇Gx,ts,tr) ZeroOperator(); - γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr)] - return int - else - int = [nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); - ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr); - nt×(∇G∇B)+k^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G)] - return int - end -end -function interaction(testobj::Object, trialobj::Object, embobj::Object, - testtype::ObjectType,trialtype::ObjectType,strat::Union{PRECVPPMCHWT2}; sign=1,dual=true,trace=true) - tr = sign*strat.trace - k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - switch_collums(mat) = [mat[:,3:4] mat[:,1:2]] - - zer = Matrix{AbstractOperator}(undef,4,4) - fill!(zer,ZeroOperator()) - rows = strat.rows - cols = strat.cols - - bs = geometry(trialobj) - ts = geometry(testobj) - if trace - ∇Gx = BEAST.build_potential(gradG×B,bs) - Gn = BEAST.build_potential(G*(n*B),bs) - #Gnx = BEAST.build_potential(G*(n × B),bs) - ∇G = BEAST.build_potential(gradG*B,bs) - ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) - ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) - - Gr = BEAST.build_potential(G*B,bs) - ∇G∇B = BEAST.build_potential(gradG*div(B),bs) - ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) - else - ∇Gx = gradG×B - Gn = G*(nb*B) - #Gnx = G*(n × B) - ∇G = gradG*B - ∇Gdotn = nb ⋅ (gradG*B) - ∇Gdot = B ⋅ gradG - - Gr = G*B - ∇G∇B = gradG*div(B) - ∇Gxn = gradG×(nb*B) - - end - #gebruik gamma^c --> sign = + - # #without extra ncross - # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); - # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); - # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); - # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] - # #with extra ncross - if dual && trace - int = [-γₜ(∇Gx,ts,tr) γₜ(Gn,ts,tr) -γₜ(Gr,ts,tr) γₜ(∇G,ts,tr); - ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr); - -γₜ(∇G∇B,ts,tr)-k^2*γₜ(Gr,ts,tr) γₜ(∇Gxn,ts,tr) -γₜ(∇Gx,ts,tr) ZeroOperator(); - γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr)] - out = switch_collums(int) - elseif dual - int = [nt×(nt×(∇Gx)) -nt×(nt×(Gn)) nt×(nt×(Gr)) nt×(nt×(∇G)); - ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr); - nt×(nt×(∇G∇B))+k^2*nt×(nt×(Gr)) -nt×(nt×(∇Gxn)) nt×(nt×(∇Gx)) ZeroOperator(); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G)] - out = switch_collums(int) - elseif trace - int = [γₛ(∇Gx,ts,tr) -γₛ(Gn,ts,tr) γₛ(Gr,ts,tr) -γₛ(∇G,ts,tr); - ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr); - γₛ(∇G∇B,ts,tr)+k^2*γₛ(Gr,ts,tr) -γₛ(∇Gxn,ts,tr) γₛ(∇Gx,ts,tr) ZeroOperator(); - γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr)] - out = switch_collums(int) - else - int = [nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); - ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr); - nt×(∇G∇B)+k^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G)] - out = switch_collums(int) - end - zer[rows,cols] .+= out[rows,cols] - return zer -end -function interaction(testobj::Object, trialobj::Object, embobj::Object, - testtype::ObjectType,trialtype::ObjectType,strat::VPPMCHWT; sign=1,dual=true,trace=true) - tr = sign*strat.trace - k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - - bs = geometry(trialobj) - ts = geometry(testobj) - if trace - ∇Gx = BEAST.build_potential(gradG×B,bs) - Gn = BEAST.build_potential(G*(n*B),bs) - #Gnx = BEAST.build_potential(G*(n × B),bs) - ∇G = BEAST.build_potential(gradG*B,bs) - ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) - ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) - - Gr = BEAST.build_potential(G*B,bs) - ∇G∇B = BEAST.build_potential(gradG*div(B),bs) - ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) - else - ∇Gx = gradG×B - Gn = G*(nb*B) - #Gnx = G*(n × B) - ∇G = gradG*B - ∇Gdotn = nb ⋅ (gradG*B) - ∇Gdot = B ⋅ gradG - - Gr = G*B - ∇G∇B = gradG*div(B) - ∇Gxn = gradG×(nb*B) - - end - #gebruik gamma^c --> sign = + - # #without extra ncross - # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); - # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); - # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); - # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] - # #with extra ncross - if dual && trace - int = [-γₜ(∇Gx,ts,tr) γₜ(Gn,ts,tr) -γₜ(Gr,ts,tr) γₜ(∇G,ts,tr); - γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr); - -γₜ(∇G∇B,ts,tr)-k^2*γₜ(Gr,ts,tr) γₜ(∇Gxn,ts,tr) -γₜ(∇Gx,ts,tr) ZeroOperator(); - ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr)] - return int - elseif dual - int = [nt×(nt×(∇Gx)) -nt×(nt×(Gn)) nt×(nt×(Gr)) nt×(nt×(∇G)); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); - nt×(nt×(∇G∇B))+k^2*nt×(nt×(Gr)) -nt×(nt×(∇Gxn)) nt×(nt×(∇Gx)) ZeroOperator(); - ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr)] - return int - elseif trace - int = [γₛ(∇Gx,ts,tr) -γₛ(Gn,ts,tr) γₛ(Gr,ts,tr) -γₛ(∇G,ts,tr); - γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr); - γₛ(∇G∇B,ts,tr)+k^2*γₛ(Gr,ts,tr) -γₛ(∇Gxn,ts,tr) γₛ(∇Gx,ts,tr) ZeroOperator(); - ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr)] - return int - else - int = [nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); - nt×(∇G∇B)+k^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); - ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr)] - return int - end -end -function interaction(testobj::Object, trialobj::Object, embobj::Object, - testtype::ObjectType,trialtype::ObjectType,strat::VPPMCHWT2; sign=1,dual=true,trace=true) - tr = sign*strat.trace - k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - - bs = geometry(trialobj) - ts = geometry(testobj) - if trace - ∇Gx = BEAST.build_potential(gradG×B,bs) - Gn = BEAST.build_potential(G*(n*B),bs) - #Gnx = BEAST.build_potential(G*(n × B),bs) - ∇G = BEAST.build_potential(gradG*B,bs) - ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) - ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) - - Gr = BEAST.build_potential(G*B,bs) - ∇G∇B = BEAST.build_potential(gradG*div(B),bs) - ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) - else - ∇Gx = gradG×B - Gn = G*(nb*B) - #Gnx = G*(n × B) - ∇G = gradG*B - ∇Gdotn = nb ⋅ (gradG*B) - ∇Gdot = B ⋅ gradG - - Gr = G*B - ∇G∇B = gradG*div(B) - ∇Gxn = gradG×(nb*B) - - end - #gebruik gamma^c --> sign = + - # #without extra ncross - # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); - # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); - # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); - # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] - # #with extra ncross - if dual && trace - int = [-γₜ(∇G∇B,ts,tr)-k^2*γₜ(Gr,ts,tr) γₜ(∇Gxn,ts,tr) -γₜ(∇Gx,ts,tr) ZeroOperator(); - γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr); - -γₜ(∇Gx,ts,tr) γₜ(Gn,ts,tr) -γₜ(Gr,ts,tr) γₜ(∇G,ts,tr); - ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr)] - return int - elseif dual - int = [nt×(nt×(∇G∇B))+k^2*nt×(nt×(Gr)) -nt×(nt×(∇Gxn)) nt×(nt×(∇Gx)) ZeroOperator(); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); - nt×(nt×(∇Gx)) -nt×(nt×(Gn)) nt×(nt×(Gr)) -nt×(nt×(∇G)); - ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr)] - return int - elseif trace - int = [γₛ(∇G∇B,ts,tr)+k^2*γₛ(Gr,ts,tr) -γₛ(∇Gxn,ts,tr) γₛ(∇Gx,ts,tr) ZeroOperator(); - γₙ(∇Gx,ts,tr) -γₙ(Gn,ts,tr) γₙ(Gr,ts,tr) -γₙ(∇G,ts,tr); - γₛ(∇Gx,ts,tr) -γₛ(Gn,ts,tr) γₛ(Gr,ts,tr) -γₛ(∇G,ts,tr); - ZeroOperator() -τ(∇Gdotn,ts,tr) τ(∇Gdot,ts,tr) k^2*τ(Gr,ts,tr)] - return int - else - int = [nt×(∇G∇B)+k^2*nt×(Gr) -nt×(∇Gxn) nt×(∇Gx) ZeroOperator(); - nt ⋅(∇Gx) -nt ⋅(Gn) nt ⋅(Gr) -nt ⋅(∇G); - nt×(∇Gx) -nt×(Gn) nt×(Gr) -nt×(∇G); - ZeroOperator() -(∇Gdotn) (∇Gdot) k^2*(Gr)] - return int - end -end -# function interaction(testobj::Object, trialobj::Object, embobj::Object, -# testtype::ObjectType,trialtype::ObjectType,strat::VP; sign=1) -# trace = sign*strat.trace -# k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) -# G = BEAST.greenhh3d(wavenumber=k) -# gradG = BEAST.∇(G) - - -# ∇Gx = BEAST.build_potential(gradG×B) -# Gn = BEAST.build_potential(G*(n*B)) -# #Gnx = BEAST.build_potential(G*(n × B),bs) -# ∇G = BEAST.build_potential(gradG*B) -# ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B)) -# ∇Gdot = BEAST.build_potential(B ⋅ gradG) - -# Gr = BEAST.build_potential(G*B) -# ∇G∇B = BEAST.build_potential(gradG*div(B)) -# ∇Gxn = BEAST.build_potential(gradG×(n*B)) - -# #gebruik gamma^c --> sign = + -# # #without extra ncross -# # int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); -# # ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); -# # γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); -# # γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] -# # #with extra ncross -# int = [-γₜ(∇Gx,trace) γₜ(Gn,trace) -γₜ(Gr,trace) γₜ(∇G,trace); -# ZeroOperator() -τ(∇Gdotn,trace) τ(∇Gdot,trace) k^2*τ(Gr,trace); -# -γₜ(∇G∇B,trace)-k^2*γₜ(Gr,trace) γₜ(∇Gxn,trace) -γₜ(∇Gx,trace) ZeroOperator(); -# γₙ(∇Gx,trace) -γₙ(Gn,trace) γₙ(Gr,trace) -γₙ(∇G,trace)] -# return int -# end - -# function interaction(testobj::Object, trialobj::Object, embobj::Object, -# testtype::ObjectType,trialtype::ObjectType,strat::PRECVP; sign=1,dual=true) -# trace = sign*strat.trace -# k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) -# G = BEAST.greenhh3d(wavenumber=k) -# gradG = BEAST.∇(G) - -# bs = barycentric_refinement(geometry(trialobj); sort = :spacefillingcurve) -# ts = barycentric_refinement(geometry(testobj); sort = :spacefillingcurve) - -# bss = geometry(trialobj) -# tss = geometry(testobj) - -# ∇Gx = BEAST.build_potential(gradG×B,bs)# -# Gn = BEAST.build_potential(G*(n*B),bss)# -# #Gnx = BEAST.build_potential(G*(n × B),bs) -# ∇G = BEAST.build_potential(gradG*B,bss)# -# ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bss)# -# ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs)# - -# Gr = BEAST.build_potential(G*B,bs)# -# Grs = BEAST.build_potential(G*B,bss)# -# ∇G∇B = BEAST.build_potential(gradG*div(B),bs)# -# ∇Gxn = BEAST.build_potential(gradG×(n*B),bss)# - -# int = [-γₜ(∇Gx,ts,trace) γₜ(Gn,ts,trace) -γₜ(Gr,ts,trace) γₜ(∇G,ts,trace); -# ZeroOperator() -τ(∇Gdotn,tss,trace) τ(∇Gdot,tss,trace) k^2*τ(Grs,tss,trace); -# -γₜ(∇G∇B,ts,trace)-k^2*γₜ(Gr,ts,trace) γₜ(∇Gxn,ts,trace) -γₜ(∇Gx,ts,trace) ZeroOperator(); -# γₙ(∇Gx,tss,trace) -γₙ(Gn,tss,trace) γₙ(Gr,tss,trace) -γₙ(∇G,tss,trace)] -# return int -# end -function _identity(::ObjectType,strat::PRECVP) - [NCross() ZeroOperator() ZeroOperator() ZeroOperator(); - ZeroOperator() Identity() ZeroOperator() ZeroOperator(); - ZeroOperator() ZeroOperator() NCross() ZeroOperator(); - ZeroOperator() ZeroOperator() ZeroOperator() Identity()] -end -_identity(p::PEC,strat::PRECVP) = _identity(p.inside,strat)[1:2,1:2] - -function identity(objtype::ObjectType,strat::Union{VP,VPPMCHWT,VPPMCHWT2,PRECVPPMCHWT2}) - [NCross() ZeroOperator() ZeroOperator() ZeroOperator(); - ZeroOperator() Identity() ZeroOperator() ZeroOperator(); - ZeroOperator() ZeroOperator() NCross() ZeroOperator(); - ZeroOperator() ZeroOperator() ZeroOperator() Identity()] -end -function identity(objtype::ObjectType,strat::PRECVP) - [NCross() ZeroOperator() ZeroOperator() ZeroOperator(); - ZeroOperator() Identity() ZeroOperator() ZeroOperator(); - ZeroOperator() ZeroOperator() NCross() ZeroOperator(); - ZeroOperator() ZeroOperator() ZeroOperator() Identity()] -end -# function identity(objtype::PECCFIE,strat::Union{PRECVP,VP}) -# (1-objtype.alpha)*identity(objtype.inside,strat)[3:4,3:4] -# end -function identity(objtype::PECMFIE,strat::Union{PRECVP,VP,VPPMCHWT2,PRECVPPMCHWT2}) - identity(objtype.inside,strat)[3:4,3:4] -end -function identity(objtype::PECEFIE,strat::Union{PRECVP,VP,VPPMCHWT2,PRECVPPMCHWT2}) - [ZeroOperator() ZeroOperator(); - ZeroOperator() ZeroOperator()] -end -identity(o::HOM,strat::Union{PRECVP,VP,VPPMCHWT,VPPMCHWT2,PRECVPPMCHWT2}) = identity(o.inside,strat) -# function interaction(testobj::Inside{Object{<:Union{FreeSpace,HOM}}}, -# trialobj::Object, embobj::Object, -# strat::VP) - -# trace = -strat.trace -# a = [1 0 0 0; -# 0 1 0 0; -# 0 0 mu(testobj)/mu(parent(testobj)) 0; -# 0 0 0 epsilon(parent(testobj.object))/epsilon(testobj)] - -# k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) -# G = BEAST.greenhh3d(wavenumber=k) -# gradG = BEAST.∇(G) - -# bs = geometry(trialobj) -# ts = geometry(testobj) - -# ∇Gx = BEAST.build_potential(gradG×B,bs) -# Gn = BEAST.build_potential(G*(n*B),bs) -# #Gnx = BEAST.build_potential(G*(n × B),bs) -# ∇G = BEAST.build_potential(gradG*B,bs) -# ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) -# ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) - -# Gr = BEAST.build_potential(G*B,bs) -# ∇G∇B = BEAST.build_potential(gradG*div(B),bs) -# ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) - -# #gebruik gamma^c --> sign = - -# int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); -# ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); -# γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); -# γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] -# return (a^-1)*int -# end - -# function interaction(testobj::Object, trialobj::Object, embobj::Object, strat::VP) -# trace = strat.trace -# k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) -# G = BEAST.greenhh3d(wavenumber=k) -# gradG = BEAST.∇(G) - -# bs = geometry(trialobj) -# ts = geometry(testobj) - -# ∇Gx = BEAST.build_potential(gradG×B,bs) -# Gn = BEAST.build_potential(G*(n*B),bs) -# #Gnx = BEAST.build_potential(G*(n × B),bs) -# ∇G = BEAST.build_potential(gradG*B,bs) -# ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) -# ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) - -# Gr = BEAST.build_potential(G*B,bs) -# ∇G∇B = BEAST.build_potential(gradG*div(B),bs) -# ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) - -# #gebruik gamma^c --> sign = + -# int = [γₛ(∇Gx,ts,trace) -γₛ(Gn,ts,trace) γₛ(Gr,ts,trace) -γₛ(∇G,ts,trace); -# ZeroOperator() -τ(∇Gdotn,ts,trace) τ(∇Gdot,ts,trace) k^2*τ(Gr,ts,trace); -# γₛ(∇G∇B,ts,trace)+k^2*γₛ(Gr,ts,trace) -γₛ(∇Gxn,ts,trace) γₛ(∇Gx,ts,trace) ZeroOperator(); -# γₙ(∇Gx,ts,trace) -γₙ(Gn,ts,trace) γₙ(Gr,ts,trace) -γₙ(∇G,ts,trace)] -# return int - -# end - -function excitation(obj::Object,emb::Object,objtype::ObjectType,ex::VPExcitation,strat::VP) - emb.index ∉ ex.objectids && return [0,0,0,0] - a = [-1* ((n × FunctionExcitation{ComplexF64}(ex.A))×n), - FunctionExcitation{ComplexF64}(ex.divA), - -1* ((n × FunctionExcitation{ComplexF64}(ex.curlA))×n), - NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(ex.A))] - @warn "fix this type" - return a -end -function excitation(obj::Object,emb::Object,objtype::ObjectType,ex::VPExcitation,strat::VPPMCHWT) - emb.index ∉ ex.objectids && return [0,0,0,0] - a = [-1* ((n × FunctionExcitation{ComplexF64}(ex.A))×n), - NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(ex.A)), - -1* ((n × FunctionExcitation{ComplexF64}(ex.curlA))×n), - FunctionExcitation{ComplexF64}(ex.divA)] - @warn "fix this type" - return a -end -function excitation(obj::Object,emb::Object,objtype::ObjectType,ex::VPExcitation,strat::VPPMCHWT2) - emb.index ∉ ex.objectids && return [0,0,0,0] - a = [-1* ((n × FunctionExcitation{ComplexF64}(ex.curlA))×n), - NDotTrace{ComplexF64}(FunctionExcitation{ComplexF64}(ex.A)), - -1* ((n × FunctionExcitation{ComplexF64}(ex.A))×n), - FunctionExcitation{ComplexF64}(ex.divA)] - @warn "fix this type" - return a -end -function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation,strat::VP) - a = [1 0 0 0; - 0 1 0 0; - 0 0 mu(testobj)/mu(parent(testobj)) 0; - 0 0 0 epsilon(parent(testobj))/epsilon(testobj)] - - return a^-1*excitation(testobj,emb,objtype.inside,ex,strat) -end -function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation,strat::VPPMCHWT) - a = [1 0 0 0; - 0 epsilon(parent(testobj))/epsilon(testobj) 0 0; - 0 0 mu(testobj)/mu(parent(testobj)) 0; - 0 0 0 1] - - return a^-1*excitation(testobj,emb,objtype.inside,ex,strat) -end -function excitation(testobj::Object,emb::Object,objtype::Inside,ex::VPExcitation,strat::VPPMCHWT2) - a = [mu(testobj)/mu(parent(testobj)) 0 0 0; - 0 epsilon(parent(testobj))/epsilon(testobj) 0 0; - 0 0 1 0; - 0 0 0 1] - - return a^-1*excitation(testobj,emb,objtype.inside,ex,strat) -end -# function excitation(testobj::Object,emb::Object,objtype::PECCFIE,ex::VPExcitation,strat::VP) - -# objtype.alpha*excitation(testobj,emb,objtype.inside,ex,strat)[1:2]+ -# (1-objtype.alpha)*excitation(testobj,emb,objtype.inside,ex,strat)[3:4] -# end -function excitation(testobj::Object,emb::Object,objtype::PECEFIE,ex::VPExcitation,strat::Union{VP,VPPMCHWT2}) - - excitation(testobj,emb,objtype.inside,ex,strat)[1:2] -end -function excitation(testobj::Object,emb::Object,objtype::PECMFIE,ex::VPExcitation,strat::Union{VP,VPPMCHWT2}) - - excitation(testobj,emb,objtype.inside,ex,strat)[3:4] -end -excitation(testobj::Object,emb::Object,objtype::HOM,ex::VPExcitation,strat::Union{VP,VPPMCHWT,VPPMCHWT2}) = excitation(testobj,emb,objtype.inside,ex,strat) - - -### Post Processing -function list_of_operators(embobj::Object,basisobj::Object{<:HOM},::AField,::VP) - k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - - ∇Gx = gradG×B - Gn = G*(nb*B) - ∇G = gradG*B - Gr = G*B - - return [∇Gx, -Gn, Gr, -∇G] -end - -function list_of_operators(embobj::Object,basisobj::Object{<:HOM}, ::BField, ::VP) - k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - - ∇Gx = gradG×B - Gr = G*B - ∇G∇B = gradG*div(B) - ∇Gxn = gradG×(nb*B) - return [∇G∇B+k^2*Gr, -∇Gxn, ∇Gx, ZeroOperator()] -end -function list_of_operators(embobj::Object,basisobj::Object{<:PEC},::AField,::VP) - k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - - ∇Gx = gradG×B - Gn = G*(nb*B) - ∇G = gradG*B - Gr = G*B - - return [Gr, -∇G] -end - -function list_of_operators(embobj::Object,basisobj::Object{<:PEC}, ::BField, ::VP) - k = sqrt(epsilon(embobj)*mu(embobj))*omega(embobj) - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - - ∇Gx = gradG×B - Gr = G*B - ∇G∇B = gradG*div(B) - ∇Gxn = gradG×(nb*B) - return [∇Gx, ZeroOperator()] -end -function transform(obj,strat::VP) - a = -[1 0 0 0; - 0 1 0 0; - 0 0 mu(obj)/mu(parent(obj)) 0; - 0 0 0 epsilon(parent(obj))/epsilon(obj)] - return a -end - - diff --git a/src/multi-trace/efie.jl b/src/multi-trace/efie.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/multi-trace/interactions.jl b/src/multi-trace/interactions.jl deleted file mode 100644 index b092e1d6..00000000 --- a/src/multi-trace/interactions.jl +++ /dev/null @@ -1,415 +0,0 @@ -using BEAST -using Combinatorics -import Base: +,-,* -import Base -@hilbertspace b[1:4] -@hilbertspace t[1:4] - -# nodig: 1) functies die gegeven 2 objecten(volumes) en hilbertspacede linforms teruggeven. -# ok 2) volumes hebben een type, PEC of HOMOGEEN -# 3) maak een interactie aan en geef deze ook telkens mee, vb: mfie, efie, pmchwt, cfie, vectorpotential -# ok 4) multi-trace struct als wrapper voor deze types -# ok 5) normal is outward pointing --> opslaan in object of het een outward of inward normal object is -# 6) detector for this normal -# ok 7) functie die matrix kan maken voor gegeven object. -# 8) functie die matrices combineert in 1 grote. -# 9) preconditioner als wrapper -# 10) post processing of a volume - -@hilbertspace a -@hilbertspace b - -@hilbertspace c -@hilbertspace d - -t = BEAST.Identity() -q = t[a,b] - -struct Zero end -+(a,b::Zero) = a -+(a::Zero,b) = b -+(a::Zero,b::Zero) = a -*(a::Zero,b) = a -*(b,a::Zero) = a - -struct ObjectType end - -struct Inside{T} - inside::T -end -struct PECEFIE - mesh - ω - inside -end -PECEFIE(a,b) = PECEFIE(a,b,ObjectType()) -struct PECMFIE - mesh - ω - inside -end -PECMFIE(a,b) = PECMFIE(a,b,ObjectType()) -struct PECCFIE - mesh - ω - alpha - inside -end -PECCFIE(a,b,c) = PECCFIE(a,b,c,ObjectType()) -PEC = Union{PECEFIE,PECMFIE} -struct CavityPEC - mesh - ω - inside - -end - - -struct HOM{T} - mesh - ϵ::T - μ::T - ω::T - inside - -end -HOM(a,b,c,d) = HOM(a,b,c,d,ObjectType()) -struct FreeSpace{T} - ϵ::T - μ::T - ω::T - inside -end -FreeSpace(a,b,c) = FreeSpace(a,b,c,ObjectType()) -mutable struct Object{T} - index::Int - type::T - children::Vector{} - parent -end -children(obj::Object) = obj.children -parent(obj::Object) = obj.parent - -mutable struct World - objecttree - objectarray - testhilbertspace - trialhilbertspace - testhilbertspacemap# given an index yields basis index, TODO write function that can be used in both directions - trialhilbertspacemap - testdirectproductspace - trialdirectproductspace -end -World(a,b,c,d,e,f) = World(a,b,c,d,e,f,nothing,nothing) -Base.copy(w::World) = World(w.objecttree,w.objectarray, -w.testhilbertspace,w.trialhilbertspace, -w.testhilbertspacemap,w.trialhilbertspacemap, -w.testdirectproductspace,w.trialdirectproductspace) - -function add_child!(obj,child) - push!(obj.children,child) -end -function add_parent!(obj,parent) - obj.parent = parent -end -""" - -parent at 0 means no parent. -""" -function create_world(embeddings::Vector{Int}, objecttypes::Vector) - @assert length(embeddings) == length(objecttypes) - - objectarray = [Object(i,objecttypes[i],[],nothing) for i in 1:length(objecttypes)] - testhilbertspacemap = zeros(Int,length(embeddings)) - trialhilbertspacemap = zeros(Int,length(embeddings)) - #embeddings[embeddings.==0] = embeddings[embeddings.==0] .+ length(embeddings) .+ 1 - counter = 1 - for (ind,parent) in enumerate(embeddings[1:end]) - parent==0 && continue - add_child!(objectarray[parent],objectarray[ind]) - add_parent!(objectarray[ind],objectarray[parent]) - if typeof(objecttypes[ind]) != FreeSpace - testhilbertspacemap[ind] = counter - trialhilbertspacemap[ind] = counter - counter += 1 - end - end - testhilbertspace = BEAST.hilbertspace(:t, counter-1) - trialhilbertspace = BEAST.hilbertspace(:b, counter-1) - return World(objectarray[end],objectarray,testhilbertspace,trialhilbertspace,testhilbertspacemap,trialhilbertspacemap) -end - -function assign_basis!(w::World, strat) - w.testdirectproductspace = BEAST.DirectProductSpace([testbasis(w.objectarray[i],strat) for (i,j) in enumerate(w.testhilbertspacemap) if j!=0]) - w.trialdirectproductspace = BEAST.DirectProductSpace([trialbasis(w.objectarray[i],strat) for (i,j) in enumerate(w.trialhilbertspacemap) if j!=0]) -end - - -abstract type Interaction end - -struct VP <: Interaction - trace::Int -end # VectorPotential - -VP() = VP(1) - -abstract type Excitation end -struct EHExcitation <: Excitation end -struct CurrentExcitation <: Excitation end -struct VPExcitation <: Excitation - A - curlA - divA - objectids -end - - - -# struct Outside{T} -# object::T -# end -parent(obj::Inside) = parent(obj.object) - -epsilon(o::Union{HOM,FreeSpace}) = o.ϵ -epsilon(o::Object) = epsilon(o.type) -epsilon(o::Inside) = epsilon(o.inside) - -mu(o::Union{HOM,FreeSpace}) = o.μ -mu(o::Object) = mu(o.type) -mu(o::Inside) = mu(o.inside) - -omega(o::Union{HOM,FreeSpace,PEC}) = o.ω -omega(o::Object) = omega(o.type) -omega(o::Inside) = omega(o.inside) - -geometry(o::Object) = geometry(o.type) -geometry(o::Union{HOM,FreeSpace,PEC}) = o.mesh -geometry(o::Inside) = geometry(o.inside) - -# function matrix_to_bilform(mat;dims=size(mat),kwargs...) -# nrows,ncols = size(mat) -# tin = BEAST.hilbertspace(:tin,dims[1]) -# bin = BEAST.hilbertspace(:bin,dims[2]) -# terms = [mat[i,j][tin[i],bin[j]] for i in 1:minimum([nrows,dims[1]]), j in 1:minimum([ncols,dims[2]]) if typeof(mat[i,j]) != ZeroOperator] -# if length(terms) > 0 -# return sum(terms) -# else -# return ZeroOperator()[tin[1],bin[1]] -# end -# end - -# function array_to_linform(array;dim=length(array)) -# nrows = length(array) -# tin = BEAST.hilbertspace(:tin,dim) -# println(sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])])) -# return sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])]) -# end - -# function discretise_rhs(w::World, ex::Excitation, strat::Interaction) -# out = [] -# l = length(w.objectarray)-1 # no bases for the free space -# test = [] -# testb = BEAST.DirectProductSpace([testbasis(obj,strat) for obj in w.objectarray]) -# for obj in w.objectarray - -# if !inside_interaction_matters(obj.type) -# push!(out,0) -# continue -# end -# t = test[obj.index] -# lins = array_to_linform(excitation(obj.type,obj.type,ex,strat))[t] -# for c in children(obj) -# tc = test[c.index] -# lins += array_to_linform(excitation(c.type,obj.type,ex,strat))[tc] -# end -# push!(out,assemble(lins,testb)) -# end -# return out -# end - -function discretise_rhs(w::World, ex::Excitation, strat::Interaction) - tesths = w.testhilbertspace - - testb = w.testdirectproductspace - - maptesths = w.testhilbertspacemap - - out = _discretise_rhs_matrix.(w.objectarray,Ref(tesths),Ref(testb),Ref(maptesths),Ref(ex),Ref(strat)) - return out -end -function _discretise_rhs_matrix(obj::Object{T},tesths,testb,mapt,ex,strat) where {T <: FreeSpace} - out = [] - for child in children(obj) - - u = tesths[mapt[child.index]] - - push!(out,array_to_linform(excitation(child,obj,child.type,ex,strat))[u]) - - end - x = assemble(sum(out),testb) - return x -end -function _discretise_rhs_matrix(obj::Object{T},tesths,testb,mapt,ex,strat) where {T <: HOM} - out = [] - push!(out,array_to_linform(excitation(obj,obj,Inside(obj.type),ex,strat))[tesths[mapt[obj.index]]]) - for child in children(obj) - u = tesths[mapt[child.index]] - push!(out,array_to_linform(excitation(child,obj,child.type,ex,strat))[u]) - end - s = sum(out) - println(s) - return assemble(s,testb) -end -function _discretise_rhs_matrix(obj::Object{T},tesths,testb,mapt,ex,strat) where {T <: PEC} - return Zero() -end -function identity(w1::World,w2::World,strat) - t = w1.trialhilbertspace - b = w2.testhilbertspace - @assert length(t) == length(b) - bil = Zero() - - for (k,(tt,bb)) in enumerate(zip(t,b)) - ind = findfirst(==(k),w1.trialhilbertspacemap) - bil += matrix_to_bilform(_identity(w1.objectarray[ind].type,strat))[tt,bb] - end - println(t) - return assemble(bil,w1.trialdirectproductspace,w2.testdirectproductspace) -end - -function diag_prec(w::World, strat::Interaction) - l = length(w.objectarray)-1 # no bases for the free space - tesths = w.testhilbertspace - basishs = w.trialhilbertspace - testb = w.testdirectproductspace - trialb = w.trialdirectproductspace - maptesths = w.testhilbertspacemap - maptrialhs = w.trialhilbertspacemap - out = _diag_prec.(w.objectarray,Ref(tesths),Ref(basishs),Ref(testb),Ref(trialb),Ref(maptesths),Ref(maptrialhs),Ref(strat)) - return out - -end - -function discretise_lhs(w::World, strat::Interaction;id=1.0,dual=true,trace=true) - - l = length(w.objectarray)-1 # no bases for the free space - tesths = w.testhilbertspace - basishs = w.trialhilbertspace - testb = w.testdirectproductspace - trialb = w.trialdirectproductspace - maptesths = w.testhilbertspacemap - maptrialhs = w.trialhilbertspacemap - out = _discretise_lhs_matrix.(w.objectarray,Ref(tesths),Ref(basishs),Ref(testb),Ref(trialb),Ref(maptesths),Ref(maptrialhs),Ref(strat);id = id,dual=dual,trace=trace) - return out -# returned the assambled matrices for each struct -end -function _discretise_lhs_matrix(obj::Object{<:HOM},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0,dual=true, trace=true) - t = tesths[mapt[obj.index]] - b = basishs[mapb[obj.index]] - # bils = BEAST.BlockDiagonalOperator(Identity())[t,b] - bils = id*matrix_to_bilform(identity(obj.type,strat))[t,b] - println(bils) - bils -= matrix_to_bilform(interaction(obj,obj,obj,Inside(obj.type),Inside(obj.type),strat;dual=dual,trace=trace))[t,b] - for child in children(obj) - u = tesths[mapt[child.index]] - v = basishs[mapb[child.index]] - bils += id*matrix_to_bilform(identity(child.type,strat))[u,v] - bils -= matrix_to_bilform(interaction(obj,child,obj,Inside(obj.type),child.type,strat;dual=dual,trace=trace))[t,v] - bils -= matrix_to_bilform(interaction(child,obj,obj,child.type,Inside(obj.type),strat;dual=dual,trace=trace))[u,b] - bils -= matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat;dual=dual,trace=trace))[u,v] - end - if length(children(obj)) > 1 - for (c1,c2) in combinations(children(obj),2) - t1 = tesths[mapt[c1.index]] - t2 = tesths[mapt[c2.index]] - b1 = basishs[mapb[c1.index]] - b2 = basishs[mapb[c2.index]] - bils -= matrix_to_bilform(interaction(c1,c2,obj,c1.type,c2.type,strat;dual=dual,trace=trace))[t1,b2] - bils -= matrix_to_bilform(interaction(c2,c1,obj,c1.type,c2.type,strat;dual=dual,trace=trace))[t2,b1] - end - end - println(typeof(bils.terms[1])) - println(typeof(testb.factors[1])) - return assemble(bils,testb,trialb) -end -function _diag_prec(obj::Object{<:HOM},tesths,basishs,testb,trialb,mapt,mapb,strat) - t = tesths[mapt[obj.index]] - b = basishs[mapb[obj.index]] - # bils = BEAST.BlockDiagonalOperator(Identity())[t,b] - bils = matrix_to_bilform(identity(obj.type,strat))[t,b] - println(bils) - bils -= matrix_to_bilform(interaction(obj,obj,obj,Inside(obj.type),Inside(obj.type),strat))[t,b] - for child in children(obj) - u = tesths[mapt[child.index]] - v = basishs[mapb[child.index]] - bils += matrix_to_bilform(identity(child.type,strat))[u,v] - bils -= matrix_to_bilform(interaction(child,child,obj,child.type,child.typ,strat))[u,v] - end - return assemble(bils,testb,trialb) -end -function _diag_prec(obj::Object{<:PEC},tesths,basishs,testb,trialb,mapt,mapb,strat) - return Zero() -end - -function _discretise_lhs_matrix(obj::Object{<:PEC},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0,dual=true,trace=true) - return Zero() -end -function _discretise_lhs_matrix(obj::Object{<:FreeSpace},tesths,basishs,testb,trialb,mapt,mapb,strat;id=1.0,dual=true,trace=true) - bilslist = [] - for child in children(obj) - u = tesths[mapt[child.index]] - v = basishs[mapb[child.index]] - push!(bilslist,id*matrix_to_bilform(identity(child.type,strat))[u,v]) - push!(bilslist,-matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat;dual=dual,trace=trace))[u,v]) - end - bils = sum(bilslist) - if length(children(obj)) > 1 - for (c1,c2) in combinations(children(obj),2) - t1 = tesths[mapt[c1.index]] - t2 = tesths[mapt[c2.index]] - b1 = basishs[mapb[c1.index]] - b2 = basishs[mapb[c2.index]] - bils -= matrix_to_bilform(interaction(c1,c2,obj,c1.type,c2.type,strat;dual=dual,trace=trace))[t1,b2] - bils -= matrix_to_bilform(interaction(c2,c1,obj,c1.type,c2.type,strat;dual=dual,trace=trace))[t2,b1] - end - end - return assemble(bils,testb,trialb) -end -function _diag_prec(obj::Object{<:FreeSpace},tesths,basishs,testb,trialb,mapt,mapb,strat) - bilslist = [] - for child in children(obj) - u = tesths[mapt[child.index]] - v = basishs[mapb[child.index]] - push!(bilslist,matrix_to_bilform(identity(child.type,strat))[u,v]) - push!(bilslist,-matrix_to_bilform(interaction(child,child,obj,child.type,child.type,strat))[u,v]) - end - bils = sum(bilslist) - return assemble(bils,testb,trialb) -end - - - -# inside_interaction_matters(obj::PEC) = false -# inside_interaction_matters(obj::ObjectType) = true - -#create these type of functions -# function testbasis(obj::ObjectType,::VP) -# return -# end -# function trialbasis(obj::ObjectType,::VP) -# end - -# # function interaction(testobj::ObjectType,basisobj::Inside{PEC},embedobj::HOM,::VP) -# # return 0 -# # end - -# function interaction() - -# end - -# function excitation(testobj::ObjectType,embedobj::FreeSpace,ex::VPExcitation,::VP) - -# end -# excitation(testobj::ObjectType,embedobj::ObjectType,ex::VPExcitation,::VP) = 0 - - diff --git a/src/multi-trace/interactions_new.jl b/src/multi-trace/interactions_new.jl deleted file mode 100644 index 86204570..00000000 --- a/src/multi-trace/interactions_new.jl +++ /dev/null @@ -1,44 +0,0 @@ -import Base:*, +, - - -mutable struct DiscreteEq - lhs - rhs - trialspace -end - -function +(a::VGL,b::VGL) - @assert a.trialspace == b.trialspace - return VGL(a.lhs+b.lhs,a.rhs+b.rhs,a.trialspace) -end - -*(a::Union{LinearMap,Number},b::VGL) = VGL(a*b.lhs,a*b.rhs,b.trialspace) --(a::VGL,b::VGL) = a + (-1)*b - -function generate_discrete_equations(w::World,strat;kwargs...) - # create hilbertspaces - - -end - -### to define for your specific problem -function hilbertspace(obj,strat) - return true -end - -function getequations(strat,dict)# builds the equations in vp case there are 2 homogeneous equations and 2 pec cfie equations - - return [] -end -##### vanaf hier voor vp - -function getequations(strat::VPPMCHWT,d::Dict) - homind = d[HOM()] - mfie = d[MFIE()] - efie = d[EFIE()] - cfie = d[CFIE()] - freespace = d[FREESPACE()] - eq1 = [] -end -function testspace(obj,strat) end -function trialspace(obj,strat) end -function getequations(strat::VP,dict) end \ No newline at end of file diff --git a/src/multi-trace/mfie.jl b/src/multi-trace/mfie.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/multi-trace/multi-trace-old/configuration.jl b/src/multi-trace/multi-trace-old/configuration.jl deleted file mode 100644 index 6443c14a..00000000 --- a/src/multi-trace/multi-trace-old/configuration.jl +++ /dev/null @@ -1,272 +0,0 @@ -abstract type DomainData end -abstract type Domain{T<:DomainData} end -using PrettyTables -""" -A is the type of the test structure, B is the type of the trial structure, C the type of ths structure embedding -""" -struct Interaction{A,B,C}# wordt gecrieerd bij de itteratie over alle volumes. - config - testvol::A - trialvol::B - embedvol::C -end -# abstract type PhysicalInformation end #depends on the strategy -""" -subtypes of the NumericalStrategy type descirbe the followed strategy. for example a preconditioning strategy for a vector potential based problem, - a vector potential based problem, a fields based problem,... -""" -abstract type NumericalStrategy end - -export NumericalStrategy -mutable struct HomogeneousDomain <: DomainData -physicalinformation -testbasises -trialbasises -coeff -testindex -trialindex -HomogeneousDomain(a,b,c,d) = new(a,b,c,d,[],[]) -end - -struct BackgroundDomain <: DomainData - physicalinformation - coeff -end -physicalconstants(d::DomainData) = d.physicalinformation -physicalconstants(d::Domain) = physicalconstants(d.data) -testspace(d::DomainData) = d.testbasises -trialspace(d::DomainData) = d.trialbasises - -mutable struct SubDomain{T} <: Domain{T} - id::Int - children::Vector{Domain} - parent::Domain - data::T - excitation - results -end -mutable struct RootDomain{T} <: Domain{T} - id::Int - children::Vector{Domain} - data::T - excitation -end - -mutable struct Configuration #TODO add dict contining all subbasis info af touching objects - domains::Dict{Int,Domain} - root::RootDomain - touching::Dict{Tuple{Int,Int},Vector} - testdirectproductspace - trialdirectproductspace -end -Configuration(dom,root,touching) = Configuration(dom,root,touching,nothing,nothing) - - -function _adddomain(config::Configuration, newdom::Domain) - id = newdom.id - @assert !(id in keys(config.domains)) - dom = newdom.parent - config.domains[id] = newdom - for space in newdom.data.testbasises - config.testdirectproductspace = config.testdirectproductspace × space - push!(newdom.data.testindex,length(config.testdirectproductspace.factors)) - end - for space in newdom.data.trialbasises - config.trialdirectproductspace = config.trialdirectproductspace × space - push!(newdom.data.trialindex,length(config.trialdirectproductspace.factors)) - end - push!(dom.children,newdom) -end - -function _createdomain(config::Configuration,id::Int,parentid::Int,values;excitation) - dom = SubDomain(id,Domain[],config.domains[parentid],values::DomainData,excitation,[]) - return dom -end -function _createdomain(config::Configuration,id::Int,parentdom::Domain,values;excitation) - _createdomain(config,id,parentdom.id,values;excitation) -end - -function createdomain(config::Configuration,id::Int,parent::Union{Int,Domain},values::DomainData;excitation=Dict()) - _adddomain(config,_createdomain(config,id,parent,values;excitation)) -end -""" -a child of b -""" -function is_child_of(a,b) - return a∈b.children -end - -function brothers(a,b) -return is_child_of(a,b.parent) -end -function createconfiguration(data::BackgroundDomain,excitation=Dict()) - r = RootDomain(0,Domain[],data,excitation) - Configuration(Dict{Int,Domain}(0=>r),r,Dict{Tuple{Int,Int},Any}()) # typle of the indices, returns the spaces: [test1,trial1,test2,trial2] -end - -function createdomains(config::Configuration,confdict::Dict) end#the confdict is the dictionary containing the information about the mesh, physical parameters,... - -""" -all objects in a domain touch each other, not with subdomains, well with the boundary - -""" -function alltouching(config::Configuration) - for i in keys(config.domains) - #config.touching[(i,i)] = [config.domains[i].data.testbasises,config.domains[i].data.trialbasises,config.domains[i].data.testbasises,config.domains[i].data.trialbasises] - for child in config.domains[i].children - j = child.id - if typeof(config.domains[i]) <: SubDomain - config.touching[(i,j)] = [config.domains[i].data.testbasises,config.domains[i].data.trialbasises,child.data.testbasises,child.data.trialbasises] - config.touching[(j,i)] = [config.touching[(i,j)][3],config.touching[(i,j)][4],config.touching[(i,j)][1],config.touching[(i,j)][2]] - end - for child2 in config.domains[i].children - k = child2.id - config.touching[(j,k)] = [child.data.testbasises,child.data.trialbasises,child2.data.testbasises,child2.data.trialbasises] - config.touching[(k,j)] = [child2.data.testbasises,child2.data.trialbasises,child.data.testbasises,child.data.trialbasises] - end - end - end -end - -function (dom::Domain)(n::NormalVector,dom2::Domain) - if dom==dom2 - return 1.0 - elseif dom2 ∈ dom.children - return -1.0 - else - @error "domain is not in children of parent domain" - end - -end - -function generate_configuration(typelist,id_of_parentlist,background,backgroundexcitation=Dict()) - conf = createconfiguration(background,backgroundexcitation) - l = length(typelist) - for (ind,t,parent_id) in zip(1:l,typelist,id_of_parentlist) - createdomain(conf,ind,parent_id,t) - end - return conf -end -# function _create_bilform(operator_matrix,test_direct_productspace,trial_direct_productspace) -# #TODO create the bilform - -# end -#function convert_inside_to_outside_basis(Ωchild,Ωparent,strat) end -function interaction_matrix(config::Configuration,id,strat::NumericalStrategy) - @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) - N = length(config.testdirectproductspace.factors) - OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) - indexen = [] - Ω = config.domains[id] - if id != 0 - indexen = [indexen; Ω.data.testindex] - inter = Interaction(config,Ω,Ω,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) - for child in Ω.children - inter = Interaction(config,Ω,child,Ω) - OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat) - inter = Interaction(config,child,Ω,Ω) - OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) - end - - end - for Ω1 in Ω.children - indexen = [indexen; Ω1.data.testindex] - inter = Interaction(config,Ω1,Ω1,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += inter(strat) - - for Ω2 in Ω.children - if Ω1!==Ω2 - inter = Interaction(config,Ω1,Ω2,Ω) - OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += inter(strat) - end - end - end - - - id = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) - for i in 1:N - i∈indexen && (id[i,i] = Identity()) - end - pretty_table(id-OperatorMatrix, noheader=true, backend=Val(:latex)) - return assemble(dot(config.testdirectproductspace,id-OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) -end - -# function generate_problem_lhs(config::Configuration,strat::NumericalStrategy)#Make more correct by assambling for eacht domain an add with coeffeicient, add idetity at that place -# @assert length(config.testdirectproductspace.factors)==length(config.trialdirectproductspace.factors) -# N = length(config.testdirectproductspace.factors) -# OperatorMatrix = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) -# for (id,Ω) in config.domains -# c = Ω.data.coeff -# if id != 0 -# inter = Interaction(config,Ω,Ω,Ω) -# OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) -# for child in Ω.children -# inter = Interaction(config,Ω,child,Ω) -# OperatorMatrix[Ω.data.testindex[1]:last(Ω.data.testindex),child.data.trialindex[1]:last(child.data.trialindex)] += c*inv(convert_outside_to_inside_basis(Ω,Ω.parent,strat))*inter(strat) -# inter = Interaction(config,child,Ω,Ω) -# OperatorMatrix[child.data.testindex[1]:last(child.data.testindex),Ω.data.trialindex[1]:last(Ω.data.trialindex)] += c*inter(strat)*convert_outside_to_inside_basis(Ω,Ω.parent,strat) -# end - -# end -# for Ω1 in Ω.children - -# inter = Interaction(config,Ω1,Ω1,Ω) -# OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω1.data.trialindex[1]:last(Ω1.data.trialindex)] += c*inter(strat) - -# for Ω2 in Ω.children -# if Ω1!==Ω2 -# inter = Interaction(config,Ω1,Ω2,Ω) -# OperatorMatrix[Ω1.data.testindex[1]:last(Ω1.data.testindex),Ω2.data.trialindex[1]:last(Ω2.data.trialindex)] += c*inter(strat) -# end -# end -# end - -# end -# id = fill!(Array{AbstractOperator}(undef,N,N),ZeroOperator()) -# for i in 1:N -# id[i,i] = 2*Identity() -# end -# pretty_table(id-OperatorMatrix, noheader=true, backend=Val(:latex)) -# return assemble(dot(config.testdirectproductspace,id-OperatorMatrix,config.trialdirectproductspace),config.testdirectproductspace,config.trialdirectproductspace) - -# end -function generate_problem_lhs(config::Configuration,strat::NumericalStrategy) - out = interaction_matrix(config,0,strat) - for (id,Ω) in config.domains - id==0 && continue - out += Ω.data.coeff* interaction_matrix(config,id,strat) - end - return out -end - -function generate_problem_rhs(config::Configuration) - linterms = Vector{LinTerm}() - @warn "only excitations in root domain implemented, check first if same aproach for others is appropriate" - for (id,Ω) in config.domains end - - for (key,func) in config.root.excitation - for child in config.root.children - - - push!(linterms,LinTerm(child.data.testindex[key],[],1,func)) - end - end - - return assemble(LinForm([],linterms),config.testdirectproductspace) -end - -function map_solution_to_volumes!(config,solution) - for (id,dom) in config.domains - id==0 && continue - out = [] - for i in dom.data.trialindex - push!(out,solution[Block(i)]) - end - dom.results = out - end -end - - - - diff --git a/src/multi-trace/multi-trace-old/design of the multi-trace approach.txt b/src/multi-trace/multi-trace-old/design of the multi-trace approach.txt deleted file mode 100644 index a65637f9..00000000 --- a/src/multi-trace/multi-trace-old/design of the multi-trace approach.txt +++ /dev/null @@ -1,11 +0,0 @@ -design of the multi-trace approach: - -structure is devided in a tree like domain of open domains, there is the free space, domain 1, and then all other domains are in this free space. (mesh object is a domain, thus when you ask in which domain it is it gives the upstream domain). The basis of a mesh object is in the domain of the mesh object. - -Object interacts with every object in the domain and with the boundary of the domain it is in. - -object domain:(Physical information, test and trial bases boundary, mesh, touching information: for each object it returns the subd test and trial basis, also for the object itself!!!!) - -intersect(\Omega1, \Omega2) = (subd test, trial 1), (subd test,trial 2) - -work with strategies, \ No newline at end of file diff --git a/src/multi-trace/multi-trace-old/interactions.jl b/src/multi-trace/multi-trace-old/interactions.jl deleted file mode 100644 index 268260f7..00000000 --- a/src/multi-trace/multi-trace-old/interactions.jl +++ /dev/null @@ -1,238 +0,0 @@ - -using LinearAlgebra -""" -Write for each type of interaction this type of function. -""" -function (int::Interaction{<:Domain{BackgroundDomain},})() - i = [] #interaction matrix - normalorient.(i,Ω1,Ω2,Ω3) # example - - return nothing -end - -# function alpha(Ω1,Ω2) - - -# end -# """ -# cauchylimit needs to be applied before the normalorient function -# """ - -# function cauchylimit(operator::AbstractOperator;Ω1,Ω2,Ω3) -# #check first if touching is non empty -# @assert is_child_of(Ω1,Ω3)||Ω1===Ω3 -# @assert is_child_of(Ω2,Ω3)||Ω2===Ω3 -# # if Ω2!==Ω3 -# # sign = -1 -# # elseif Ω2===Ω3 -# # sign = 1 -# # end -# @warn "correct sign for inside is 1?" -# sign = 1 - -# trace(operator,sign) - -# end - -# function trace(op::AbstractOperator,sign) -# @warn "general abstract opterator trace function called returning pv of operator!: "*string(typeof(op)) -# return op -# end -# function normalorient(op::AbstractOperator,signtest,signtrial) -# @warn "normalorient not implemented for: "*string(typeof(op)) -# return op -# end -# trace(op::ZeroOperator,s) = op - -# function trace(op::LinearCombinationOfOperators,sign) -# result = ZeroOperator() -# for (c,o) in zip(op.coeffs,op.ops) -# result += c*trace(o,sign) -# end -# return result -# end - - -# function normalorient(op::LinearCombinationOfOperators,signtest,signtrial) -# result = ZeroOperator() -# for (c,o) in zip(op.coeffs,op.ops) -# result += c*normalorient(o,signtest,signtrial) -# end -# return result -# end - -# function normalorient(operator::AbstractOperator;Ω1,Ω2,Ω3) -# if Ω1===Ω3 -# sign_test_normal = 1 -# else -# sign_test_normal = -1 -# end -# if Ω2===Ω3 -# sign_trial_normal = 1 -# else -# sign_trial_normal = -1 -# end -# normalorient(operator,sign_test_normal,sign_trial_normal) -# end - -# normalorient(op::ZeroOperator,a,b) = op - -###### Interactions -struct VectorStrat <: BEAST.NumericalStrategy end - -function convert_outside_to_inside_basis(child,parent,::VectorStrat) - p = physicalconstants(parent.data) - c = physicalconstants(child.data) - a = [-1 0 0 0 - 0 1 0 0 - 0 0 -c.μ/p.μ 0 - 0 0 0 -p.ϵ/c.ϵ] - - return a -end - - - - -# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: RootDomain})(::VectorStrat) -# p = physicalconstants(int.embedvol.data) -# k = sqrt(p.ϵ*p.μ)*p.ω -# green = HHH.green(wavenumber=k) -# gradgreen = HHH.gradgreen(wavenumber=k) -# b = basisfunction() -# @warn "check if extra - in front of a is correct, describtion of As from paper asumes n outward so inward in outer domain?" -# a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen -# BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) -# -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() -# -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] -# id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() -# ZeroOperator() Identity() ZeroOperator() ZeroOperator() -# ZeroOperator() ZeroOperator() Identity() ZeroOperator() -# ZeroOperator() ZeroOperator() ZeroOperator() Identity()] -# #a = id - a - -# if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) -# println("cauchy limit taken") -# a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) -# end -# a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) - -# return a - -# end -# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<: SubDomain})(::VectorStrat) -# p = physicalconstants(int.embedvol.data) -# k = sqrt(p.ϵ*p.μ)*p.ω -# green = HHH.green(wavenumber=k) -# gradgreen = HHH.gradgreen(wavenumber=k) -# b = basisfunction() - -# a = -[n×(gradgreen×nothing) n×(green(n*b)) -(n×green) n×gradgreen -# BEAST.ZeroOperator() -(gradgreen⋅nothing)(n*b) (gradgreen⋅nothing) -(-k^2*green) -# -(n×(gradgreen(∇⋅b)))-k^2*(n×green) -(n×((gradgreen×nothing)(n*b))) n×(gradgreen×nothing) BEAST.ZeroOperator() -# -(n⋅(gradgreen×nothing)) -(n⋅green(n*b)) n⋅green -(n⋅gradgreen)] -# id = [Identity() ZeroOperator() ZeroOperator() ZeroOperator() -# ZeroOperator() Identity() ZeroOperator() ZeroOperator() -# ZeroOperator() ZeroOperator() Identity() ZeroOperator() -# ZeroOperator() ZeroOperator() ZeroOperator() Identity()] -# #a = id - a - -# if (int.testvol.id,int.trialvol.id) in keys(int.config.touching) -# println("cauchy limit taken") -# a = BEAST.cauchylimit.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) -# end -# a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) -# return a - -# end - - -# function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<:Union{RootDomain,SubDomain}})(::VectorStrat) -# p = physicalconstants(int.embedvol.data) -# k = sqrt(p.ϵ*p.μ)*p.ω -# G = BEAST.greenhh3d(wavenumber=k) -# ∇G = BEAST.∇(G) -# Ω1=int.testvol -# Ω2=int.trialvol -# Ω3=int.embedvol -# bs = Ω2.data.trialbasises[1].geo -# ts = Ω1.data.testbasises[1].geo - -# ∇Gx = BEAST.build_potential(∇G×B,bs) -# Gn = BEAST.build_potential(G*n*B,bs) -# Gnx = BEAST.build_potential(G*n × B,bs) -# ∇G = BEAST.build_potential(∇G*B,bs) -# ∇Gdotn = BEAST.build_potential(∇G⋅n*B,bs) -# ∇Gdot = BEAST.build_potential(∇G⋅B,bs) - -# Gr = BEAST.build_potential(G*B,bs) -# ∇G∇B = BEAST.build_potential(∇G*∇(B),bs) -# ∇Gxn = BEAST.build_potential(∇G×n*B,bs) - -# if Ω1==Ω2 -# a = -[γₛ(∇Gx,ts) γₛ(Gn,ts) -γₛ(Gnx,ts) γₛ(∇G,ts) -# BEAST.ZeroOperator() -τ(∇Gdotn,ts) τ(∇Gdot,ts) k^2*τ(Gr,ts) -# -γₛ(∇G∇B,ts)-k^2*γₛ(Gr,ts) -γₛ(∇Gxn,ts) γₛ(∇Gx,ts) BEAST.ZeroOperator() -# -γₙ(∇Gx,ts) -γₙ(Gn,ts) γₙ(Gr,ts) -γₙ(∇G,ts)] -# else -# a = -[γₛᶜ(∇Gx,ts) γₛᶜ(Gn,ts) -γₛᶜ(Gnx,ts) γₛᶜ(∇G,ts) -# BEAST.ZeroOperator() -τᶜ(∇Gdotn,ts) τᶜ(∇Gdot,ts) k^2*τᶜ(Gr,ts) -# -γₛᶜ(∇G∇B,ts)-k^2*γₛᶜ(Gr,ts) -γₛᶜ(∇Gxn,ts) γₛᶜ(∇Gx,ts) BEAST.ZeroOperator() -# -γₙᶜ(∇Gx,ts) -γₙᶜ(Gn,ts) γₙᶜ(Gr,ts) -γₙᶜ(∇G,ts)] -# end - - -# #a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) - -# return a - -# end - -function (int::Interaction{<: Domain{HomogeneousDomain},<: Domain{HomogeneousDomain},<:Union{RootDomain,SubDomain}})(::VectorStrat) - p = physicalconstants(int.embedvol.data) - k = sqrt(p.ϵ*p.μ)*p.ω - G = BEAST.greenhh3d(wavenumber=k) - gradG = BEAST.∇(G) - Ω1=int.testvol - Ω2=int.trialvol - Ω3=int.embedvol - bs = Ω2.data.trialbasises[1].geo - ts = Ω1.data.testbasises[1].geo - - ∇Gx = BEAST.build_potential(gradG×B,bs) - Gn = BEAST.build_potential(G*(n*B),bs) - Gnx = BEAST.build_potential(G*(n × B),bs) - ∇G = BEAST.build_potential(gradG*B,bs) - ∇Gdotn = BEAST.build_potential(nb ⋅ (gradG*B),bs) - ∇Gdot = BEAST.build_potential(B ⋅ gradG,bs) - - Gr = BEAST.build_potential(G*B,bs) - ∇G∇B = BEAST.build_potential(gradG*div(B),bs) - ∇Gxn = BEAST.build_potential(gradG×(n*B),bs) - sign = 1 - if Ω1==Ω2==Ω3 - - elseif Ω1==Ω2!=Ω3 - ts = -ts - bs = -bs - - elseif Ω1!=Ω2 - ts = -ts - bs = -bs - sign = -1 - - else - @error "none of previous" - - end - - a = -[γₛ(∇Gx,ts,ts,sign) γₛ(Gn,ts,ts,sign) -γₛ(Gnx,ts,ts,sign) γₛ(∇G,ts,ts,sign) - BEAST.ZeroOperator() -τ(∇Gdotn,ts,ts,sign) τ(∇Gdot,ts,ts,sign) k^2*τ(Gr,ts,ts,sign) - -γₛ(∇G∇B,ts,ts,sign)-k^2*γₛ(Gr,ts,ts,sign) -γₛ(∇Gxn,ts,ts,sign) γₛ(∇Gx,ts,ts,sign) BEAST.ZeroOperator() - -γₙ(∇Gx,ts,ts,sign) -γₙ(Gn,ts,ts,sign) γₙ(Gr,ts,ts,sign) -γₙ(∇G,ts,ts,sign)] - - #a = BEAST.normalorient.(a;Ω1=int.testvol,Ω2=int.trialvol,Ω3=int.embedvol) - - return a - -end \ No newline at end of file diff --git a/src/multi-trace/multi-trace-old/postprocessing.jl b/src/multi-trace/multi-trace-old/postprocessing.jl deleted file mode 100644 index 317734ab..00000000 --- a/src/multi-trace/multi-trace-old/postprocessing.jl +++ /dev/null @@ -1,118 +0,0 @@ -import Base.Threads: @spawn -function nearfield_A(dom::Domain{HomogeneousDomain},pts,strat::VectorStrat) - p = physicalconstants(dom) - parent_const = physicalconstants(dom.parent) - k = sqrt(p.ϵ*p.μ)*p.ω - - nxb_out1,σ_out1,a_out1,γ_out1 = dom.results - nxb1,σ1,a1,γ1 = dom.data.trialbasises - - vector_potential = p.μ/parent_const.μ* potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out1,a1) .- - potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out1,nxb1) .- - parent_const.ϵ/p.ϵ*potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out1,γ1) .-#compensatie omdat normal naar buiten wijst - potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out1,σ1); - - for Ω in dom.children - nxb_out,σ_out,a_out,γ_out = Ω.results - nxb,σ,a,γ = Ω.data.trialbasises - vector_potential = vector_potential .+ -1*potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out,a) .+ - potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out,nxb) .+ - potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out,γ) .+#compensatie omdat normal naar buiten wijst - potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); - end - return vector_potential -end -function nearfield_A(dom::Domain{BackgroundDomain},pts,strat::VectorStrat) - p = physicalconstants(dom) - k = sqrt(p.ϵ*p.μ)*p.ω - vector_potential = zeros(SVector{3,Complex},size(pts)) - for Ω in dom.children - nxb_out,σ_out,a_out,γ_out = Ω.results - nxb,σ,a,γ = Ω.data.trialbasises - vector_potential = vector_potential + -1*potential(BEAST.HHHGreenField(wavenumber=k),pts,a_out,a) + - potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,nxb_out,nxb) + - potential(BEAST.HHHGradGreenField(wavenumber=k),pts,γ_out,γ) +#compensatie omdat normal naar buiten wijst - potential(BEAST.HHHGreenField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); - end - return vector_potential -end -function nearfield_A(config::Configuration,points,strat::VectorStrat) - tasks = [] - for (id,dom) in config.domains - push!(tasks,@spawn nearfield_A(dom,points,strat)) - end - fields = fetch.(tasks) - out = zeros(SVector{3,Complex},size(points)) - for field in fields - out = out .+ field - end - return out -end -function nearfield_B(dom::Domain{HomogeneousDomain},pts,strat::VectorStrat) - p = physicalconstants(dom) - parent_const = physicalconstants(dom.parent) - k = sqrt(p.ϵ*p.μ)*p.ω - - nxb_out1,σ_out1,a_out1,γ_out1 = dom.results - nxb1,σ1,a1,γ1 = dom.data.trialbasises - - BField = p.μ/parent_const.μ* potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out1,a1) .- - (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out1,nxb1)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out1,nxb1)) .- - potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out1,σ1); - - for Ω in dom.children - nxb_out,σ_out,a_out,γ_out = Ω.results - nxb,σ,a,γ = Ω.data.trialbasises - BField = BField .+ -1*potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out,a) .+ - (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out,nxb)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out,nxb)) .+ - potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ); - end - return BField -end - -function nearfield_H(dom::Domain{HomogeneousDomain},points,strat::VectorStrat) - nearfield_B(dom,points,strat)./physicalconstants(dom).μ -end - - -function nearfield_B(dom::Domain{BackgroundDomain},pts,strat::VectorStrat) - p = physicalconstants(dom) - k = sqrt(p.ϵ*p.μ)*p.ω - BField = zeros(SVector{3,Complex},size(pts)) - for Ω in dom.children - nxb_out,σ_out,a_out,γ_out = Ω.results - nxb,σ,a,γ = Ω.data.trialbasises - BField = BField + -1*potential(BEAST.HHHGradGreenCrossField(wavenumber=k),pts,a_out,a) + - (potential(BEAST.HHHGradGreenField(k*im,BEAST.HHHDivergenceField()),pts,nxb_out,nxb)+k^2*potential(BEAST.HHHGreenField(wavenumber=k),pts,nxb_out,nxb)) + - potential(BEAST.HHHGradGreenCrossField(k*im,BEAST.HHHBasisNtimesField(BEAST.HHHIdentityField())),pts,σ_out,σ) - end - return BField -end -function nearfield_B(config::Configuration,points,strat::VectorStrat) - tasks = [] - for (id,dom) in config.domains - push!(tasks,@spawn nearfield_B(dom,points,strat)) - end - fields = fetch.(tasks) - out = zeros(SVector{3,Complex},size(points)) - for field in fields - out = out .+ field - end - return out -end -function nearfield_H(dom::Domain{BackgroundDomain},points,strat::VectorStrat) - nearfield_B(dom,points,strat)./physicalconstants(dom).μ -end - -function nearfield_H(config::Configuration,points,strat::VectorStrat) - tasks = [] - for (id,dom) in config.domains - push!(tasks,nearfield_H(dom,points,strat)) - end - #fields = fetch.(tasks) - out = zeros(SVector{3,Complex},size(points)) - for field in tasks - out = out .+ field - end - return out -end \ No newline at end of file diff --git a/src/multi-trace/postprocessing.jl b/src/multi-trace/postprocessing.jl deleted file mode 100644 index 74c536fb..00000000 --- a/src/multi-trace/postprocessing.jl +++ /dev/null @@ -1,93 +0,0 @@ - -#### Post processing -abstract type PostField end -struct AField <: PostField - world::World - result::PseudoBlockVector - volumes::Vector{Int} -end - -struct BField <: PostField - world::World - result::PseudoBlockVector - volumes::Vector{Int} -end -struct Field{T} - field::T -end -import Base -+(a::Field,b::Field) = Field(a.field + b.field) -+(a::Field{<:Nothing},b::Field) = b -+(a::Field,b::Field{<:Nothing}) = a -+(a::Field{<:Nothing},b::Field{<:Nothing}) = a -*(a::Number,b::Field) = Field(a*b.field) -*(a::Number,b::Field{<:Nothing}) = b - - -function calculate_field(points,f::PostField,strat) - out = [] - for v in f.volumes - obj = f.world.objectarray[v] - push!(out,_calculate_field(points,obj,f,strat)) - end - return sum(out) -end - -function _calculate_field(points,obj::Object{<:FreeSpace},f::PostField,strat) - map = f.world.trialhilbertspacemap - out = [] - for c in children(obj) - push!(out,sum(_calculate_field.(Ref(points),list_of_operators(obj,c,f,strat),BlockArrays.blocks(f.result[Block(map[c.index])]), f.world.trialdirectproductspace.factors[map[c.index]].factors))) - end - return sum(out) -end - -function _calculate_field(points,obj::Object{<:HOM},f::PostField,strat) - map = f.world.trialhilbertspacemap - typeof(f.result) - out = sum(_calculate_field.(Ref(points),transform(obj,strat)*list_of_operators(obj,obj,f,strat),BlockArrays.blocks(f.result[Block(map[obj.index])]), f.world.trialdirectproductspace.factors[map[obj.index]].factors)) - for c in children(obj) - out += sum(_calculate_field.(Ref(points),list_of_operators(obj,c,f,strat),BlockArrays.blocks(f.result[Block(map[c.index])]), f.world.trialdirectproductspace.factors[map[c.index]].factors)) - end - return out -end -function _calculate_field(points,obj::Object{<:PEC},f::PostField,strat) - return Field(nothing) -end - -function _calculate_field(points,operator::LinearCombinationOfOperators,coeffs,basis) - out = [] - for (coeff,op) in zip(operator.coeffs,operator.ops) - push!(out,coeff*_calculate_field(points,op,coeffs,basis)) - end - return sum(out) -end -function _calculate_field(points,operator::ComposedOperator,coeffs,basis) - x = potential(operator,points,coeffs,basis) - - return Field(x) -end -function _calculate_field(points,operator::ZeroOperator,coeffs,basis) - return Field(nothing) -end - -#### complement error -function complement_error(world,solution,volume::Vector{Int},strat::T;trace=true) where {T} - @warn "exclude free space!!!" - newstrat = T(-strat.trace) - - lhs = discretise_lhs(world,newstrat;id=0.0,dual=false,trace=trace) - out = lhs[volume].*Ref(solution) - g = BlockDiagonalOperator(BlockDiagonalOperator(Identity())) - G = assemble(g,world.testdirectproductspace,world.testdirectproductspace) - G2 = assemble(g,world.trialdirectproductspace,world.trialdirectproductspace) - println("started inversion") - ttt = Ref(G).\Vector.(out) - println("G inverted") - return dot.(Vector.(out),ttt)/dot(solution,G2,solution),ttt,out,G,dot(solution,G2,solution) - # norm(sum(out))/norm(solution) -end - -# x'Zxa = x'xb => b andere volgorde dan a, x' is testvector, x is trialvector --> zelfde doordat b andere volgorde heeft. -# (G-1) Z a = b , integreer b, dit geeft: b xx b -# finaal resultaat, ttt (G-1) ttt, componenten in volgorde van b, \ No newline at end of file diff --git a/src/multi-trace/test_multi-trace_VP.jl b/src/multi-trace/test_multi-trace_VP.jl deleted file mode 100644 index eea76676..00000000 --- a/src/multi-trace/test_multi-trace_VP.jl +++ /dev/null @@ -1,121 +0,0 @@ -using BEAST -using CompScienceMeshes -using BlockArrays -using LinearAlgebra -# import Plots - -radius = 1.0 -hh=0.15 -ϵ0 = 8.854e-12 -μ0 = 4π*1e-7 -ϵr = 2.0 -μr = 3.0 -c = 1/√(ϵ0*μ0) -λ = 2.9979563769321627 -ω = 2π*c/λ - -k0 = ω*sqrt(ϵ0*μ0) -T = boundary(CompScienceMeshes.tetmeshsphere(radius,hh)) - -S = BEAST.HOM(T,ϵ0*ϵr,μ0*μr,ω) -F = BEAST.FreeSpace(ϵ0,μ0,ω) -world = BEAST.create_world([2,0],[S,F]) -strat = BEAST.VP() -BEAST.assign_basis!(world,strat) - -lhs = BEAST.discretise_lhs(world,strat) - -A(x) = [1.0,0.0,0.0]*1im/ω*exp(-1.0im*k0*x[3]) -∇xA(x) = [0.0,1.0,0.0]*k0/ω*exp(-1.0im*k0*x[3]) -∇A(x) = 0.0+0.0im - -ex = BEAST.VPExcitation(A,∇xA,∇A,[2]) -rhs = BEAST.discretise_rhs(world,ex,strat) - -t =lhs[1]+lhs[2] -u = BEAST.gmres_ch(rhs[1]+rhs[2],t,world.trialdirectproductspace) - -Bf = BEAST.BField(world,u[1],[1,2]) -nx, nz = 100, 100 -xs, zs = range(-4,stop=4,length=nx), range(-6,stop=6,length=nz) -pts = [point(0,x,z) for x in xs, z in zs] - -BField = BEAST.calculate_field(pts,Bf,strat) -# display(Plots.heatmap(xs, zs, real.(getindex.(BField.field,2).+getindex.(∇xA.(pts),2)),show=true)) -# display(Plots.heatmap(xs, zs, imag.(getindex.(BField.field,2).+getindex.(∇xA.(pts),2)),show=true)) - - - - - - -function nearfield(um,uj,Xm,Xj,κ,η,points, - Einc=(x->point(0,0,0)), - Hinc=(x->point(0,0,0))) - - K = BEAST.MWDoubleLayerField3D(wavenumber=κ) - T = BEAST.MWSingleLayerField3D(wavenumber=κ) - - Em = potential(K, points, um, Xm) - Ej = potential(T, points, uj, Xj) - E = -Em + η * Ej + Einc.(points) - - Hm = potential(T, points, um, Xm) - Hj = potential(K, points, uj, Xj) - H = 1/η*Hm + Hj + Hinc.(points) - - return E, H -end - - - -X = raviartthomas(T) - -κ, η = ω/c, √(μ0/ϵ0) -κ′, η′ = κ*√(ϵr*μr), η*√(μr/ϵr) - -T = Maxwell3D.singlelayer(wavenumber=κ) -T′ = Maxwell3D.singlelayer(wavenumber=κ′) -K = Maxwell3D.doublelayer(wavenumber=κ) -K′ = Maxwell3D.doublelayer(wavenumber=κ′) - -E = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=κ) -H = -1/(im*κ*η)*curl(E) - -e = (n × E) × n -h = (n × H) × n - -@hilbertspace j m -@hilbertspace k l - -α, α′ = 1/η, 1/η′ -pmchwt = @discretise( - (η*T+η′*T′)[k,j] - (K+K′)[k,m] + - (K+K′)[l,j] + (α*T+α′*T′)[l,m] == -e[k] - h[l], - j∈X, m∈X, k∈X, l∈X) - -uu = solve(pmchwt) - -import Base.Threads: @spawn -task1 = @spawn nearfield(uu[m],uu[j],X,X,κ,η,pts,E,H) -task2 = @spawn nearfield(-uu[m],-uu[j],X,X,κ′,η′,pts) - -E_ex, H_ex = fetch(task1) -E_in, H_in = fetch(task2) - -B_tot = H_in*μ0*μr + H_ex*μ0 - -# display(Plots.heatmap(xs, zs, real.(getindex.(B_tot,2)))) -# display(Plots.heatmap(xs, zs, imag.(getindex.(B_tot,2)))) - -# maximum(norm.(B_tot-BField.field-∇xA.(pts))./norm.(B_tot)) - -# display(Plots.heatmap(xs,zs,norm.(B_tot-BField.field-∇xA.(pts))./maximum(norm.(B_tot)))) -# display(Plots.heatmap(xs,zs,norm.(B_tot))) - -# import PlotlyJS - -# PlotlyJS.plot(PlotlyJS.heatmap(x=xs,y=zs,z=norm.(B_tot))) - -# old = 0.008153372950474812 -@test norm.(B_tot-BField.field-∇xA.(pts)))/sum(norm.(B_tot) < 0.01 \ No newline at end of file From a6aa7b756046fbeda0629f1039f2e6f911bcdccf Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Mar 2024 14:34:21 +0100 Subject: [PATCH 098/110] update --- Project.toml | 1 + examples/pmchwt.jl | 13 +- examples/vppmchwt.jl | 273 ----------------- src/BEAST.jl | 11 - src/bases/basis.jl | 6 - src/bases/local/laglocal.jl | 20 +- src/bases/local/rtlocal.jl | 1 - src/composedoperator/composedoperator.jl | 368 +++-------------------- src/excitation.jl | 17 ++ src/integralop.jl | 44 +-- src/localop.jl | 109 +------ src/operator.jl | 22 -- src/quadrature/sauterschwabints.jl | 29 -- src/solvers/solver.jl | 28 -- src/utils/variational.jl | 12 +- test/runtests.jl | 2 - test/test_basis.jl | 1 - test/test_multi-trace_VP.jl | 121 -------- 18 files changed, 90 insertions(+), 988 deletions(-) delete mode 100644 test/test_multi-trace_VP.jl diff --git a/Project.toml b/Project.toml index 3e74ddb1..cea50799 100644 --- a/Project.toml +++ b/Project.toml @@ -25,6 +25,7 @@ NestedUnitRanges = "032820ab-dc03-4b49-91f4-7d58d4da98b3" Plotly = "58dd65bb-95f3-509e-9936-c39a10fdeae7" PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" Requires = "ae029012-a4dd-5104-9daa-d747884805df" Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" diff --git a/examples/pmchwt.jl b/examples/pmchwt.jl index 721e1ba6..defc8538 100644 --- a/examples/pmchwt.jl +++ b/examples/pmchwt.jl @@ -20,7 +20,14 @@ function nearfield(um,uj,Xm,Xj,κ,η,points, return E, H end +ϵ0 = 8.854e-12 +μ0 = 4π*1e-7 +c = 1/√(ϵ0*μ0) +λ = 2.9979563769321627 +ω = 2π*c/λ + +Ω = CompScienceMeshes.tetmeshsphere(λ,0.1*λ) Ω = CompScienceMeshes.tetmeshsphere(λ,0.3*λ) Γ = boundary(Ω) X = raviartthomas(Γ) @@ -93,7 +100,7 @@ Plotly.plot(patch(Γ, norm.(fcrm))) Z = range(-6,6,length=200) Y = range(-4,4,length=200) -nfpoints = [point(0,y,z) for y in Y, z in Z] +nfpoints = [point(0,y,z) for z in Z, y in Y] import Base.Threads: @spawn task1 = @spawn nearfield(u[m],u[j],X,X,κ,η,nfpoints,E,H) @@ -110,8 +117,8 @@ Plots.contour(real.(getindex.(H_tot,2))) Plots.heatmap(Z, Y, clamp.(real.(getindex.(E_tot,1)),-1.5,1.5)) Plots.heatmap(Z, Y, clamp.(imag.(getindex.(E_tot,1)),-1.5,1.5)) -display(Plots.heatmap(Y, Z, real.(getindex.(H_tot,2)))) -display(Plots.heatmap(Y, Z, imag.(getindex.(H_tot,2)))) +Plots.heatmap(Z, Y, real.(getindex.(H_tot,2))) +Plots.heatmap(Z, Y, imag.(getindex.(H_tot,2))) Plots.plot(real.(getindex.(E_tot[:,51],1))) Plots.plot(real.(getindex.(H_tot[:,51],2))) \ No newline at end of file diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl index cc3eddd0..a35b730b 100644 --- a/examples/vppmchwt.jl +++ b/examples/vppmchwt.jl @@ -338,276 +338,3 @@ save_itterZ && (out[:itter_Z] = uz[2]) -# ##### nearfield -# using BlockArrays -# function nearfield_B(u,X,κ,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume -# G = BEAST.greenhh3d(wavenumber=κ) -# gradG = BEAST.∇(G) -# ∇Gx = gradG×B -# Gn = G*(nb*B) -# #Gnx = G*(n × B) -# ∇G = gradG*B -# ∇Gdotn = nb ⋅ (gradG*B) -# ∇Gdot = B ⋅ gradG - -# Gr = G*B -# ∇G∇B = gradG*BEAST.div(B) -# ∇Gxn = gradG×(nb*B) - - -# if HOM -# @hilbertspace T D R N -# Bb = -Q[1,1]*potential(∇G∇B, points, u[T], X.factors[1])-Q[1,1]*κ^2* potential(Gr, points, u[T], X.factors[1]) -# Bb .+= Q[2,2]*potential(∇Gxn, points, u[D], X.factors[2]) -# Bb .+= -Q[3,3]*potential(∇Gx, points, u[R], X.factors[3]) - -# else -# @hilbertspace R N -# Bb = -potential(∇Gx, points, u[R], X.factors[1]) - -# end - -# return sign*Bb -# end - -# function nearfield_A(u,X,κ,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume -# G = BEAST.greenhh3d(wavenumber=κ) -# gradG = BEAST.∇(G) -# ∇Gx = gradG×B -# Gn = G*(nb*B) -# #Gnx = G*(n × B) -# ∇G = gradG*B -# ∇Gdotn = nb ⋅ (gradG*B) -# ∇Gdot = B ⋅ gradG - -# Gr = G*B -# ∇G∇B = gradG*BEAST.div(B) -# ∇Gxn = gradG×(nb*B) - - -# if HOM -# @hilbertspace T D R N -# A = -Q[1,1]*potential(∇Gx, points, u[T], X.factors[1]) -# A .+= Q[2,2]*potential(Gn, points, u[D], X.factors[2]) -# A .+= -Q[3,3]*potential(Gr, points, u[R], X.factors[3]) -# A .+= Q[4,4]*potential(∇G, points, u[N], X.factors[4]) -# else -# @hilbertspace R N -# A = -potential(Gr, points, u[R], X.factors[1]) -# A .+= potential(∇G, points, u[N], X.factors[2]) -# end - -# return sign*A -# end -# function nearfield_phi(u,X,κ,ω,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume -# G = BEAST.greenhh3d(wavenumber=κ) -# gradG = BEAST.∇(G) -# ∇Gx = gradG×B -# Gn = G*(nb*B) -# #Gnx = G*(n × B) -# ∇G = gradG*B -# ∇Gdotn = nb ⋅ (gradG*B) -# ∇Gdot = B ⋅ gradG - -# Gr = G*B -# ∇G∇B = gradG*BEAST.div(B) -# ∇Gxn = gradG×(nb*B) - - -# if HOM -# @hilbertspace T D R N -# A = Q[2,2]*potential(∇Gdotn, points, u[D], X.factors[2]) -# A .+= -Q[3,3]*potential(∇Gdot, points, u[R], X.factors[3]) -# A .+= -κ^2* Q[4,4]*potential(Gr, points, u[N], X.factors[4]) -# else -# @hilbertspace R N -# A = -potential(∇Gdot, points, u[R], X.factors[1]) -# A .+= -κ^2* potential(Gr, points, u[N], X.factors[2]) -# end - -# return sign*A/κ^2*im*ω -# end -# function nearfield_E(u,X,κ,ω,points;sign=1,HOM=true,Q=diagm([1.0,1.0,1.0,1.0]))#nearfield of single volume -# G = BEAST.greenhh3d(wavenumber=κ) -# gradG = BEAST.∇(G) -# graddivG = BEAST.graddiv(G) -# ∇Gx = gradG×B -# Gn = G*(nb*B) -# #Gnx = G*(n × B) -# ∇G = gradG*B -# ∇Gdotn = nb ⋅ (gradG*B) -# graddivGdotn = graddivG*(nb*B) -# graddivGdot = graddivG*B -# ∇Gdot = B ⋅ gradG - -# Gr = G*B -# ∇G∇B = gradG*BEAST.div(B) -# ∇Gxn = gradG×(nb*B) - - -# if HOM -# @hilbertspace T D R N -# p = Q[2,2]*potential(graddivGdotn, points, u[D], X.factors[2]) -# p .+= -Q[3,3]*potential(graddivGdot, points, u[R], X.factors[3]) -# p .+= -κ^2* Q[4,4]*potential(∇G, points, u[N], X.factors[4]) -# else -# @hilbertspace R N -# p = -potential(graddivGdot, points, u[R], X.factors[1]) -# p .+= -κ^2* potential(∇G, points, u[N], X.factors[2]) -# end -# if HOM -# @hilbertspace T D R N -# A = -Q[1,1]*potential(∇Gx, points, u[T], X.factors[1]) -# A .+= Q[2,2]*potential(Gn, points, u[D], X.factors[2]) -# A .+= -Q[3,3]*potential(Gr, points, u[R], X.factors[3]) -# A .+= Q[4,4]*potential(∇G, points, u[N], X.factors[4]) -# else -# @hilbertspace R N -# A = -potential(Gr, points, u[R], X.factors[1]) -# A .+= potential(∇G, points, u[N], X.factors[2]) -# end -# return -sign*p/κ^2*im*ω-sign*im*ω*A -# end -# Xs = range(-2.0,2.0,length=150) -# Zs = range(-1.5,2.5,length=100) -# pts = [point(x,0.5,z) for z in Zs, x in Xs] - -# A1 = [nearfield_A(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] -# A2 = [nearfield_A(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] -# A3 = [nearfield_A(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -# Atot = sum(A1)+sum(A2)+sum(A3)-A.(pts) - -# B1 = [nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] -# B2 = [nearfield_B(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] -# B3 = [nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -# Btot = sum(B1)+sum(B2)+sum(B3)-curlA.(pts) - -# H1 = [1/HomPars[parent(i,Tree)][2]*nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts) for i in HOM] -# H2 = [1/HomPars[i][2]*nearfield_B(u[Block(i)],X[i],κ[i],pts;sign=-1,Q=Q[i]^-1) for i in HOM] -# H3 = [1/HomPars[parent(i,Tree)][2]*nearfield_B(u[Block(i)],X[i],κ[parent(i,Tree)],pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -# Htot = sum(H1)+sum(H2)+sum(H3)-1/μ0*curlA.(pts) - -# E1 = [nearfield_E(u[Block(i)],X[i],κ[parent(i,Tree)],ω,pts) for i in HOM] -# E2 = [nearfield_E(u[Block(i)],X[i],κ[i],ω,pts;sign=-1,Q=Q[i]^-1) for i in HOM] -# E3 = [nearfield_E(u[Block(i)],X[i],κ[parent(i,Tree)],ω,pts;HOM=false) for i in [EFIE...,MFIE...,CFIE...]] -# Etot = sum(E1)+sum(E2)+sum(E3)-(-im*ω*A.(pts)-graddivA.(pts)/κ0^2*im*ω) - -# ##### complement error, different from aps paper, traces from inside are compared, for the reset same formula as in aps paper, for pec all are treated with mfie, as efie yields zero traces in denominator. - - -# ### to generate plot -# using Plots -# using LaTeXStrings -# using ColorSchemes -# p1 = Plots.heatmap(Xs, Zs, (real.(getindex.(Htot,2)))*1000,clim=(-0.01001*1000,0.01*1000),show=true, - -# xlabel="z-axis [m]", -# ylabel="x-axis [m]", -# colorbar_title=" \nHy [mA/m]", -# c= :PuBu, -# right_margin = 7Plots.mm) -# rectangle(w, h, x, y) = Plots.Shape(x .+ [0,w,w,0], y .+ [0,0,h,h]) -# # plot!(rectangle(1,1,0,0),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4) -# # plot!(rectangle(1,1,-1,0),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4) -# # plot!(rectangle(1,1,0,-1),fillcolor=plot_color(nothing),linecolor=:black,linewidth=4,legend=false) -# # annotate!(-0.5,0.5,"Ω₃", :black) -# # annotate!(0.5,0.5,"Ω₁", :black) -# # annotate!(0.5,-0.5,"Ω₂", :black) -# display(plot!( -# xtickfont=font(11), -# ytickfont=font(11), -# xguidefontsize=12, -# yguidefontsize=13, -# colorbar_titlefontsize=13 -# )) -# #savefig("Hfield.pdf") - - - -# ##### define equation -# ceqs2hom = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -sum(BEAST.BilForm[Z(κ0;cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xin_notdual[t[ci]] -# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end -# # ceqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# # -sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xind_notdual[t[ci]] -# # for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end -# ceqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==-Xinn_notdual[t[ci]] -# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ [MFIE...,EFIE...]]end -# # ceqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# # -α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == -# # -α[ci]*Xind_notdual[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -# ceqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Z(κ0;rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == -(1-α[ci])*Xinn_notdual[t[ci]] -# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end - -# # deqs2hom = BEAST.discretise(eqs2hom, (t.∈X),(b.∈X)) -# # deqs2efie = BEAST.discretise(eqs2efie, (t.∈X),(b.∈X)) -# # deqs2mfie = BEAST.discretise(eqs2mfie, (t.∈Y),(b.∈X)) -# # deqs2cefie = BEAST.discretise(eqs2cefie, (t.∈X),(b.∈X)) -# # deqs2cmfie = BEAST.discretise(eqs2cmfie, (t.∈Y),(b.∈X)) - - -# ##### define equation -# ceqs3hom = begin BEAST.Equation[(Z(κ[i];tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ -# -sum(BEAST.BilForm[Z(κ[i];tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -sum(BEAST.BilForm[Z(κ[i];cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 -# for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ HOM] end -# # ceqs3efie = begin BEAST.Equation[(Z(κ[i];rows=[3,4],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ -# # -sum(BEAST.BilForm[Z(κ[i];rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# # -sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 -# # for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end -# ceqs3mfie = begin BEAST.Equation[(Z(κ[i];rows=[1,2],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ -# -sum(BEAST.BilForm[Z(κ[i];rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 -# for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ [MFIE...,EFIE...]]end -# # ceqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[3,4],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ -# # -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# # -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[3,4],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) ==0 -# # for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end -# ceqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Z(κ[i];rows=[1,2],tr=-1,dual=false)*(Q[i]^-1))[t[ci],b[i]]+ -# -(1-α[ci])* sum(BEAST.BilForm[Z(κ[i];rows=[1,2],tr=-1,dual=false)[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -# -(1-α[ci])*sum(BEAST.BilForm[Z(κ[i];rows=[1,2],cols=[3,4],tr=-1,dual=false)[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == 0 -# for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end - - - -# ceq = sum(ceqs2hom)+sum(ceqs3hom) -# cmeq = sum(ceqs2cmfie)+sum(ceqs2mfie)+sum(ceqs3cmfie)+sum(ceqs3mfie) - -# Dseq = BEAST.discretise(ceq+cmeq, (t.∈X)..., (b.∈X)...) - -# F,bsa,_,_ = assemble(Dseq) - -# using NestedUnitRanges - -# ax = nestedrange(BEAST.DirectProductSpace(X), 1,numfunctions) -# u_error = PseudoBlockVector(F*u-bsa, (ax,)) -# #select in u_error en in u - -# function select_trace(u,trace_ind) -# usub = 0*deepcopy(u) -# N = length(blocks(u)) -# println(N) -# for i in 1:N -# if i ∈ HOM - -# usub2 = deepcopy(usub[Block(i)]) -# usub2[Block(trace_ind)] .+= u[Block(i)][Block(trace_ind)] -# usub[Block(i)] .+= usub2 -# elseif i∈ [EFIE...,MFIE...,CFIE...] && trace_ind ∈ [3,4] -# println("pec") -# usub2 = deepcopy(usub[Block(i)]) -# usub2[Block(trace_ind-2)] .+= u[Block(i)][Block(trace_ind-2)] -# usub[Block(i)] .+= usub2 -# end -# end -# return usub -# end - -# Gsym = assemble(BEAST.diag(BEAST.diag(Identity())),BEAST.DirectProductSpace(X),BEAST.DirectProductSpace(X)) -# Ginvsym = inv(Matrix(Gsym)) - -# nom = sqrt.([Array(select_trace(u_error,i))'*Ginvsym*Array(select_trace(u_error,i)) for i in 1:4]) -# denom = sqrt.([Array(select_trace(u,i))'*Matrix(Gsym)*Array(select_trace(u,i)) for i in 1:4]) -# error = 1/4*sum(nom./denom)* \ No newline at end of file diff --git a/src/BEAST.jl b/src/BEAST.jl index 3b87d68c..aa480dcd 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -264,17 +264,6 @@ include("utils/plotlyglue.jl") include("composedoperator/tracesimplex.jl") include("composedoperator/composedoperator.jl") -# include("composedoperator/postprocessing.jl") - -# include("multi-trace/interactions.jl") -# include("multi-trace/postprocessing.jl") -# include("multi-trace/VectorPotential.jl") - - -# include("multi-trace/multi-trace-old/interactions.jl") -# include("multi-trace/multi-trace-old/configuration.jl") - -# include("multi-trace/multi-trace-old/postprocessing.jl") const x̂ = point(1, 0, 0) const ŷ = point(0, 1, 0) diff --git a/src/bases/basis.jl b/src/bases/basis.jl index ba5ede60..d8f67f9f 100644 --- a/src/bases/basis.jl +++ b/src/bases/basis.jl @@ -2,10 +2,6 @@ abstract type RefSpace{T,D} end abstract type AbstractSpace end abstract type Space{T} <: AbstractSpace end -# struct EmptySpace{Nothing} <: Space{Nothing} end -# numfunctions(::EmptySpace) = 0 - - Base.length(s::AbstractSpace) = numfunctions(s) Base.in(x, s::AbstractSpace) = (x => s) @@ -88,10 +84,8 @@ function Base.:+(x::AbstractSpace...) T = scalartype(x...) return DirectProductSpace{T, AbstractSpace}([x...]) end -#cross(a::Nothing,b::AbstractSpace) = b cross(a::Space{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}(Space{T}[a,b]) cross(a::DirectProductSpace{T}, b::Space{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b]) -#cross(a::DirectProductSpace{T}, b::DirectProductSpace{T}) where {T} = DirectProductSpace{T,Space{T}}([a.factors; b.factors]) numfunctions(S::DirectProductSpace) = sum([numfunctions(s) for s in S.factors]) Base.length(S::DirectProductSpace) = numfunctions(S) scalartype(s::DirectProductSpace{T}) where {T} = T diff --git a/src/bases/local/laglocal.jl b/src/bases/local/laglocal.jl index 9a019379..56089dfc 100644 --- a/src/bases/local/laglocal.jl +++ b/src/bases/local/laglocal.jl @@ -81,7 +81,6 @@ function gradient(ref::LagrangeRefSpace{T,1,4}, sh, tet) where {T} opp_face = faces(tet)[sh.refid] ctr_opp_face = center(opp_face) n = normal(ctr_opp_face) - # n = normalize(tangents(ctr_opp_face,1)×tangents(ctr_opp_face,2)) h = -dot(this_vert - cartesian(ctr_opp_face), n) @assert h > 0 gradval = -(1/h)*n @@ -172,6 +171,7 @@ end ## Quadratic Lagrange element on a triangle function (f::LagrangeRefSpace{T,2,3})(t) where T + u,v,w, = barycentric(t) j = jacobian(t) p = t.patch @@ -192,18 +192,18 @@ end # function (f::LagrangeRefSpace{T,2,3})(t, ::Type{Val{:withcurl}}) where T # # Evaluete quadratic Lagrange elements on a triange, together with their curl -# tu = tangents(t,1) -# tv = tangents(t,2) -# j = jacobian(t)*sign(dot(normal(t),tu×tv)) +# j = jacobian(t) # u,v,w, = barycentric(t) # p = t.patch + +# σ = sign(dot(normal(t), cross(p[1]-p[3],p[2]-p[3]))) # SVector( -# (value=u*(2*u-1), curl=(p[3]-p[2])*(4u-1)/j), -# (value=v*(2*v-1), curl=(p[1]-p[3])*(4v-1)/j), -# (value=w*(2*w-1), curl=(p[2]-p[1])*(4w-1)/j), -# (value=4*v*w, curl=4*(w*(p[1]-p[3])+v*(p[2]-p[1]))/j), -# (value=4*w*u, curl=4*(w*(p[3]-p[2])+u*(p[2]-p[1]))/j), -# (value=4*u*v, curl=4*(u*(p[1]-p[3])+v*(p[3]-p[2]))/j), +# (value=u*(2*u-1), curl=σ*(p[3]-p[2])*(4u-1)/j), +# (value=v*(2*v-1), curl=σ*(p[1]-p[3])*(4v-1)/j), +# (value=w*(2*w-1), curl=σ*(p[2]-p[1])*(4w-1)/j), +# (value=4*v*w, curl=4*σ*(w*(p[1]-p[3])+v*(p[2]-p[1]))/j), +# (value=4*w*u, curl=4*σ*(w*(p[3]-p[2])+u*(p[2]-p[1]))/j), +# (value=4*u*v, curl=4*σ*(u*(p[1]-p[3])+v*(p[3]-p[2]))/j), # ) # end diff --git a/src/bases/local/rtlocal.jl b/src/bases/local/rtlocal.jl index 53b8433b..ecba697b 100644 --- a/src/bases/local/rtlocal.jl +++ b/src/bases/local/rtlocal.jl @@ -65,7 +65,6 @@ function restrict(ϕ::RTRefSpace{T}, dom1, dom2) where T t = b - a l = norm(t) n = normal(dom2) - #n = normalize(tangents(dom2,1)×tangents(dom2,2)) m = cross(t, n) / l u = carttobary(dom1, c) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index bcfe7baf..aeeba267 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -27,16 +27,13 @@ export nt export nb struct Potential{T} <: AbstractOperator operator::T - # surface::M end -#Potential(a) = Potential(a,nothing) -#surface(p::Potential) = p.surface -function Potential(linop::LinearCombinationOfOperators)#,surface::TraceMesh) +function Potential(linop::LinearCombinationOfOperators) out = ZeroOperator() for (op,coeff) in zip(linop.ops,linop.coeffs) - out += coeff*Potential(op)#,surface) + out += coeff*Potential(op) end return out end @@ -52,13 +49,7 @@ function TraceOperator(linop::LinearCombinationOfOperators,direction::Int) end return out end -# function TraceOperator(linop::LinearCombinationOfOperators) -# out = ZeroOperator() -# for (op,coeff) in zip(linop.ops,linop.coeffs) -# out += coeff*TraceOperator(op) -# end -# return out -# end + direction(p::TraceOperator) = p.direction struct TimesLocal{U,V} <: ComposedOperatorLocal @@ -174,19 +165,6 @@ scalartype(op::Operations) = promote_type(scalartype(op.lhs),scalartype(op.rhs)) scalartype(op::Potential) = scalartype(op.operator) scalartype(op::TraceOperator) = scalartype(op.operator) -# function count_test_normals(op::Operations) -# count_test_normals(op.lhs) + count_test_normals(op.rhs) -# end -# count_test_normals(op::Kernel) = 0 -# count_test_normals(op::TestNormal) = 1 -# count_test_normals(op::TrialNormal) = 0 - -# function count_trial_normals(op::Operations) -# count_trial_normals(op.lhs) + count_trial_normals(op.rhs) -# end -# count_trial_normals(op::Kernel) = 0 -# count_trial_normals(op::TestNormal) = 0 -# count_trial_normals(op::TrialNormal) = 1 function replace_normal_by_testnormal(op::Operations) get_constructor(op)(replace_normal_by_testnormal(op.lhs),replace_normal_by_testnormal(op.rhs)) @@ -204,18 +182,7 @@ replace_normal_by_trialnormal(op::NormalVector) = TrialNormal() -# function build_potential(op::ComposedOperator,surface::CompScienceMeshes.AbstractMesh) -# newop = replace_normal_by_trialnormal(op) -# Potential(newop,TraceMesh(surface)) -# end -# function build_potential(op::ComposedOperator,surface::TraceMesh) -# newop = replace_normal_by_trialnormal(op) -# Potential(newop,surface) -# end -# function build_potential(op::ComposedOperator) -# newop = replace_normal_by_trialnormal(op) -# Potential(newop,nothing) -# end + function build_potential(op::ComposedOperator,surface::CompScienceMeshes.AbstractMesh) newop = replace_normal_by_trialnormal(op) Potential(newop) @@ -235,146 +202,43 @@ end γ(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction}) = op -# function check_if_coincide(a,b) -# @warn "all meshes coincide" -# return true -# end - - -# function γₜ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = nt × (γ(op.operator) × nt) -# return TraceOperator(Potential(newop,op.surface),sign) -# end -# function γₛ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = nt × γ(op.operator) -# return TraceOperator(Potential(newop,op.surface),sign) -# end -# function γₙ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = nt ⋅ γ(op.operator) -# return TraceOperator(Potential(newop,op.surface),sign) -# end -# function τ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = γ(op.operator) -# return TraceOperator(Potential(newop,op.surface),sign) -# end -function γₜ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise - # check_if_coincide(op.surface,surface) || return op.operator - newop = nt × (γ(op.operator) × nt) - return TraceOperator(Potential(newop),sign) - end - function γₛ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise - # check_if_coincide(op.surface,surface) || return op.operator - newop = nt × γ(op.operator) - return TraceOperator(Potential(newop),sign) - end - function γₙ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise - # check_if_coincide(op.surface,surface) || return op.operator - newop = nt ⋅ γ(op.operator) - return TraceOperator(Potential(newop),sign) - end - function τ(op::Potential,sign::Int)# sign + if according to normal on surface, - otherwise - # check_if_coincide(op.surface,surface) || return op.operator - newop = γ(op.operator) - return TraceOperator(Potential(newop),sign) - end -# function γ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = nt × (γ(op.operator) × nt) -# # direction = [] -# # for i in 1:numcells(surface) -# # c = chart(surface,i) -# # push!(direction,sign*normal(c)/3) -# # end -# charts = chart.(Ref(surface),1:numcells(surface)) -# direction = sign/3*normal.(charts) -# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) -# end - -# # function γ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# # # check_if_coincide(op.surface,surface) || return op.operator -# # newop = nt × (γ(op.operator) × nt) -# # direction = [] -# # for i in 1:numcells(surface) -# # c = chart(surface,i) -# # push!(direction,sign*normal(c)/3) -# # end -# # return TraceOperator(Potential(newop,op.surface),SVector{length(direction),typeof(direction[1])}(direction)+surface) -# # end - - -# function γₛ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = nt × γ(op.operator) -# # direction = [] -# # for i in 1:numcells(surface) -# # c = chart(surface,i) -# # push!(direction,sign*normal(c)/3) -# # end -# charts = chart.(Ref(surface),1:numcells(surface)) -# direction = sign/3*normal.(charts) -# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) -# end -# # function γₛ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# # # check_if_coincide(op.surface,surface) || return op.operator -# # newop = nt × γ(op.operator) -# # # direction = [] -# # # for i in 1:numcells(surface) -# # # c = chart(surface,i) -# # # push!(direction,sign*normal(c)/3) -# # # end -# # charts = chart.(Ref(surface),1:numcells(surface)) -# # direction = sign/3*normal.(charts) -# # return TraceOperator(Potential(newop,op.surface),direction+surface) -# # end - -# function γₜ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = (nt × γ(op.operator)) × nt -# charts = chart.(Ref(surface),1:numcells(surface)) -# direction = sign/3*normal.(charts) -# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) -# end -# # function γₜ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# # # check_if_coincide(op.surface,surface) || return op.operator -# # newop = (nt × γ(op.operator)) × nt -# # charts = chart.(Ref(surface),1:numcells(surface)) -# # direction = sign/3*normal.(charts) -# # return TraceOperator(Potential(newop,op.surface),direction+surface) -# # end - -# function γₙ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = nt ⋅ γ(op.operator) -# charts = chart.(Ref(surface),1:numcells(surface)) -# direction = sign/3*normal.(charts) -# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) -# end -# # function γₙ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# # # check_if_coincide(op.surface,surface) || return op.operator -# # newop = nt ⋅ γ(op.operator) -# # charts = chart.(Ref(surface),1:numcells(surface)) -# # direction = sign/3*normal.(charts) -# # return TraceOperator(Potential(newop,op.surface),direction+surface) -# # end - -# function τ(op::Potential,surface::CompScienceMeshes.AbstractMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# # check_if_coincide(op.surface,surface) || return op.operator -# newop = γ(op.operator) -# charts = chart.(Ref(surface),1:numcells(surface)) -# direction = sign/3*normal.(charts) -# return TraceOperator(Potential(newop,op.surface),TraceMesh(surface,direction)) -# end -# # function τ(op::Potential,surface::TraceMesh,sign::Int)# sign + if according to normal on surface, - otherwise -# # # check_if_coincide(op.surface,surface) || return op.operator -# # newop = γ(op.operator) -# # charts = chart.(Ref(surface),1:numcells(surface)) -# # direction = sign/3*normal.(charts) -# # return TraceOperator(Potential(newop,op.surface),direction+surface) -# # end + +""" + function γₜ(potential,sign) + tangential trace: n×(operator×n) + sign is -1 for trace according to the normal ("from the inside") or 1 for trace opposite to normal ("from the outside") +""" +function γₜ(op::Potential,sign::Int) + newop = nt × (γ(op.operator) × nt) + return TraceOperator(Potential(newop),sign) +end +""" + function γₛ(potential,sign) + rotated trace: n×operator + sign is -1 for trace according to the normal ("from the inside") or 1 for trace opposite to normal ("from the outside") +""" +function γₛ(op::Potential,sign::Int) + newop = nt × γ(op.operator) + return TraceOperator(Potential(newop),sign) +end +""" + function γₙ(potential,sign) + normal trace: n×operator + sign is -1 for trace according to the normal ("from the inside") or 1 for trace opposite to normal ("from the outside") +""" +function γₙ(op::Potential,sign::Int) + newop = nt ⋅ γ(op.operator) + return TraceOperator(Potential(newop),sign) +end +""" + function τ(potential,sign) + scallar trace: operator + sign is -1 for trace according to the normal ("from the inside") or 1 for trace opposite to normal ("from the outside") +""" +function τ(op::Potential,sign::Int) + newop = γ(op.operator) + return TraceOperator(Potential(newop),sign) +end export γₛ, γₜ, γₙ, γ, τ #### Define kernel functions below @@ -450,9 +314,7 @@ function (op::GradDivGreenHH3D)(x::Union{SVector,Vector},y,g) df = (3*iR^2-gamma*iR+gamma^2)*green*iR Ref(df*(r*r')+f*I) end -# gamma(op::ComposedOperations) = gamma(op.rhs)+gamma(op.lhs) -# gamma(op::ComposedValues) = 0 -# gamma(op::Union{GreenHH3D,GradGreenHH3D,GradDivGreenHH3D}) = op.gamma + function (op::GradGreenHH3D)(x,y,g) gamma = op.gamma @@ -461,11 +323,7 @@ function (op::GradGreenHH3D)(x,y,g) iR = 1/R green = exp(-gamma*R)*(iR*i4pi) gradgreen = -(gamma + iR) * green * (iR * r) - # tt = Ref(gradgreen) - # if maximum(abs.(gradgreen)) === NaN - # display(R) - # end return Ref(gradgreen) end function (op::GradGreenHH3D)(x::Union{SVector,Vector},y,g) @@ -478,9 +336,6 @@ function (op::GradGreenHH3D)(x::Union{SVector,Vector},y,g) gradgreen = -(gamma + iR) * green * (iR * r) tt = Ref(gradgreen) - # if maximum(abs.(gradgreen)) === NaN - # display(R) - # end return tt end @@ -555,48 +410,6 @@ function integrand(op::ComposedOperator,kernel, y, f, x) return r end -# function ex(op::Type{TimesIntegral{U,V}}) where{U,V} -# lhs = ex(U) -# rhs = ex(V) -# return :($lhs.*$rhs) -# end -# function ex(op::Type{TimesLocal{U,V}}) where{U,V} -# lhs = ex(U) -# rhs = ex(V) -# return :($lhs.*$rhs) -# end -# function ex(op::Type{CrossIntegral{U,V}}) where{U,V} -# lhs = ex(U) -# rhs = ex(V) -# return :(cross.($lhs,$rhs)) -# end -# function ex(op::Type{CrossLocal{U,V}}) where{U,V} -# lhs = ex(U) -# rhs = ex(V) -# return :(cross.($lhs,$rhs)) -# end -# function ex(op::Type{DotIntegral{U,V}}) where{U,V} -# lhs = ex(U) -# rhs = ex(V) -# return :(transpose.($lhs).*$rhs) -# end -# function ex(op::Type{DotLocal{U,V}}) where{U,V} -# lhs = ex(U) -# rhs = ex(V) -# return :(transpose.($lhs).*$rhs) -# end -# ex(op::Type{TestNormal}) = :(Ref(normal(x))) -# ex(op::Type{TrialNormal}) = :(Ref(normal(y))) -# ex(op::Type{TraceDirection}) = :(Ref(approx_sign(dot(normal(x),(direction(y)-direction(x))))*normal(x))) -# ex(op::Type{BasisFunction}) = :(getvalue(g)) -# ex(op::Type{DivBasisFunction}) = :(getdivergence(g)) - - -# @generated function integrand(igd::ComposedOperator,kernel,x,y,f,g) -# exp = ex(igd) -# out = quote _krondot(getvalue(f),$exp) end -# return out -# end kernelvals(op::ComposedOperatorLocal,x) = nothing kernelvals(op::ComposedOperatorIntegral, y,x) = nothing quaddata(op::ComposedOperatorIntegral,rs,els,qs::SingleNumQStrat) = quadpoints(rs,els,(qs.quad_rule,)) @@ -605,10 +418,6 @@ quadrule(op::ComposedOperatorIntegral,refspace,p,y,q,el,qdata,qs::SingleNumQStra defaultquadstrat(op::ComposedOperatorIntegral, basis) = SingleNumQStrat(6) defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(7,8,5,5,4,3) defaultquadstrat(op::ComposedOperatorLocal,testspace::Space,trialpsace::Space) = SingleNumQStrat(8) -#sign_upon_permutation(op::ComposedOperator,I,J) = Combinatorics.levicivita(I)^count_test_normals(op)*Combinatorics.levicivita(J)^count_trial_normals(op) - - -#normalorient(op::ComposedOperator,sign_test_normal,sign_trial_normal) = sign_test_normal^count_test_normals*sign_trial_normal^count_trial_normals defaultquadstrat(op::TraceOperator,test,trial) = defaultquadstrat(op.operator,test,trial) @@ -616,106 +425,17 @@ defaultquadstrat(op::Potential,test,trial) = defaultquadstrat(op.operator,test,t -# function assemble!(op::Potential, test_functions::Space, trial_functions::Space, -# store, threading = Threading{:multi}; -# quadstrat = defaultquadstrat(op, test_functions, trial_functions)) -# # checks if surface given in basis is the same as surface given in potential -# dsurf = surface(op) -# surf = geometry(trial_functions) -# @assert same_geometry(dsurf,surf) -# nsurf = mesh(dsurf) -# trial_functions = redefine_geometrie(trial_functions,TraceMesh(OrientedMesh(surf,nsurf),direction(dsurf))) - -# assemble!(op.operator, test_functions, trial_functions, store, threading; -# quadstrat = quadstrat) -# end function assemble!(op::Potential, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; kwargs...) - # checks if surface given in basis is the same as surface given in potential - # dsurf = surface(op) + surf = geometry(trial_functions) - # @assert same_geometry(dsurf,surf) - # nsurf = mesh(dsurf) + trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) assemble!(op.operator, test_functions, trial_functions, store, threading; kwargs...) end -# function assemble!(op::Potential{T,Nothing}, test_functions::Space, trial_functions::Space, -# store, threading = Threading{:multi}; -# quadstrat = defaultquadstrat(op, test_functions, trial_functions)) where {T} - -# surf = geometry(trial_functions) -# trial_functions = redefine_geometrie(trial_functions,TraceMesh(OrientedMesh(surf,surf))) - -# assemble!(op.operator, test_functions, trial_functions, store, threading; -# quadstrat = quadstrat) -# end -# function assemble!(op::Potential{T,Nothing}, test_functions::Space, trial_functions::Space, -# store, threading = Threading{:multi}; -# kwargs...) where {T} - -# surf = geometry(trial_functions) -# trial_functions = redefine_geometrie(trial_functions,TraceMesh(surf)) - -# assemble!(op.operator, test_functions, trial_functions, store, threading; -# kwargs...) -# end - -# function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, -# store, threading = Threading{:multi}; -# quadstrat = defaultquadstrat(op, test_functions, trial_functions)) - -# dsurf = surface(op) -# surf = geometry(test_functions) -# println(typeof(surf)) -# println(typeof(mesh(dsurf))) -# @assert same_geometry(dsurf,surf) -# nsurf = mesh(dsurf) - -# test_functions = redefine_geometrie(test_functions,TraceMesh(OrientedMesh(surf,nsurf),direction(dsurf))) - -# assemble!(op.operator, test_functions, trial_functions, store, threading; -# quadstrat = quadstrat) -# end - -# function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, -# store, threading = Threading{:multi}; -# kwargs...) - -# dsurf = surface(op) -# surf = geometry(test_functions) -# println(typeof(surf)) -# println(typeof(mesh(dsurf))) -# @assert same_geometry(dsurf,surf) -# nsurf = mesh(dsurf) - -# test_functions = redefine_geometrie(test_functions,TraceMesh(surf,direction(dsurf))) - -# assemble!(op.operator, test_functions, trial_functions, store, threading; -# kwargs...) -# end -# function assemble!(op::TraceOperator{T,Int}, test_functions::Space, trial_functions::Space, -# store, threading = Threading{:multi}; -# kwargs...) where {T} - -# surface = geometry(test_functions) - -# sign = op.surface -# direction = [sign*normal(c)/3 for c in chart.(Ref(surface),1:numcells(surface))] - -# if typeof(surface) <: TraceMesh -# surf = surface + direction -# else -# surf = TraceMesh(surface,direction) -# end - -# test_functions = redefine_geometrie(test_functions,surf) - -# assemble!(op.operator, test_functions, trial_functions, store, threading; -# kwargs...) -# end function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Space, store, threading = Threading{:multi}; kwargs...) diff --git a/src/excitation.jl b/src/excitation.jl index 64718255..6cd06951 100644 --- a/src/excitation.jl +++ b/src/excitation.jl @@ -163,3 +163,20 @@ function celltestvalues(tshs::subReferenceSpace{T,D}, tcell, field, qr) where {T return interactions end +struct FunctionExcitation{T} <: Functional + f +end +export FunctionExcitation + + + +function (func::FunctionExcitation)(x) + return func.f(x) +end +function (func::FunctionExcitation)(x::Union{CompScienceMeshes.MeshPointNM,BEAST.TraceMeshPointNM}) + return func.f(cartesian(x)) +end +scalartype(ff::FunctionExcitation{T}) where {T} = T +cross(::NormalVector, p::FunctionExcitation) = CrossTraceMW(p) +integrand(::FunctionExcitation,tval,fval) = tval[1]*fval +export FunctionExcitation diff --git a/src/integralop.jl b/src/integralop.jl index 14eef015..898a24e4 100644 --- a/src/integralop.jl +++ b/src/integralop.jl @@ -112,7 +112,7 @@ function assemblechunk_body!(biop, trial_shapes, trial_elements, trial_assembly_data, qd, zlocal, store; quadstrat) myid = Threads.threadid() - myid == 1 && print(" dots out of 10: ") + myid == 1 && print("dots out of 10: ") todo, done, pctg = length(test_elements), 0, 0 for (p,tcell) in enumerate(test_elements) for (q,bcell) in enumerate(trial_elements) @@ -139,43 +139,7 @@ function assemblechunk_body!(biop, end end myid == 1 && println("") end -# function assemblechunk_body!(biop, -# test_shapes, test_elements::Vector{CompScienceMeshes.Simplex{3,2,1,3,U}}, test_assembly_data, -# trial_shapes, trial_elements::Vector{CompScienceMeshes.Simplex{3,2,1,3,V}}, trial_assembly_data, -# qd, zlocal, store; quadstrat) where {U,V} - -# @info "triangle assemblechunk_body used" -# myid = Threads.threadid() -# myid == 1 && print(string(typeof(biop))*" dots out of 10: ") -# todo, done, pctg = length(test_elements), 0, 0 -# for (p,tcell) in enumerate(test_elements) -# for (q,bcell) in enumerate(trial_elements) - -# fill!(zlocal, 0) -# if overlap(tcell,bcell) -# momintegrals_overlap!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, quadstrat) -# else -# qrule = quadrule(biop, test_shapes, trial_shapes, p, tcell, q, bcell, qd, quadstrat) -# momintegrals!(biop, test_shapes, trial_shapes, tcell, bcell, zlocal, qrule) -# end -# I = length(test_assembly_data[p]) -# J = length(trial_assembly_data[q]) -# for j in 1 : J, i in 1 : I -# zij = zlocal[i,j] -# for (n,b) in trial_assembly_data[q][j] -# zb = zij*b -# for (m,a) in test_assembly_data[p][i] -# store(a*zb, m, n) -# end end end end - -# done += 1 -# new_pctg = round(Int, done / todo * 100) -# if new_pctg > pctg + 9 -# myid == 1 && print(".") -# pctg = new_pctg -# end end -# myid == 1 && println("") -# end + function assemblechunk_body_test_refines_trial!(biop, test_functions, test_charts, test_assembly_data, test_cells, @@ -186,7 +150,7 @@ function assemblechunk_body_test_refines_trial!(biop, trial_shapes = refspace(trial_functions) myid = Threads.threadid() - myid == 1 && print(" dots out of 10: ") + myid == 1 && print("dots out of 10: ") todo, done, pctg = length(test_charts), 0, 0 for (p,(tcell,tchart)) in enumerate(zip(test_cells, test_charts)) for (q,(bcell,bchart)) in enumerate(zip(trial_cells, trial_charts)) @@ -227,7 +191,7 @@ function assemblechunk_body_trial_refines_test!(biop, trial_shapes = refspace(trial_functions) myid = Threads.threadid() - myid == 1 && print(" dots out of 10: ") + myid == 1 && print("dots out of 10: ") todo, done, pctg = length(test_charts), 0, 0 for (p,(tcell,tchart)) in enumerate(zip(test_cells, test_charts)) for (q,(bcell,bchart)) in enumerate(zip(trial_cells, trial_charts)) diff --git a/src/localop.jl b/src/localop.jl index 8d1cd916..3f4aaec3 100644 --- a/src/localop.jl +++ b/src/localop.jl @@ -1,25 +1,3 @@ -####### designing neighborhood object which can save 2 normals -# using ReusePatterns -# using CompScienceMeshes -# struct MeshPointNormals -# meshpoint::CompScienceMeshes.MeshPointNM -# testnormal -# trialnormal -# end -#ReusePatterns.@forward (MeshPointNormals, :meshpoint) CompScienceMeshes.MeshPointNM - -# code = forward((MeshPointNormals, :meshpoint),CompScienceMeshes.MeshPointNM) -# uit = [code[1]] -# for line in code[2:length(code)] -# push!(uit,replace(line, " CompScienceMeshes " => " ")) -# end -# eval.(Meta.parse.(uit)) - -# function extendedneighborhood(p::CompScienceMeshes.Simplex, bary,nt,nb) -# MeshPointNormals(CompScienceMeshes.neighborhood(p,bary),nt,nb) -# end - -# normals(m::MeshPointNormals) = (m.testnormal,m.trialnormal) using CollisionDetection @@ -123,7 +101,7 @@ function assemble_local_matched!(biop::LocalOperator, tfs::Space, bfs::Space, st qd = quaddata(biop, trefs, brefs, tels, bels, quadstrat) verbose = length(tels) > 10_000 - verbose && print(" dots out of 20: ") + verbose && print("dots out of 20: ") todo, done, pctg = length(tels), 0, 0 locmat = zeros(scalartype(biop, trefs, brefs), numfunctions(trefs), numfunctions(brefs)) @@ -174,7 +152,7 @@ function assemble_local_refines!(biop::LocalOperator, tfs::Space, bfs::Space, st qd = quaddata(biop, trefs, brefs, tels, bels, quadstrat) - print(" dots out of 10: ") + print("dots out of 10: ") todo, done, pctg = length(tels), 0, 0 for (p,tcell) in enumerate(tels) @@ -299,7 +277,7 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} # store the bcells in an octree tree = elementstree(bels) - print(" dots out of 10: ") + print("dots out of 10: ") todo, done, pctg = length(tels), 0, 0 for (p,tcell) in enumerate(tels) @@ -350,31 +328,6 @@ function assemble_local_mixed!(biop::LocalOperator, tfs::Space{T}, bfs::Space{T} end -# function cellinteractions_matched!(zlocal, biop, trefs, brefs, cell, qr,tcell=nothing,bcell=nothing) - -# num_tshs = length(qr[1][3]) -# num_bshs = length(qr[1][4]) - -# # zlocal = zeros(Float64, num_tshs, num_bshs) -# for q in qr - -# w, mp, tvals, bvals = q[1], q[2], q[3], q[4] -# j = w * jacobian(mp) -# kernel = kernelvals(biop, mp) - -# for n in 1 : num_bshs -# bval = bvals[n] -# for m in 1 : num_tshs -# tval = tvals[m] - -# igd = integrand(biop, kernel, mp, tval, bval) -# zlocal[m,n] += j * igd -# end -# end -# end - -# return zlocal -# end function cellinteractions_matched!(zlocal, biop, trefs, brefs, cellt,cellb, qr) @@ -393,34 +346,6 @@ function cellinteractions_matched!(zlocal, biop, trefs, brefs, cellt,cellb, qr) return zlocal end -# function cellinteractions(biop, trefs::U, brefs::V, cell,qr,tcell,bcell) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} - -# num_tshs = length(qr[1][3]) -# num_bshs = length(qr[1][4]) - -# zlocal = zeros(T, num_tshs, num_bshs) - -# for q in qr - -# w, mp, tvals, bvals = q[1], q[2], q[3], q[4] -# j = w * jacobian(mp) -# kernel = kernelvals(biop, mp) - -# for m in 1 : num_tshs -# tval = tvals[m] - -# for n in 1 : num_bshs -# bval = bvals[n] - -# igd = integrand(biop, kernel, mp, tval, bval) -# zlocal[m,n] += j * igd - -# end -# end -# end - -# return zlocal -# end function cellinteractions(biop, trefs::U, brefs::V, cellt,cellb,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} @@ -445,32 +370,4 @@ function cellinteractions(biop, trefs::U, brefs::V, cellt,cellb,qr) where {U<:Re end getvalue(list::Matrix{T}) where {T} = SVector{length(list),T}([i for i in list]) -# function cellinteractions(biop, trefs::U, brefs::V, cell,qr) where {U<:RefSpace{T},V<:RefSpace{T}} where {T} - -# num_tshs = length(qr[1][3]) -# num_bshs = length(qr[1][4]) - -# zlocal = zeros(T, num_tshs, num_bshs) - -# for q in qr - -# w, mp, tvals, bvals = q[1], q[2], q[3], q[4] -# j = w * jacobian(mp) -# kernel = kernelvals(biop, mp) - -# for m in 1 : num_tshs -# tval = tvals[m] - -# for n in 1 : num_bshs -# bval = bvals[n] - -# igd = integrand(biop, kernel, mp, tval, bval) -# zlocal[m,n] += j * igd - -# end -# end -# end - -# return zlocal -# end diff --git a/src/operator.jl b/src/operator.jl index d12bd4b8..ba57896d 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -216,8 +216,6 @@ function assemble!(operator::Operator, test_functions::Space, trial_functions::S assemblechunk!(operator, test_functions, trial_functions, store; kwargs...) end -# defaultquadstrat(op::BasisOperatorLeft,tfs,bfs) = defaultquadstrat(op.operator,op.left_function(tfs),bfs) -# defaultquadstrat(op::BasisOperatorRight,tfs,bfs) = defaultquadstrat(op.operator,tfs,op.right_function(bfs)) function assemble!(op::TransposedOperator, tfs::Space, bfs::Space, @@ -232,18 +230,6 @@ function assemble!(op::ZeroOperator, tfs::Space, bfs::Space, kwargs...) end -# function assemble!(op::BasisOperatorLeft, tfs::Space, bfs::Space, store,threading = Threading{:multi}; -# quadstrat=defaultquadstrat(op, tfs, bfs)) -# #quadstrat = defaultquadstrat(op.operator,op.left_function(tfs),bfs) -# assemble!(op.operator,op.left_function(tfs),bfs,store,threading;quadstrat) -# end - -# function assemble!(op::BasisOperatorRight, tfs::Space, bfs::Space, store,threading = Threading{:multi}; -# quadstrat=defaultquadstrat(op, tfs, bfs)) -# #quadstrat = defaultquadstrat(op.operator,tfs,op.right_function(bfs)) -# assemble!(op.operator,tfs,op.right_function(bfs),store,threading;quadstrat) -# end - function assemble!(op::LinearCombinationOfOperators, tfs::AbstractSpace, bfs::AbstractSpace, store, threading = Threading{:multi}; @@ -341,12 +327,6 @@ function assemble!(op::BlockFullOperators, U::DirectProductSpace, V::DirectProdu I = Int[0]; for u in U.factors push!(I, last(I) + numfunctions(u)) end J = Int[0]; for v in V.factors push!(J, last(J) + numfunctions(v)) end - # k = 1 - # for (u,v) in zip(U.factors, V.factors) - # store1(v,m,n) = store(v, I[k] + m, J[k] + n) - # assemble!(op.op, u, v, store1; quadstrat) - # k += 1 - # end for (k,u) in enumerate(U.factors) for (l,v) in enumerate(V.factors) @@ -357,8 +337,6 @@ function assemble!(op::BlockFullOperators, U::DirectProductSpace, V::DirectProdu end -# strace(op::Operator,orientation::Orientation) = Strace(op,orientation) -# ttrace(op::Operator,orientation::Orientation) = Ttrace(op,orientation) diff --git a/src/quadrature/sauterschwabints.jl b/src/quadrature/sauterschwabints.jl index 79d2b892..7c1bab78 100644 --- a/src/quadrature/sauterschwabints.jl +++ b/src/quadrature/sauterschwabints.jl @@ -205,32 +205,3 @@ function momintegrals_trial_refines_test!(out, op, end end -# function momintegrals_overlap!(biop, -# test_shapes, trial_shapes, -# tcell, bcell, -# out, quadstrat) -# tcells, bcells = CompScienceMeshes.complementary_mesh(tcell,bcell) - -# qd = quaddata(biop,test_shapes,trial_shapes,tcells,bcells,quadstrat) - -# Nt = numfunctions(test_shapes) -# Nb = numfunctions(trial_shapes) - - -# for (p,tsubcell) in enumerate(tcells) -# for (q,bsubcell) in enumerate(bcells) -# zlocal = zero(out) -# qrule = quadrule(biop, test_shapes, trial_shapes, p, tsubcell, q, bsubcell, qd, quadstrat) -# momintegrals!(biop, test_shapes, trial_shapes, tsubcell, bsubcell, zlocal, qrule) -# Qt = restrict(test_shapes,tcell,tsubcell) -# Qb = restrict(trial_shapes,bcell,bsubcell) -# for j in 1:Nb -# for i in 1:Nt -# for m in 1:Nb -# for n in 1:Nt -# out[i,j] += Qt[i,n] * zlocal[n,m] * Qb[j,m] -# end end end end -# end -# end - -# end \ No newline at end of file diff --git a/src/solvers/solver.jl b/src/solvers/solver.jl index e2f1f7b3..519f4aa7 100644 --- a/src/solvers/solver.jl +++ b/src/solvers/solver.jl @@ -243,31 +243,3 @@ function assemble(bf::BilForm, pairs::Pair...;kwargs...) dbf = discretise(bf, pairs...) assemble(dbf;kwargs...) end -# struct BilFormDirectProductSpace -# test_space -# trial_space -# terms -# end - -# function LinearAlgebra.dot(test::DirectProductSpace,op::Matrix{AbstractOperator},trial::DirectProductSpace) -# test_length = length(test.factors) -# trial_length = length(trial.factors) -# @assert size(op)==(test_length,trial_length) -# terms = Vector{BilTerm}() -# test_space_dict = Dict() -# trial_space_dict = Dict() -# for (i,space) in enumerate(test.factors) -# test_space_dict[i]=space -# end -# for (i,space) in enumerate(trial.factors) -# trial_space_dict[i]=space -# end - -# for i in 1:test_length -# for j in 1:trial_length -# push!(terms,BilTerm(i,j,[],[],1.0,op[i,j])) -# end -# end -# BilForm([],[],terms) -# end - diff --git a/src/utils/variational.jl b/src/utils/variational.jl index 5351f0de..9ee5044a 100644 --- a/src/utils/variational.jl +++ b/src/utils/variational.jl @@ -538,17 +538,7 @@ function *(b::BilForm,a::Union{Matrix,SMatrix}) out = [term*a[term.trial_id,term.trial_id] for term in b.terms] return BilForm(b.test_space,b.trial_space,out) end -# mutable struct ProdBilTerm -# bilterm1 -# bilterm2 -# betweenspace -# end -# function *(a::BilForm,b::BilForm) -# @assert a.trial_space == b.test_space -# r = [[term.trial_id for term in a.terms];[term.test_id for term in b.terms]...] -# @assert allequal(r) -# return BilForm(a.test_space,b.trial_space,ProdBilTerm(a.terms,b.terms,a.trial_space)) -# end + struct ZeroBilForm end struct ZeroLinForm end diff --git a/test/runtests.jl b/test/runtests.jl index f393b52a..e5bde14b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -74,8 +74,6 @@ include("test_td_tensoroperator.jl") include("test_variational.jl") include("test_composed_operator.jl") -#include("test_momintegrals_overlap.jl") -#inlcude("test_multi-trace_VP.jl") try Pkg.installed("BogaertInts10") diff --git a/test/test_basis.jl b/test/test_basis.jl index 644f9a2c..97732886 100644 --- a/test/test_basis.jl +++ b/test/test_basis.jl @@ -22,7 +22,6 @@ for T in [Float32, Float64] @test size(N) == (numfunctions(X), numfunctions(X)) @test size(I) == (numfunctions(X), numfunctions(X)) - println(X) @test rank(I) == numfunctions(X) @time e = assemble(PlaneWaveNeumann(κ, point(0.0, 1.0)), X) diff --git a/test/test_multi-trace_VP.jl b/test/test_multi-trace_VP.jl deleted file mode 100644 index eea76676..00000000 --- a/test/test_multi-trace_VP.jl +++ /dev/null @@ -1,121 +0,0 @@ -using BEAST -using CompScienceMeshes -using BlockArrays -using LinearAlgebra -# import Plots - -radius = 1.0 -hh=0.15 -ϵ0 = 8.854e-12 -μ0 = 4π*1e-7 -ϵr = 2.0 -μr = 3.0 -c = 1/√(ϵ0*μ0) -λ = 2.9979563769321627 -ω = 2π*c/λ - -k0 = ω*sqrt(ϵ0*μ0) -T = boundary(CompScienceMeshes.tetmeshsphere(radius,hh)) - -S = BEAST.HOM(T,ϵ0*ϵr,μ0*μr,ω) -F = BEAST.FreeSpace(ϵ0,μ0,ω) -world = BEAST.create_world([2,0],[S,F]) -strat = BEAST.VP() -BEAST.assign_basis!(world,strat) - -lhs = BEAST.discretise_lhs(world,strat) - -A(x) = [1.0,0.0,0.0]*1im/ω*exp(-1.0im*k0*x[3]) -∇xA(x) = [0.0,1.0,0.0]*k0/ω*exp(-1.0im*k0*x[3]) -∇A(x) = 0.0+0.0im - -ex = BEAST.VPExcitation(A,∇xA,∇A,[2]) -rhs = BEAST.discretise_rhs(world,ex,strat) - -t =lhs[1]+lhs[2] -u = BEAST.gmres_ch(rhs[1]+rhs[2],t,world.trialdirectproductspace) - -Bf = BEAST.BField(world,u[1],[1,2]) -nx, nz = 100, 100 -xs, zs = range(-4,stop=4,length=nx), range(-6,stop=6,length=nz) -pts = [point(0,x,z) for x in xs, z in zs] - -BField = BEAST.calculate_field(pts,Bf,strat) -# display(Plots.heatmap(xs, zs, real.(getindex.(BField.field,2).+getindex.(∇xA.(pts),2)),show=true)) -# display(Plots.heatmap(xs, zs, imag.(getindex.(BField.field,2).+getindex.(∇xA.(pts),2)),show=true)) - - - - - - -function nearfield(um,uj,Xm,Xj,κ,η,points, - Einc=(x->point(0,0,0)), - Hinc=(x->point(0,0,0))) - - K = BEAST.MWDoubleLayerField3D(wavenumber=κ) - T = BEAST.MWSingleLayerField3D(wavenumber=κ) - - Em = potential(K, points, um, Xm) - Ej = potential(T, points, uj, Xj) - E = -Em + η * Ej + Einc.(points) - - Hm = potential(T, points, um, Xm) - Hj = potential(K, points, uj, Xj) - H = 1/η*Hm + Hj + Hinc.(points) - - return E, H -end - - - -X = raviartthomas(T) - -κ, η = ω/c, √(μ0/ϵ0) -κ′, η′ = κ*√(ϵr*μr), η*√(μr/ϵr) - -T = Maxwell3D.singlelayer(wavenumber=κ) -T′ = Maxwell3D.singlelayer(wavenumber=κ′) -K = Maxwell3D.doublelayer(wavenumber=κ) -K′ = Maxwell3D.doublelayer(wavenumber=κ′) - -E = Maxwell3D.planewave(direction=ẑ, polarization=x̂, wavenumber=κ) -H = -1/(im*κ*η)*curl(E) - -e = (n × E) × n -h = (n × H) × n - -@hilbertspace j m -@hilbertspace k l - -α, α′ = 1/η, 1/η′ -pmchwt = @discretise( - (η*T+η′*T′)[k,j] - (K+K′)[k,m] + - (K+K′)[l,j] + (α*T+α′*T′)[l,m] == -e[k] - h[l], - j∈X, m∈X, k∈X, l∈X) - -uu = solve(pmchwt) - -import Base.Threads: @spawn -task1 = @spawn nearfield(uu[m],uu[j],X,X,κ,η,pts,E,H) -task2 = @spawn nearfield(-uu[m],-uu[j],X,X,κ′,η′,pts) - -E_ex, H_ex = fetch(task1) -E_in, H_in = fetch(task2) - -B_tot = H_in*μ0*μr + H_ex*μ0 - -# display(Plots.heatmap(xs, zs, real.(getindex.(B_tot,2)))) -# display(Plots.heatmap(xs, zs, imag.(getindex.(B_tot,2)))) - -# maximum(norm.(B_tot-BField.field-∇xA.(pts))./norm.(B_tot)) - -# display(Plots.heatmap(xs,zs,norm.(B_tot-BField.field-∇xA.(pts))./maximum(norm.(B_tot)))) -# display(Plots.heatmap(xs,zs,norm.(B_tot))) - -# import PlotlyJS - -# PlotlyJS.plot(PlotlyJS.heatmap(x=xs,y=zs,z=norm.(B_tot))) - -# old = 0.008153372950474812 -@test norm.(B_tot-BField.field-∇xA.(pts)))/sum(norm.(B_tot) < 0.01 \ No newline at end of file From 2b42b55203332313c0537e0b744a2c5e55add6e7 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Mar 2024 14:49:57 +0100 Subject: [PATCH 099/110] update --- examples/vppmchwt.jl | 20 +++++++++----------- src/bases/local/laglocal.jl | 2 +- src/composedoperator/composedoperator.jl | 18 ++++++++++++++++++ src/excitation.jl | 16 ---------------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl index a35b730b..e7d39d3c 100644 --- a/examples/vppmchwt.jl +++ b/examples/vppmchwt.jl @@ -78,7 +78,7 @@ function T2(κ;trace=true,tr=1,kwargs...) end return BEAST.matrix_to_bilform(int) end -function A(κ;trace=true,tr=1,kwargs...) +function Aa(κ;trace=true,tr=1,kwargs...) G = BEAST.greenhh3d(wavenumber=κ) gradG = BEAST.∇(G) if trace @@ -154,8 +154,8 @@ function Bb(κ;trace=true,tr=1,kwargs...) return BEAST.matrix_to_bilform(int) end -Z(κ;rows = [1,2],cols = [1,2],kwargs...) = BEAST.matrix_to_bilform([Bb(κ;kwargs...) T2(κ;kwargs...);T1(κ;kwargs...) A(κ;kwargs...)][rows,cols];kwargs...) -Zp(κ;rows = [1,2],cols = [1,2],kwargs...) = BEAST.matrix_to_bilform([A(κ;kwargs...) T1(κ;kwargs...);T2(κ;kwargs...) Bb(κ;kwargs...)][rows,cols];kwargs...) +Z(κ;rows = [1,2],cols = [1,2],kwargs...) = BEAST.matrix_to_bilform([Bb(κ;kwargs...) T2(κ;kwargs...);T1(κ;kwargs...) Aa(κ;kwargs...)][rows,cols];kwargs...) +Zp(κ;rows = [1,2],cols = [1,2],kwargs...) = BEAST.matrix_to_bilform([Aa(κ;kwargs...) T1(κ;kwargs...);T2(κ;kwargs...) Bb(κ;kwargs...)][rows,cols];kwargs...) function excitation_dirichlet(A,curlA,divA) @@ -200,7 +200,7 @@ end hh = 0.3 Γ1 = meshcuboid(1.0, 1.0, 1.0, hh) Γ2 = (@SVector [-1.0,0.0,0.0]) + BEAST.TraceMesh(-Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1)))) -Γ3 = (@SVector [0.0,0.0,-1.0]) + BEAST.TraceMesh(-translate(Mesh([point(x,y,-z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))),[0.0,0.0,0.0])) +Γ3 = (@SVector [0.0,0.0,-1.0]) + BEAST.TraceMesh(-CompScienceMeshes.translate(Mesh([point(x,y,-z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))),[0.0,0.0,0.0])) Γ = [Γ1,Γ2,Γ3] Tree = [0,0,0] # give index in which volume material is @@ -276,7 +276,7 @@ eqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[2])[t[ci] -α[ci]*Xind[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end eqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Z(κ0;rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -(1-α[ci])*idnd()[t[ci],b[ci]] == -(1-α[ci])*Xinn[t[ci]] + -(1-α[ci])*idnd[t[ci],b[ci]] == -(1-α[ci])*Xinn[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end @@ -291,7 +291,7 @@ eqs3efie = begin BEAST.Equation[(Z(κ[i];rows=[2])*(Qinv[i]))[t[ci],b[i]]+ eqs3mfie = begin BEAST.Equation[(Z(κ[i];rows=[1])*(Qinv[i]))[t[ci],b[i]]+ -sum(BEAST.BilForm[Z(κ[i];rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -sum(BEAST.BilForm[Z(κ[i];rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -idnd()[t[ci],b[ci]] ==0 + -idnd[t[ci],b[ci]] ==0 for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end eqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[2])*(Qinv[i]))[t[ci],b[i]]+ -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ @@ -300,7 +300,7 @@ eqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[2])*(Qinv[i]))[t[ci],b[i] eqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Z(κ[i];rows=[1])*(Qinv[i]))[t[ci],b[i]]+ -(1-α[ci])* sum(BEAST.BilForm[Z(κ[i];rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -(1-α[ci])*sum(BEAST.BilForm[Z(κ[i];rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -(1-α[ci])*idnd()[t[ci],b[ci]] == 0 + -(1-α[ci])*idnd[t[ci],b[ci]] == 0 for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end ## sum the equations in the two parts in a pmchwt fassion, @@ -317,7 +317,7 @@ asymfilled && (Dasymeq = BEAST.discretise(asymeq, (t.∈Xtmfie)..., (b.∈Xb)... #assemble system - +qsZ = [8,8,7,8,5,5,4,3] qs(::BEAST.LocalOperator, a, b) = BEAST.SingleNumQStrat(qsZ[1]) qs(op::BEAST.ComposedOperatorLocal,testspace,trialpsace) = BEAST.SingleNumQStrat(qsZ[2]) qs(op::BEAST.ComposedOperatorIntegral,testspace,trialspace) = BEAST.DoubleNumSauterQstrat(qsZ[3:end]...) @@ -332,9 +332,7 @@ Zunprec = Za*I+Zs*I bunprec = ba .+ bs uz = solve(Zunprec,bunprec,BEAST.DirectProductSpace(Xb);strat=solvestrat,tol=abstol_Z, maxiter=maxiter_Z, restart=restart_Z) -save_uZ && (out[:uZ] = uz[1]) -save_uZ && (out[:basis] = Xb) -save_itterZ && (out[:itter_Z] = uz[2]) + diff --git a/src/bases/local/laglocal.jl b/src/bases/local/laglocal.jl index 56089dfc..71e46318 100644 --- a/src/bases/local/laglocal.jl +++ b/src/bases/local/laglocal.jl @@ -32,7 +32,7 @@ function (f::LagrangeRefSpace{T,1,3})(t) where T # (value=w,)) j = jacobian(t) - p = t.patch + p = chart(t) σ = sign(dot(normal(t), cross(p[1]-p[3],p[2]-p[3]))) SVector( (value=u, curl=σ*(p[3]-p[2])/j), diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index aeeba267..18806463 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -449,3 +449,21 @@ function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Sp assemble!(op.operator, test_functions, trial_functions, store, threading; kwargs...) end + +struct FunctionExcitation{T} <: Functional + f +end +export FunctionExcitation + + + +function (func::FunctionExcitation)(x) + return func.f(x) +end +function (func::FunctionExcitation)(x::Union{CompScienceMeshes.MeshPointNM,BEAST.TraceMeshPointNM}) + return func.f(cartesian(x)) +end +scalartype(ff::FunctionExcitation{T}) where {T} = T +cross(::NormalVector, p::FunctionExcitation) = CrossTraceMW(p) +integrand(::FunctionExcitation,tval,fval) = tval[1]*fval +export FunctionExcitation \ No newline at end of file diff --git a/src/excitation.jl b/src/excitation.jl index 6cd06951..62f0d2bc 100644 --- a/src/excitation.jl +++ b/src/excitation.jl @@ -163,20 +163,4 @@ function celltestvalues(tshs::subReferenceSpace{T,D}, tcell, field, qr) where {T return interactions end -struct FunctionExcitation{T} <: Functional - f -end -export FunctionExcitation - - -function (func::FunctionExcitation)(x) - return func.f(x) -end -function (func::FunctionExcitation)(x::Union{CompScienceMeshes.MeshPointNM,BEAST.TraceMeshPointNM}) - return func.f(cartesian(x)) -end -scalartype(ff::FunctionExcitation{T}) where {T} = T -cross(::NormalVector, p::FunctionExcitation) = CrossTraceMW(p) -integrand(::FunctionExcitation,tval,fval) = tval[1]*fval -export FunctionExcitation From 18e36e0046d767c5cd4f5e49601df01ff8c76a4a Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Mar 2024 15:30:11 +0100 Subject: [PATCH 100/110] update --- examples/vppmchwt.jl | 13 ++++++++----- src/operator.jl | 9 +++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl index e7d39d3c..587b4bff 100644 --- a/examples/vppmchwt.jl +++ b/examples/vppmchwt.jl @@ -238,6 +238,9 @@ idnd = BEAST.matrix_to_bilform(diagm([Identity(),Identity()])) @hilbertspace t1 t2 @hilbertspace b1 b2 id = idnd[t1,b1]+idnd[t2,b2] +@hilbertspace t1 +@hilbertspace b1 +idnd2 = idnd[t1,b1] N = length(Γ) Q = Dict(i=>diagm([diagm(@SVector [1.0,1.0]),diagm(SVector{2,Float64}([HomPars[parent(i,Tree)][2]/HomPars[i][2],HomPars[i][1]/HomPars[parent(i,Tree)][1]]))]) for i in HOM) @@ -269,14 +272,14 @@ eqs2efie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[2])[t[ci],b[j]] f for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ EFIE] end eqs2mfie = begin BEAST.Equation[-sum(BEAST.BilForm[Z(κ0;rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -sum(BEAST.BilForm[Z(κ0;rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -idnd[t[ci],b[ci]] ==-Xinn[t[ci]] + -idnd2[t[ci],b[ci]] ==-Xinn[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end eqs2cefie =begin BEAST.Equation[-α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -α[ci]*sum(BEAST.BilForm[Z(κ0;rows=[2],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) == -α[ci]*Xind[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end eqs2cmfie = begin BEAST.Equation[-(1-α[ci])* sum(BEAST.BilForm[Z(κ0;rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -(1-α[ci])*sum(BEAST.BilForm[Z(κ0;rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -(1-α[ci])*idnd[t[ci],b[ci]] == -(1-α[ci])*Xinn[t[ci]] + -(1-α[ci])*idnd2[t[ci],b[ci]] == -(1-α[ci])*Xinn[t[ci]] for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end @@ -291,7 +294,7 @@ eqs3efie = begin BEAST.Equation[(Z(κ[i];rows=[2])*(Qinv[i]))[t[ci],b[i]]+ eqs3mfie = begin BEAST.Equation[(Z(κ[i];rows=[1])*(Qinv[i]))[t[ci],b[i]]+ -sum(BEAST.BilForm[Z(κ[i];rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -sum(BEAST.BilForm[Z(κ[i];rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -idnd[t[ci],b[ci]] ==0 + -idnd2[t[ci],b[ci]] ==0 for i in [0], ci in 1:N if ci ∈ children(i,Tree) ∩ MFIE]end eqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[2])*(Qinv[i]))[t[ci],b[i]]+ -α[ci]*sum(BEAST.BilForm[Z(κ[i];rows=[2])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ @@ -300,7 +303,7 @@ eqs3cefie = begin BEAST.Equation[α[ci]*(Z(κ[i];rows=[2])*(Qinv[i]))[t[ci],b[i] eqs3cmfie = begin BEAST.Equation[(1-α[ci])*(Z(κ[i];rows=[1])*(Qinv[i]))[t[ci],b[i]]+ -(1-α[ci])* sum(BEAST.BilForm[Z(κ[i];rows=[1])[t[ci],b[j]] for j in HOM ∩ children(i,Tree)])+ -(1-α[ci])*sum(BEAST.BilForm[Z(κ[i];rows=[1],cols=[2])[t[ci],b[j]] for j in [EFIE...,MFIE...,CFIE...] ∩ children(i,Tree)]) + - -(1-α[ci])*idnd[t[ci],b[ci]] == 0 + -(1-α[ci])*idnd2[t[ci],b[ci]] == 0 for i in HOM, ci in 1:N if ci ∈ children(i,Tree) ∩ CFIE] end ## sum the equations in the two parts in a pmchwt fassion, @@ -331,7 +334,7 @@ Zunprec = Za*I+Zs*I bunprec = ba .+ bs -uz = solve(Zunprec,bunprec,BEAST.DirectProductSpace(Xb);strat=solvestrat,tol=abstol_Z, maxiter=maxiter_Z, restart=restart_Z) +uz = solve(Zunprec,bunprec,BEAST.DirectProductSpace(Xb);strat=:GMRES,tol=real(sqrt(eps())), maxiter=20000, restart=20000) diff --git a/src/operator.jl b/src/operator.jl index ba57896d..39ba8150 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -240,6 +240,15 @@ function assemble!(op::LinearCombinationOfOperators, tfs::AbstractSpace, bfs::Ab assemble!(A, tfs, bfs, store1, threading; kwargs...) end end +function assemble!(op::LinearCombinationOfOperators, tfs::DirectProductSpace, bfs::DirectProductSpace, + store, threading = Threading{:multi}; + kwargs...) + + for (a,A) in zip(op.coeffs, op.ops) + store1(v,m,n) = store(a*v,m,n) + assemble!(A, tfs, bfs, store1, threading; kwargs...) + end +end # Support for direct product spaces From 603607f01c8d00626d442cf6d8e12a9394e0183e Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Mar 2024 15:49:51 +0100 Subject: [PATCH 101/110] removed exports, .gitignore adjusted --- .gitignore | 5 ----- src/composedoperator/composedoperator.jl | 11 +++++------ src/operator.jl | 6 +++--- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 7c294c59..b879feb5 100644 --- a/.gitignore +++ b/.gitignore @@ -11,8 +11,3 @@ dev/ profile/ /Manifest.toml /envs/ -programs/ -results/ -src/todo.txt - -dev_test/ \ No newline at end of file diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 18806463..652ec333 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -12,8 +12,8 @@ struct DivBasisFunction <: ComposedOperatorLocal end const B = BasisFunction() Base.div(::BasisFunction) = DivBasisFunction() -export B -export BasisFunction +# export B +# export BasisFunction struct TestNormal <: ComposedOperatorLocal end @@ -23,8 +23,8 @@ struct TraceDirection <: ComposedOperatorLocal end const nt = TestNormal() const nb = TrialNormal() -export nt -export nb +# export nt +# export nb struct Potential{T} <: AbstractOperator operator::T end @@ -453,7 +453,7 @@ end struct FunctionExcitation{T} <: Functional f end -export FunctionExcitation +# export FunctionExcitation @@ -466,4 +466,3 @@ end scalartype(ff::FunctionExcitation{T}) where {T} = T cross(::NormalVector, p::FunctionExcitation) = CrossTraceMW(p) integrand(::FunctionExcitation,tval,fval) = tval[1]*fval -export FunctionExcitation \ No newline at end of file diff --git a/src/operator.jl b/src/operator.jl index 39ba8150..2871ccca 100644 --- a/src/operator.jl +++ b/src/operator.jl @@ -17,7 +17,7 @@ abstract type Operator <: AbstractOperator end struct ZeroOperator <: AbstractOperator end -export ZeroOperator +# export ZeroOperator Base.zero(op::Type{<:AbstractOperator}) = ZeroOperator() mutable struct TransposedOperator <: AbstractOperator op::AbstractOperator @@ -377,5 +377,5 @@ function array_to_linform(array;dim=length(array)) return sum([array[i][tin[i]] for i in 1:minimum([nrows,dim])]) end -export matrix_to_bilform -export array_to_linform \ No newline at end of file +# export matrix_to_bilform +# export array_to_linform \ No newline at end of file From 68ffca2efa717542566df63dc54cebfb5a27a774 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Mar 2024 15:52:13 +0100 Subject: [PATCH 102/110] adjusted toml --- Project.toml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Project.toml b/Project.toml index cea50799..c4f68704 100644 --- a/Project.toml +++ b/Project.toml @@ -14,21 +14,13 @@ Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838" FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" -GmshTools = "82e2f556-b1bd-5f1a-9576-f93c0da5f0ee" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" -Lazy = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" LiftedMaps = "d22a30c1-52ac-4762-a8c9-5838452405e0" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" NestedUnitRanges = "032820ab-dc03-4b49-91f4-7d58d4da98b3" -Plotly = "58dd65bb-95f3-509e-9936-c39a10fdeae7" -PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" -PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" Requires = "ae029012-a4dd-5104-9daa-d747884805df" -Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" SauterSchwab3D = "0a13313b-1c00-422e-8263-562364ed9544" SauterSchwabQuadrature = "535c7bfe-2023-5c1d-b712-654ef9d93a38" SharedArrays = "1a1011a3-84de-559e-8e89-a11a2f7dc383" @@ -36,8 +28,6 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" SparseMatrixDicts = "5cb6c4b0-9b79-11e8-24c9-f9621d252589" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" -TableView = "40c74d1a-b44c-5b06-a7c1-6cbea58ea978" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" WiltonInts84 = "a3e2863e-c0ee-5ff6-a523-307a4cdc8724" [compat] From 682c69c163dfba8224350fcdda96b1c356811464 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Mar 2024 15:55:35 +0100 Subject: [PATCH 103/110] updated vppmchwt to not rely on exports --- examples/vppmchwt.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl index 587b4bff..4303e165 100644 --- a/examples/vppmchwt.jl +++ b/examples/vppmchwt.jl @@ -3,7 +3,7 @@ using CompScienceMeshes using LinearAlgebra using AbstractTrees using StaticArrays -using Plots +import BEAST: FunctionExcitation, matrix_to_bilform, B, nb, nt, ZeroOperator function T1(κ;trace=true,tr=1,kwargs...) G = BEAST.greenhh3d(wavenumber=κ) gradG = BEAST.∇(G) From 65c1ed75cb0bbb841dfd58106b63e39d2c04becb Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Mar 2024 16:07:45 +0100 Subject: [PATCH 104/110] update to pass tests --- examples/vppmchwt.jl | 2 +- src/BEAST.jl | 1 - test/test_composed_operator.jl | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl index 4303e165..b160c9eb 100644 --- a/examples/vppmchwt.jl +++ b/examples/vppmchwt.jl @@ -3,7 +3,7 @@ using CompScienceMeshes using LinearAlgebra using AbstractTrees using StaticArrays -import BEAST: FunctionExcitation, matrix_to_bilform, B, nb, nt, ZeroOperator +import BEAST: FunctionExcitation, matrix_to_bilform, B, nb, nt, ZeroOperator, ∇ function T1(κ;trace=true,tr=1,kwargs...) G = BEAST.greenhh3d(wavenumber=κ) gradG = BEAST.∇(G) diff --git a/src/BEAST.jl b/src/BEAST.jl index aa480dcd..a84889bf 100644 --- a/src/BEAST.jl +++ b/src/BEAST.jl @@ -274,6 +274,5 @@ const n = NormalVector() export n const ∇ = Nabla() -export ∇ end # module diff --git a/test/test_composed_operator.jl b/test/test_composed_operator.jl index 4cb53257..81b9bb66 100644 --- a/test/test_composed_operator.jl +++ b/test/test_composed_operator.jl @@ -1,6 +1,7 @@ using CompScienceMeshes using BEAST using Test +import BEAST: BasisFunction, ∇ m = meshrectangle(1.0, 1.0, 0.5, 3) k = 1.2 From 2a48cbc45beda2bceeb07c9999f5e9b84b73bddd Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Wed, 13 Mar 2024 09:49:12 +0100 Subject: [PATCH 105/110] update vppmchwt --- examples/vppmchwt.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/vppmchwt.jl b/examples/vppmchwt.jl index b160c9eb..553bb4c9 100644 --- a/examples/vppmchwt.jl +++ b/examples/vppmchwt.jl @@ -253,9 +253,9 @@ b = BEAST.hilbertspace(:b, length(Γ)) ##### define space perm = sortperm([HOM...,EFIE...,CFIE...,MFIE...]) Xt = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Xnt(Γ[i]),Xdt(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Xdt(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] -Yt = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ydt(Γ[i]),Ynt(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ydt(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] +Yt = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ydt(Γ[i]),Ynt(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ynt(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] Xb = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Xdb(Γ[i]),Xnb(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Xnb(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] -Yb = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ynb(Γ[i]),Ydb(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ynb(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] +Yb = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ynb(Γ[i]),Ydb(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ydb(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] Xtmfie = [BEAST.DirectProductSpace[BEAST.DirectProductSpace([Xnt(Γ[i]),Xdt(Γ[i])]) for i in HOM];BEAST.DirectProductSpace[BEAST.DirectProductSpace([Ynt(Γ[i])]) for i in [EFIE...,CFIE...,MFIE...]]][perm] ##### define equation From 9e4495ba848d9c379910bd0b9ff59e5f230e5b4f Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Thu, 14 Mar 2024 11:12:10 +0100 Subject: [PATCH 106/110] farfield local for composed operator --- src/postproc.jl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/postproc.jl b/src/postproc.jl index 961ad2e9..20c13c29 100644 --- a/src/postproc.jl +++ b/src/postproc.jl @@ -280,6 +280,21 @@ function farfieldlocal!(zlocal,op,refspace,y,el,qr) end +end +function farfieldlocal!(zlocal,op::ComposedOperator,refspace,y,el,qr) + + for q in qr + x = q.point + F = q.value + dx = q.weight + + krn = kernelvals(op, y, x) + + zlocal .+= integrand(op,krn,y,F,x) * dx + + + end + end function farfieldlocal!(zlocal,op,trialrefs, timerefs, From f9bcea2f6812fe0db049781810e5269471108cdb Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 15 Mar 2024 14:45:52 +0100 Subject: [PATCH 107/110] update --- src/composedoperator/composedoperator.jl | 34 ++++++++++++++++++++---- src/postproc.jl | 14 ---------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 652ec333..9dd5d269 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -154,11 +154,16 @@ CrossLocal(a::ComposedOperatorIntegral,b::Union{ComposedOperatorLocal,NormalVect CrossLocal(a::Union{ComposedOperatorLocal,NormalVector},b::ComposedOperatorIntegral) = CrossIntegral(a,b) CrossLocal(a::ComposedOperatorIntegral,b::ComposedOperatorIntegral) = CrossIntegral(a,b) -×(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators}) = CrossLocal(a,b) -⋅(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators}) = DotLocal(a,b) -*(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators}) = TimesLocal(a,b) - +×(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators,ZeroOperator},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators,ZeroOperator}) = CrossLocal(a,b) +⋅(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators,ZeroOperator},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators,ZeroOperator}) = DotLocal(a,b) +*(a::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators,ZeroOperator},b::Union{ComposedOperator,NormalVector,LinearCombinationOfOperators,ZeroOperator}) = TimesLocal(a,b) +TimesLocal(a,b::ZeroOperator) = ZeroOperator() +TimesLocal(a::ZeroOperator,b) = ZeroOperator() +DotLocal(a,b::ZeroOperator) = ZeroOperator() +CrossLocal(a,b::ZeroOperator) = ZeroOperator() +DotLocal(a::ZeroOperator,b) = ZeroOperator() +CrossLocal(a::ZeroOperator,b) = ZeroOperator() scalartype(op::Union{TestNormal,TrialNormal,BasisFunction,DivBasisFunction,TraceDirection}) = Float16 scalartype(op::Operations) = promote_type(scalartype(op.lhs),scalartype(op.rhs)) @@ -343,6 +348,7 @@ end γ(op::GradDivGreenHH3D) = op γ(op::GradGreenHH3D) = op + 1/2*TraceDirection() + grad(G::GreenHH3D) = GradGreenHH3D(G.gamma) graddiv(G::GreenHH3D) = GradDivGreenHH3D(G.gamma) function (::Nabla)(G::Kernel) @@ -393,6 +399,7 @@ function (op::DivBasisFunction)(x,y,g) getdivergence(g) end function approx_sign(a::T; tol=eps(T)) where {T <: Number} + @assert abs(a) > tol abs(a) < tol && return zero(T) return sign(a) end @@ -445,7 +452,7 @@ function assemble!(op::TraceOperator, test_functions::Space, trial_functions::Sp dir = [sign*normal(c)/3 for c in chart.(Ref(surface),1:numcells(surface))] surf = TraceMesh(surface,dir) test_functions = redefine_geometrie(test_functions,surf) - + println(norm(surf.direction[1])) assemble!(op.operator, test_functions, trial_functions, store, threading; kwargs...) end @@ -466,3 +473,20 @@ end scalartype(ff::FunctionExcitation{T}) where {T} = T cross(::NormalVector, p::FunctionExcitation) = CrossTraceMW(p) integrand(::FunctionExcitation,tval,fval) = tval[1]*fval + + +function farfieldlocal!(zlocal,op::ComposedOperator,refspace,y,el,qr) + + for q in qr + x = q.point + F = q.value + dx = q.weight + + krn = kernelvals(op, y, x) + + zlocal .+= integrand(op,krn,y,F,x) * dx + + + end + +end \ No newline at end of file diff --git a/src/postproc.jl b/src/postproc.jl index 20c13c29..6ccd881d 100644 --- a/src/postproc.jl +++ b/src/postproc.jl @@ -281,21 +281,7 @@ function farfieldlocal!(zlocal,op,refspace,y,el,qr) end end -function farfieldlocal!(zlocal,op::ComposedOperator,refspace,y,el,qr) - for q in qr - x = q.point - F = q.value - dx = q.weight - - krn = kernelvals(op, y, x) - - zlocal .+= integrand(op,krn,y,F,x) * dx - - - end - -end function farfieldlocal!(zlocal,op,trialrefs, timerefs, p, testel, q, trialel, k, timeel, tb,quadrule) From ddf51f4adae16cf4de29d728619136aca5e4d43c Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Fri, 15 Mar 2024 14:46:19 +0100 Subject: [PATCH 108/110] fix error restrict function --- src/bases/local/ndlocal.jl | 4 ++-- src/bases/local/rtlocal.jl | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bases/local/ndlocal.jl b/src/bases/local/ndlocal.jl index b39a5dfe..f5421952 100644 --- a/src/bases/local/ndlocal.jl +++ b/src/bases/local/ndlocal.jl @@ -55,12 +55,12 @@ function restrict(ϕ::NDRefSpace{T}, dom1, dom2) where T u = carttobary(dom1, c) x = neighborhood(dom1, u) - + σ = sign(dot(normalize(tangents(dom2,1)×tangents(dom2,2)),normal(dom2))) y = ϕ(x) for j in 1:K # Q[j,i] = dot(y[j][1], m) * l - Q[j,i] = dot(y[j][1], t) + Q[j,i] = dot(y[j][1], t)*σ end end diff --git a/src/bases/local/rtlocal.jl b/src/bases/local/rtlocal.jl index ecba697b..a4325ec0 100644 --- a/src/bases/local/rtlocal.jl +++ b/src/bases/local/rtlocal.jl @@ -64,7 +64,8 @@ function restrict(ϕ::RTRefSpace{T}, dom1, dom2) where T # find the outer binormal there t = b - a l = norm(t) - n = normal(dom2) + + n = normalize(tangents(dom2,1)×tangents(dom2,2)) m = cross(t, n) / l u = carttobary(dom1, c) From 41e7a0b47ae14af89bbff4011511f156aea49ba3 Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Nov 2024 13:37:54 +0100 Subject: [PATCH 109/110] update 1 before sync --- Project.toml | 2 + examples/ex_globalmultitrace.jl | 1 + examples/pmchwt.jl | 30 ++++++------ src/postproc.jl | 81 +++++++++++++++++++++++++++++++-- 4 files changed, 97 insertions(+), 17 deletions(-) diff --git a/Project.toml b/Project.toml index c4f68704..0c8a9d0a 100644 --- a/Project.toml +++ b/Project.toml @@ -16,10 +16,12 @@ FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838" FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" +JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" LiftedMaps = "d22a30c1-52ac-4762-a8c9-5838452405e0" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" NestedUnitRanges = "032820ab-dc03-4b49-91f4-7d58d4da98b3" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Requires = "ae029012-a4dd-5104-9daa-d747884805df" SauterSchwab3D = "0a13313b-1c00-422e-8263-562364ed9544" SauterSchwabQuadrature = "535c7bfe-2023-5c1d-b712-654ef9d93a38" diff --git a/examples/ex_globalmultitrace.jl b/examples/ex_globalmultitrace.jl index 8b9a5efc..c3a6f4a3 100644 --- a/examples/ex_globalmultitrace.jl +++ b/examples/ex_globalmultitrace.jl @@ -15,6 +15,7 @@ h = 0.125 Γ2 = -Mesh([point(-x,y,z) for (x,y,z) in vertices(Γ1)], deepcopy(cells(Γ1))) Γ = [Γ1, Γ2] + # Beyond this point the problem description is completely independent # of the number of domains and their relative positioning diff --git a/examples/pmchwt.jl b/examples/pmchwt.jl index defc8538..fb60c09b 100644 --- a/examples/pmchwt.jl +++ b/examples/pmchwt.jl @@ -24,17 +24,18 @@ end μ0 = 4π*1e-7 c = 1/√(ϵ0*μ0) -λ = 2.9979563769321627 -ω = 2π*c/λ +# λ = 2.9979563769321627 +# ω = 2π*c/λ +ω = 10.0^8*2*pi -Ω = CompScienceMeshes.tetmeshsphere(λ,0.1*λ) -Ω = CompScienceMeshes.tetmeshsphere(λ,0.3*λ) +# Ω = CompScienceMeshes.tetmeshsphere(λ,0.1*λ) +Ω = CompScienceMeshes.tetmeshsphere(1.0,0.2) Γ = boundary(Ω) X = raviartthomas(Γ) @show numfunctions(X) ϵr = 2.0 -μr = 1.0 +μr = 3.0 κ, η = ω/c, √(μ0/ϵ0) κ′, η′ = κ*√(ϵr*μr), η*√(μr/ϵr) @@ -62,7 +63,7 @@ pmchwt = @discretise( (K+K′)[l,j] + (α*T+α′*T′)[l,m] == -e[k] - h[l], j∈X, m∈X, k∈X, l∈X) -u = solve(pmchwt) +u = BEAST.solve(pmchwt) Θ, Φ = range(0.0,stop=2π,length=100), 0.0 ffpoints = [point(cos(ϕ)*sin(θ), sin(ϕ)*sin(θ), cos(θ)) for θ in Θ for ϕ in Φ] @@ -98,10 +99,10 @@ Plotly.plot(patch(Γ, norm.(fcrm))) -Z = range(-6,6,length=200) -Y = range(-4,4,length=200) -nfpoints = [point(0,y,z) for z in Z, y in Y] - +Zz = range(-1,1,length=130) +Yy = range(-1,1,length=100) +nfpoints = [point(z,0,y) for z in Zz, y in Yy] +nfpoints = pts import Base.Threads: @spawn task1 = @spawn nearfield(u[m],u[j],X,X,κ,η,nfpoints,E,H) task2 = @spawn nearfield(-u[m],-u[j],X,X,κ′,η′,nfpoints) @@ -117,8 +118,11 @@ Plots.contour(real.(getindex.(H_tot,2))) Plots.heatmap(Z, Y, clamp.(real.(getindex.(E_tot,1)),-1.5,1.5)) Plots.heatmap(Z, Y, clamp.(imag.(getindex.(E_tot,1)),-1.5,1.5)) -Plots.heatmap(Z, Y, real.(getindex.(H_tot,2))) -Plots.heatmap(Z, Y, imag.(getindex.(H_tot,2))) +Plots.heatmap(Yy, Zz, norm.(getindex.(H_tot,2))) +Plots.heatmap(Y, Z, norm.(getindex.(H_tot,2))) Plots.plot(real.(getindex.(E_tot[:,51],1))) -Plots.plot(real.(getindex.(H_tot[:,51],2))) \ No newline at end of file +Plots.plot(real.(getindex.(H_tot[:,51],2))) + +Plots.heatmap(Zz,Yy,norm.(getindex.(-Bbb[1].+Bbb[3].-Bbb[2]/2,2))/μ0,clim=(0,0.02)) +Plots.heatmap(Zz,Yy,real(getindex.(H.(pts),2))) diff --git a/src/postproc.jl b/src/postproc.jl index 6ccd881d..f1a73594 100644 --- a/src/postproc.jl +++ b/src/postproc.jl @@ -129,11 +129,12 @@ end function potential(op, points, coeffs, basis; type=SVector{3,ComplexF64}, - quadstrat=defaultquadstrat(op, basis)) + quadstrat=defaultquadstrat(op, basis), + threading = Threading{:multi}) ff = zeros(type, size(points)) store(v,m,n) = (ff[m] += v*coeffs[n]) - potential!(store, op, points, basis; type, quadstrat) + potential!(store, op, points, basis; type, quadstrat,threading) return ff end @@ -147,7 +148,8 @@ end function potential(op, points, coeffs, space::DirectProductSpace; type=SVector{3,ComplexF64}, - quadstrat=defaultquadstrat(op,space)) + quadstrat=defaultquadstrat(op,space), + threading = Threading{:multi}) ff = zeros(type, size(points)) @assert length(coeffs) == numfunctions(space) @@ -155,13 +157,41 @@ function potential(op, points, coeffs, space::DirectProductSpace; offset = 0 for fct in space.factors store(v,m,n) = (ff[m] += v*coeffs[offset+n]) - potential!(store, op, points, fct; type, quadstrat) + potential!(store, op, points, fct; type, quadstrat, threading) offset += numfunctions(fct) end ff end + +function potential!(store, op, points, basis; + type=SVector{3,ComplexF64}, + quadstrat=defaultquadstrat(op, basis), + threading::Type{Threading{:multi}}) + P = Threads.nthreads()-1 + if P==0 + p = [points] + l = 0 + else + l = div(length(points),P) + r = length(points)%P + if r == 0 + p = [points[i*l+1:i*l+l] for i in 0:P-1] + else + p = [points[i*l+1:i*l+l] for i in 0:P-1] + p = [p;[points[end-r+1:end]]] + end + end + @assert sum(length.(p))==length(points) + + Threads.@threads for i in 1:(P+1) + partial_store(v,m,n) = store(v,m+(i-1)*l,n) + potential_points!(partial_store,op,p[i],basis;type,quadstrat) + end + + +end function potential!(store, op, points, basis; type=SVector{3,ComplexF64}, quadstrat=defaultquadstrat(op, basis)) @@ -204,6 +234,49 @@ function potential!(store, op, points, basis; println("") +end +function potential_points!(store, op, points, basis; + type=SVector{3,ComplexF64}, + quadstrat=defaultquadstrat(op, basis)) + + z = zeros(type,length(points)) + + els, ad = assemblydata(basis) + rs = refspace(basis) + + zlocal = Array{type}(undef,numfunctions(rs)) + qdata = quaddata(op,rs,els,quadstrat) + + print("dots out of 10: ") + + todo, done, pctg = length(points), 0, 0 + + for (p,y) in enumerate(points) + for (q,el) in enumerate(els) + + fill!(zlocal,zero(type)) + qr = quadrule(op,rs,p,y,q,el,qdata,quadstrat) + farfieldlocal!(zlocal,op,rs,y,el,qr) + + # assemble from local contributions + for (r,z) in enumerate(zlocal) + for (n,b) in ad[q,r] + store(z*b,p,n) + end + end + end + + done += 1 + new_pctg = round(Int, done / todo * 100) + if new_pctg > pctg + 9 + #println(todo," ",done," ",new_pctg) + print(".") + pctg = new_pctg + end + end + + println("") + end function potential!(store, op, points, basis::SpaceTimeBasis) From 0e93c3f4419b637de559374f9a4e5225d8d236ad Mon Sep 17 00:00:00 2001 From: PaulOlyslager Date: Tue, 12 Nov 2024 13:38:23 +0100 Subject: [PATCH 110/110] update 2 before sync --- src/bases/lagrange.jl | 11 +++++++++++ src/composedoperator/composedoperator.jl | 12 ++++++------ src/identityop.jl | 2 +- src/integralop.jl | 2 +- src/postproc.jl | 6 +++--- src/quadrature/sauterschwabints.jl | 25 ++++++++++++------------ src/solvers/solver.jl | 4 ++-- 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/bases/lagrange.jl b/src/bases/lagrange.jl index dc26e01d..445c53f4 100644 --- a/src/bases/lagrange.jl +++ b/src/bases/lagrange.jl @@ -423,6 +423,17 @@ function duallagrangec0d1(mesh, refined, jct_pred, ::Type{Val{3}}) face_ctr = barytocart(coarse_chart, uv_face_ctr) I = CollisionDetection.find(fine_vertices, face_ctr) + # if length(I) != 1 + # println(I) + # println(face_ctr) + # for j in vertices(refined) + # if norm(face_ctr-j) < 0.1 + # println(j) + # println(j) + # end + # end + # end + @assert length(I) == 1 face_center_ids[f] = I[1] end diff --git a/src/composedoperator/composedoperator.jl b/src/composedoperator/composedoperator.jl index 9dd5d269..e9a8bdf2 100644 --- a/src/composedoperator/composedoperator.jl +++ b/src/composedoperator/composedoperator.jl @@ -9,12 +9,10 @@ ComposedOperator = Union{ComposedOperatorIntegral,ComposedOperatorLocal} struct BasisFunction <: ComposedOperatorLocal end struct DivBasisFunction <: ComposedOperatorLocal end + const B = BasisFunction() Base.div(::BasisFunction) = DivBasisFunction() -# export B -# export BasisFunction - struct TestNormal <: ComposedOperatorLocal end struct TrialNormal <: ComposedOperatorLocal end @@ -23,12 +21,14 @@ struct TraceDirection <: ComposedOperatorLocal end const nt = TestNormal() const nb = TrialNormal() -# export nt -# export nb + struct Potential{T} <: AbstractOperator operator::T end +##### macro definition + +##### function Potential(linop::LinearCombinationOfOperators) out = ZeroOperator() @@ -422,7 +422,7 @@ kernelvals(op::ComposedOperatorIntegral, y,x) = nothing quaddata(op::ComposedOperatorIntegral,rs,els,qs::SingleNumQStrat) = quadpoints(rs,els,(qs.quad_rule,)) quadrule(op::ComposedOperatorIntegral,refspace,p,y,q,el,qdata,qs::SingleNumQStrat) = qdata[1,q] -defaultquadstrat(op::ComposedOperatorIntegral, basis) = SingleNumQStrat(6) +defaultquadstrat(op::ComposedOperatorIntegral, basis) = SingleNumQStrat(9) defaultquadstrat(op::ComposedOperatorIntegral,testspace::Space,trialspace::Space) = DoubleNumSauterQstrat(7,8,5,5,4,3) defaultquadstrat(op::ComposedOperatorLocal,testspace::Space,trialpsace::Space) = SingleNumQStrat(8) diff --git a/src/identityop.jl b/src/identityop.jl index 9d32fbe3..d79f127d 100644 --- a/src/identityop.jl +++ b/src/identityop.jl @@ -93,7 +93,7 @@ function quadrule(op::LocalOperator, ψ::RefSpace, ϕ::RefSpace, τ,σ, (qd,A), q = qd[i] w, p1, p2 = q[1], neighborhood(τ,q[2]), neighborhood(σ,q[2]) A[i] = (w, (p1,p2), ψ(p1), ϕ(p2)) - + @assert cartesian(p1)≈cartesian(p2) end return A end diff --git a/src/integralop.jl b/src/integralop.jl index 898a24e4..7194e38d 100644 --- a/src/integralop.jl +++ b/src/integralop.jl @@ -86,7 +86,7 @@ function assemblechunk!(biop::IntegralOperator, tfs::Space, bfs::Space, store; bgeo = geometry(bfs) qd = quaddata(biop, tshapes, bshapes, test_elements, bsis_elements, quadstrat) - zlocal = zeros(scalartype(biop, tfs, bfs), 2num_tshapes, 2num_bshapes) + zlocal = zeros(scalartype(biop, tfs, bfs), num_tshapes, num_bshapes) if CompScienceMeshes.refines(tgeo, bgeo) assemblechunk_body_test_refines_trial!(biop, diff --git a/src/postproc.jl b/src/postproc.jl index f1a73594..4667b434 100644 --- a/src/postproc.jl +++ b/src/postproc.jl @@ -134,7 +134,7 @@ function potential(op, points, coeffs, basis; ff = zeros(type, size(points)) store(v,m,n) = (ff[m] += v*coeffs[n]) - potential!(store, op, points, basis; type, quadstrat,threading) + potential_multi!(store, op, points, basis; type, quadstrat,threading) return ff end @@ -165,7 +165,7 @@ function potential(op, points, coeffs, space::DirectProductSpace; end -function potential!(store, op, points, basis; +function potential_multi!(store, op, points, basis; type=SVector{3,ComplexF64}, quadstrat=defaultquadstrat(op, basis), threading::Type{Threading{:multi}}) @@ -246,7 +246,7 @@ function potential_points!(store, op, points, basis; zlocal = Array{type}(undef,numfunctions(rs)) qdata = quaddata(op,rs,els,quadstrat) - + println(quadstrat) print("dots out of 10: ") todo, done, pctg = length(points), 0, 0 diff --git a/src/quadrature/sauterschwabints.jl b/src/quadrature/sauterschwabints.jl index 7c1bab78..691ab75c 100644 --- a/src/quadrature/sauterschwabints.jl +++ b/src/quadrature/sauterschwabints.jl @@ -149,12 +149,13 @@ function momintegrals_test_refines_trial!(out, op, zlocal = zero(out) momintegrals!(op, test_local_space, trial_local_space, test_chart, chart, zlocal, qr) - - for j in 1:3 - for i in 1:3 - for k in 1:3 - out[i,j] += zlocal[i,k] * Q[j,k] -end end end end end + out .+= zlocal*transpose(Q) +# for j in 1:3 +# for i in 1:3 +# for k in 1:3 +# out[i,j] += zlocal[i,k] * Q[j,k] +# end end end +end end @@ -196,12 +197,12 @@ function momintegrals_trial_refines_test!(out, op, zlocal = zero(out) momintegrals!(op, test_local_space, trial_local_space, chart, trial_chart, zlocal, qr) - - for j in 1:3 - for i in 1:3 - for k in 1:3 - out[i,j] += Q[i,k] * zlocal[k,j] - end end end + out .+= Q*zlocal + # for j in 1:3 + # for i in 1:3 + # for k in 1:3 + # out[i,j] += Q[i,k] * zlocal[k,j] + # end end end end end diff --git a/src/solvers/solver.jl b/src/solvers/solver.jl index 519f4aa7..2ba2eab6 100644 --- a/src/solvers/solver.jl +++ b/src/solvers/solver.jl @@ -228,8 +228,8 @@ function assemble(bf::BilForm, X::DirectProductSpace, Y::DirectProductSpace; y = op[end](op[1:end-1]..., y) end - a = term.coeff * term.kernel - z = materialize(a, x, y;kwargs...) + a = term.kernel + z = term.coeff * materialize(a, x, y;kwargs...) lift(z, Block(term.test_id), Block(term.trial_id), U, V) end end