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 ) &
48 type (hecmwst_local_mesh),
intent(in) :: hecmesh
51 integer(kind=kint) :: itype, is, ie, ic_type, icel, iis, nn
54 if( hecmesh%n_dof < 6 )
return
55 if( .not.
associated( fstrsolid%elements ) )
return
57 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
77 type (hecmwst_local_mesh),
intent(in) :: hecmesh
79 integer(kind=kint),
intent(in) :: ndof
80 integer(kind=kint),
intent(out) :: shell_node_mode(:)
82 integer(kind=kint) :: itype, is, ie, ic_type, icel, iis, nn, j, node_id
84 shell_node_mode(:) = 0
86 if( .not.
associated( fstrsolid%elements ) )
return
88 do itype = 1, hecmesh%n_elem_type
89 is = hecmesh%elem_type_index(itype-1) + 1
90 ie = hecmesh%elem_type_index(itype)
91 ic_type = hecmesh%elem_type_item(itype)
95 iis = hecmesh%elem_node_index(icel-1)
96 nn = hecmesh%elem_node_index(icel) - iis
97 if( .not.
associated( fstrsolid%elements(icel)%gausses ) ) cycle
99 fstrsolid%elements(icel)%gausses(1)%pMaterial ) ) cycle
102 node_id = hecmesh%elem_node_item(iis+j)
103 if( node_id > 0 .and. node_id <=
size(shell_node_mode) ) shell_node_mode(node_id) = 1
110 real(kind=kreal),
intent(in) :: theta(3)
111 real(kind=kreal),
intent(out) :: rotmat(3, 3)
114 real(kind=kreal) :: theta_norm, theta_norm2
115 real(kind=kreal) :: sin_over_theta, one_minus_cos_over_theta2
116 real(kind=kreal) :: skew(3, 3), skew2(3, 3)
118 theta_norm2 = dot_product(theta, theta)
119 theta_norm = dsqrt(theta_norm2)
121 skew2 = matmul(skew, skew)
123 if (theta_norm < 1.0d-12)
then
124 sin_over_theta = 1.0d0-theta_norm2/6.0d0+theta_norm2*theta_norm2/120.0d0
125 one_minus_cos_over_theta2 = 0.5d0-theta_norm2/24.0d0+theta_norm2*theta_norm2/720.0d0
127 sin_over_theta = dsin(theta_norm)/theta_norm
128 one_minus_cos_over_theta2 = (1.0d0-dcos(theta_norm))/theta_norm2
131 rotmat = sin_over_theta*skew+one_minus_cos_over_theta2*skew2
133 rotmat(i, i) = rotmat(i, i)+1.0d0
138 real(kind=kreal),
intent(in) :: rotmat(3, 3)
139 real(kind=kreal),
intent(out) :: theta(3)
141 real(kind=kreal) :: pi, trace_r, cos_angle, angle, sin_angle
142 real(kind=kreal) :: axis(3), axis_abs
144 pi = 4.0d0*datan(1.0d0)
145 trace_r = rotmat(1, 1)+rotmat(2, 2)+rotmat(3, 3)
146 cos_angle = max(-1.0d0, min(1.0d0, 0.5d0*(trace_r-1.0d0)))
147 angle = dacos(cos_angle)
149 theta(1) = rotmat(3, 2)-rotmat(2, 3)
150 theta(2) = rotmat(1, 3)-rotmat(3, 1)
151 theta(3) = rotmat(2, 1)-rotmat(1, 2)
153 if (angle < 1.0d-12)
then
155 else if (pi-angle < 1.0d-8)
then
156 axis(1) = dsqrt(max(0.0d0, 0.5d0*(rotmat(1, 1)+1.0d0)))
157 axis(2) = dsqrt(max(0.0d0, 0.5d0*(rotmat(2, 2)+1.0d0)))
158 axis(3) = dsqrt(max(0.0d0, 0.5d0*(rotmat(3, 3)+1.0d0)))
159 if (rotmat(2, 1)+rotmat(1, 2) < 0.0d0) axis(2) = -axis(2)
160 if (rotmat(3, 1)+rotmat(1, 3) < 0.0d0) axis(3) = -axis(3)
161 axis_abs = dsqrt(dot_product(axis, axis))
162 if (axis_abs > 1.0d-12)
then
163 theta = angle*axis/axis_abs
168 sin_angle = dsin(angle)
169 theta = angle*theta/(2.0d0*sin_angle)
174 real(kind=kreal),
intent(in) :: vector(3)
175 real(kind=kreal) :: matrix(3, 3)
178 matrix(1, 2) = -vector(3)
179 matrix(1, 3) = vector(2)
180 matrix(2, 1) = vector(3)
181 matrix(2, 3) = -vector(1)
182 matrix(3, 1) = -vector(2)
183 matrix(3, 2) = vector(1)
187 real(kind=kreal),
intent(in) :: theta_old(3), theta_inc(3)
188 real(kind=kreal),
intent(out) :: theta_new(3)
190 real(kind=kreal) :: rot_old(3, 3), rot_inc(3, 3), rot_new(3, 3)
194 rot_new = matmul(rot_inc, rot_old)
200 real(kind=kreal),
intent(in) :: triad_in(3, 3)
201 real(kind=kreal),
intent(out) :: triad_out(3, 3)
203 real(kind=kreal) :: e1(3), e2(3), e3(3), normv
207 normv = dsqrt(dot_product(e3, e3))
208 if (normv < 1.0d-14)
then
209 e3 = (/ 0.0d0, 0.0d0, 1.0d0 /)
214 e1 = e1-dot_product(e1, e3)*e3
215 normv = dsqrt(dot_product(e1, e1))
216 if (normv < 1.0d-14)
then
217 if (dabs(e3(1)) < 0.9d0)
then
218 e1 = (/ 1.0d0, 0.0d0, 0.0d0 /)
220 e1 = (/ 0.0d0, 1.0d0, 0.0d0 /)
222 e1 = e1-dot_product(e1, e3)*e3
223 normv = dsqrt(dot_product(e1, e1))
226 e2(1) = e3(2)*e1(3)-e3(3)*e1(2)
227 e2(2) = e3(3)*e1(1)-e3(1)*e1(3)
228 e2(3) = e3(1)*e1(2)-e3(2)*e1(1)
236 real(kind=kreal),
intent(in) :: triad_old(3, 3), drill_old, theta_inc(3)
237 real(kind=kreal),
intent(out) :: triad_new(3, 3), drill_new
239 integer :: isub, nsub
240 real(kind=kreal) :: triad_base(3, 3)
241 real(kind=kreal) :: director(3), theta_step(3), theta_phys(3)
242 real(kind=kreal) :: drill_acc, drill_inc, theta_norm
243 real(kind=kreal) :: rot_inc(3, 3), rot_full(3, 3), triad_trial(3, 3)
246 theta_norm = dsqrt(dot_product(theta_inc, theta_inc))
247 nsub = max(1, ceiling(theta_norm/5.0d-2))
248 theta_step = theta_inc/dble(nsub)
249 drill_acc = drill_old
252 director = triad_base(:, 3)
253 drill_inc = dot_product(theta_step, director)
254 theta_phys = theta_step-drill_inc*director
256 triad_trial = matmul(rot_inc, triad_base)
258 drill_acc = drill_acc+drill_inc
262 triad_trial = triad_base
263 triad_trial(:, 3) = matmul(rot_full, triad_old(:, 3))
265 drill_new = drill_acc
269 integer(kind=kint),
intent(in) :: ndof, nn
270 real(kind=kreal),
intent(in) :: disp_old(:, :), disp_inc(:, :)
271 real(kind=kreal),
intent(out) :: disp_new(6, nn)
273 integer :: i, ndof_copy
276 ndof_copy = min(ndof, 6)
278 disp_new(1:min(3, ndof_copy), i) = disp_old(1:min(3, ndof_copy), i)+disp_inc(1:min(3, ndof_copy), i)
279 if (ndof_copy >= 6)
then
281 else if (ndof_copy > 3)
then
282 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.
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.