@@ -514,15 +514,14 @@ def _get_alpha_vec(x, y, tris_pts):
514
514
ab = _transpose_vectorized (abT )
515
515
OM = np .stack ([x , y ], axis = 1 ) - tris_pts [:, 0 , :]
516
516
517
- metric = _prod_vectorized ( ab , abT )
517
+ metric = ab @ abT
518
518
# Here we try to deal with the colinear cases.
519
519
# metric_inv is in this case set to the Moore-Penrose pseudo-inverse
520
520
# meaning that we will still return a set of valid barycentric
521
521
# coordinates.
522
522
metric_inv = _pseudo_inv22sym_vectorized (metric )
523
- Covar = _prod_vectorized (ab , _transpose_vectorized (
524
- np .expand_dims (OM , ndim )))
525
- ksi = _prod_vectorized (metric_inv , Covar )
523
+ Covar = ab @ _transpose_vectorized (np .expand_dims (OM , ndim ))
524
+ ksi = metric_inv @ Covar
526
525
alpha = _to_matrix_vectorized ([
527
526
[1 - ksi [:, 0 , 0 ]- ksi [:, 1 , 0 ]], [ksi [:, 0 , 0 ]], [ksi [:, 1 , 0 ]]])
528
527
return alpha
@@ -576,9 +575,9 @@ def _compute_tri_eccentricities(tris_pts):
576
575
c = np .expand_dims (tris_pts [:, 1 , :] - tris_pts [:, 0 , :], axis = 2 )
577
576
# Do not use np.squeeze, this is dangerous if only one triangle
578
577
# in the triangulation...
579
- dot_a = _prod_vectorized (_transpose_vectorized (a ), a )[:, 0 , 0 ]
580
- dot_b = _prod_vectorized (_transpose_vectorized (b ), b )[:, 0 , 0 ]
581
- dot_c = _prod_vectorized (_transpose_vectorized (c ), c )[:, 0 , 0 ]
578
+ dot_a = (_transpose_vectorized (a ) @ a )[:, 0 , 0 ]
579
+ dot_b = (_transpose_vectorized (b ) @ b )[:, 0 , 0 ]
580
+ dot_c = (_transpose_vectorized (c ) @ c )[:, 0 , 0 ]
582
581
# Note that this line will raise a warning for dot_a, dot_b or dot_c
583
582
# zeros, but we choose not to support triangles with duplicate points.
584
583
return _to_matrix_vectorized ([[(dot_c - dot_b ) / dot_a ],
@@ -711,15 +710,12 @@ def get_function_values(self, alpha, ecc, dofs):
711
710
V = _to_matrix_vectorized ([
712
711
[x_sq * x ], [y_sq * y ], [z_sq * z ], [x_sq * z ], [x_sq * y ], [y_sq * x ],
713
712
[y_sq * z ], [z_sq * y ], [z_sq * x ], [x * y * z ]])
714
- prod = _prod_vectorized (self .M , V )
715
- prod += _scalar_vectorized (E [:, 0 , 0 ],
716
- _prod_vectorized (self .M0 , V ))
717
- prod += _scalar_vectorized (E [:, 1 , 0 ],
718
- _prod_vectorized (self .M1 , V ))
719
- prod += _scalar_vectorized (E [:, 2 , 0 ],
720
- _prod_vectorized (self .M2 , V ))
713
+ prod = self .M @ V
714
+ prod += _scalar_vectorized (E [:, 0 , 0 ], self .M0 @ V )
715
+ prod += _scalar_vectorized (E [:, 1 , 0 ], self .M1 @ V )
716
+ prod += _scalar_vectorized (E [:, 2 , 0 ], self .M2 @ V )
721
717
s = _roll_vectorized (prod , 3 * subtri , axis = 0 )
722
- return _prod_vectorized (dofs , s )[:, 0 , 0 ]
718
+ return (dofs @ s )[:, 0 , 0 ]
723
719
724
720
def get_function_derivatives (self , alpha , J , ecc , dofs ):
725
721
"""
@@ -761,23 +757,20 @@ def get_function_derivatives(self, alpha, J, ecc, dofs):
761
757
[ - z_sq , 2. * x * z - z_sq ],
762
758
[ x * z - y * z , x * y - y * z ]])
763
759
# Puts back dV in first apex basis
764
- dV = _prod_vectorized (dV , _extract_submatrices (
765
- self .rotate_dV , subtri , block_size = 2 , axis = 0 ))
766
-
767
- prod = _prod_vectorized (self .M , dV )
768
- prod += _scalar_vectorized (E [:, 0 , 0 ],
769
- _prod_vectorized (self .M0 , dV ))
770
- prod += _scalar_vectorized (E [:, 1 , 0 ],
771
- _prod_vectorized (self .M1 , dV ))
772
- prod += _scalar_vectorized (E [:, 2 , 0 ],
773
- _prod_vectorized (self .M2 , dV ))
760
+ dV = dV @ _extract_submatrices (
761
+ self .rotate_dV , subtri , block_size = 2 , axis = 0 )
762
+
763
+ prod = (self .M @ dV
764
+ + _scalar_vectorized (E [:, 0 , 0 ], self .M0 @ dV )
765
+ + _scalar_vectorized (E [:, 1 , 0 ], self .M1 @ dV )
766
+ + _scalar_vectorized (E [:, 2 , 0 ], self .M2 @ dV ))
774
767
dsdksi = _roll_vectorized (prod , 3 * subtri , axis = 0 )
775
- dfdksi = _prod_vectorized ( dofs , dsdksi )
768
+ dfdksi = dofs @ dsdksi
776
769
# In global coordinates:
777
770
# Here we try to deal with the simplest colinear cases, returning a
778
771
# null matrix.
779
772
J_inv = _safe_inv22_vectorized (J )
780
- dfdx = _prod_vectorized ( J_inv , _transpose_vectorized (dfdksi ) )
773
+ dfdx = J_inv @ _transpose_vectorized (dfdksi )
781
774
return dfdx
782
775
783
776
def get_function_hessians (self , alpha , J , ecc , dofs ):
@@ -800,9 +793,9 @@ def get_function_hessians(self, alpha, J, ecc, dofs):
800
793
as a column-matrices of shape (N x 3 x 1).
801
794
"""
802
795
d2sdksi2 = self .get_d2Sidksij2 (alpha , ecc )
803
- d2fdksi2 = _prod_vectorized ( dofs , d2sdksi2 )
796
+ d2fdksi2 = dofs @ d2sdksi2
804
797
H_rot = self .get_Hrot_from_J (J )
805
- d2fdx2 = _prod_vectorized ( d2fdksi2 , H_rot )
798
+ d2fdx2 = d2fdksi2 @ H_rot
806
799
return _transpose_vectorized (d2fdx2 )
807
800
808
801
def get_d2Sidksij2 (self , alpha , ecc ):
@@ -837,15 +830,12 @@ def get_d2Sidksij2(self, alpha, ecc):
837
830
[ 0. , 2. * x - 4. * z , - 2. * z ],
838
831
[ - 2. * z , - 2. * y , x - y - z ]])
839
832
# Puts back d2V in first apex basis
840
- d2V = _prod_vectorized (d2V , _extract_submatrices (
841
- self .rotate_d2V , subtri , block_size = 3 , axis = 0 ))
842
- prod = _prod_vectorized (self .M , d2V )
843
- prod += _scalar_vectorized (E [:, 0 , 0 ],
844
- _prod_vectorized (self .M0 , d2V ))
845
- prod += _scalar_vectorized (E [:, 1 , 0 ],
846
- _prod_vectorized (self .M1 , d2V ))
847
- prod += _scalar_vectorized (E [:, 2 , 0 ],
848
- _prod_vectorized (self .M2 , d2V ))
833
+ d2V = d2V @ _extract_submatrices (
834
+ self .rotate_d2V , subtri , block_size = 3 , axis = 0 )
835
+ prod = self .M @ d2V
836
+ prod += _scalar_vectorized (E [:, 0 , 0 ], self .M0 @ d2V )
837
+ prod += _scalar_vectorized (E [:, 1 , 0 ], self .M1 @ d2V )
838
+ prod += _scalar_vectorized (E [:, 2 , 0 ], self .M2 @ d2V )
849
839
d2sdksi2 = _roll_vectorized (prod , 3 * subtri , axis = 0 )
850
840
return d2sdksi2
851
841
@@ -868,8 +858,8 @@ def get_bending_matrices(self, J, ecc):
868
858
n = np .size (ecc , 0 )
869
859
870
860
# 1) matrix to rotate dofs in global coordinates
871
- J1 = _prod_vectorized ( self .J0_to_J1 , J )
872
- J2 = _prod_vectorized ( self .J0_to_J2 , J )
861
+ J1 = self .J0_to_J1 @ J
862
+ J2 = self .J0_to_J2 @ J
873
863
DOF_rot = np .zeros ([n , 9 , 9 ], dtype = np .float64 )
874
864
DOF_rot [:, 0 , 0 ] = 1
875
865
DOF_rot [:, 3 , 3 ] = 1
@@ -891,13 +881,11 @@ def get_bending_matrices(self, J, ecc):
891
881
alpha = np .expand_dims (alpha , 2 )
892
882
weight = weights [igauss ]
893
883
d2Skdksi2 = self .get_d2Sidksij2 (alpha , ecc )
894
- d2Skdx2 = _prod_vectorized (d2Skdksi2 , H_rot )
895
- K += weight * _prod_vectorized (_prod_vectorized (d2Skdx2 , self .E ),
896
- _transpose_vectorized (d2Skdx2 ))
884
+ d2Skdx2 = d2Skdksi2 @ H_rot
885
+ K += weight * (d2Skdx2 @ self .E @ _transpose_vectorized (d2Skdx2 ))
897
886
898
887
# 4) With nodal (not elem) dofs
899
- K = _prod_vectorized (_prod_vectorized (_transpose_vectorized (DOF_rot ),
900
- K ), DOF_rot )
888
+ K = _transpose_vectorized (DOF_rot ) @ K @ DOF_rot
901
889
902
890
# 5) Need the area to compute total element energy
903
891
return _scalar_vectorized (area , K )
@@ -968,9 +956,8 @@ def get_Kff_and_Ff(self, J, ecc, triangles, Uc):
968
956
c_indices , triangles [:, 2 ]* 2 , triangles [:, 2 ]* 2 + 1 ]])
969
957
970
958
expand_indices = np .ones ([ntri , 9 , 1 ], dtype = np .int32 )
971
- f_row_indices = _prod_vectorized (_transpose_vectorized (f_dof_indices ),
972
- _transpose_vectorized (expand_indices ))
973
- f_col_indices = _prod_vectorized (expand_indices , f_dof_indices )
959
+ f_row_indices = _transpose_vectorized (expand_indices @ f_dof_indices )
960
+ f_col_indices = expand_indices @ f_dof_indices
974
961
K_elem = self .get_bending_matrices (J , ecc )
975
962
976
963
# Extracting sub-matrices
@@ -993,7 +980,7 @@ def get_Kff_and_Ff(self, J, ecc, triangles, Uc):
993
980
# Computing Ff force vector in sparse coo format
994
981
Kfc_elem = K_elem [np .ix_ (vec_range , f_dof , c_dof )]
995
982
Uc_elem = np .expand_dims (Uc , axis = 2 )
996
- Ff_elem = - _prod_vectorized (Kfc_elem , Uc_elem )[:, :, 0 ]
983
+ Ff_elem = - (Kfc_elem @ Uc_elem )[:, :, 0 ]
997
984
Ff_indices = f_dof_indices [np .ix_ (vec_range , [0 ], f_dof )][:, 0 , :]
998
985
999
986
# Extracting Ff force vector in dense format
@@ -1058,12 +1045,12 @@ def get_dof_vec(tri_z, tri_dz, J):
1058
1045
"""
1059
1046
npt = tri_z .shape [0 ]
1060
1047
dof = np .zeros ([npt , 9 ], dtype = np .float64 )
1061
- J1 = _prod_vectorized ( _ReducedHCT_Element .J0_to_J1 , J )
1062
- J2 = _prod_vectorized ( _ReducedHCT_Element .J0_to_J2 , J )
1048
+ J1 = _ReducedHCT_Element .J0_to_J1 @ J
1049
+ J2 = _ReducedHCT_Element .J0_to_J2 @ J
1063
1050
1064
- col0 = _prod_vectorized ( J , np .expand_dims (tri_dz [:, 0 , :], axis = 2 ) )
1065
- col1 = _prod_vectorized ( J1 , np .expand_dims (tri_dz [:, 1 , :], axis = 2 ) )
1066
- col2 = _prod_vectorized ( J2 , np .expand_dims (tri_dz [:, 2 , :], axis = 2 ) )
1051
+ col0 = J @ np .expand_dims (tri_dz [:, 0 , :], axis = 2 )
1052
+ col1 = J1 @ np .expand_dims (tri_dz [:, 1 , :], axis = 2 )
1053
+ col2 = J2 @ np .expand_dims (tri_dz [:, 2 , :], axis = 2 )
1067
1054
1068
1055
dfdksi = _to_matrix_vectorized ([
1069
1056
[col0 [:, 0 , 0 ], col1 [:, 0 , 0 ], col2 [:, 0 , 0 ]],
@@ -1377,7 +1364,6 @@ def _cg(A, b, x0=None, tol=1.e-10, maxiter=1000):
1377
1364
# The following private functions:
1378
1365
# :func:`_safe_inv22_vectorized`
1379
1366
# :func:`_pseudo_inv22sym_vectorized`
1380
- # :func:`_prod_vectorized`
1381
1367
# :func:`_scalar_vectorized`
1382
1368
# :func:`_transpose_vectorized`
1383
1369
# :func:`_roll_vectorized`
@@ -1499,23 +1485,6 @@ def _pseudo_inv22sym_vectorized(M):
1499
1485
return M_inv
1500
1486
1501
1487
1502
- def _prod_vectorized (M1 , M2 ):
1503
- """
1504
- Matrix product between arrays of matrices, or a matrix and an array of
1505
- matrices (*M1* and *M2*)
1506
- """
1507
- sh1 = M1 .shape
1508
- sh2 = M2 .shape
1509
- assert len (sh1 ) >= 2
1510
- assert len (sh2 ) >= 2
1511
- assert sh1 [- 1 ] == sh2 [- 2 ]
1512
-
1513
- ndim1 = len (sh1 )
1514
- t1_index = [* range (ndim1 - 2 ), ndim1 - 1 , ndim1 - 2 ]
1515
- return np .sum (np .transpose (M1 , t1_index )[..., np .newaxis ] *
1516
- M2 [..., np .newaxis , :], - 3 )
1517
-
1518
-
1519
1488
def _scalar_vectorized (scalar , M ):
1520
1489
"""
1521
1490
Scalar product between scalars and matrices.
0 commit comments