From f27df6dd26fd5f47e015b6f8de1886093c6b8ed8 Mon Sep 17 00:00:00 2001 From: Antoine Marteau Date: Fri, 8 Nov 2024 17:21:44 +1100 Subject: [PATCH 1/4] make evaluate! of AttachDirichletMap type stable if `mat` and `vec` are real valued and `vals` is complex valued, we still want to force the `copyto!(vec_with_bcs,vec)` to have a complex valued return type fixes #974 --- src/CellData/AttachDirichlet.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/CellData/AttachDirichlet.jl b/src/CellData/AttachDirichlet.jl index f38b2cd2d..3e686f238 100644 --- a/src/CellData/AttachDirichlet.jl +++ b/src/CellData/AttachDirichlet.jl @@ -70,13 +70,14 @@ function Arrays.return_cache(k::AttachDirichletMap,matvec::Tuple,vals,mask) end function Arrays.evaluate!(cache,k::AttachDirichletMap,matvec::Tuple,vals,mask) + mat, vec = matvec if mask - mat, vec = matvec vec_with_bcs = evaluate!(cache,k.muladd,mat,vals,vec) - (mat, vec_with_bcs) else - matvec + identity_muladd = MulAddMap(0,1) + vec_with_bcs = evaluate!(cache,identity_muladd ,mat,vals,vec) end + (mat, vec_with_bcs) end function Arrays.return_value(k::AttachDirichletMap,mat,vals,mask) From d443e8c86a380ce5c852faa5eb9f6208aa0f6e91 Mon Sep 17 00:00:00 2001 From: Antoine Marteau Date: Mon, 11 Nov 2024 10:31:50 +1100 Subject: [PATCH 2/4] add MWE of issue 974 --- test/GridapTests/issue_974.jl | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 test/GridapTests/issue_974.jl diff --git a/test/GridapTests/issue_974.jl b/test/GridapTests/issue_974.jl new file mode 100644 index 000000000..2c82250bb --- /dev/null +++ b/test/GridapTests/issue_974.jl @@ -0,0 +1,31 @@ +using Gridap + +T = ComplexF64 + +# Operator creating a linear system where the matrix and RHS are Float64 but the unknown vector is ComplexF64. +domain = (0, 1, 0, 1) +partition = (4, 4) +model = CartesianDiscreteModel(domain, partition) + +order = 1 +reffe = ReferenceFE(lagrangian, Float64, order) + +V1 = TestFESpace(model, reffe; conformity=:H1, vector_type=Vector{T}) +V2 = TestFESpace(model, reffe; conformity=:H1, vector_type=Vector{T}) + +U1 = TrialFESpace(V1) +U2 = TrialFESpace(V2) + +Y = MultiFieldFESpace([V1, V2]) +X = MultiFieldFESpace([U1, U2]) + +degree = 2 * order +Ω = Triangulation(model) +dΩ = Measure(Ω, degree) + +# Project constant 1 into both spaces. +a((u1, u2), (v1, v2)) = ∫(v1 * u1)dΩ + ∫(v2 * u2)dΩ +l((v1, v2)) = ∫(v1 + v2)dΩ + +op = AffineFEOperator(a, l, X, Y) +uh1, uh2 = solve(op) From e206e08e0fc338f48f8ed66a3664869a95822fcc Mon Sep 17 00:00:00 2001 From: Antoine Marteau Date: Fri, 8 Nov 2024 17:28:10 +1100 Subject: [PATCH 3/4] optimization of trivial MulAddMap evaluate! The (0,1) AttachDirichletMap is just (A,b,c) -> c . So we can avoid `mul!` in this case (but keep the `copyto!` for type stability when c is real but b and d=cache[2] are complex). I believe this is safe regarding type stability since `return_cache(::AttachDirichletMap)` uses an eager `Base.*` to create the `cache`, it does not rely on this evaluate. --- src/Arrays/AlgebraMaps.jl | 1 + src/Fields/ArrayBlocks.jl | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Arrays/AlgebraMaps.jl b/src/Arrays/AlgebraMaps.jl index c6bd5144c..546ab393b 100644 --- a/src/Arrays/AlgebraMaps.jl +++ b/src/Arrays/AlgebraMaps.jl @@ -35,6 +35,7 @@ function evaluate!(cache,k::MulAddMap,a,b,c) setsize!(cache,size(c)) d = cache.array copyto!(d,c) + iszero(k.α) && isone(k.β) && return d mul!(d,a,b,k.α,k.β) d end diff --git a/src/Fields/ArrayBlocks.jl b/src/Fields/ArrayBlocks.jl index 500fabfc6..12e03a04d 100644 --- a/src/Fields/ArrayBlocks.jl +++ b/src/Fields/ArrayBlocks.jl @@ -1281,6 +1281,7 @@ function evaluate!(cache,k::MulAddMap,a::ArrayBlock,b::ArrayBlock,c::ArrayBlock) _setsize_mul!(c1,a,b) d = evaluate!(c2,unwrap_cached_array,c1) copyto!(d,c) + iszero(k.α) && isone(k.β) && return d mul!(d,a,b,k.α,k.β) d end @@ -1517,4 +1518,4 @@ function Base.show(io::IO,o::ArrayBlockView) end LinearAlgebra.diag(a::MatrixBlockView) = view(a.array.array, diag(a.block_map)) -LinearAlgebra.diag(a::MatrixBlock) = view(a.array,diag(CartesianIndices(a.array))) \ No newline at end of file +LinearAlgebra.diag(a::MatrixBlock) = view(a.array,diag(CartesianIndices(a.array))) From 6462fd0e28f09856d63089ded454dce1a5236e9a Mon Sep 17 00:00:00 2001 From: Antoine Marteau Date: Mon, 11 Nov 2024 10:48:45 +1100 Subject: [PATCH 4/4] Update NEWS.md --- NEWS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.md b/NEWS.md index f2973a265..35a4ffd6b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +### Fixed + +- Fixed #974, an error when weak form is real but unknown vector is complex. Since PR[#1050](https://github.com/gridap/Gridap.jl/pull/1050). + ## [0.18.7] - 2024-10-8 ### Added