Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MultiValues component names export #1038

Merged
merged 10 commits into from
Oct 24, 2024
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Added MacroFElements. These are defined as having the basis/dof-basis of a FESpace created on top of a RefinementRule. Since PR[#1024](/~https://github.com/gridap/Gridap.jl/pull/1024).
- Added Barycentric refinement rule in 2D and 3D. Added Simplexify refinement rule. Since PR[#1024](/~https://github.com/gridap/Gridap.jl/pull/1024).
- Added names to vector and tensor components in VTK exports, to avoid Paraview's automatic (sometimes wrong) guesses. See `TensorValues.indep_components_names`. Since PR[#1038](/~https://github.com/gridap/Gridap.jl/pull/1038).

## [0.18.6] - 2024-08-29

Expand Down
12 changes: 12 additions & 0 deletions src/TensorValues/MultiValueTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,15 @@ end
function data_index(::Type{<:MultiValue},i...)
@abstractmethod
end

"""
indep_components_names(::MultiValue)

Returns an array of strings containing the component labels in the order they are stored internally, consistently with _prepare_data(::Multivalue)

If all dimensions of the tensor shape S are smaller than 3, the components should be named with letters "X","Y" and "Z" similarly to the automatic naming of Paraview. Else, if max(S)>3, they are labeled from "1" to "\$dim".
"""
function indep_components_names(::Type{MultiValue{S,T,N,L}}) where {S,T,N,L}
return ["$i" for i in 1:L]
end

15 changes: 14 additions & 1 deletion src/TensorValues/SymFourthOrderTensorValueTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
# This is in fact the "symmetrized" 4th order identity
@generated function one(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T}
S = typeof(one(T)/2)
str = join(["($i==$k && $j==$l) ? ( $i==$j ? one($S) : one(T)/2) : zero($S), " for i in 1:D for j in i:D for k in 1:D for l in k:D])
str = join(["($i==$k && $j==$l) ? ( $i==$j ? one($S) : one($S)/2) : zero($S), " for i in 1:D for j in i:D for k in 1:D for l in k:D])
Meta.parse("SymFourthOrderTensorValue{D,$S}(($str))")
end
one(::SymFourthOrderTensorValue{D,T}) where {D,T} = one(SymFourthOrderTensorValue{D,T})
Expand Down Expand Up @@ -116,3 +116,16 @@
num_components(::Type{<:SymFourthOrderTensorValue{D}}) where {D} = length(SymFourthOrderTensorValue{D})
num_components(::SymFourthOrderTensorValue{D}) where {D} = num_components(SymFourthOrderTensorValue{D})

###############################################################
# VTK export (SymFourthOrderTensorValue)
###############################################################

function indep_components_names(::Type{<:SymFourthOrderTensorValue{A}}) where A
if A>3
return ["$i$j$k$l" for i in 1:A for j in i:A for k in 1:A for l in k:A ]

Check warning on line 125 in src/TensorValues/SymFourthOrderTensorValueTypes.jl

View check run for this annotation

Codecov / codecov/patch

src/TensorValues/SymFourthOrderTensorValueTypes.jl#L125

Added line #L125 was not covered by tests
else
c_name = ["X", "Y", "Z"]
return [c_name[i]*c_name[j]*c_name[k]*c_name[l] for i in 1:A for j in i:A for k in 1:A for l in k:A ]
end
end

13 changes: 13 additions & 0 deletions src/TensorValues/SymTensorValueTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,16 @@ length(::SymTensorValue{D}) where {D} = length(SymTensorValue{D})

num_components(::Type{<:SymTensorValue{D}}) where {D} = length(SymTensorValue{D})
num_components(::SymTensorValue{D}) where {D} = num_components(SymTensorValue{D})

###############################################################
# VTK export (SymTensorValue)
###############################################################

function indep_components_names(::Type{<:SymTensorValue{D}}) where D
if D>3
return ["$i$j" for i in 1:D for j in i:D ]
else
c_name = ["X", "Y", "Z"]
return [c_name[i]*c_name[j] for i in 1:D for j in i:D ]
end
end
14 changes: 13 additions & 1 deletion src/TensorValues/TensorValueTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct TensorValue{D1,D2,T,L} <: MultiValue{Tuple{D1,D2},T,2,L}
end

###############################################################
# Constructors
# Constructors
###############################################################

# Empty TensorValue constructor
Expand Down Expand Up @@ -145,3 +145,15 @@ num_components(::Type{<:TensorValue{D}}) where {D} = length(TensorValue{D,D})
num_components(::Type{<:TensorValue{D1,D2}}) where {D1,D2} = length(TensorValue{D1,D2})
num_components(::TensorValue{D1,D2}) where {D1,D2} = num_components(TensorValue{D1,D2})

###############################################################
# VTK export (TensorValue)
###############################################################

function indep_components_names(::Type{<:TensorValue{D1,D2}}) where {D1,D2}
if D1>3 || D2>3
return ["$i$j" for i in 1:D1 for j in 1:D2 ]
else
c_name = ["X", "Y", "Z"]
return [c_name[i]*c_name[j] for i in 1:D1 for j in 1:D2 ]
end
end
1 change: 1 addition & 0 deletions src/TensorValues/TensorValues.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export ⋅¹
export ⋅²
export double_contraction
export data_index
export indep_components_names

import Base: show
import Base: zero, one
Expand Down
13 changes: 13 additions & 0 deletions src/TensorValues/ThirdOrderTensorValueTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,16 @@ length(::ThirdOrderTensorValue{D1,D2,D3}) where {D1,D2,D3} = length(ThirdOrderTe
num_components(::Type{<:ThirdOrderTensorValue{D1,D2,D3}}) where {D1,D2,D3} = length(ThirdOrderTensorValue{D1,D2,D3})
num_components(::ThirdOrderTensorValue{D1,D2,D3}) where {D1,D2,D3} = num_components(ThirdOrderTensorValue{D1,D2,D3})

###############################################################
# VTK export (ThirdOrderTensorValue)
###############################################################

function indep_components_names(::Type{<:ThirdOrderTensorValue{D1,D2,D3}}) where {D1,D2,D3}
if D1>3 || D2>3 || D3>3
return ["$i$j$k" for i in 1:D1 for j in 1:D2 for k in 1:D3 ]
else
c_name = ["X", "Y", "Z"]
return [c_name[i]*c_name[j]*c_name[k] for i in 1:D1 for j in 1:D2 for k in 1:D3]
end
end

14 changes: 14 additions & 0 deletions src/TensorValues/VectorValueTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,17 @@ length(::VectorValue{D}) where {D} = length(VectorValue{D})

num_components(::Type{<:VectorValue{D}}) where {D} = length(VectorValue{D})
num_components(::VectorValue{D}) where {D} = num_components(VectorValue{D})

###############################################################
# VTK export (VectorValue)
###############################################################

function indep_components_names(::Type{<:VectorValue{A}}) where A
[ "$i" for i in 1:A ]
if A>3
return ["$i" for i in 1:A ]
else
c_name = ["X", "Y", "Z"]
return [c_name[i] for i in 1:A ]
end
end
5 changes: 0 additions & 5 deletions src/Visualization/Visualization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,15 @@ import Gridap.Geometry: get_cell_type
import Gridap.Geometry: get_node_coordinates
import Gridap.Geometry: get_cell_node_ids

#import AbstractTrees

export writevtk
export createvtk
export createpvd
export savepvd
export write_vtk_file
#export print_op_tree
export visualization_data
export VisualizationData

include("VisualizationData.jl")
include("Vtk.jl")

#include("PrintOpTrees.jl")

end # module
19 changes: 14 additions & 5 deletions src/Visualization/Vtk.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ This function only creates the vtkFile, without writing to disk.
The optional WriteVTK kwargs `vtk_kwargs` are passed to the `vtk_grid` constructor.
"""
function create_vtk_file(
trian::Grid, filebase; celldata=Dict(), nodaldata=Dict(),
trian::Grid, filebase; celldata=Dict(), nodaldata=Dict(),
compress=false, append=true, ascii=false, vtkversion=:default
)

Expand All @@ -94,10 +94,12 @@ function create_vtk_file(

if num_cells(trian)>0
for (k,v) in celldata
vtk_cell_data(vtkfile, _prepare_data(v), k)
component_names = _data_component_names(v)
vtk_cell_data(vtkfile, _prepare_data(v), k; component_names)
end
for (k,v) in nodaldata
vtk_point_data(vtkfile, _prepare_data(v), k)
component_names = _data_component_names(v)
vtk_point_data(vtkfile, _prepare_data(v), k; component_names)
end
end

Expand All @@ -118,10 +120,13 @@ function create_pvtk_file(

if num_cells(trian) > 0
for (k, v) in celldata
vtkfile[k, VTKCellData()] = _prepare_data(v)
# component_names are actually always nothing as there are no field in ptvk atm
component_names = _data_component_names(v)
vtkfile[k, VTKCellData(), component_names=component_names] = _prepare_data(v)
end
for (k, v) in nodaldata
vtkfile[k, VTKPointData()] = _prepare_data(v)
component_names = _data_component_names(v)
vtkfile[k, VTKPointData(), component_names=component_names] = _prepare_data(v)
end
end
return vtkfile
Expand Down Expand Up @@ -181,6 +186,10 @@ function _generate_vtk_cells(

end

_data_component_names(v) = nothing

_data_component_names(v::AbstractArray{T}) where T<:MultiValue = indep_components_names(T)

_prepare_data(v) = v

function _prepare_data(v::AbstractArray{<:MultiValue})
Expand Down
13 changes: 13 additions & 0 deletions test/TensorValuesTests/TypesTests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,19 @@ v = VectorValue(m)
@test num_components(SymTensorValue(1,2,3)) == 4
@test num_components(SymFourthOrderTensorValue(1111,1121,1122, 2111,2121,2122, 2211,2221,2222)) == 16

@test indep_components_names(VectorValue{3}) == ["X","Y","Z"]
@test indep_components_names(VectorValue{4}) == ["1","2","3","4"]
@test indep_components_names(TensorValue{2,2}) == ["XX","XY","YX","YY"]
@test indep_components_names(TensorValue{2,4}) == ["11","12","13","14","21","22","23","24",]
@test indep_components_names(SymTensorValue{2}) == ["XX","XY","YY"]
@test indep_components_names(SymTensorValue{4}) == ["11","12","13","14","22","23","24","33","34","44"]
@test indep_components_names(ThirdOrderTensorValue{2,2,1}) == ["XXX","XYX","YXX","YYX"]
@test indep_components_names(ThirdOrderTensorValue{1,4,1}) == ["111","121","131","141"]
@test indep_components_names(SymFourthOrderTensorValue{2}) == [
"XXXX", "XXXY", "XXYY", "XYXX", "XYXY", "XYYY", "YYXX", "YYXY", "YYYY"
]
@test indep_components_names(MultiValue{Tuple{3,4},Int,2,5}) == ["1","2","3","4","5"]

a = VectorValue(1,2,3,4)
@test change_eltype(a,Float64) == VectorValue{4,Float64}

Expand Down
Loading