31 integer(kind=kint),
intent(in) :: etype
32 integer(kind=kint),
intent(in) :: nn
38 integer(kind=kint),
intent(in) :: etype
39 integer(kind=kint),
intent(in) :: nn
43 .and. ( material%nlgeom_flag ==
totallag .or. material%nlgeom_flag ==
updatelag ) &
49 type (hecmwst_local_mesh),
intent(in) :: hecmesh
52 integer(kind=kint) :: itype, is, ie, ic_type, icel, iis, nn
53 logical :: local_has_finite_rotation_kinematics
55 local_has_finite_rotation_kinematics = .false.
56 if( hecmesh%n_dof >= 6 .and.
associated( fstrsolid%elements ) )
then
57 element_type_loop:
do itype = 1, hecmesh%n_elem_type
58 is = hecmesh%elem_type_index(itype-1) + 1
59 ie = hecmesh%elem_type_index(itype)
60 ic_type = hecmesh%elem_type_item(itype)
64 iis = hecmesh%elem_node_index(icel-1)
65 nn = hecmesh%elem_node_index(icel) - iis
66 if( .not.
associated( fstrsolid%elements(icel)%gausses ) ) cycle
68 fstrsolid%elements(icel)%gausses(1)%pMaterial ) )
then
69 local_has_finite_rotation_kinematics = .true.
70 exit element_type_loop
73 end do element_type_loop
84 type (hecmwst_local_mesh),
intent(in) :: hecmesh
86 integer(kind=kint),
intent(in) :: ndof
87 integer(kind=kint),
intent(out) :: shell_node_mode(:)
89 integer(kind=kint) :: itype, is, ie, ic_type, icel, iis, nn, j, node_id
91 shell_node_mode(:) = 0
93 if( .not.
associated( fstrsolid%elements ) )
return
95 do itype = 1, hecmesh%n_elem_type
96 is = hecmesh%elem_type_index(itype-1) + 1
97 ie = hecmesh%elem_type_index(itype)
98 ic_type = hecmesh%elem_type_item(itype)
102 iis = hecmesh%elem_node_index(icel-1)
103 nn = hecmesh%elem_node_index(icel) - iis
104 if( .not.
associated( fstrsolid%elements(icel)%gausses ) ) cycle
106 fstrsolid%elements(icel)%gausses(1)%pMaterial ) ) cycle
109 node_id = hecmesh%elem_node_item(iis+j)
110 if( node_id > 0 .and. node_id <=
size(shell_node_mode) ) shell_node_mode(node_id) = 1
117 real(kind=kreal),
intent(in) :: theta(3)
118 real(kind=kreal),
intent(out) :: rotmat(3, 3)
121 real(kind=kreal) :: theta_norm, theta_norm2
122 real(kind=kreal) :: sin_over_theta, one_minus_cos_over_theta2
123 real(kind=kreal) :: skew(3, 3), skew2(3, 3)
125 theta_norm2 = dot_product(theta, theta)
126 theta_norm = dsqrt(theta_norm2)
128 skew2 = matmul(skew, skew)
130 if (theta_norm < 1.0d-12)
then
131 sin_over_theta = 1.0d0-theta_norm2/6.0d0+theta_norm2*theta_norm2/120.0d0
132 one_minus_cos_over_theta2 = 0.5d0-theta_norm2/24.0d0+theta_norm2*theta_norm2/720.0d0
134 sin_over_theta = dsin(theta_norm)/theta_norm
135 one_minus_cos_over_theta2 = (1.0d0-dcos(theta_norm))/theta_norm2
138 rotmat = sin_over_theta*skew+one_minus_cos_over_theta2*skew2
140 rotmat(i, i) = rotmat(i, i)+1.0d0
145 real(kind=kreal),
intent(in) :: rotmat(3, 3)
146 real(kind=kreal),
intent(out) :: theta(3)
148 real(kind=kreal) :: pi, trace_r, cos_angle, angle, sin_angle
149 real(kind=kreal) :: axis(3), axis_abs
151 pi = 4.0d0*datan(1.0d0)
152 trace_r = rotmat(1, 1)+rotmat(2, 2)+rotmat(3, 3)
153 cos_angle = max(-1.0d0, min(1.0d0, 0.5d0*(trace_r-1.0d0)))
154 angle = dacos(cos_angle)
156 theta(1) = rotmat(3, 2)-rotmat(2, 3)
157 theta(2) = rotmat(1, 3)-rotmat(3, 1)
158 theta(3) = rotmat(2, 1)-rotmat(1, 2)
160 if (angle < 1.0d-12)
then
162 else if (pi-angle < 1.0d-8)
then
163 axis(1) = dsqrt(max(0.0d0, 0.5d0*(rotmat(1, 1)+1.0d0)))
164 axis(2) = dsqrt(max(0.0d0, 0.5d0*(rotmat(2, 2)+1.0d0)))
165 axis(3) = dsqrt(max(0.0d0, 0.5d0*(rotmat(3, 3)+1.0d0)))
166 if (rotmat(2, 1)+rotmat(1, 2) < 0.0d0) axis(2) = -axis(2)
167 if (rotmat(3, 1)+rotmat(1, 3) < 0.0d0) axis(3) = -axis(3)
168 axis_abs = dsqrt(dot_product(axis, axis))
169 if (axis_abs > 1.0d-12)
then
170 theta = angle*axis/axis_abs
175 sin_angle = dsin(angle)
176 theta = angle*theta/(2.0d0*sin_angle)
181 real(kind=kreal),
intent(in) :: vector(3)
182 real(kind=kreal) :: matrix(3, 3)
185 matrix(1, 2) = -vector(3)
186 matrix(1, 3) = vector(2)
187 matrix(2, 1) = vector(3)
188 matrix(2, 3) = -vector(1)
189 matrix(3, 1) = -vector(2)
190 matrix(3, 2) = vector(1)
194 real(kind=kreal),
intent(in) :: theta_old(3), theta_inc(3)
195 real(kind=kreal),
intent(out) :: theta_new(3)
197 real(kind=kreal) :: rot_old(3, 3), rot_inc(3, 3), rot_new(3, 3)
201 rot_new = matmul(rot_inc, rot_old)
207 real(kind=kreal),
intent(in) :: triad_in(3, 3)
208 real(kind=kreal),
intent(out) :: triad_out(3, 3)
210 real(kind=kreal) :: e1(3), e2(3), e3(3), normv
214 normv = dsqrt(dot_product(e3, e3))
215 if (normv < 1.0d-14)
then
216 e3 = (/ 0.0d0, 0.0d0, 1.0d0 /)
221 e1 = e1-dot_product(e1, e3)*e3
222 normv = dsqrt(dot_product(e1, e1))
223 if (normv < 1.0d-14)
then
224 if (dabs(e3(1)) < 0.9d0)
then
225 e1 = (/ 1.0d0, 0.0d0, 0.0d0 /)
227 e1 = (/ 0.0d0, 1.0d0, 0.0d0 /)
229 e1 = e1-dot_product(e1, e3)*e3
230 normv = dsqrt(dot_product(e1, e1))
233 e2(1) = e3(2)*e1(3)-e3(3)*e1(2)
234 e2(2) = e3(3)*e1(1)-e3(1)*e1(3)
235 e2(3) = e3(1)*e1(2)-e3(2)*e1(1)
243 real(kind=kreal),
intent(in) :: triad_old(3, 3), drill_old, theta_inc(3)
244 real(kind=kreal),
intent(out) :: triad_new(3, 3), drill_new
246 integer :: isub, nsub
247 real(kind=kreal) :: triad_base(3, 3)
248 real(kind=kreal) :: director(3), theta_step(3), theta_phys(3)
249 real(kind=kreal) :: drill_acc, drill_inc, theta_norm
250 real(kind=kreal) :: rot_inc(3, 3), rot_full(3, 3), triad_trial(3, 3)
253 theta_norm = dsqrt(dot_product(theta_inc, theta_inc))
254 nsub = max(1, ceiling(theta_norm/5.0d-2))
255 theta_step = theta_inc/dble(nsub)
256 drill_acc = drill_old
259 director = triad_base(:, 3)
260 drill_inc = dot_product(theta_step, director)
261 theta_phys = theta_step-drill_inc*director
263 triad_trial = matmul(rot_inc, triad_base)
265 drill_acc = drill_acc+drill_inc
269 triad_trial = triad_base
270 triad_trial(:, 3) = matmul(rot_full, triad_old(:, 3))
272 drill_new = drill_acc
276 integer(kind=kint),
intent(in) :: ndof, nn
277 real(kind=kreal),
intent(in) :: disp_old(:, :), disp_inc(:, :)
278 real(kind=kreal),
intent(out) :: disp_new(6, nn)
280 integer :: i, ndof_copy
283 ndof_copy = min(ndof, 6)
285 disp_new(1:min(3, ndof_copy), i) = disp_old(1:min(3, ndof_copy), i)+disp_inc(1:min(3, ndof_copy), i)
286 if (ndof_copy >= 6)
then
288 else if (ndof_copy > 3)
then
289 disp_new(4:ndof_copy, i) = disp_old(4:ndof_copy, i)+disp_inc(4:ndof_copy, i)
This module encapsulate the basic functions of all elements provide by this software.
integer, parameter fe_mitc4_shell
Shared finite-rotation nodal kinematics and rotation algebra.
logical function, public fstr_is_finite_rotation_shell_element(etype, nn)
pure subroutine, public shellrotationvectortomatrix(theta, rotmat)
pure subroutine, public shellorthonormalizetriad(triad_in, triad_out)
logical function, public fstr_has_finite_rotation_kinematics(hecMESH, fstrSOLID)
pure real(kind=kreal) function, dimension(3, 3), public shellskewmatrix(vector)
pure subroutine, public shellupdatetriadwithincrement(triad_old, drill_old, theta_inc, triad_new, drill_new)
logical function, public fstr_uses_finite_rotation_kinematics(etype, nn, material)
pure subroutine, public shellcomposenodaldisplacement(ndof, nn, disp_old, disp_inc, disp_new)
pure subroutine, public shellcomposerotationvector(theta_old, theta_inc, theta_new)
subroutine, public fstr_mark_finite_rotation_nodes(hecMESH, fstrSOLID, ndof, shell_node_mode)
pure subroutine, public shellrotationmatrixtovector(rotmat, theta)
This module defines common data and basic structures for analysis.
subroutine hecmw_allreduce_l1(hecMESH, flag, ntag)
This module summarizes all information of material properties.
integer(kind=kint), parameter totallag
logical function iselastic(mtype)
If it is an elastic material?
integer(kind=kint), parameter updatelag
Structure to manage all material related data.