31 integer(kind=kint),
intent(in) :: etype
32 integer(kind=kint),
intent(in) :: nn
42 integer(kind=kint),
intent(in) :: etype
43 integer(kind=kint),
intent(in) :: nn
47 .and. ( material%nlgeom_flag ==
totallag .or. material%nlgeom_flag ==
updatelag ) &
53 type (hecmwst_local_mesh),
intent(in) :: hecmesh
56 integer(kind=kint) :: itype, is, ie, ic_type, icel, iis, nn
57 logical :: local_has_finite_rotation_kinematics
59 local_has_finite_rotation_kinematics = .false.
60 if( hecmesh%n_dof >= 3 .and.
associated( fstrsolid%elements ) )
then
61 element_type_loop:
do itype = 1, hecmesh%n_elem_type
62 is = hecmesh%elem_type_index(itype-1) + 1
63 ie = hecmesh%elem_type_index(itype)
64 ic_type = hecmesh%elem_type_item(itype)
66 iis = hecmesh%elem_node_index(icel-1)
67 nn = hecmesh%elem_node_index(icel) - iis
69 if( .not.
associated( fstrsolid%elements(icel)%gausses ) ) cycle
71 fstrsolid%elements(icel)%gausses(1)%pMaterial ) )
then
72 local_has_finite_rotation_kinematics = .true.
73 exit element_type_loop
76 end do element_type_loop
87 type (hecmwst_local_mesh),
intent(in) :: hecmesh
89 integer(kind=kint),
intent(in) :: ndof
90 integer(kind=kint),
intent(out) :: shell_node_mode(:)
92 integer(kind=kint) :: itype, is, ie, ic_type, icel, iis, nn, j, node_id
93 integer(kind=kint) :: node_offset, node_mode, shell_nnode
95 shell_node_mode(:) = 0
97 if( .not.
associated( fstrsolid%elements ) )
return
99 do itype = 1, hecmesh%n_elem_type
100 is = hecmesh%elem_type_index(itype-1) + 1
101 ie = hecmesh%elem_type_index(itype)
102 ic_type = hecmesh%elem_type_item(itype)
122 if( node_mode == 1 .and. ndof < 6 ) cycle
124 iis = hecmesh%elem_node_index(icel-1)
125 nn = hecmesh%elem_node_index(icel) - iis
127 if( .not.
associated( fstrsolid%elements(icel)%gausses ) ) cycle
129 fstrsolid%elements(icel)%gausses(1)%pMaterial ) ) cycle
131 do j = 1, shell_nnode
132 node_id = hecmesh%elem_node_item(iis+node_offset+j)
133 if( node_id > 0 .and. node_id <=
size(shell_node_mode) ) shell_node_mode(node_id) = node_mode
140 real(kind=kreal),
intent(in) :: theta(3)
141 real(kind=kreal),
intent(out) :: rotmat(3, 3)
144 real(kind=kreal) :: theta_norm, theta_norm2
145 real(kind=kreal) :: sin_over_theta, one_minus_cos_over_theta2
146 real(kind=kreal) :: skew(3, 3), skew2(3, 3)
148 theta_norm2 = dot_product(theta, theta)
149 theta_norm = dsqrt(theta_norm2)
151 skew2 = matmul(skew, skew)
153 if (theta_norm < 1.0d-12)
then
154 sin_over_theta = 1.0d0-theta_norm2/6.0d0+theta_norm2*theta_norm2/120.0d0
155 one_minus_cos_over_theta2 = 0.5d0-theta_norm2/24.0d0+theta_norm2*theta_norm2/720.0d0
157 sin_over_theta = dsin(theta_norm)/theta_norm
158 one_minus_cos_over_theta2 = (1.0d0-dcos(theta_norm))/theta_norm2
161 rotmat = sin_over_theta*skew+one_minus_cos_over_theta2*skew2
163 rotmat(i, i) = rotmat(i, i)+1.0d0
168 real(kind=kreal),
intent(in) :: rotmat(3, 3)
169 real(kind=kreal),
intent(out) :: theta(3)
171 real(kind=kreal) :: pi, trace_r, cos_angle, angle, sin_angle
172 real(kind=kreal) :: axis(3), axis_abs
174 pi = 4.0d0*datan(1.0d0)
175 trace_r = rotmat(1, 1)+rotmat(2, 2)+rotmat(3, 3)
176 cos_angle = max(-1.0d0, min(1.0d0, 0.5d0*(trace_r-1.0d0)))
177 angle = dacos(cos_angle)
179 theta(1) = rotmat(3, 2)-rotmat(2, 3)
180 theta(2) = rotmat(1, 3)-rotmat(3, 1)
181 theta(3) = rotmat(2, 1)-rotmat(1, 2)
183 if (angle < 1.0d-12)
then
185 else if (pi-angle < 1.0d-8)
then
186 axis(1) = dsqrt(max(0.0d0, 0.5d0*(rotmat(1, 1)+1.0d0)))
187 axis(2) = dsqrt(max(0.0d0, 0.5d0*(rotmat(2, 2)+1.0d0)))
188 axis(3) = dsqrt(max(0.0d0, 0.5d0*(rotmat(3, 3)+1.0d0)))
189 if (rotmat(2, 1)+rotmat(1, 2) < 0.0d0) axis(2) = -axis(2)
190 if (rotmat(3, 1)+rotmat(1, 3) < 0.0d0) axis(3) = -axis(3)
191 axis_abs = dsqrt(dot_product(axis, axis))
192 if (axis_abs > 1.0d-12)
then
193 theta = angle*axis/axis_abs
198 sin_angle = dsin(angle)
199 theta = angle*theta/(2.0d0*sin_angle)
204 real(kind=kreal),
intent(in) :: vector(3)
205 real(kind=kreal) :: matrix(3, 3)
208 matrix(1, 2) = -vector(3)
209 matrix(1, 3) = vector(2)
210 matrix(2, 1) = vector(3)
211 matrix(2, 3) = -vector(1)
212 matrix(3, 1) = -vector(2)
213 matrix(3, 2) = vector(1)
217 real(kind=kreal),
intent(in) :: theta_old(3), theta_inc(3)
218 real(kind=kreal),
intent(out) :: theta_new(3)
220 real(kind=kreal) :: rot_old(3, 3), rot_inc(3, 3), rot_new(3, 3)
224 rot_new = matmul(rot_inc, rot_old)
230 real(kind=kreal),
intent(in) :: triad_in(3, 3)
231 real(kind=kreal),
intent(out) :: triad_out(3, 3)
233 real(kind=kreal) :: e1(3), e2(3), e3(3), normv
237 normv = dsqrt(dot_product(e3, e3))
238 if (normv < 1.0d-14)
then
239 e3 = (/ 0.0d0, 0.0d0, 1.0d0 /)
244 e1 = e1-dot_product(e1, e3)*e3
245 normv = dsqrt(dot_product(e1, e1))
246 if (normv < 1.0d-14)
then
247 if (dabs(e3(1)) < 0.9d0)
then
248 e1 = (/ 1.0d0, 0.0d0, 0.0d0 /)
250 e1 = (/ 0.0d0, 1.0d0, 0.0d0 /)
252 e1 = e1-dot_product(e1, e3)*e3
253 normv = dsqrt(dot_product(e1, e1))
256 e2(1) = e3(2)*e1(3)-e3(3)*e1(2)
257 e2(2) = e3(3)*e1(1)-e3(1)*e1(3)
258 e2(3) = e3(1)*e1(2)-e3(2)*e1(1)
266 real(kind=kreal),
intent(in) :: triad_old(3, 3), drill_old, theta_inc(3)
267 real(kind=kreal),
intent(out) :: triad_new(3, 3), drill_new
269 integer :: isub, nsub
270 real(kind=kreal) :: triad_base(3, 3)
271 real(kind=kreal) :: director(3), theta_step(3), theta_phys(3)
272 real(kind=kreal) :: drill_acc, drill_inc, theta_norm
273 real(kind=kreal) :: rot_inc(3, 3), rot_full(3, 3), triad_trial(3, 3)
276 theta_norm = dsqrt(dot_product(theta_inc, theta_inc))
277 nsub = max(1, ceiling(theta_norm/5.0d-2))
278 theta_step = theta_inc/dble(nsub)
279 drill_acc = drill_old
282 director = triad_base(:, 3)
283 drill_inc = dot_product(theta_step, director)
284 theta_phys = theta_step-drill_inc*director
286 triad_trial = matmul(rot_inc, triad_base)
288 drill_acc = drill_acc+drill_inc
292 triad_trial = triad_base
293 triad_trial(:, 3) = matmul(rot_full, triad_old(:, 3))
295 drill_new = drill_acc
299 integer(kind=kint),
intent(in) :: ndof, nn
300 real(kind=kreal),
intent(in) :: disp_old(:, :), disp_inc(:, :)
301 real(kind=kreal),
intent(out) :: disp_new(6, nn)
303 integer :: i, ndof_copy
306 ndof_copy = min(ndof, 6)
308 disp_new(1:min(3, ndof_copy), i) = disp_old(1:min(3, ndof_copy), i)+disp_inc(1:min(3, ndof_copy), i)
309 if (ndof_copy >= 6)
then
311 else if (ndof_copy > 3)
then
312 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_mitc3_shell361
integer, parameter fe_mitc4_shell
integer, parameter fe_mitc4_shell361
integer, parameter fe_mitc3_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.