Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Daniel Boeckenhoff
tfields
Commits
46a81e34
Commit
46a81e34
authored
May 13, 2020
by
dboe
Browse files
indexing tests work
parent
309bb161
Changes
4
Hide whitespace changes
Inline
Side-by-side
test/test_core.py
View file @
46a81e34
...
...
@@ -71,6 +71,40 @@ class Tensors_Check(AbstractNdarray_Check):
self
.
assertEqual
(
self
.
_inst
.
coord_sys
,
other
.
coord_sys
)
self
.
assertEqual
(
self
.
_inst
.
name
,
other
.
name
)
def
test_slice_indexing
(
self
):
self
.
demand_index_equal
(
slice
(
0
,
None
,
None
),
'type'
)
def
test_pick_indexing
(
self
):
self
.
demand_index_equal
(
0
,
(
np
.
ndarray
,
np
.
integer
,
np
.
float
))
def
test_mask_indexing
(
self
):
mask
=
np
.
array
([
True
if
i
%
2
==
0
else
False
for
i
in
range
(
len
(
self
.
_inst
))])
self
.
demand_index_equal
(
mask
,
'type'
)
def
test_iteration
(
self
):
# iteration
iterator
=
iter
(
self
.
_inst
)
if
len
(
self
.
_inst
)
>
0
:
next
(
iterator
)
def
demand_index_equal
(
self
,
index
,
check_type
):
if
check_type
==
'type'
:
check_type
=
type
(
self
.
_inst
)
tensors
=
np
.
array
(
self
.
_inst
)
if
len
(
self
.
_inst
)
>
0
:
item
=
self
.
_inst
[
index
]
self
.
assertTrue
(
np
.
array_equal
(
item
,
tensors
[
index
]))
self
.
assertIsInstance
(
item
,
check_type
)
def
check_indexing
(
self
):
if
not
self
.
_inst
.
fields
and
len
(
self
.
_inst
)
==
0
:
return
fields
=
[
np
.
array
(
field
)
for
field
in
self
.
_inst
.
fields
]
for
f
,
field
in
enumerate
(
fields
):
self
.
_inst
.
fields
[
f
]
def
test_self_equality
(
self
):
# Test equality
self
.
demand_equal
(
self
.
_inst
)
...
...
@@ -126,6 +160,7 @@ class Tensors_Check(AbstractNdarray_Check):
class
TensorFields_Check
(
Tensors_Check
):
def
test_fields
(
self
):
self
.
assertIsNotNone
(
self
.
_inst
.
fields
)
if
self
.
_inst
.
fields
:
# field is of type list
self
.
assertTrue
(
isinstance
(
self
.
_inst
.
fields
,
list
))
...
...
@@ -136,11 +171,27 @@ class TensorFields_Check(Tensors_Check):
# fields are copied not reffered by a pointer
self
.
assertFalse
(
field
is
target_field
)
def
demand_index_equal
(
self
,
index
,
check_type
):
super
().
demand_index_equal
(
index
,
check_type
)
if
len
(
self
.
_inst
)
>
0
:
item
=
self
.
_inst
[
index
]
for
i
,
field
in
enumerate
(
self
.
_inst
.
fields
):
if
check_type
==
'type'
:
check_type
=
type
(
self
.
_inst
.
fields
[
i
])
self
.
assertTrue
(
np
.
array_equal
(
item
.
fields
[
i
],
np
.
array
(
self
.
_inst
.
fields
[
i
])[
index
]))
self
.
assertIsInstance
(
item
.
fields
[
i
],
check_type
)
class
TensorMaps_Check
(
TensorFields_Check
):
def
test_maps
(
self
):
self
.
assertIsNotNone
(
self
.
_inst
.
maps
)
def
demand_index_equal
(
self
,
index
,
check_type
):
super
().
demand_index_equal
(
index
,
check_type
)
# TODO: this is hard to check generically
"""
EMPTY TESTS
...
...
@@ -200,6 +251,14 @@ class TensorMaps_Test(TensorMaps_Empty_Test):
maps
=
self
.
_maps
)
class
TensorMaps_NoFields_Test
(
TensorMaps_Test
):
def
setUp
(
self
):
self
.
_inst
=
tfields
.
TensorMaps
(
[[
1
,
2
,
3
],
[
3
,
3
,
3
],
[
0
,
0
,
0
],
[
5
,
6
,
7
]],
maps
=
[[[
0
,
1
,
2
],
[
1
,
2
,
3
]],
[[
1
]],
[[
0
,
1
,
2
,
3
]]]
)
class
Maps_Test
(
Base_Check
,
unittest
.
TestCase
):
def
demand_equal
(
self
,
other
):
self
.
_inst
.
equal
(
other
)
...
...
test/test_mesh3D.py
View file @
46a81e34
...
...
@@ -4,13 +4,13 @@ import unittest
import
sympy
# NOQA: F401
import
os
import
sys
from
.test_core
import
Tensor
Field
s_Check
from
.test_core
import
Tensor
Map
s_Check
THIS_DIR
=
os
.
path
.
dirname
(
os
.
path
.
realpath
(
os
.
path
.
join
(
os
.
getcwd
(),
os
.
path
.
expanduser
(
__file__
))))
sys
.
path
.
append
(
os
.
path
.
normpath
(
os
.
path
.
join
(
THIS_DIR
)))
class
Mesh3D_Check
(
Tensor
Field
s_Check
):
class
Mesh3D_Check
(
Tensor
Map
s_Check
):
def
test_cut_split
(
self
):
x
,
y
,
z
=
sympy
.
symbols
(
'x y z'
)
self
.
_inst
.
cut
(
x
+
1.
/
100
*
y
>
0
,
at_intersection
=
'split'
)
...
...
tfields/core.py
View file @
46a81e34
...
...
@@ -557,8 +557,10 @@ class AbstractNdarray(np.ndarray, AbstractObject):
>>> import tfields
>>> m = tfields.TensorMaps(
... [[1,2,3], [3,3,3], [0,0,0], [5,6,7]],
... maps=[[[0, 1, 2], [1, 2, 3]], [
1, 2])
])
... maps=[[[0, 1, 2], [1, 2, 3]], [
[1]], [[0, 1, 2, 3]]
])
>>> mc = m.copy()
>>> mc.equal(m)
True
>>> mc is m
False
>>> mc.maps[3].fields[0] is m.maps[3].fields[0]
...
...
@@ -1828,10 +1830,11 @@ class TensorFields(Tensors):
>>> import tfields
>>> import numpy as np
>>> vectors = tfields.Tensors([[0, 0, 0], [0, 0, 1], [0, -1, 0]])
>>> scalar_field = tfields.TensorFields(vectors,
... [42, 21, 10.5],
... [1, 2, 3],
... [[0, 0], [-1, -1], [-2, -2]])
>>> scalar_field = tfields.TensorFields(
... vectors,
... [42, 21, 10.5],
... [1, 2, 3],
... [[0, 0], [-1, -1], [-2, -2]])
Slicing
...
...
@@ -1858,7 +1861,7 @@ class TensorFields(Tensors):
>>> _ = [point for point in scalar_field]
"""
item
=
super
(
TensorFields
,
self
).
__getitem__
(
index
)
item
=
super
().
__getitem__
(
index
)
try
:
if
issubclass
(
type
(
item
),
TensorFields
):
if
isinstance
(
index
,
tuple
):
...
...
@@ -2112,36 +2115,41 @@ class Maps(sortedcontainers.SortedDict, AbstractObject):
sortedcontainers
.
SortedItemsView
):
args
=
tuple
([
v
for
k
,
v
in
args
[
0
]])
elif
len
(
args
)
==
1
and
isinstance
(
args
[
0
],
list
):
if
args
[
0
]:
# not not Maps([])
if
issubclass
(
type
(
args
[
0
][
0
]),
tuple
):
# Maps([(key, value), (key, value), ...])
args
=
tuple
(
v
for
k
,
v
in
args
[
0
])
new_args
=
tuple
()
for
entry
in
args
[
0
]:
if
issubclass
(
type
(
entry
),
tuple
):
if
np
.
issubdtype
(
type
(
entry
[
0
]),
np
.
integer
):
# Maps([(key, value), ...])
new_args
+=
(
entry
[
1
])
else
:
# Maps([(tensors, field1, field2), ...])
new_args
+=
(
entry
)
else
:
# Maps([mp, mp, ...])
args
=
tuple
(
args
[
0
])
else
:
# Maps([]) -> Maps()
args
=
tuple
()
args
=
new_args
elif
len
(
args
)
==
1
and
issubclass
(
type
(
args
[
0
]),
dict
):
# Maps([]) - includes Maps i.e. copy
# dangerous because we run beefore super init
args
=
tuple
(
args
[
0
].
values
())
elif
len
(
args
)
==
0
and
kwargs
:
args
=
tuple
(
kwargs
.
values
())
kwags
=
{}
kwa
r
gs
=
{}
# By now everything must have been converted to flat args
# Maps(tfields.TensorFields([], dim=3), [[1,2,3]])
arg_tuple_list
=
[]
for
i
,
arg
in
enumerate
(
args
):
if
not
isinstance
(
type
(
arg
),
tuple
):
dimension
=
dim
(
arg
)
mp
=
arg
if
isinstance
(
type
(
arg
),
list
):
mp
=
self
.
to_map
(
*
arg
,
copy
=
True
)
dimension
=
dim
(
mp
)
elif
not
isinstance
(
type
(
arg
),
tuple
):
mp
=
self
.
to_map
(
arg
,
copy
=
True
)
dimension
=
dim
(
mp
)
else
:
dimension
,
mp
=
arg
dimension
=
int
(
dimension
)
arg_tuple_list
.
append
((
dimension
,
self
.
to_map
(
mp
,
copy
=
True
)
))
mp
=
self
.
to_map
(
mp
,
copy
=
True
)
arg_tuple_list
.
append
((
dimension
,
mp
))
super
().
__init__
(
arg_tuple_list
,
**
kwargs
)
...
...
@@ -2149,7 +2157,7 @@ class Maps(sortedcontainers.SortedDict, AbstractObject):
def
to_map
(
mp
,
*
fields
,
copy
=
False
):
if
not
copy
:
if
isinstance
(
mp
,
TensorFields
)
and
not
fields
:
if
not
np
.
issubdtype
(
n
p
.
int32
,
np
.
integer
):
if
not
np
.
issubdtype
(
m
p
.
dtype
,
np
.
integer
):
mp
=
mp
.
astype
(
int
)
else
:
copy
=
True
...
...
@@ -2161,28 +2169,19 @@ class Maps(sortedcontainers.SortedDict, AbstractObject):
)
return
mp
def
__setitem__
(
self
,
dim
,
mp
):
def
__setitem__
(
self
,
dim
ension
,
mp
):
mp
=
self
.
to_map
(
mp
)
if
not
dim
==
mp
.
dim
:
if
not
dim
ension
==
mp
.
dim
:
raise
KeyError
(
"Incorrect map dimension {mp.dim} for index {dim}"
.
format
(
**
locals
())
)
if
dim
==
0
:
warnings
.
warn
(
"Using map dimension {dim}"
.
format
(
**
locals
())
)
super
().
__setitem__
(
dim
,
mp
)
super
().
__setitem__
(
dimension
,
mp
)
def
__getitem__
(
self
,
dim
):
if
dim
==
0
:
warnings
.
warn
(
"Using map dimension {dim}"
.
format
(
**
locals
())
)
return
super
().
__getitem__
(
dim
)
def
__getitem__
(
self
,
dimension
):
if
dimension
==
0
:
warnings
.
warn
(
"Using map dimension 0"
)
return
super
().
__getitem__
(
dimension
)
def
_args
(
self
):
return
super
().
_args
()
+
tuple
(
self
.
values
())
...
...
@@ -2195,8 +2194,8 @@ class Maps(sortedcontainers.SortedDict, AbstractObject):
"""
if
not
self
.
keys
()
==
other
.
keys
():
return
False
for
dim
in
self
.
keys
():
if
not
self
[
dim
].
equal
(
other
[
dim
],
**
kwargs
):
for
dim
ension
in
self
.
keys
():
if
not
self
[
dim
ension
].
equal
(
other
[
dim
ension
],
**
kwargs
):
return
False
return
True
...
...
@@ -2311,14 +2310,15 @@ class TensorMaps(TensorFields):
index
=
index
[
0
]
if
item
.
maps
:
item
.
maps
=
Maps
(
item
.
maps
)
indices
=
np
.
a
rray
(
range
(
len
(
self
))
)
indices
=
np
.
arange
(
len
(
self
))
keep_indices
=
indices
[
index
]
if
isinstanc
e
(
keep_indices
,
(
int
,
np
.
int64
,
np
.
int
32
)
):
if
np
.
issubdtyp
e
(
keep_indices
.
dtype
,
np
.
int
eger
):
keep_indices
=
[
keep_indices
]
delete_indices
=
set
(
indices
).
difference
(
set
(
keep_indices
))
delete_indices
=
set
(
indices
.
flatten
())
\
.
difference
(
set
(
keep_indices
.
flatten
))
# correct all maps that contain deleted indices
for
map_dim
in
self
.
maps
.
keys
()
:
for
map_dim
in
self
.
maps
:
# build mask, where the map should be deleted
map_delete_mask
=
np
.
full
(
(
len
(
self
.
maps
[
map_dim
]),),
False
,
dtype
=
bool
...
...
tfields/mesh3D.py
View file @
46a81e34
...
...
@@ -141,15 +141,12 @@ def fields_to_scalars(fields):
def
faces_to_maps
(
faces
,
*
fields
):
# TODO: replace by Maps.to_maps or so
return
tfields
.
Maps
(
tfields
.
TensorFields
(
faces
,
*
fields
,
dtype
=
int
,
dim
=
3
)
)
def
maps_to_faces
(
maps
):
return
np
.
array
(
maps
[
3
])
class
Mesh3D
(
tfields
.
TensorMaps
):
# pylint: disable=R0904
"""
...
...
@@ -226,8 +223,7 @@ class Mesh3D(tfields.TensorMaps):
else
:
map_fields
=
[]
if
faces
is
not
None
:
kwargs
[
'maps'
]
=
faces_to_maps
(
faces
,
*
map_fields
)
kwargs
[
'maps'
]
=
[(
faces
,)
+
tuple
(
map_fields
)]
obj
=
super
(
Mesh3D
,
cls
).
__new__
(
cls
,
tensors
,
*
fields
,
**
kwargs
)
if
len
(
obj
.
maps
)
>
1
:
raise
ValueError
(
"Mesh3D only allows one map"
)
...
...
@@ -264,7 +260,8 @@ class Mesh3D(tfields.TensorMaps):
norm
=
colors
.
Normalize
(
vmin
,
vmax
)
color_map
=
plt
.
get_cmap
(
cmap
)
else
:
# switch for not coloring the triangles and thus not producing the materials
# switch for not coloring the triangles and thus not producing the
# materials
norm
=
None
if
len
(
kwargs
)
!=
0
:
...
...
@@ -286,7 +283,8 @@ class Mesh3D(tfields.TensorMaps):
mf
.
write
(
"Kd 0 0 0
\n\n
"
)
else
:
mf
.
write
(
"newmtl mtl_{0}
\n
"
.
format
(
s
))
mf
.
write
(
"Kd {c[0]} {c[1]} {c[2]}
\n\n
"
.
format
(
c
=
color_map
(
norm
(
s
))))
mf
.
write
(
"Kd {c[0]} {c[1]} {c[2]}
\n\n
"
.
format
(
c
=
color_map
(
norm
(
s
))))
else
:
sorted_faces
=
self
.
faces
...
...
@@ -493,18 +491,25 @@ class Mesh3D(tfields.TensorMaps):
@
property
def
faces
(
self
):
return
maps_to_faces
(
self
.
maps
)
if
self
.
maps
:
return
self
.
maps
[
3
]
else
:
return
tfields
.
Maps
.
to_map
(
np
.
empty
((
0
,
3
)))
# empty TensorFields object
@
faces
.
setter
def
faces
(
self
,
faces
):
self
.
maps
=
faces_to_maps
(
faces
)
self
.
maps
=
tfields
.
Maps
()
# circumvent the copy constructor
mp
=
tfields
.
Maps
.
to_map
(
faces
)
self
.
maps
[
tfields
.
dim
(
mp
)]
=
mp
@
property
def
faceScalars
(
self
):
# TODO: BAD NAME
return
fields_to_scalars
(
self
.
maps
[
3
].
fields
)
@
faceScalars
.
setter
def
faceScalars
(
self
,
scalars
):
# TODO: BAD NAME
self
.
maps
[
3
].
fields
=
scalars_to_fields
(
scalars
)
@
cached_property
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment